Files
zeekayandHanzo Dev 1ab6e799c1 cd: the module is github.com/hanzoai/cd, where it is actually hosted
go.mod still declared `module github.com/hanzoai/deploy` after the repo was
renamed. A Go module path is not cosmetic — it is the resolvable location. So
`go get github.com/hanzoai/cd` could not work, and anything importing this
module had to spell a name that no longer exists at that address. The build log
of v3.6.0 is where it surfaced: the compiler was still emitting
github.com/hanzoai/deploy/cmd/cd/commands.

3541 import paths across 690 .go, 19 .proto, 4 .yaml, 3 .sh, 2 .mod, Procfile
and Makefile. Plus the 62 ghcr.io/hanzoai/deploy image references, moved to
ghcr.io/hanzoai/cd to match hanzo.yml's build target — a distinct string from
the module path, replaced separately so neither could clobber the other.

go mod tidy clean, CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./... clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:16:24 -07:00

109 lines
2.9 KiB
Go

package plugin
import (
"errors"
"fmt"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/hanzoai/cd/common"
"github.com/hanzoai/cd/reposerver/apiclient"
configUtil "github.com/hanzoai/cd/util/config"
)
const (
ConfigManagementPluginKind string = "ConfigManagementPlugin"
)
type PluginConfig struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ObjectMeta `json:"metadata"`
Spec PluginConfigSpec `json:"spec"`
}
type PluginConfigSpec struct {
Version string `json:"version"`
Init Command `json:"init,omitempty"`
Generate Command `json:"generate"`
Discover Discover `json:"discover"`
Parameters Parameters `yaml:"parameters"`
PreserveFileMode bool `json:"preserveFileMode,omitempty"`
ProvideGitCreds bool `json:"provideGitCreds,omitempty"`
}
// Discover holds find and fileName
type Discover struct {
Find Find `json:"find"`
FileName string `json:"fileName"`
}
func (d Discover) IsDefined() bool {
return d.FileName != "" || d.Find.Glob != "" || len(d.Find.Command.Command) > 0
}
// Command holds binary path and arguments list
type Command struct {
Command []string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
}
// Find holds find command or glob pattern
type Find struct {
Command
Glob string `json:"glob"`
}
// Parameters holds static and dynamic configurations
type Parameters struct {
Static []*apiclient.ParameterAnnouncement `yaml:"static"`
Dynamic Command `yaml:"dynamic"`
}
// Dynamic hold the dynamic announcements for CMP's
type Dynamic struct {
Command
}
func ReadPluginConfig(filePath string) (*PluginConfig, error) {
path := fmt.Sprintf("%s/%s", strings.TrimRight(filePath, "/"), common.PluginConfigFileName)
var config PluginConfig
err := configUtil.UnmarshalLocalFile(path, &config)
if err != nil {
return nil, err
}
err = ValidatePluginConfig(config)
if err != nil {
return nil, err
}
return &config, nil
}
func ValidatePluginConfig(config PluginConfig) error {
if config.Metadata.Name == "" {
return errors.New("invalid plugin configuration file. metadata.name should be non-empty")
}
if config.Kind != ConfigManagementPluginKind {
return fmt.Errorf("invalid plugin configuration file. kind should be %s, found %s", ConfigManagementPluginKind, config.Kind)
}
if len(config.Spec.Generate.Command) == 0 {
return errors.New("invalid plugin configuration file. spec.generate command should be non-empty")
}
// discovery field is optional as apps can now specify plugin names directly
return nil
}
func (cfg *PluginConfig) Address() string {
var address string
pluginSockFilePath := common.GetPluginSockFilePath()
if cfg.Spec.Version != "" {
address = fmt.Sprintf("%s/%s-%s.sock", pluginSockFilePath, cfg.Metadata.Name, cfg.Spec.Version)
} else {
address = fmt.Sprintf("%s/%s.sock", pluginSockFilePath, cfg.Metadata.Name)
}
return address
}