diff --git a/pkg/apis/api.kusion.io/v1/types.go b/pkg/apis/api.kusion.io/v1/types.go index 498f192e..4a4b3539 100644 --- a/pkg/apis/api.kusion.io/v1/types.go +++ b/pkg/apis/api.kusion.io/v1/types.go @@ -1,5 +1,11 @@ package v1 +import ( + "time" + + "kusionstack.io/kusion/pkg/version" +) + // Project is a definition of Kusion project resource. // // A project is composed of one or more applications and is linked to a Git repository(monorepo or polyrepo), @@ -13,6 +19,8 @@ type Project struct { Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` // Path is a directory path within the Git repository. Path string `json:"path,omitempty" yaml:"path,omitempty"` + // The set of stacks that are known about this project. + Stacks []*Stack `json:"stacks,omitempty" yaml:"stacks,omitempty"` } // Stack is a definition of Kusion stack resource. @@ -30,6 +38,11 @@ type Stack struct { Path string `json:"path,omitempty" yaml:"path,omitempty"` } +const ( + DefaultBlock = "default" + ProjectSelectorField = "projectSelector" +) + // Workspace is a logical concept representing a target that stacks will be deployed to. // // Workspace is managed by platform engineers, which contains a set of configurations @@ -289,3 +302,49 @@ type Resource struct { // Extensions specifies arbitrary metadata of this resource Extensions map[string]interface{} `json:"extensions,omitempty" yaml:"extensions,omitempty"` } + +// State is a record of an operation's result. It is a mapping between resources in KCL and the actual infra +// resource and often used as a datasource for 3-way merge/diff in operations like Apply or Preview. +type State struct { + // State ID + ID int64 `json:"id" yaml:"id"` + + // Project name + Project string `json:"project" yaml:"project"` + + // Stack name + Stack string `json:"stack" yaml:"stack"` + + // Workspace name + Workspace string `json:"workspace" yaml:"workspace"` + + // State version + Version int `json:"version" yaml:"version"` + + // KusionVersion represents the Kusion's version when this State is created + KusionVersion string `json:"kusionVersion" yaml:"kusionVersion"` + + // Serial is an auto-increase number that represents how many times this State is modified + Serial uint64 `json:"serial" yaml:"serial"` + + // Operator represents the person who triggered this operation + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + + // Resources records all resources in this operation + Resources Resources `json:"resources" yaml:"resources"` + + // CreateTime is the time State is created + CreateTime time.Time `json:"createTime" yaml:"createTime"` + + // ModifiedTime is the time State is modified each time + ModifiedTime time.Time `json:"modifiedTime,omitempty" yaml:"modifiedTime,omitempty"` +} + +func NewState() *State { + s := &State{ + KusionVersion: version.ReleaseVersion(), + Version: 1, + Resources: []Resource{}, + } + return s +} diff --git a/pkg/apis/core/group.go b/pkg/apis/core/group.go deleted file mode 100644 index f4f30736..00000000 --- a/pkg/apis/core/group.go +++ /dev/null @@ -1,6 +0,0 @@ -package core - -const ( - Group = "api.kusionstack.io" - BuiltinModulePrefix = "kam." -) diff --git a/pkg/apis/core/v1/appconfiguration.go b/pkg/apis/core/v1/appconfiguration.go deleted file mode 100644 index 8ab8a21c..00000000 --- a/pkg/apis/core/v1/appconfiguration.go +++ /dev/null @@ -1,66 +0,0 @@ -package v1 - -import ( - "kusionstack.io/kusion/pkg/apis/core/v1/workload" -) - -type Accessory map[string]interface{} - -// AppConfiguration is a developer-centric definition that describes how to run an App. The application model is built on a decade -// of experience from AntGroup in operating a large-scale internal developer platform and combines the best ideas and practices from the -// community. -// -// Note: AppConfiguration per se is not a Kusion ModulePath -// -// Example: -// import kam.v1 as ac -// import kam.v1.workload as wl -// import kam.v1.workload.container as c -// import kam.v1.workload.container.probe as p -// import kam.v1.monitoring as m -// import kam.v1.database as d -// -// helloWorld: ac.AppConfiguration { -// # Built-in module -// workload: wl.Service { -// containers: { -// "main": c.Container { -// image: "ghcr.io/kusion-stack/samples/helloworld:latest" -// # Configure a HTTP readiness probe -// readinessProbe: p.Probe { -// probeHandler: p.Http { -// url: "http://localhost:80" -// } -// } -// } -// } -// } -// -// # a collection of accessories that will be attached to the workload -// accessories: { -// # Built-in module -// "my-database" : d.MySQL { -// type: "cloud" -// version: "8.0" -// } -// # Built-in module -// "my-prometheus" : m.Prometheus { -// path: "/metrics" -// } -// # Customized module -// "my-customize": customizedModule { -// ... -// } -// } -// } -type AppConfiguration struct { - // Name of the target App. - Name string `json:"name,omitempty" yaml:"name,omitempty"` - // Workload defines how to run your application code. - Workload *workload.Workload `json:"workload" yaml:"workload"` - // Accessories defines a collection of accessories that will be attached to the workload. - Accessories map[string]Accessory `json:"accessories,omitempty" yaml:"accessories,omitempty"` - // Labels and Annotations can be used to attach arbitrary metadata as key-value pairs to resources. - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` -} diff --git a/pkg/apis/core/v1/config.go b/pkg/apis/core/v1/config.go deleted file mode 100644 index 86a75a70..00000000 --- a/pkg/apis/core/v1/config.go +++ /dev/null @@ -1,200 +0,0 @@ -package v1 - -const ConfigBackends = "backends" - -// Config contains configurations for kusion cli, which stores in ${KUSION_HOME}/config.yaml. -type Config struct { - // Backends contains the configurations for multiple backends. - Backends *BackendConfigs `yaml:"backends,omitempty" json:"backends,omitempty"` -} - -const ( - DefaultBackendName = "default" - - BackendCurrent = "current" - BackendType = "type" - BackendConfigItems = "configs" - BackendLocalPath = "path" - BackendMysqlDBName = "dbName" - BackendMysqlUser = "user" - BackendMysqlPassword = "password" - BackendMysqlHost = "host" - BackendMysqlPort = "port" - BackendGenericOssEndpoint = "endpoint" - BackendGenericOssAK = "accessKeyID" - BackendGenericOssSK = "accessKeySecret" - BackendGenericOssBucket = "bucket" - BackendGenericOssPrefix = "prefix" - BackendS3Region = "region" - - BackendTypeLocal = "local" - BackendTypeMysql = "mysql" - BackendTypeOss = "oss" - BackendTypeS3 = "s3" - - EnvBackendMysqlPassword = "KUSION_BACKEND_MYSQL_PASSWORD" - EnvOssAccessKeyID = "OSS_ACCESS_KEY_ID" - EnvOssAccessKeySecret = "OSS_ACCESS_KEY_SECRET" - EnvAwsAccessKeyID = "AWS_ACCESS_KEY_ID" - EnvAwsSecretAccessKey = "AWS_SECRET_ACCESS_KEY" - EnvAwsDefaultRegion = "AWS_DEFAULT_REGION" - EnvAwsRegion = "AWS_REGION" - - DefaultMysqlPort = 3306 -) - -// BackendConfigs contains the configuration of multiple backends and the current backend. -type BackendConfigs struct { - // Current is the name of the current used backend. - Current string `yaml:"current,omitempty" json:"current,omitempty"` - - // Backends contains the types and configs of multiple backends, whose key is the backend name. - Backends map[string]*BackendConfig `yaml:",omitempty,inline" json:",omitempty,inline"` -} - -// BackendConfig contains the type and configs of a backend, which is used to store Spec, State and Workspace. -type BackendConfig struct { - // Type is the backend type, supports BackendTypeLocal, BackendTypeMysql, BackendTypeOss, BackendTypeS3. - Type string `yaml:"type,omitempty" json:"type,omitempty"` - - // Configs contains config items of the backend, whose keys differ from different backend types. - Configs map[string]any `yaml:"configs,omitempty" json:"configs,omitempty"` -} - -// BackendLocalConfig contains the config of using local file system as backend, which can be converted -// from BackendConfig if Type is BackendTypeLocal. -type BackendLocalConfig struct { - // Path of the directory to store the files. - Path string `yaml:"path,omitempty" json:"path,omitempty"` -} - -// BackendMysqlConfig contains the config of using mysql database as backend, which can be converted -// from BackendConfig if Type is BackendMysqlConfig. -type BackendMysqlConfig struct { - // DBName is the database name. - DBName string `yaml:"dbName" json:"dbName"` - - // User of the database. - User string `yaml:"user" json:"user"` - - // Password of the database. - Password string `yaml:"password,omitempty" json:"password,omitempty"` - - // Host of the database. - Host string `yaml:"host" json:"host"` - - // Port of the database. If not set, then it will be set to DeprecatedDefaultMysqlPort. - Port int `yaml:"port,omitempty" json:"port,omitempty"` -} - -// BackendOssConfig contains the config of using OSS as backend, which can be converted from BackendConfig -// if Type is BackendOssConfig. -type BackendOssConfig struct { - *GenericBackendObjectStorageConfig `yaml:",inline" json:",inline"` // OSS asks for non-empty endpoint -} - -// BackendS3Config contains the config of using S3 as backend, which can be converted from BackendConfig -// if Type is BackendS3Config. -type BackendS3Config struct { - *GenericBackendObjectStorageConfig `yaml:",inline" json:",inline"` - - // Region of S3. - Region string `yaml:"region,omitempty" json:"region,omitempty"` -} - -// GenericBackendObjectStorageConfig contains generic configs which can be reused by BackendOssConfig and -// BackendS3Config. -type GenericBackendObjectStorageConfig struct { - // Endpoint of the object storage service. - Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` - - // AccessKeyID of the object storage service. - AccessKeyID string `yaml:"accessKeyID,omitempty" json:"accessKeyID,omitempty"` - - // AccessKeySecret of the object storage service. - AccessKeySecret string `yaml:"accessKeySecret,omitempty" json:"accessKeySecret,omitempty"` - - // Bucket of the object storage service. - Bucket string `yaml:"bucket" json:"bucket"` - - // Prefix of the key to store the files. - Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"` -} - -// ToLocalBackend converts BackendConfig to structured BackendLocalConfig, works only when the Type -// is BackendTypeLocal, and the Configs are with correct type, or return nil. -func (b *BackendConfig) ToLocalBackend() *BackendLocalConfig { - if b.Type != BackendTypeLocal { - return nil - } - path, _ := b.Configs[BackendLocalPath].(string) - return &BackendLocalConfig{ - Path: path, - } -} - -// ToMysqlBackend converts BackendConfig to structured BackendMysqlConfig, works only when the Type -// is BackendTypeMysql, and the Configs are with correct type, or return nil. -func (b *BackendConfig) ToMysqlBackend() *BackendMysqlConfig { - if b.Type != BackendTypeMysql { - return nil - } - dbName, _ := b.Configs[BackendMysqlDBName].(string) - user, _ := b.Configs[BackendMysqlUser].(string) - password, _ := b.Configs[BackendMysqlPassword].(string) - host, _ := b.Configs[BackendMysqlHost].(string) - port, _ := b.Configs[BackendMysqlPort].(int) - return &BackendMysqlConfig{ - DBName: dbName, - User: user, - Password: password, - Host: host, - Port: port, - } -} - -// ToOssBackend converts BackendConfig to structured BackendOssConfig, works only when the Type is -// BackendTypeOss, and the Configs are with correct type, or return nil. -func (b *BackendConfig) ToOssBackend() *BackendOssConfig { - if b.Type != BackendTypeOss { - return nil - } - endpoint, _ := b.Configs[BackendGenericOssEndpoint].(string) - accessKeyID, _ := b.Configs[BackendGenericOssAK].(string) - accessKeySecret, _ := b.Configs[BackendGenericOssSK].(string) - bucket, _ := b.Configs[BackendGenericOssBucket].(string) - prefix, _ := b.Configs[BackendGenericOssPrefix].(string) - return &BackendOssConfig{ - &GenericBackendObjectStorageConfig{ - Endpoint: endpoint, - AccessKeyID: accessKeyID, - AccessKeySecret: accessKeySecret, - Bucket: bucket, - Prefix: prefix, - }, - } -} - -// ToS3Backend converts BackendConfig to structured BackendS3Config, works only when the Type is -// BackendTypeS3, and the Configs are with correct type, or return nil. -func (b *BackendConfig) ToS3Backend() *BackendS3Config { - if b.Type != BackendTypeS3 { - return nil - } - endpoint, _ := b.Configs[BackendGenericOssEndpoint].(string) - accessKeyID, _ := b.Configs[BackendGenericOssAK].(string) - accessKeySecret, _ := b.Configs[BackendGenericOssSK].(string) - bucket, _ := b.Configs[BackendGenericOssBucket].(string) - prefix, _ := b.Configs[BackendGenericOssPrefix].(string) - region, _ := b.Configs[BackendS3Region].(string) - return &BackendS3Config{ - GenericBackendObjectStorageConfig: &GenericBackendObjectStorageConfig{ - Endpoint: endpoint, - AccessKeyID: accessKeyID, - AccessKeySecret: accessKeySecret, - Bucket: bucket, - Prefix: prefix, - }, - Region: region, - } -} diff --git a/pkg/apis/core/v1/intent.go b/pkg/apis/core/v1/intent.go deleted file mode 100644 index e57abab2..00000000 --- a/pkg/apis/core/v1/intent.go +++ /dev/null @@ -1,25 +0,0 @@ -package v1 - -type Type string - -const ( - Kubernetes Type = "Kubernetes" - Terraform Type = "Terraform" -) - -const ( - // ResourceExtensionGVK is the key for resource extension, which is used to - // store the GVK of the resource. - ResourceExtensionGVK = "GVK" - // ResourceExtensionKubeConfig is the key for resource extension, which is used - // to indicate the path of kubeConfig for Kubernetes type resource. - ResourceExtensionKubeConfig = "kubeConfig" -) - -// Intent describes the desired state how the infrastructure should look like: which workload to run, -// the load-balancer setup, the location of the database schema, and so on. Based on that information, -// the Kusion engine takes care of updating the production state to match the Intent. -type Intent struct { - // Resources is the list of Resource this Intent contains. - Resources Resources `json:"resources" yaml:"resources"` -} diff --git a/pkg/apis/core/v1/patcher.go b/pkg/apis/core/v1/patcher.go deleted file mode 100644 index 1a03ff7d..00000000 --- a/pkg/apis/core/v1/patcher.go +++ /dev/null @@ -1,13 +0,0 @@ -package v1 - -import v1 "k8s.io/api/core/v1" - -// Patcher contains fields should be patched into the workload corresponding fields -type Patcher struct { - // Environments represent the environment variables patched to all containers in the workload. - Environments []v1.EnvVar `json:"environments" yaml:"environments"` - // Labels represent the labels patched to both the workload and pod. - Labels map[string]string `json:"labels" yaml:"labels"` - // Annotations represent the annotations patched to both the workload and pod. - Annotations map[string]string `json:"annotations" yaml:"annotations"` -} diff --git a/pkg/apis/core/v1/project.go b/pkg/apis/core/v1/project.go deleted file mode 100644 index 1a880ba3..00000000 --- a/pkg/apis/core/v1/project.go +++ /dev/null @@ -1,35 +0,0 @@ -package v1 - -type ( - BuilderType string -) - -const ( - KCLBuilder BuilderType = "KCL" - AppConfigurationBuilder BuilderType = "AppConfiguration" -) - -// GeneratorConfig holds the intent generation configurations defined in Project resource. -type GeneratorConfig struct { - // Type specifies the type of Generator. can be either "KCL" or "AppConfiguration". - Type BuilderType `json:"type" yaml:"type"` - // Configs contains extra configurations used by the Generator. - Configs map[string]interface{} `json:"configs,omitempty" yaml:"configs,omitempty"` -} - -// Project is a definition of Kusion Project resource. -// A project is composed of one or more applications and is linked to a Git repository, which contains the project's desired manifests. -type Project struct { - // Name is a required fully qualified name. - Name string `json:"name" yaml:"name"` - // Description is an optional informational description. - Description *string `json:"description,omitempty" yaml:"description,omitempty"` - // Labels is the list of labels that are assigned to this project. - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - // Path is a directory path within the Git repository. - Path string `json:"path,omitempty" yaml:"path,omitempty"` - // Generator controls how to generate the Intent. - Generator *GeneratorConfig `json:"generator,omitempty" yaml:"generator,omitempty"` - // The set of stacks that are known about this project. - Stacks []*Stack `json:"stacks,omitempty" yaml:"stacks,omitempty"` -} diff --git a/pkg/apis/core/v1/resource.go b/pkg/apis/core/v1/resource.go deleted file mode 100644 index a7582650..00000000 --- a/pkg/apis/core/v1/resource.go +++ /dev/null @@ -1,75 +0,0 @@ -package v1 - -import ( - "encoding/json" -) - -type Resources []Resource - -// Resource is the representation of a resource in the state. -type Resource struct { - // ID is the unique key of this resource in the whole State. - // ApiVersion:Kind:Namespace:Name is an idiomatic way for Kubernetes resources. - // providerNamespace:providerName:resourceType:resourceName for Terraform resources - ID string `json:"id" yaml:"id"` - - // Type represents all Runtimes we supported like Kubernetes and Terraform - Type Type `json:"type" yaml:"type"` - - // Attributes represents all specified attributes of this resource - Attributes map[string]interface{} `json:"attributes" yaml:"attributes"` - - // DependsOn contains all resources this resource depends on - DependsOn []string `json:"dependsOn,omitempty" yaml:"dependsOn,omitempty"` - - // Extensions specifies arbitrary metadata of this resource - Extensions map[string]interface{} `json:"extensions,omitempty" yaml:"extensions,omitempty"` -} - -func (r *Resource) ResourceKey() string { - return r.ID -} - -// DeepCopy return a copy of resource -func (r *Resource) DeepCopy() *Resource { - var out Resource - data, err := json.Marshal(r) - if err != nil { - panic(err) - } - _ = json.Unmarshal(data, &out) - return &out -} - -func (rs Resources) Index() map[string]*Resource { - m := make(map[string]*Resource) - for i := range rs { - m[rs[i].ResourceKey()] = &rs[i] - } - return m -} - -// GVKIndex returns a map of GVK to resources, for now, only Kubernetes resources. -func (rs Resources) GVKIndex() map[string][]*Resource { - m := make(map[string][]*Resource) - for i := range rs { - resource := &rs[i] - if resource.Type != Kubernetes { - continue - } - gvk := resource.Extensions[ResourceExtensionGVK].(string) - m[gvk] = append(m[gvk], resource) - } - return m -} - -func (rs Resources) Len() int { return len(rs) } -func (rs Resources) Swap(i, j int) { rs[i], rs[j] = rs[j], rs[i] } -func (rs Resources) Less(i, j int) bool { - switch { - case rs[i].ID != rs[j].ID: - return rs[i].ID < rs[j].ID - default: - return false - } -} diff --git a/pkg/apis/core/v1/stack.go b/pkg/apis/core/v1/stack.go deleted file mode 100644 index fa921974..00000000 --- a/pkg/apis/core/v1/stack.go +++ /dev/null @@ -1,17 +0,0 @@ -package v1 - -// Stack is a definition of Kusion Stack resource. -// -// Stack provides a mechanism to isolate multiple deploys of same application, -// it's the target workspace that an application will be deployed to, also the -// smallest operation unit that can be configured and deployed independently. -type Stack struct { - // Name is a required fully qualified name. - Name string `json:"name" yaml:"name"` - // Description is an optional informational description. - Description *string `json:"description,omitempty" yaml:"description,omitempty"` - // Labels is the list of labels that are assigned to this stack. - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - // Path is a directory path within the Git repository. - Path string `json:"path,omitempty" yaml:"path,omitempty"` -} diff --git a/pkg/apis/core/v1/state.go b/pkg/apis/core/v1/state.go deleted file mode 100644 index 2e8c0f78..00000000 --- a/pkg/apis/core/v1/state.go +++ /dev/null @@ -1,53 +0,0 @@ -package v1 - -import ( - "time" - - "kusionstack.io/kusion/pkg/version" -) - -// State is a record of an operation's result. It is a mapping between resources in KCL and the actual infra -// resource and often used as a datasource for 3-way merge/diff in operations like Apply or Preview. -type State struct { - // State ID - ID int64 `json:"id" yaml:"id"` - - // Project name - Project string `json:"project" yaml:"project"` - - // Stack name - Stack string `json:"stack" yaml:"stack"` - - // Workspace name - Workspace string `json:"workspace" yaml:"workspace"` - - // State version - Version int `json:"version" yaml:"version"` - - // KusionVersion represents the Kusion's version when this State is created - KusionVersion string `json:"kusionVersion" yaml:"kusionVersion"` - - // Serial is an auto-increase number that represents how many times this State is modified - Serial uint64 `json:"serial" yaml:"serial"` - - // Operator represents the person who triggered this operation - Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` - - // Resources records all resources in this operation - Resources Resources `json:"resources" yaml:"resources"` - - // CreateTime is the time State is created - CreateTime time.Time `json:"createTime" yaml:"createTime"` - - // ModifiedTime is the time State is modified each time - ModifiedTime time.Time `json:"modifiedTime,omitempty" yaml:"modifiedTime,omitempty"` -} - -func NewState() *State { - s := &State{ - KusionVersion: version.ReleaseVersion(), - Version: 1, - Resources: []Resource{}, - } - return s -} diff --git a/pkg/apis/core/v1/workload/common.go b/pkg/apis/core/v1/workload/common.go deleted file mode 100644 index 7b324efc..00000000 --- a/pkg/apis/core/v1/workload/common.go +++ /dev/null @@ -1,24 +0,0 @@ -package workload - -import "kusionstack.io/kusion/pkg/apis/core/v1/workload/container" - -const ( - FieldLabels = "labels" - FieldAnnotations = "annotations" -) - -// Base defines set of attributes shared by different workload profile, e.g. Service and Job. You can inherit this Schema to reuse these -// common attributes. -type Base struct { - // The templates of containers to be run. - Containers map[string]container.Container `yaml:"containers,omitempty" json:"containers,omitempty"` - // The number of containers that should be run. - Replicas *int32 `yaml:"replicas,omitempty" json:"replicas,omitempty"` - // Secret - Secrets map[string]Secret `json:"secrets,omitempty" yaml:"secrets,omitempty"` - // Dirs configures one or more volumes to be mounted to the specified folder. - Dirs map[string]string `json:"dirs,omitempty" yaml:"dirs,omitempty"` - // Labels and Annotations can be used to attach arbitrary metadata as key-value pairs to resources. - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` -} diff --git a/pkg/apis/core/v1/workload/container/container.go b/pkg/apis/core/v1/workload/container/container.go deleted file mode 100644 index 82ae908a..00000000 --- a/pkg/apis/core/v1/workload/container/container.go +++ /dev/null @@ -1,364 +0,0 @@ -package container - -import ( - "encoding/json" - "errors" - "fmt" - - "gopkg.in/yaml.v2" - - "kusionstack.io/kusion/pkg/apis/core" -) - -const ( - ProbePrefix = "v1.workload.container.probe." - TypeHTTP = core.BuiltinModulePrefix + ProbePrefix + "Http" - TypeExec = core.BuiltinModulePrefix + ProbePrefix + "Exec" - TypeTCP = core.BuiltinModulePrefix + ProbePrefix + "Tcp" -) - -// Container describes how the App's tasks are expected to be run. -type Container struct { - // Image to run for this container - Image string `yaml:"image" json:"image"` - // Entrypoint array. - // The image's ENTRYPOINT is used if this is not provided. - Command []string `yaml:"command,omitempty" json:"command,omitempty"` - // Arguments to the entrypoint. - // The image's CMD is used if this is not provided. - Args []string `yaml:"args,omitempty" json:"args,omitempty"` - // Collection of environment variables to set in the container. - // The value of environment variable may be static text or a value from a secret. - Env yaml.MapSlice `yaml:"env,omitempty" json:"env,omitempty"` - // The current working directory of the running process defined in entrypoint. - WorkingDir string `yaml:"workingDir,omitempty" json:"workingDir,omitempty"` - // Resource requirements for this container. - Resources map[string]string `yaml:"resources,omitempty" json:"resources,omitempty"` - // Files configures one or more files to be created in the container. - Files map[string]FileSpec `yaml:"files,omitempty" json:"files,omitempty"` - // Dirs configures one or more volumes to be mounted to the specified folder. - Dirs map[string]string `yaml:"dirs,omitempty" json:"dirs,omitempty"` - // Periodic probe of container liveness. - LivenessProbe *Probe `yaml:"livenessProbe,omitempty" json:"livenessProbe,omitempty"` - // Periodic probe of container service readiness. - ReadinessProbe *Probe `yaml:"readinessProbe,omitempty" json:"readinessProbe,omitempty"` - // StartupProbe indicates that the Pod has successfully initialized. - StartupProbe *Probe `yaml:"startupProbe,omitempty" json:"startupProbe,omitempty"` - // Actions that the management system should take in response to container lifecycle events. - Lifecycle *Lifecycle `yaml:"lifecycle,omitempty" json:"lifecycle,omitempty"` -} - -// FileSpec defines the target file in a Container -type FileSpec struct { - // The content of target file in plain text. - Content string `yaml:"content,omitempty" json:"content,omitempty"` - // Source for the file content, might be a reference to a secret value. - ContentFrom string `yaml:"contentFrom,omitempty" json:"contentFrom,omitempty"` - // Mode bits used to set permissions on this file. - Mode string `yaml:"mode" json:"mode"` -} - -// TypeWrapper is a thin wrapper to make YAML decoder happy. -type TypeWrapper struct { - // Type of action to be taken. - Type string `yaml:"_type" json:"_type"` -} - -// Probe describes a health check to be performed against a container to determine whether it is -// alive or ready to receive traffic. -type Probe struct { - // The action taken to determine the health of a container. - ProbeHandler *ProbeHandler `yaml:"probeHandler" json:"probeHandler"` - // Number of seconds after the container has started before liveness probes are initiated. - InitialDelaySeconds int32 `yaml:"initialDelaySeconds,omitempty" json:"initialDelaySeconds,omitempty"` - // Number of seconds after which the probe times out. - TimeoutSeconds int32 `yaml:"timeoutSeconds,omitempty" json:"timeoutSeconds,omitempty"` - // How often (in seconds) to perform the probe. - PeriodSeconds int32 `yaml:"periodSeconds,omitempty" json:"periodSeconds,omitempty"` - // Minimum consecutive successes for the probe to be considered successful after having failed. - SuccessThreshold int32 `yaml:"successThreshold,omitempty" json:"successThreshold,omitempty"` - // Minimum consecutive failures for the probe to be considered failed after having succeeded. - FailureThreshold int32 `yaml:"failureThreshold,omitempty" json:"failureThreshold,omitempty"` -} - -// ProbeHandler defines a specific action that should be taken in a probe. -// One and only one of the fields must be specified. -type ProbeHandler struct { - // Type of action to be taken. - TypeWrapper `yaml:"_type" json:"_type"` - // Exec specifies the action to take. - // +optional - *ExecAction `yaml:",inline" json:",inline"` - // HTTPGet specifies the http request to perform. - // +optional - *HTTPGetAction `yaml:",inline" json:",inline"` - // TCPSocket specifies an action involving a TCP port. - // +optional - *TCPSocketAction `yaml:",inline" json:",inline"` -} - -// ExecAction describes a "run in container" action. -type ExecAction struct { - // Command is the command line to execute inside the container, the working directory for the - // command is root ('/') in the container's filesystem. - // Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - Command []string `yaml:"command,omitempty" json:"command,omitempty"` -} - -// HTTPGetAction describes an action based on HTTP Get requests. -type HTTPGetAction struct { - // URL is the full qualified url location to send HTTP requests. - URL string `yaml:"url,omitempty" json:"url,omitempty"` - // Custom headers to set in the request. HTTP allows repeated headers. - Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"` -} - -// TCPSocketAction describes an action based on opening a socket. -type TCPSocketAction struct { - // URL is the full qualified url location to open a socket. - URL string `yaml:"url,omitempty" json:"url,omitempty"` -} - -// Lifecycle describes actions that the management system should take in response -// to container lifecycle events. -type Lifecycle struct { - // PreStop is called immediately before a container is terminated due to an - // API request or management event such as liveness/startup probe failure, - // preemption, resource contention, etc. - PreStop *LifecycleHandler `yaml:"preStop,omitempty" json:"preStop,omitempty"` - // PostStart is called immediately after a container is created. - PostStart *LifecycleHandler `yaml:"postStart,omitempty" json:"postStart,omitempty"` -} - -// LifecycleHandler defines a specific action that should be taken in a lifecycle -// hook. One and only one of the fields, except TCPSocket must be specified. -type LifecycleHandler struct { - // Type of action to be taken. - TypeWrapper `yaml:"_type" json:"_type"` - // Exec specifies the action to take. - // +optional - *ExecAction `yaml:",inline" json:",inline"` - // HTTPGet specifies the http request to perform. - // +optional - *HTTPGetAction `yaml:",inline" json:",inline"` -} - -// MarshalJSON implements the json.Marshaler interface for ProbeHandler. -func (p *ProbeHandler) MarshalJSON() ([]byte, error) { - switch p.Type { - case TypeHTTP: - return json.Marshal(struct { - TypeWrapper `json:",inline"` - *HTTPGetAction `json:",inline"` - }{ - TypeWrapper: TypeWrapper{p.Type}, - HTTPGetAction: p.HTTPGetAction, - }) - case TypeExec: - return json.Marshal(struct { - TypeWrapper `json:",inline"` - *ExecAction `json:",inline"` - }{ - TypeWrapper: TypeWrapper{p.Type}, - ExecAction: p.ExecAction, - }) - case TypeTCP: - return json.Marshal(struct { - TypeWrapper `json:",inline"` - *TCPSocketAction `json:",inline"` - }{ - TypeWrapper: TypeWrapper{p.Type}, - TCPSocketAction: p.TCPSocketAction, - }) - default: - return nil, fmt.Errorf("unrecognized probe handler type: %s", p.Type) - } -} - -// UnmarshalJSON implements the json.Unmarshaller interface for ProbeHandler. -func (p *ProbeHandler) UnmarshalJSON(data []byte) error { - var probeType TypeWrapper - err := json.Unmarshal(data, &probeType) - if err != nil { - return err - } - - p.Type = probeType.Type - switch p.Type { - case TypeHTTP: - handler := &HTTPGetAction{} - err = json.Unmarshal(data, handler) - p.HTTPGetAction = handler - case TypeExec: - handler := &ExecAction{} - err = json.Unmarshal(data, handler) - p.ExecAction = handler - case TypeTCP: - handler := &TCPSocketAction{} - err = json.Unmarshal(data, handler) - p.TCPSocketAction = handler - default: - return fmt.Errorf("unrecognized probe handler type: %s", p.Type) - } - - return err -} - -// MarshalYAML implements the yaml.Marshaler interface for ProbeHandler. -func (p *ProbeHandler) MarshalYAML() (interface{}, error) { - switch p.Type { - case TypeHTTP: - return struct { - TypeWrapper `yaml:",inline" json:",inline"` - HTTPGetAction `yaml:",inline" json:",inline"` - }{ - TypeWrapper: TypeWrapper{Type: p.Type}, - HTTPGetAction: *p.HTTPGetAction, - }, nil - case TypeExec: - return struct { - TypeWrapper `yaml:",inline" json:",inline"` - ExecAction `yaml:",inline" json:",inline"` - }{ - TypeWrapper: TypeWrapper{Type: p.Type}, - ExecAction: *p.ExecAction, - }, nil - case TypeTCP: - return struct { - TypeWrapper `yaml:",inline" json:",inline"` - TCPSocketAction `yaml:",inline" json:",inline"` - }{ - TypeWrapper: TypeWrapper{Type: p.Type}, - TCPSocketAction: *p.TCPSocketAction, - }, nil - } - - return nil, nil -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface for ProbeHandler. -func (p *ProbeHandler) UnmarshalYAML(unmarshal func(interface{}) error) error { - var probeType TypeWrapper - err := unmarshal(&probeType) - if err != nil { - return err - } - - p.Type = probeType.Type - switch p.Type { - case TypeHTTP: - handler := &HTTPGetAction{} - err = unmarshal(handler) - p.HTTPGetAction = handler - case TypeExec: - handler := &ExecAction{} - err = unmarshal(handler) - p.ExecAction = handler - case TypeTCP: - handler := &TCPSocketAction{} - err = unmarshal(handler) - p.TCPSocketAction = handler - default: - return fmt.Errorf("unrecognized probe handler type: %s", p.Type) - } - - return err -} - -// MarshalJSON implements the json.Marshaler interface for LifecycleHandler. -func (l *LifecycleHandler) MarshalJSON() ([]byte, error) { - switch l.Type { - case TypeHTTP: - return json.Marshal(struct { - TypeWrapper `json:",inline"` - *HTTPGetAction `json:",inline"` - }{ - TypeWrapper: TypeWrapper{l.Type}, - HTTPGetAction: l.HTTPGetAction, - }) - case TypeExec: - return json.Marshal(struct { - TypeWrapper `json:",inline"` - *ExecAction `json:",inline"` - }{ - TypeWrapper: TypeWrapper{l.Type}, - ExecAction: l.ExecAction, - }) - default: - return nil, errors.New("unrecognized lifecycle handler type") - } -} - -// UnmarshalJSON implements the json.Unmarshaller interface for LifecycleHandler. -func (l *LifecycleHandler) UnmarshalJSON(data []byte) error { - var handlerType TypeWrapper - err := json.Unmarshal(data, &handlerType) - if err != nil { - return err - } - - l.Type = handlerType.Type - switch l.Type { - case TypeHTTP: - handler := &HTTPGetAction{} - err = json.Unmarshal(data, handler) - l.HTTPGetAction = handler - case TypeExec: - handler := &ExecAction{} - err = json.Unmarshal(data, handler) - l.ExecAction = handler - default: - return errors.New("unrecognized lifecycle handler type") - } - - return err -} - -// MarshalYAML implements the yaml.Marshaler interface for LifecycleHandler. -func (l *LifecycleHandler) MarshalYAML() (interface{}, error) { - switch l.Type { - case TypeHTTP: - return struct { - TypeWrapper `yaml:",inline" json:",inline"` - HTTPGetAction `yaml:",inline" json:",inline"` - }{ - TypeWrapper: TypeWrapper{Type: l.Type}, - HTTPGetAction: *l.HTTPGetAction, - }, nil - case TypeExec: - return struct { - TypeWrapper `yaml:",inline" json:",inline"` - ExecAction `yaml:",inline" json:",inline"` - }{ - TypeWrapper: TypeWrapper{Type: l.Type}, - ExecAction: *l.ExecAction, - }, nil - default: - return nil, errors.New("unrecognized lifecycle handler type") - } -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface for LifecycleHandler. -func (l *LifecycleHandler) UnmarshalYAML(unmarshal func(interface{}) error) error { - var handlerType TypeWrapper - err := unmarshal(&handlerType) - if err != nil { - return err - } - - l.Type = handlerType.Type - switch l.Type { - case TypeHTTP: - handler := &HTTPGetAction{} - err = unmarshal(handler) - l.HTTPGetAction = handler - case TypeExec: - handler := &ExecAction{} - err = unmarshal(handler) - l.ExecAction = handler - default: - return errors.New("unrecognized lifecycle handler type") - } - - return err -} diff --git a/pkg/apis/core/v1/workload/container/container_test.go b/pkg/apis/core/v1/workload/container/container_test.go deleted file mode 100644 index 6c26f6c8..00000000 --- a/pkg/apis/core/v1/workload/container/container_test.go +++ /dev/null @@ -1,791 +0,0 @@ -package container - -import ( - "encoding/json" - "reflect" - "testing" - - "gopkg.in/yaml.v2" -) - -func TestContainerMarshalJSON(t *testing.T) { - cases := []struct { - input Container - result string - }{ - { - input: Container{ - Image: "nginx:v1", - Resources: map[string]string{ - "cpu": "4", - "memory": "8Gi", - }, - Files: map[string]FileSpec{ - "/tmp/test.txt": { - Content: "hello world", - Mode: "0644", - }, - }, - }, - result: `{"image":"nginx:v1","resources":{"cpu":"4","memory":"8Gi"},"files":{"/tmp/test.txt":{"content":"hello world","mode":"0644"}}}`, - }, - { - input: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"},"initialDelaySeconds":10}}`, - }, - { - input: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"cat", "/tmp/healthy"}, - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Exec","command":["cat","/tmp/healthy"]},"initialDelaySeconds":10}}`, - }, - { - input: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Tcp"}, - TCPSocketAction: &TCPSocketAction{ - URL: "127.0.0.1:8080", - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Tcp","url":"127.0.0.1:8080"},"initialDelaySeconds":10}}`, - }, - { - input: Container{ - Image: "nginx:v1", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"}, - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"}, - }, - }, - }, - }, - result: `{"image":"nginx:v1","lifecycle":{"preStop":{"_type":"kam.v1.workload.container.probe.Exec","command":["/bin/sh","-c","echo Hello from the postStart handler \u003e /usr/share/message"]},"postStart":{"_type":"kam.v1.workload.container.probe.Exec","command":["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]}}}`, - }, - { - input: Container{ - Image: "nginx:v1", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - }, - }, - result: `{"image":"nginx:v1","lifecycle":{"preStop":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"},"postStart":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"}}}`, - }, - } - - for _, c := range cases { - result, err := json.Marshal(&c.input) - if err != nil { - t.Errorf("Failed to marshal input: '%v': %v", c.input, err) - } - if string(result) != c.result { - t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", c.input, c.result, string(result)) - } - } -} - -func TestContainerUnmarshalJSON(t *testing.T) { - cases := []struct { - input string - result Container - }{ - { - input: `{"image":"nginx:v1","resources":{"cpu":"4","memory":"8Gi"},"files":{"/tmp/test.txt":{"content":"hello world","mode":"0644"}}}`, - result: Container{ - Image: "nginx:v1", - Resources: map[string]string{ - "cpu": "4", - "memory": "8Gi", - }, - Files: map[string]FileSpec{ - "/tmp/test.txt": { - Content: "hello world", - Mode: "0644", - }, - }, - }, - }, - { - input: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"},"initialDelaySeconds":10}}`, - result: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Exec","command":["cat","/tmp/healthy"]},"initialDelaySeconds":10}}`, - result: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"cat", "/tmp/healthy"}, - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `{"image":"nginx:v1","readinessProbe":{"probeHandler":{"_type":"kam.v1.workload.container.probe.Tcp","url":"127.0.0.1:8080"},"initialDelaySeconds":10}}`, - result: Container{ - Image: "nginx:v1", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Tcp"}, - TCPSocketAction: &TCPSocketAction{ - URL: "127.0.0.1:8080", - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `{"image":"nginx:v1","lifecycle":{"preStop":{"_type":"kam.v1.workload.container.probe.Exec","command":["/bin/sh","-c","echo Hello from the postStart handler \u003e /usr/share/message"]},"postStart":{"_type":"kam.v1.workload.container.probe.Exec","command":["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]}}}`, - result: Container{ - Image: "nginx:v1", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"}, - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"}, - }, - }, - }, - }, - }, - { - input: `{"image":"nginx:v1","lifecycle":{"preStop":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"},"postStart":{"_type":"kam.v1.workload.container.probe.Http","url":"http://localhost:80"}}}`, - result: Container{ - Image: "nginx:v1", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - }, - }, - }, - } - - for _, c := range cases { - var result Container - if err := json.Unmarshal([]byte(c.input), &result); err != nil { - t.Errorf("Failed to unmarshal input '%v': %v", c.input, err) - } - if !reflect.DeepEqual(result, c.result) { - t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result) - } - } -} - -func TestContainerMarshalYAML(t *testing.T) { - cases := []struct { - input Container - result string - }{ - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -`, - }, - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 - initialDelaySeconds: 10 -`, - }, - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"cat", "/tmp/healthy"}, - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Exec - command: - - cat - - /tmp/healthy - initialDelaySeconds: 10 -`, - }, - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Tcp"}, - TCPSocketAction: &TCPSocketAction{ - URL: "127.0.0.1:8080", - }, - }, - InitialDelaySeconds: 10, - }, - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Tcp - url: 127.0.0.1:8080 - initialDelaySeconds: 10 -`, - }, - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"}, - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"}, - }, - }, - }, - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -lifecycle: - preStop: - _type: kam.v1.workload.container.probe.Exec - command: - - /bin/sh - - -c - - echo Hello from the postStart handler > /usr/share/message - postStart: - _type: kam.v1.workload.container.probe.Exec - command: - - /bin/sh - - -c - - nginx -s quit; while killall -0 nginx; do sleep 1; done -`, - }, - { - input: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - }, - }, - result: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -lifecycle: - preStop: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 - postStart: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 -`, - }, - } - - for _, c := range cases { - result, err := yaml.Marshal(&c.input) - if err != nil { - t.Errorf("Failed to marshal input: '%v': %v", c.input, err) - } - if string(result) != c.result { - t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", c.input, c.result, string(result)) - } - } -} - -func TestContainerUnmarshalYAML(t *testing.T) { - cases := []struct { - input string - result Container - }{ - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - }, - }, - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 - initialDelaySeconds: 10 -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Exec - command: - - cat - - /tmp/healthy - initialDelaySeconds: 10 -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"cat", "/tmp/healthy"}, - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -readinessProbe: - probeHandler: - _type: kam.v1.workload.container.probe.Tcp - url: 127.0.0.1:8080 - initialDelaySeconds: 10 -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - ReadinessProbe: &Probe{ - ProbeHandler: &ProbeHandler{ - TypeWrapper: TypeWrapper{Type: "kam.v1.workload.container.probe.Tcp"}, - TCPSocketAction: &TCPSocketAction{ - URL: "127.0.0.1:8080", - }, - }, - InitialDelaySeconds: 10, - }, - }, - }, - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -lifecycle: - preStop: - _type: kam.v1.workload.container.probe.Exec - command: - - /bin/sh - - -c - - echo Hello from the postStart handler > /usr/share/message - postStart: - _type: kam.v1.workload.container.probe.Exec - command: - - /bin/sh - - -c - - nginx -s quit; while killall -0 nginx; do sleep 1; done -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"}, - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Exec"}, - ExecAction: &ExecAction{ - Command: []string{"/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"}, - }, - }, - }, - }, - }, - { - input: `image: nginx:v1 -command: -- /bin/sh -- -c -- echo hi -args: -- /bin/sh -- -c -- echo hi -env: - env1: VALUE -workingDir: /tmp -lifecycle: - preStop: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 - postStart: - _type: kam.v1.workload.container.probe.Http - url: http://localhost:80 -`, - result: Container{ - Image: "nginx:v1", - Command: []string{"/bin/sh", "-c", "echo hi"}, - Args: []string{"/bin/sh", "-c", "echo hi"}, - Env: yaml.MapSlice{ - { - Key: "env1", - Value: "VALUE", - }, - }, - WorkingDir: "/tmp", - Lifecycle: &Lifecycle{ - PostStart: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - PreStop: &LifecycleHandler{ - TypeWrapper: TypeWrapper{"kam.v1.workload.container.probe.Http"}, - HTTPGetAction: &HTTPGetAction{ - URL: "http://localhost:80", - }, - }, - }, - }, - }, - } - - for _, c := range cases { - var result Container - if err := yaml.Unmarshal([]byte(c.input), &result); err != nil { - t.Errorf("Failed to unmarshal input '%v': %v", c.input, err) - } - if !reflect.DeepEqual(result, c.result) { - t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result) - } - } -} diff --git a/pkg/apis/core/v1/workload/job.go b/pkg/apis/core/v1/workload/job.go deleted file mode 100644 index 252155d7..00000000 --- a/pkg/apis/core/v1/workload/job.go +++ /dev/null @@ -1,11 +0,0 @@ -package workload - -const ModuleJob = "job" - -// Job is a kind of workload profile that describes how to run your application code. This is typically used for tasks that take from -// a few seconds to a few days to complete. -type Job struct { - Base `yaml:",inline" json:",inline"` - // The scheduling strategy in Cron format: https://en.wikipedia.org/wiki/Cron. - Schedule string `yaml:"schedule,omitempty" json:"schedule,omitempty"` -} diff --git a/pkg/apis/core/v1/workload/network/port.go b/pkg/apis/core/v1/workload/network/port.go deleted file mode 100644 index 959fc4f8..00000000 --- a/pkg/apis/core/v1/workload/network/port.go +++ /dev/null @@ -1,18 +0,0 @@ -package network - -type Protocol string - -const ( - TCP Protocol = "TCP" - UDP Protocol = "UDP" -) - -// Port defines the exposed port of workload.Service -type Port struct { - // Port is the exposed port of the workload.Service. - Port int `yaml:"port,omitempty" json:"port,omitempty"` - // TargetPort is the backend container.Container port. - TargetPort int `yaml:"targetPort,omitempty" json:"targetPort,omitempty"` - // Protocol is protocol used to expose the port, support ProtocolTCP and ProtocolUDP. - Protocol Protocol `yaml:"protocol,omitempty" json:"protocol,omitempty"` -} diff --git a/pkg/apis/core/v1/workload/secret.go b/pkg/apis/core/v1/workload/secret.go deleted file mode 100644 index ab0eb506..00000000 --- a/pkg/apis/core/v1/workload/secret.go +++ /dev/null @@ -1,8 +0,0 @@ -package workload - -type Secret struct { - Type string `yaml:"type" json:"type"` - Params map[string]string `yaml:"params,omitempty" json:"params,omitempty"` - Data map[string]string `yaml:"data,omitempty" json:"data,omitempty"` - Immutable bool `yaml:"immutable,omitempty" json:"immutable,omitempty"` -} diff --git a/pkg/apis/core/v1/workload/service.go b/pkg/apis/core/v1/workload/service.go deleted file mode 100644 index 336fa4b4..00000000 --- a/pkg/apis/core/v1/workload/service.go +++ /dev/null @@ -1,25 +0,0 @@ -package workload - -import ( - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" -) - -type ServiceType string - -const ( - ModuleService = "service" - ModuleServiceType = "type" - Deployment ServiceType = "Deployment" - Collaset ServiceType = "CollaSet" -) - -// Service is a kind of workload profile that describes how to run your application code. -// This is typically used for long-running web applications that should "never" go down, and handle short-lived latency-sensitive -// web requests, or events. -type Service struct { - Base `yaml:",inline" json:",inline"` - // Type represents the type of workload.Service, support Deployment and CollaSet. - Type ServiceType `yaml:"type" json:"type"` - // Ports describe the list of ports need getting exposed. - Ports []network.Port `yaml:"ports,omitempty" json:"ports,omitempty"` -} diff --git a/pkg/apis/core/v1/workload/workload.go b/pkg/apis/core/v1/workload/workload.go deleted file mode 100644 index 74e0dc6b..00000000 --- a/pkg/apis/core/v1/workload/workload.go +++ /dev/null @@ -1,120 +0,0 @@ -package workload - -import ( - "encoding/json" - "fmt" - - "kusionstack.io/kusion/pkg/apis/core" -) - -type Type string - -const ( - TypeJob = core.BuiltinModulePrefix + "v1.workload.Job" - TypeService = core.BuiltinModulePrefix + "v1.workload.Service" - FieldReplicas = "replicas" -) - -type Header struct { - Type string `yaml:"_type" json:"_type"` -} - -type Workload struct { - Header `yaml:",inline" json:",inline"` - *Service `yaml:",inline" json:",inline"` - *Job `yaml:",inline" json:",inline"` -} - -func (w *Workload) MarshalJSON() ([]byte, error) { - switch w.Header.Type { - case TypeService: - return json.Marshal(struct { - Header `yaml:",inline" json:",inline"` - *Service `json:",inline"` - }{ - Header: Header{w.Header.Type}, - Service: w.Service, - }) - case TypeJob: - return json.Marshal(struct { - Header `yaml:",inline" json:",inline"` - *Job `json:",inline"` - }{ - Header: Header{w.Header.Type}, - Job: w.Job, - }) - default: - return nil, fmt.Errorf("unknown workload type: %s", w.Header.Type) - } -} - -func (w *Workload) UnmarshalJSON(data []byte) error { - var workloadData Header - err := json.Unmarshal(data, &workloadData) - if err != nil { - return err - } - - w.Header.Type = workloadData.Type - switch w.Header.Type { - case TypeJob: - var v Job - err = json.Unmarshal(data, &v) - w.Job = &v - case TypeService: - var v Service - err = json.Unmarshal(data, &v) - w.Service = &v - default: - err = fmt.Errorf("unknown workload type: %s", w.Header.Type) - } - - return err -} - -func (w *Workload) MarshalYAML() (interface{}, error) { - switch w.Header.Type { - case TypeService: - return struct { - Header `yaml:",inline" json:",inline"` - Service `yaml:",inline" json:",inline"` - }{ - Header: Header{w.Header.Type}, - Service: *w.Service, - }, nil - case TypeJob: - return struct { - Header `yaml:",inline" json:",inline"` - *Job `yaml:",inline" json:",inline"` - }{ - Header: Header{w.Header.Type}, - Job: w.Job, - }, nil - default: - return nil, fmt.Errorf("unknown workload type: %s", w.Header.Type) - } -} - -func (w *Workload) UnmarshalYAML(unmarshal func(interface{}) error) error { - var workloadData Header - err := unmarshal(&workloadData) - if err != nil { - return err - } - - w.Header.Type = workloadData.Type - switch w.Header.Type { - case TypeJob: - var v Job - err = unmarshal(&v) - w.Job = &v - case TypeService: - var v Service - err = unmarshal(&v) - w.Service = &v - default: - err = fmt.Errorf("unknown workload type: %s", w.Header.Type) - } - - return err -} diff --git a/pkg/apis/core/v1/workload/workload_test.go b/pkg/apis/core/v1/workload/workload_test.go deleted file mode 100644 index 28d49762..00000000 --- a/pkg/apis/core/v1/workload/workload_test.go +++ /dev/null @@ -1,313 +0,0 @@ -package workload - -import ( - "encoding/json" - "errors" - "testing" - - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" -) - -func TestWorkload_MarshalJSON(t *testing.T) { - r2 := int32(2) - tests := []struct { - name string - data *Workload - expected string - expectedError error - }{ - { - name: "Valid MarshalJSON for Service", - data: &Workload{ - Header: Header{ - Type: TypeService, - }, - Service: &Service{ - Type: "Deployment", - Base: Base{ - Replicas: &r2, - Labels: map[string]string{ - "app": "my-service", - }, - }, - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: `{"_type":"kam.v1.workload.Service", "replicas": 2, "labels": {"app": "my-service"}, "type": "Deployment"}`, - expectedError: nil, - }, - { - name: "Valid MarshalJSON for Job", - data: &Workload{ - Header: Header{ - Type: TypeJob, - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: `{"_type":"kam.v1.workload.Job", "schedule": "* * * * *"}`, - expectedError: nil, - }, - { - name: "Unknown _Type", - data: &Workload{ - Header: Header{ - Type: "Unknown", - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: "", - expectedError: errors.New("unknown workload type"), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - actual, actualErr := json.Marshal(test.data) - if test.expectedError == nil { - assert.JSONEq(t, test.expected, string(actual)) - assert.NoError(t, actualErr) - } else { - assert.ErrorContains(t, actualErr, test.expectedError.Error()) - } - }) - } -} - -func TestWorkload_UnmarshalJSON(t *testing.T) { - r1 := int32(1) - tests := []struct { - name string - data string - expected Workload - expectedError error - }{ - { - name: "Valid UnmarshalJSON for Service", - data: `{"_type":"kam.v1.workload.Service", "replicas": 1, "labels": {}, "annotations": {}, "dirs": {}, "schedule": "* * * * *"}`, - expected: Workload{ - Header: Header{ - Type: TypeService, - }, - Service: &Service{ - Base: Base{ - Replicas: &r1, - Labels: map[string]string{}, - Annotations: map[string]string{}, - Dirs: map[string]string{}, - }, - }, - }, - expectedError: nil, - }, - { - name: "Valid UnmarshalJSON for Job", - data: `{"_type":"kam.v1.workload.Job", "schedule": "* * * * *"}`, - expected: Workload{ - Header: Header{ - Type: TypeJob, - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expectedError: nil, - }, - { - name: "Unknown _Type", - data: `{"_type": "Unknown", "replicas": 1, "labels": {}, "annotations": {}, "dirs": {}, "schedule": "* * * * *"}`, - expected: Workload{ - Header: Header{ - Type: "Unknown", - }, - }, - expectedError: errors.New("unknown workload type"), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var actual Workload - actualErr := json.Unmarshal([]byte(test.data), &actual) - if test.expectedError == nil { - assert.Equal(t, test.expected, actual) - assert.NoError(t, actualErr) - } else { - assert.ErrorContains(t, actualErr, test.expectedError.Error()) - } - }) - } -} - -func TestWorkload_MarshalYAML(t *testing.T) { - r2 := int32(2) - tests := []struct { - name string - workload *Workload - expected string - expectedError error - }{ - { - name: "Valid MarshalYAML for Service", - workload: &Workload{ - Header: Header{ - Type: TypeService, - }, - Service: &Service{ - Type: "Deployment", - Base: Base{ - Replicas: &r2, - Labels: map[string]string{ - "app": "my-service", - }, - }, - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: `_type: kam.v1.workload.Service -replicas: 2 -labels: - app: my-service -type: Deployment`, - expectedError: nil, - }, - { - name: "Valid MarshalYAML for Job", - workload: &Workload{ - Header: Header{ - Type: TypeJob, - }, - Service: &Service{ - Type: "Deployment", - Base: Base{ - Replicas: &r2, - Labels: map[string]string{ - "app": "my-service", - }, - }, - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: `_type: kam.v1.workload.Job -schedule: '* * * * *'`, - expectedError: nil, - }, - { - name: "Unknown _Type", - workload: &Workload{ - Header: Header{ - Type: "Unknown", - }, - Job: &Job{ - Schedule: "* * * * *", - }, - }, - expected: "", - expectedError: errors.New("unknown workload type"), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - actual, actualErr := yaml.Marshal(test.workload) - if test.expectedError == nil { - assert.YAMLEq(t, test.expected, string(actual)) - assert.NoError(t, actualErr) - } else { - assert.ErrorContains(t, actualErr, test.expectedError.Error()) - } - }) - } -} - -func TestWorkload_UnmarshalYAML(t *testing.T) { - r1 := int32(1) - tests := []struct { - name string - data string - expected Workload - expectedError error - }{ - { - name: "Valid UnmarshalYAML for Service", - data: `_type: kam.v1.workload.Service -replicas: 1 -labels: {} -annotations: {} -dirs: {} -schedule: '* * * * *'`, - expected: Workload{ - Header: Header{ - Type: TypeService, - }, - Service: &Service{ - Base: Base{ - Replicas: &r1, - Labels: map[string]string{}, - Annotations: map[string]string{}, - Dirs: map[string]string{}, - }, - }, - }, - expectedError: nil, - }, - { - name: "Valid UnmarshalYAML for Job", - data: `_type: kam.v1.workload.Job -replicas: 1 -labels: {} -annotations: {} -dirs: {} -schedule: '* * * * *'`, - expected: Workload{ - Header: Header{ - Type: TypeJob, - }, - Job: &Job{ - Base: Base{ - Replicas: &r1, - Labels: map[string]string{}, - Annotations: map[string]string{}, - Dirs: map[string]string{}, - }, - Schedule: "* * * * *", - }, - }, - expectedError: nil, - }, - { - name: "Unknown _Type", - data: `_type: Unknown -replicas: 1 -labels: {} -annotations: {} -dirs: {} -schedule: '* * * * *'`, - expected: Workload{}, - expectedError: errors.New("unknown workload type"), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var actual Workload - actualErr := yaml.Unmarshal([]byte(test.data), &actual) - if test.expectedError == nil { - assert.Equal(t, test.expected, actual) - assert.NoError(t, actualErr) - } else { - assert.ErrorContains(t, actualErr, test.expectedError.Error()) - } - }) - } -} diff --git a/pkg/apis/core/v1/workspace.go b/pkg/apis/core/v1/workspace.go deleted file mode 100644 index f88d00bf..00000000 --- a/pkg/apis/core/v1/workspace.go +++ /dev/null @@ -1,219 +0,0 @@ -package v1 - -const ( - DefaultBlock = "default" - ProjectSelectorField = "projectSelector" -) - -// Workspace is a logical concept representing a target that stacks will be deployed to. -// -// Workspace is managed by platform engineers, which contains a set of configurations -// that application developers do not want or should not concern, and is reused by multiple -// stacks belonging to different projects. -type Workspace struct { - // Name identifies a Workspace uniquely. - Name string `yaml:"-" json:"-"` - - // Modules are the configs of a set of modules. - Modules ModuleConfigs `yaml:"modules,omitempty" json:"modules,omitempty"` - - // Runtimes are the configs of a set of runtimes. - Runtimes *RuntimeConfigs `yaml:"runtimes,omitempty" json:"runtimes,omitempty"` - - // SecretStore represents a secure external location for storing secrets. - SecretStore *SecretStoreSpec `yaml:"secretStore,omitempty" json:"secretStore,omitempty"` -} - -// ModuleConfigs is a set of multiple ModuleConfig, whose key is the module name. -type ModuleConfigs map[string]*ModuleConfig - -// ModuleConfig is the config of a module, which contains a default and several patcher blocks. -// -// The default block's key is "default", and value is the module inputs. The patcher blocks' keys -// are the patcher names, which are just block identifiers without specific meaning, but must -// not be "default". Besides module inputs, patcher block's value also contains a field named -// "projectSelector", whose value is a slice containing the project names that use the patcher -// configs. A project can only be assigned in a patcher's "projectSelector" field, the assignment -// in multiple patchers is not allowed. For a project, if not specified in the patcher block's -// "projectSelector" field, the default config will be used. -// -// Take the ModuleConfig of "database" for an example, which is shown as below: -// -// config := ModuleConfig { -// "default": { -// "type": "aws", -// "version": "5.7", -// "instanceType": "db.t3.micro", -// }, -// "smallClass": { -// "instanceType": "db.t3.small", -// "projectSelector": []string{"foo", "bar"}, -// }, -// } -type ModuleConfig struct { - // Default is default block of the module config. - Default GenericConfig `yaml:"default" json:"default"` - - // ModulePatcherConfigs are the patcher blocks of the module config. - ModulePatcherConfigs `yaml:",inline,omitempty" json:",inline,omitempty"` -} - -// ModulePatcherConfigs is a group of ModulePatcherConfig. -type ModulePatcherConfigs map[string]*ModulePatcherConfig - -// ModulePatcherConfig is a patcher block of the module config. -type ModulePatcherConfig struct { - // GenericConfig contains the module configs. - GenericConfig `yaml:",inline" json:",inline"` - - // ProjectSelector contains the selected projects. - ProjectSelector []string `yaml:"projectSelector" json:"projectSelector"` -} - -// RuntimeConfigs contains a set of runtime config. -type RuntimeConfigs struct { - // Kubernetes contains the config to access a kubernetes cluster. - Kubernetes *KubernetesConfig `yaml:"kubernetes,omitempty" json:"kubernetes,omitempty"` - - // Terraform contains the config of multiple terraform providers. - Terraform TerraformConfig `yaml:"terraform,omitempty" json:"terraform,omitempty"` -} - -// KubernetesConfig contains config to access a kubernetes cluster. -type KubernetesConfig struct { - // KubeConfig is the path of the kubeconfig file. - KubeConfig string `yaml:"kubeConfig" json:"kubeConfig"` -} - -// TerraformConfig contains the config of multiple terraform provider config, whose key is -// the provider name. -type TerraformConfig map[string]*ProviderConfig - -// ProviderConfig contains the full configurations of a specified provider. It is the combination -// of the specified provider's config in blocks "terraform/required_providers" and "providers" in -// terraform hcl file, where the former is described by fields Source and Version, and the latter -// is described by GenericConfig cause different provider has different config. -type ProviderConfig struct { - // Source of the provider. - Source string `yaml:"source" json:"source"` - - // Version of the provider. - Version string `yaml:"version" json:"version"` - - // GenericConfig is used to describe the config of a specified terraform provider. - GenericConfig `yaml:",inline,omitempty" json:",inline,omitempty"` -} - -// GenericConfig is a generic model to describe config which shields the difference among multiple concrete -// models. GenericConfig is designed for extensibility, used for module, terraform runtime config, etc. -type GenericConfig map[string]any - -type VaultKVStoreVersion string - -const ( - VaultKVStoreV1 VaultKVStoreVersion = "v1" - VaultKVStoreV2 VaultKVStoreVersion = "v2" -) - -// ExternalSecretRef contains information that points to the secret store data location. -type ExternalSecretRef struct { - // Specifies the name of the secret in Provider to read, mandatory. - Name string `yaml:"name" json:"name"` - - // Specifies the version of the secret to return, if supported. - Version string `yaml:"version,omitempty" json:"version,omitempty"` - - // Used to select a specific property of the secret data (if a map), if supported. - Property string `yaml:"property,omitempty" json:"property,omitempty"` -} - -// SecretStoreSpec contains configuration to describe target secret store. -type SecretStoreSpec struct { - Provider *ProviderSpec `yaml:"provider" json:"provider"` -} - -// ProviderSpec contains provider-specific configuration. -type ProviderSpec struct { - // Alicloud configures a store to retrieve secrets from Alicloud Secrets Manager. - Alicloud *AlicloudProvider `yaml:"alicloud,omitempty" json:"alicloud,omitempty"` - - // AWS configures a store to retrieve secrets from AWS Secrets Manager. - AWS *AWSProvider `yaml:"aws,omitempty" json:"aws,omitempty"` - - // Vault configures a store to retrieve secrets from HashiCorp Vault. - Vault *VaultProvider `yaml:"vault,omitempty" json:"vault,omitempty"` - - // Azure configures a store to retrieve secrets from Azure KeyVault. - Azure *AzureKVProvider `yaml:"azure,omitempty" json:"azure,omitempty"` - - // Fake configures a store with static key/value pairs - Fake *FakeProvider `yaml:"fake,omitempty" json:"fake,omitempty"` -} - -// AlicloudProvider configures a store to retrieve secrets from Alicloud Secrets Manager. -type AlicloudProvider struct { - // Alicloud Region to be used to interact with Alicloud Secrets Manager. - // Examples are cn-beijing, cn-shanghai, etc. - Region string `yaml:"region" json:"region"` -} - -// AWSProvider configures a store to retrieve secrets from AWS Secrets Manager. -type AWSProvider struct { - // AWS Region to be used to interact with AWS Secrets Manager. - // Examples are us-east-1, us-west-2, etc. - Region string `yaml:"region" json:"region"` - - // The profile to be used to interact with AWS Secrets Manager. - // If not set, the default profile created with `aws configure` will be used. - Profile string `yaml:"profile,omitempty" json:"profile,omitempty"` -} - -// VaultProvider configures a store to retrieve secrets from HashiCorp Vault. -type VaultProvider struct { - // Server is the target Vault server address to connect, e.g: "https://vault.example.com:8200". - Server string `yaml:"server" json:"server"` - - // Path is the mount path of the Vault KV backend endpoint, e.g: "secret". - Path *string `yaml:"path,omitempty" json:"path,omitempty"` - - // Version is the Vault KV secret engine version. Version can be either "v1" or - // "v2", defaults to "v2". - Version VaultKVStoreVersion `yaml:"version" json:"version"` -} - -// AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. -type AzureEnvironmentType string - -const ( - AzureEnvironmentPublicCloud AzureEnvironmentType = "PublicCloud" - AzureEnvironmentUSGovernmentCloud AzureEnvironmentType = "USGovernmentCloud" - AzureEnvironmentChinaCloud AzureEnvironmentType = "ChinaCloud" - AzureEnvironmentGermanCloud AzureEnvironmentType = "GermanCloud" -) - -// AzureKVProvider configures a store to retrieve secrets from Azure KeyVault -type AzureKVProvider struct { - // Vault Url from which the secrets to be fetched from. - VaultURL *string `yaml:"vaultUrl" json:"vaultUrl"` - - // TenantID configures the Azure Tenant to send requests to. - TenantID *string `yaml:"tenantId" json:"tenantId"` - - // EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. - // By-default it points to the public cloud AAD endpoint, and the following endpoints are available: - // PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud - // Ref: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 - EnvironmentType AzureEnvironmentType `yaml:"environmentType,omitempty" json:"environmentType,omitempty"` -} - -// FakeProvider configures a fake provider that returns static values. -type FakeProvider struct { - Data []FakeProviderData `json:"data"` -} - -type FakeProviderData struct { - Key string `json:"key"` - Value string `json:"value,omitempty"` - ValueMap map[string]string `json:"valueMap,omitempty"` - Version string `json:"version,omitempty"` -} diff --git a/pkg/apis/internal.kusion.io/v1/types.go b/pkg/apis/internal.kusion.io/v1/types.go index abd1b390..90fc553b 100644 --- a/pkg/apis/internal.kusion.io/v1/types.go +++ b/pkg/apis/internal.kusion.io/v1/types.go @@ -1,6 +1,9 @@ package v1 -import "gopkg.in/yaml.v2" +import ( + "gopkg.in/yaml.v2" + v1 "k8s.io/api/core/v1" +) // Container describes how the App's tasks are expected to be run. type Container struct { @@ -152,6 +155,12 @@ type Secret struct { Immutable bool `yaml:"immutable,omitempty" json:"immutable,omitempty"` } +const ( + FieldLabels = "labels" + FieldAnnotations = "annotations" + FieldReplicas = "replicas" +) + // Base defines set of attributes shared by different workload profile, e.g. Service and Job. type Base struct { // The templates of containers to be run. @@ -170,8 +179,10 @@ type Base struct { type ServiceType string const ( - Deployment ServiceType = "Deployment" - Collaset ServiceType = "CollaSet" + ModuleService = "service" + ModuleServiceType = "type" + Deployment ServiceType = "Deployment" + Collaset ServiceType = "CollaSet" ) // Service is a kind of workload profile that describes how to run your application code. @@ -185,6 +196,8 @@ type Service struct { Ports []Port `yaml:"ports,omitempty" json:"ports,omitempty"` } +const ModuleJob = "job" + // Job is a kind of workload profile that describes how to run your application code. This is typically used for tasks that take from // a few seconds to a few days to complete. type Job struct { @@ -280,8 +293,217 @@ type AppConfiguration struct { Workload *Workload `json:"workload" yaml:"workload"` // Accessories defines a collection of accessories that will be attached to the workload. // The key in this map represents the module source. e.g. kusionstack/mysql@v0.1 - Accessories map[string]*Accessory `json:"accessories,omitempty" yaml:"accessories,omitempty"` + Accessories map[string]Accessory `json:"accessories,omitempty" yaml:"accessories,omitempty"` // Labels and Annotations can be used to attach arbitrary metadata as key-value pairs to resources. Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` } + +// Patcher contains fields should be patched into the workload corresponding fields +type Patcher struct { + // Environments represent the environment variables patched to all containers in the workload. + Environments []v1.EnvVar `json:"environments" yaml:"environments"` + // Labels represent the labels patched to both the workload and pod. + Labels map[string]string `json:"labels" yaml:"labels"` + // Annotations represent the annotations patched to both the workload and pod. + Annotations map[string]string `json:"annotations" yaml:"annotations"` +} + +const ConfigBackends = "backends" + +// Config contains configurations for kusion cli, which stores in ${KUSION_HOME}/config.yaml. +type Config struct { + // Backends contains the configurations for multiple backends. + Backends *BackendConfigs `yaml:"backends,omitempty" json:"backends,omitempty"` +} + +const ( + DefaultBackendName = "default" + + BackendCurrent = "current" + BackendType = "type" + BackendConfigItems = "configs" + BackendLocalPath = "path" + BackendMysqlDBName = "dbName" + BackendMysqlUser = "user" + BackendMysqlPassword = "password" + BackendMysqlHost = "host" + BackendMysqlPort = "port" + BackendGenericOssEndpoint = "endpoint" + BackendGenericOssAK = "accessKeyID" + BackendGenericOssSK = "accessKeySecret" + BackendGenericOssBucket = "bucket" + BackendGenericOssPrefix = "prefix" + BackendS3Region = "region" + + BackendTypeLocal = "local" + BackendTypeMysql = "mysql" + BackendTypeOss = "oss" + BackendTypeS3 = "s3" + + EnvBackendMysqlPassword = "KUSION_BACKEND_MYSQL_PASSWORD" + EnvOssAccessKeyID = "OSS_ACCESS_KEY_ID" + EnvOssAccessKeySecret = "OSS_ACCESS_KEY_SECRET" + EnvAwsAccessKeyID = "AWS_ACCESS_KEY_ID" + EnvAwsSecretAccessKey = "AWS_SECRET_ACCESS_KEY" + EnvAwsDefaultRegion = "AWS_DEFAULT_REGION" + EnvAwsRegion = "AWS_REGION" + + DefaultMysqlPort = 3306 +) + +// BackendConfigs contains the configuration of multiple backends and the current backend. +type BackendConfigs struct { + // Current is the name of the current used backend. + Current string `yaml:"current,omitempty" json:"current,omitempty"` + + // Backends contains the types and configs of multiple backends, whose key is the backend name. + Backends map[string]*BackendConfig `yaml:",omitempty,inline" json:",omitempty,inline"` +} + +// BackendConfig contains the type and configs of a backend, which is used to store Spec, State and Workspace. +type BackendConfig struct { + // Type is the backend type, supports BackendTypeLocal, BackendTypeMysql, BackendTypeOss, BackendTypeS3. + Type string `yaml:"type,omitempty" json:"type,omitempty"` + + // Configs contains config items of the backend, whose keys differ from different backend types. + Configs map[string]any `yaml:"configs,omitempty" json:"configs,omitempty"` +} + +// BackendLocalConfig contains the config of using local file system as backend, which can be converted +// from BackendConfig if Type is BackendTypeLocal. +type BackendLocalConfig struct { + // Path of the directory to store the files. + Path string `yaml:"path,omitempty" json:"path,omitempty"` +} + +// BackendMysqlConfig contains the config of using mysql database as backend, which can be converted +// from BackendConfig if Type is BackendMysqlConfig. +type BackendMysqlConfig struct { + // DBName is the database name. + DBName string `yaml:"dbName" json:"dbName"` + + // User of the database. + User string `yaml:"user" json:"user"` + + // Password of the database. + Password string `yaml:"password,omitempty" json:"password,omitempty"` + + // Host of the database. + Host string `yaml:"host" json:"host"` + + // Port of the database. If not set, then it will be set to DeprecatedDefaultMysqlPort. + Port int `yaml:"port,omitempty" json:"port,omitempty"` +} + +// BackendOssConfig contains the config of using OSS as backend, which can be converted from BackendConfig +// if Type is BackendOssConfig. +type BackendOssConfig struct { + *GenericBackendObjectStorageConfig `yaml:",inline" json:",inline"` // OSS asks for non-empty endpoint +} + +// BackendS3Config contains the config of using S3 as backend, which can be converted from BackendConfig +// if Type is BackendS3Config. +type BackendS3Config struct { + *GenericBackendObjectStorageConfig `yaml:",inline" json:",inline"` + + // Region of S3. + Region string `yaml:"region,omitempty" json:"region,omitempty"` +} + +// GenericBackendObjectStorageConfig contains generic configs which can be reused by BackendOssConfig and +// BackendS3Config. +type GenericBackendObjectStorageConfig struct { + // Endpoint of the object storage service. + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + + // AccessKeyID of the object storage service. + AccessKeyID string `yaml:"accessKeyID,omitempty" json:"accessKeyID,omitempty"` + + // AccessKeySecret of the object storage service. + AccessKeySecret string `yaml:"accessKeySecret,omitempty" json:"accessKeySecret,omitempty"` + + // Bucket of the object storage service. + Bucket string `yaml:"bucket" json:"bucket"` + + // Prefix of the key to store the files. + Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"` +} + +// ToLocalBackend converts BackendConfig to structured BackendLocalConfig, works only when the Type +// is BackendTypeLocal, and the Configs are with correct type, or return nil. +func (b *BackendConfig) ToLocalBackend() *BackendLocalConfig { + if b.Type != BackendTypeLocal { + return nil + } + path, _ := b.Configs[BackendLocalPath].(string) + return &BackendLocalConfig{ + Path: path, + } +} + +// ToMysqlBackend converts BackendConfig to structured BackendMysqlConfig, works only when the Type +// is BackendTypeMysql, and the Configs are with correct type, or return nil. +func (b *BackendConfig) ToMysqlBackend() *BackendMysqlConfig { + if b.Type != BackendTypeMysql { + return nil + } + dbName, _ := b.Configs[BackendMysqlDBName].(string) + user, _ := b.Configs[BackendMysqlUser].(string) + password, _ := b.Configs[BackendMysqlPassword].(string) + host, _ := b.Configs[BackendMysqlHost].(string) + port, _ := b.Configs[BackendMysqlPort].(int) + return &BackendMysqlConfig{ + DBName: dbName, + User: user, + Password: password, + Host: host, + Port: port, + } +} + +// ToOssBackend converts BackendConfig to structured BackendOssConfig, works only when the Type is +// BackendTypeOss, and the Configs are with correct type, or return nil. +func (b *BackendConfig) ToOssBackend() *BackendOssConfig { + if b.Type != BackendTypeOss { + return nil + } + endpoint, _ := b.Configs[BackendGenericOssEndpoint].(string) + accessKeyID, _ := b.Configs[BackendGenericOssAK].(string) + accessKeySecret, _ := b.Configs[BackendGenericOssSK].(string) + bucket, _ := b.Configs[BackendGenericOssBucket].(string) + prefix, _ := b.Configs[BackendGenericOssPrefix].(string) + return &BackendOssConfig{ + &GenericBackendObjectStorageConfig{ + Endpoint: endpoint, + AccessKeyID: accessKeyID, + AccessKeySecret: accessKeySecret, + Bucket: bucket, + Prefix: prefix, + }, + } +} + +// ToS3Backend converts BackendConfig to structured BackendS3Config, works only when the Type is +// BackendTypeS3, and the Configs are with correct type, or return nil. +func (b *BackendConfig) ToS3Backend() *BackendS3Config { + if b.Type != BackendTypeS3 { + return nil + } + endpoint, _ := b.Configs[BackendGenericOssEndpoint].(string) + accessKeyID, _ := b.Configs[BackendGenericOssAK].(string) + accessKeySecret, _ := b.Configs[BackendGenericOssSK].(string) + bucket, _ := b.Configs[BackendGenericOssBucket].(string) + prefix, _ := b.Configs[BackendGenericOssPrefix].(string) + region, _ := b.Configs[BackendS3Region].(string) + return &BackendS3Config{ + GenericBackendObjectStorageConfig: &GenericBackendObjectStorageConfig{ + Endpoint: endpoint, + AccessKeyID: accessKeyID, + AccessKeySecret: accessKeySecret, + Bucket: bucket, + Prefix: prefix, + }, + Region: region, + } +} diff --git a/pkg/backend/backend.go b/pkg/backend/backend.go index cd2e044f..c311ce11 100644 --- a/pkg/backend/backend.go +++ b/pkg/backend/backend.go @@ -3,7 +3,7 @@ package backend import ( "fmt" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/backend/storages" "kusionstack.io/kusion/pkg/config" "kusionstack.io/kusion/pkg/engine/spec" diff --git a/pkg/backend/backend_test.go b/pkg/backend/backend_test.go index 37ec1899..3bba047d 100644 --- a/pkg/backend/backend_test.go +++ b/pkg/backend/backend_test.go @@ -8,7 +8,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/backend/storages" "kusionstack.io/kusion/pkg/config" ) diff --git a/pkg/backend/storages/completion.go b/pkg/backend/storages/completion.go index 2a03ea85..64a69129 100644 --- a/pkg/backend/storages/completion.go +++ b/pkg/backend/storages/completion.go @@ -3,7 +3,7 @@ package storages import ( "os" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/util/kfile" ) diff --git a/pkg/backend/storages/completion_test.go b/pkg/backend/storages/completion_test.go index 74b13941..9eb9ac8a 100644 --- a/pkg/backend/storages/completion_test.go +++ b/pkg/backend/storages/completion_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/util/kfile" ) diff --git a/pkg/backend/storages/local.go b/pkg/backend/storages/local.go index 392d2587..231acdfc 100644 --- a/pkg/backend/storages/local.go +++ b/pkg/backend/storages/local.go @@ -1,7 +1,7 @@ package storages import ( - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" specstorages "kusionstack.io/kusion/pkg/engine/spec/storages" "kusionstack.io/kusion/pkg/engine/state" diff --git a/pkg/backend/storages/local_test.go b/pkg/backend/storages/local_test.go index b81bf749..e77bb054 100644 --- a/pkg/backend/storages/local_test.go +++ b/pkg/backend/storages/local_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/state" statestorages "kusionstack.io/kusion/pkg/engine/state/storages" "kusionstack.io/kusion/pkg/workspace" diff --git a/pkg/backend/storages/mysql.go b/pkg/backend/storages/mysql.go index be96cf9b..c2d9aa5e 100644 --- a/pkg/backend/storages/mysql.go +++ b/pkg/backend/storages/mysql.go @@ -7,7 +7,7 @@ import ( "gorm.io/driver/mysql" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" "kusionstack.io/kusion/pkg/engine/state" statestorages "kusionstack.io/kusion/pkg/engine/state/storages" diff --git a/pkg/backend/storages/mysql_test.go b/pkg/backend/storages/mysql_test.go index 63e6c14f..5cc25c78 100644 --- a/pkg/backend/storages/mysql_test.go +++ b/pkg/backend/storages/mysql_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/state" statestorages "kusionstack.io/kusion/pkg/engine/state/storages" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/backend/storages/oss.go b/pkg/backend/storages/oss.go index 7ad294c3..8c7b0945 100644 --- a/pkg/backend/storages/oss.go +++ b/pkg/backend/storages/oss.go @@ -3,7 +3,7 @@ package storages import ( "github.com/aliyun/aliyun-oss-go-sdk/oss" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" specstorages "kusionstack.io/kusion/pkg/engine/spec/storages" "kusionstack.io/kusion/pkg/engine/state" diff --git a/pkg/backend/storages/oss_test.go b/pkg/backend/storages/oss_test.go index 15d919f9..dcda949a 100644 --- a/pkg/backend/storages/oss_test.go +++ b/pkg/backend/storages/oss_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/state" statestorages "kusionstack.io/kusion/pkg/engine/state/storages" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/backend/storages/s3.go b/pkg/backend/storages/s3.go index 7a38308f..d519fe0e 100644 --- a/pkg/backend/storages/s3.go +++ b/pkg/backend/storages/s3.go @@ -6,7 +6,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" specstoraages "kusionstack.io/kusion/pkg/engine/spec/storages" "kusionstack.io/kusion/pkg/engine/state" diff --git a/pkg/backend/storages/s3_test.go b/pkg/backend/storages/s3_test.go index 93602381..6e73445c 100644 --- a/pkg/backend/storages/s3_test.go +++ b/pkg/backend/storages/s3_test.go @@ -8,7 +8,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/state" statestorages "kusionstack.io/kusion/pkg/engine/state/storages" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/backend/storages/validation.go b/pkg/backend/storages/validation.go index 7a0bd456..40abd275 100644 --- a/pkg/backend/storages/validation.go +++ b/pkg/backend/storages/validation.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) var ( diff --git a/pkg/backend/storages/validation_test.go b/pkg/backend/storages/validation_test.go index 53ee9a6d..e0080729 100644 --- a/pkg/backend/storages/validation_test.go +++ b/pkg/backend/storages/validation_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) func TestValidateMysqlConfig(t *testing.T) { diff --git a/pkg/cmd/apply/options.go b/pkg/cmd/apply/options.go index 0195fb91..8ef60f45 100644 --- a/pkg/cmd/apply/options.go +++ b/pkg/cmd/apply/options.go @@ -10,7 +10,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pterm/pterm" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/generate" @@ -77,26 +77,26 @@ func (o *Options) Run() error { return err } - // Generate Intent - var intent *apiv1.Intent + // Generate Spec + var spec *apiv1.Spec if len(o.IntentFile) != 0 { - intent, err = generate.IntentFromFile(o.IntentFile) + spec, err = generate.SpecFromFile(o.IntentFile) } else { - intent, err = generate.GenerateIntentWithSpinner(currentProject, currentStack, currentWorkspace, true) + spec, err = generate.GenerateSpecWithSpinner(currentProject, currentStack, currentWorkspace, true) } if err != nil { return err } // return immediately if no resource found in stack - if intent == nil || len(intent.Resources) == 0 { + if spec == nil || len(spec.Resources) == 0 { fmt.Println(pretty.GreenBold("\nNo resource found in this stack.")) return nil } // compute changes for preview storage := bk.StateStorage(currentProject.Name, currentStack.Name, currentWorkspace.Name) - changes, err := preview.Preview(&o.Options, storage, intent, currentProject, currentStack) + changes, err := preview.Preview(&o.Options, storage, spec, currentProject, currentStack) if err != nil { return err } @@ -140,7 +140,7 @@ func (o *Options) Run() error { } fmt.Println("Start applying diffs ...") - if err = Apply(o, storage, intent, changes, os.Stdout); err != nil { + if err = Apply(o, storage, spec, changes, os.Stdout); err != nil { return err } @@ -152,7 +152,7 @@ func (o *Options) Run() error { if o.Watch { fmt.Println("\nStart watching changes ...") - if err = Watch(o, intent, changes); err != nil { + if err = Watch(o, spec, changes); err != nil { return err } } @@ -185,7 +185,7 @@ func (o *Options) Run() error { func Apply( o *Options, storage state.Storage, - planResources *apiv1.Intent, + planResources *apiv1.Spec, changes *models.Changes, out io.Writer, ) error { @@ -319,7 +319,7 @@ func Apply( // } func Watch( o *Options, - planResources *apiv1.Intent, + planResources *apiv1.Spec, changes *models.Changes, ) error { if o.DryRun { @@ -341,7 +341,7 @@ func Watch( Request: models.Request{ Project: changes.Project(), Stack: changes.Stack(), - Intent: &apiv1.Intent{Resources: toBeWatched}, + Intent: &apiv1.Spec{Resources: toBeWatched}, }, }); err != nil { return err diff --git a/pkg/cmd/apply/options_test.go b/pkg/cmd/apply/options_test.go index c5c300cd..5c3a08ce 100644 --- a/pkg/cmd/apply/options_test.go +++ b/pkg/cmd/apply/options_test.go @@ -12,7 +12,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/backend/storages" @@ -30,7 +30,7 @@ import ( func TestApplyOptions_Run(t *testing.T) { mockey.PatchConvey("Detail is true", t, func() { mockPatchDetectProjectAndStack() - mockGenerateIntentWithSpinner() + mockGenerateSpecWithSpinner() mockPatchNewKubernetesRuntime() mockNewBackend() mockWorkspaceStorage() @@ -46,7 +46,7 @@ func TestApplyOptions_Run(t *testing.T) { mockey.PatchConvey("DryRun is true", t, func() { mockPatchDetectProjectAndStack() - mockGenerateIntentWithSpinner() + mockGenerateSpecWithSpinner() mockPatchNewKubernetesRuntime() mockNewBackend() mockWorkspaceStorage() @@ -78,14 +78,14 @@ func mockPatchDetectProjectAndStack() *mockey.Mocker { }).Build() } -func mockGenerateIntentWithSpinner() { - mockey.Mock(generate.GenerateIntentWithSpinner).To(func( +func mockGenerateSpecWithSpinner() { + mockey.Mock(generate.GenerateSpecWithSpinner).To(func( project *apiv1.Project, stack *apiv1.Stack, workspace *apiv1.Workspace, noStyle bool, - ) (*apiv1.Intent, error) { - return &apiv1.Intent{Resources: []apiv1.Resource{sa1, sa2, sa3}}, nil + ) (*apiv1.Spec, error) { + return &apiv1.Spec{Resources: []apiv1.Resource{sa1, sa2, sa3}}, nil }).Build() } @@ -200,7 +200,7 @@ func newSA(name string) apiv1.Resource { func Test_apply(t *testing.T) { stateStorage := statestorages.NewLocalStorage(filepath.Join("", "state.yaml")) mockey.PatchConvey("dry run", t, func() { - planResources := &apiv1.Intent{Resources: []apiv1.Resource{sa1}} + planResources := &apiv1.Spec{Resources: []apiv1.Resource{sa1}} order := &models.ChangeOrder{ StepKeys: []string{sa1.ID}, ChangeSteps: map[string]*models.ChangeStep{ @@ -220,7 +220,7 @@ func Test_apply(t *testing.T) { mockey.PatchConvey("apply success", t, func() { mockOperationApply(models.Success) o := NewApplyOptions() - planResources := &apiv1.Intent{Resources: []apiv1.Resource{sa1, sa2}} + planResources := &apiv1.Spec{Resources: []apiv1.Resource{sa1, sa2}} order := &models.ChangeOrder{ StepKeys: []string{sa1.ID, sa2.ID}, ChangeSteps: map[string]*models.ChangeStep{ @@ -245,7 +245,7 @@ func Test_apply(t *testing.T) { mockOperationApply(models.Failed) o := NewApplyOptions() - planResources := &apiv1.Intent{Resources: []apiv1.Resource{sa1}} + planResources := &apiv1.Spec{Resources: []apiv1.Resource{sa1}} order := &models.ChangeOrder{ StepKeys: []string{sa1.ID}, ChangeSteps: map[string]*models.ChangeStep{ diff --git a/pkg/cmd/build/builders/appconfig_builder.go b/pkg/cmd/build/builders/appconfig_builder.go index bd990477..e00ad392 100644 --- a/pkg/cmd/build/builders/appconfig_builder.go +++ b/pkg/cmd/build/builders/appconfig_builder.go @@ -5,23 +5,24 @@ import ( "kcl-lang.io/kpm/pkg/api" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/generators" ) type AppsConfigBuilder struct { - Apps map[string]v1.AppConfiguration + Apps map[string]internalv1.AppConfiguration Workspace *v1.Workspace } -func (acg *AppsConfigBuilder) Build(kclPackage *api.KclPackage, project *v1.Project, stack *v1.Stack) (*v1.Intent, error) { - i := &v1.Intent{ +func (acg *AppsConfigBuilder) Build(kclPackage *api.KclPackage, project *v1.Project, stack *v1.Stack) (*v1.Spec, error) { + i := &v1.Spec{ Resources: []v1.Resource{}, } var gfs []modules.NewGeneratorFunc - err := modules.ForeachOrdered(acg.Apps, func(appName string, app v1.AppConfiguration) error { + err := modules.ForeachOrdered(acg.Apps, func(appName string, app internalv1.AppConfiguration) error { if kclPackage == nil { return fmt.Errorf("kcl package is nil when generating app configuration for %s", appName) } diff --git a/pkg/cmd/build/builders/appconfig_builder_test.go b/pkg/cmd/build/builders/appconfig_builder_test.go index 6dcb01e3..97734030 100644 --- a/pkg/cmd/build/builders/appconfig_builder_test.go +++ b/pkg/cmd/build/builders/appconfig_builder_test.go @@ -8,18 +8,16 @@ import ( "kcl-lang.io/kpm/pkg/api" pkg "kcl-lang.io/kpm/pkg/package" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" - - "kusionstack.io/kusion/pkg/apis/core/v1/workload" ) func TestAppsConfigBuilder_Build(t *testing.T) { p, s := buildMockProjectAndStack() appName, app := buildMockApp() acg := &AppsConfigBuilder{ - Apps: map[string]v1.AppConfiguration{ + Apps: map[string]internalv1.AppConfiguration{ appName: *app, }, Workspace: buildMockWorkspace(), @@ -39,16 +37,16 @@ func TestAppsConfigBuilder_Build(t *testing.T) { assert.NotNil(t, intent) } -func buildMockApp() (string, *v1.AppConfiguration) { - return "app1", &v1.AppConfiguration{ - Workload: &workload.Workload{ - Header: workload.Header{ +func buildMockApp() (string, *internalv1.AppConfiguration) { + return "app1", &internalv1.AppConfiguration{ + Workload: &internalv1.Workload{ + Header: internalv1.Header{ Type: "Service", }, - Service: &workload.Service{ - Base: workload.Base{}, + Service: &internalv1.Service{ + Base: internalv1.Base{}, Type: "Deployment", - Ports: []network.Port{ + Ports: []internalv1.Port{ { Port: 80, Protocol: "TCP", diff --git a/pkg/cmd/build/builders/builder.go b/pkg/cmd/build/builders/builder.go deleted file mode 100644 index a12f3cbd..00000000 --- a/pkg/cmd/build/builders/builder.go +++ /dev/null @@ -1,34 +0,0 @@ -package builders - -import ( - "kcl-lang.io/kpm/pkg/api" - - v1 "kusionstack.io/kusion/pkg/apis/core/v1" -) - -// Builder represents a method to build an Intent. Typically, it is implemented by the AppConfigureBuilder, -// but we have designed it as an interface to allow for more general usage. Any struct that implements this interface -// is considered a Builder and can be integrated into the Kusion workflow. -type Builder interface { - Build(kclPackage *api.KclPackage, project *v1.Project, stack *v1.Stack) (*v1.Intent, error) -} - -type Options struct { - // KclPkg represents the kcl package information. If it is nil, it means this workdir is not a kcl package - KclPkg *api.KclPackage - - // WorkDir represent the filesystem path where the operation is invoked - WorkDir string - - // Filenames represent all file names included in this operation - Filenames []string - - // Settings are setting args stored in the setting.yaml - Settings []string - - // Arguments are args used for a specified Builder. All Builder related args should be passed through this field - Arguments map[string]string - - // NoStyle represents whether to turn on the spinner output style - NoStyle bool -} diff --git a/pkg/cmd/build/builders/crd/crd.go b/pkg/cmd/build/builders/crd/crd.go deleted file mode 100644 index c960dc61..00000000 --- a/pkg/cmd/build/builders/crd/crd.go +++ /dev/null @@ -1,76 +0,0 @@ -package crd - -import ( - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "k8s.io/apimachinery/pkg/util/yaml" -) - -const ( - Directory = "crd" -) - -var FileExtensions = []string{".yaml", ".yml", ".json"} - -type crdVisitor struct { - Path string -} - -func NewVisitor(path string) Visitor { - return &crdVisitor{Path: path} -} - -// Visit read all YAML files under target path -func (v *crdVisitor) Visit() (objs []interface{}, err error) { - err = filepath.WalkDir(v.Path, func(filePath string, d os.DirEntry, err error) error { - if err != nil { - return err - } - - // check file extension - // todo dayuan validate yaml content to make sure it is a k8s CRD resource - - if ignoreFile(filePath, FileExtensions) { - return nil - } - - f, err := os.Open(filePath) - if err != nil { - return err - } - decoder := yaml.NewYAMLOrJSONDecoder(f, 4096) - for { - data := make(map[string]interface{}) - if err := decoder.Decode(&data); err != nil { - if err == io.EOF { - return nil - } - return fmt.Errorf("error parsing %s: %v", filePath, err) - } - if len(data) == 0 { - continue - } - - objs = append(objs, data) - } - }) - return objs, err -} - -// ignoreFile indicates a filename is ended with specified extension or not -func ignoreFile(path string, extensions []string) bool { - if len(extensions) == 0 { - return false - } - ext := filepath.Ext(path) - for _, s := range extensions { - if strings.EqualFold(s, ext) { - return false - } - } - return true -} diff --git a/pkg/cmd/build/builders/crd/crd_test.go b/pkg/cmd/build/builders/crd/crd_test.go deleted file mode 100644 index 85e87d40..00000000 --- a/pkg/cmd/build/builders/crd/crd_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package crd - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCrdVisitor(t *testing.T) { - t.Run("read single file", func(t *testing.T) { - visitor := crdVisitor{ - Path: "./testdata/one.yaml", - } - objs, err := visitor.Visit() - assert.Nil(t, err) - assert.Equal(t, 1, len(objs)) - }) - - t.Run("read multi files", func(t *testing.T) { - visitor := crdVisitor{ - Path: "./testdata", - } - objs, err := visitor.Visit() - assert.Nil(t, err) - assert.Equal(t, 3, len(objs)) - }) -} - -func Test_ignoreFile(t *testing.T) { - t.Run("not ignore .YAML file", func(t *testing.T) { - flag := ignoreFile("foo.YAML", FileExtensions) - assert.False(t, flag) - }) - - t.Run("not ignore .yaml file", func(t *testing.T) { - flag := ignoreFile("foo.yaml", FileExtensions) - assert.False(t, flag) - }) - - t.Run("not ignore .yml file", func(t *testing.T) { - flag := ignoreFile("foo.yml", FileExtensions) - assert.False(t, flag) - }) - - t.Run("ignore .go file", func(t *testing.T) { - flag := ignoreFile("bar.go", FileExtensions) - assert.True(t, flag) - }) -} diff --git a/pkg/cmd/build/builders/crd/testdata/multi.yaml b/pkg/cmd/build/builders/crd/testdata/multi.yaml deleted file mode 100644 index 3c82dfbb..00000000 --- a/pkg/cmd/build/builders/crd/testdata/multi.yaml +++ /dev/null @@ -1,66 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: foos.samplecontroller.k8s.io - # for more information on the below annotation, please see - # https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/2337-k8s.io-group-protection/README.md - annotations: - "api-approved.kubernetes.io": "unapproved, experimental-only; please get an approval from Kubernetes API reviewers if you're trying to develop a CRD in the *.k8s.io or *.kubernetes.io groups" -spec: - group: samplecontroller.k8s.io - versions: - - name: v1alpha1 - served: true - storage: true - schema: - # schema used for validation - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - deploymentName: - type: string - replicas: - type: integer - minimum: 1 - maximum: 10 - status: - type: object - properties: - availableReplicas: - type: integer - names: - kind: Foo - plural: foos - scope: Namespaced ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: guestbooks.apps.ibm.com -spec: - group: apps.ibm.com - versions: - - name: v1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - guestbookTitle: - type: string - guestbookSubtitle: - type: string - scope: Namespaced - names: - plural: guestbooks - singular: guestbook - kind: Guestbook - shortNames: - - gb diff --git a/pkg/cmd/build/builders/crd/testdata/one.yaml b/pkg/cmd/build/builders/crd/testdata/one.yaml deleted file mode 100644 index 8ac6e60c..00000000 --- a/pkg/cmd/build/builders/crd/testdata/one.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: foos.samplecontroller.k8s.io - # for more information on the below annotation, please see - # https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/2337-k8s.io-group-protection/README.md - annotations: - "api-approved.kubernetes.io": "unapproved, experimental-only; please get an approval from Kubernetes API reviewers if you're trying to develop a CRD in the *.k8s.io or *.kubernetes.io groups" -spec: - group: samplecontroller.k8s.io - versions: - - name: v1alpha1 - served: true - storage: true - schema: - # schema used for validation - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - deploymentName: - type: string - replicas: - type: integer - minimum: 1 - maximum: 10 - status: - type: object - properties: - availableReplicas: - type: integer - names: - kind: Foo - plural: foos - scope: Namespaced diff --git a/pkg/cmd/build/builders/crd/visitor.go b/pkg/cmd/build/builders/crd/visitor.go deleted file mode 100644 index cfcbebb9..00000000 --- a/pkg/cmd/build/builders/crd/visitor.go +++ /dev/null @@ -1,6 +0,0 @@ -package crd - -// Visitor walks a list of resources under target path. -type Visitor interface { - Visit() ([]interface{}, error) -} diff --git a/pkg/cmd/build/builders/kcl/rest/model.go b/pkg/cmd/build/builders/kcl/rest/model.go deleted file mode 100644 index f9fc62c1..00000000 --- a/pkg/cmd/build/builders/kcl/rest/model.go +++ /dev/null @@ -1,19 +0,0 @@ -package rest - -import ( - "kcl-lang.io/kcl-go/pkg/spec/gpyrpc" -) - -type Result struct { - Error string `json:"error"` - Result *gpyrpc.ExecProgram_Result `json:"result"` -} - -type PingResponse struct { - Error string `json:"error"` - Result *PingResult `json:"result"` -} - -type PingResult struct { - Value string `json:"value,omitempty"` -} diff --git a/pkg/cmd/build/builders/kcl/rest/rest.go b/pkg/cmd/build/builders/kcl/rest/rest.go deleted file mode 100644 index 496fb7c1..00000000 --- a/pkg/cmd/build/builders/kcl/rest/rest.go +++ /dev/null @@ -1,142 +0,0 @@ -package rest - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "time" - - "github.com/pkg/errors" - - "kcl-lang.io/kcl-go/pkg/spec/gpyrpc" - - "kusionstack.io/kusion/pkg/log" -) - -const ( - defaultCompileURL = "http://127.0.0.1:2021/api:protorpc/KclvmService.ExecProgram" - defaultPingURL = "http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping" -) - -type Client struct { - client *http.Client -} - -func newClient(client *http.Client) *Client { - return &Client{ - client: client, - } -} - -func New() (*Client, error) { - c := newClient(http.DefaultClient) - var e error - - for i := 0; i < 10; i++ { - if err := Ping(c); err != nil { - log.Errorf(err.Error()) - e = err - } else { - return c, nil - } - - time.Sleep(time.Second) - } - - return nil, e -} - -func Ping(c *Client) (err error) { - res := new(PingResponse) - req := &gpyrpc.Ping_Args{ - Value: "", - } - - resp, err := c.Post(defaultPingURL, req, res) - if err != nil { - return err - } - if resp != nil { - defer resp.Body.Close() - } - - if len(res.Error) > 0 { - return errors.New(res.Error) - } - - return nil -} - -func (c *Client) Get(url string, output interface{}) (*http.Response, error) { - return c.do("GET", url, nil, output) -} - -func (c *Client) Post(url string, input interface{}, output interface{}) (*http.Response, error) { - return c.do("POST", url, input, output) -} - -func (c *Client) Put(url string, input interface{}, output interface{}) (*http.Response, error) { - return c.do("PUT", url, input, output) -} - -func (c *Client) Delete(url string, input interface{}, output interface{}) (*http.Response, error) { - return c.do("DELETE", url, input, output) -} - -func (c *Client) do(method string, url string, input interface{}, output interface{}) (*http.Response, error) { - buf := &bytes.Buffer{} - if input != nil { - err := json.NewEncoder(buf).Encode(input) - if err != nil { - return nil, err - } - } - req, err := http.NewRequest(method, url, buf) - req = withTimeOut(req, 100*time.Second) - if err != nil { - return nil, err - } - setJSONContentType(req) - // setJSONAcceptType(req) - - resp, err := c.client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - if resp.StatusCode > 299 { - return nil, fmt.Errorf("%v: %v", url, resp.Status) - } - - err = json.NewDecoder(resp.Body).Decode(output) - return resp, err -} - -func withTimeOut(req *http.Request, timeout time.Duration) *http.Request { - ctx, cancel := context.WithCancel(context.TODO()) - time.AfterFunc(timeout, func() { - cancel() - }) - - return req.WithContext(ctx) -} - -func setJSONContentType(req *http.Request) { - req.Header.Set("Content-Type", "accept/json") -} - -func (c *Client) Compile(req *gpyrpc.ExecProgram_Args) (*Result, error) { - res := new(Result) - - resp, err := c.Post(defaultCompileURL, req, res) - if err != nil { - return nil, err - } - if resp != nil { - defer resp.Body.Close() - } - - return res, nil -} diff --git a/pkg/cmd/build/builders/kcl/rest/rest_test.go b/pkg/cmd/build/builders/kcl/rest/rest_test.go deleted file mode 100644 index 7cfad954..00000000 --- a/pkg/cmd/build/builders/kcl/rest/rest_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package rest - -import ( - "net/http" - "testing" - - "github.com/bytedance/mockey" - "github.com/stretchr/testify/assert" -) - -type bytesReadCloser struct { - bytes []byte -} - -func (b *bytesReadCloser) Read(p []byte) (n int, err error) { - copy(p, b.bytes) - return len(b.bytes), nil -} - -func (b *bytesReadCloser) Close() error { - return nil -} - -func TestNew(t *testing.T) { - mockey.PatchConvey("success", t, func() { - mockPing(nil) - _, err := New() - assert.Nil(t, err) - }) -} - -func TestPing(t *testing.T) { - mockey.PatchConvey("success", t, func() { - client := newClient(http.DefaultClient) - mockPost(client, nil) - err := Ping(client) - assert.Nil(t, err) - }) - mockey.PatchConvey("failed", t, func() { - client := newClient(http.DefaultClient) - mockPost(client, assert.AnError) - err := Ping(client) - assert.NotNil(t, err) - }) -} - -func TestGetPostPutDelete(t *testing.T) { - mockey.PatchConvey("t1", t, func() { - client := newClient(http.DefaultClient) - mockDo(client) - resp1, err := client.Get("/", &struct{ Data string }{}) - assert.Nil(t, err) - defer resp1.Body.Close() - - resp2, err := client.Post("/", &struct{ Data string }{}, &struct{ Data string }{}) - assert.Nil(t, err) - defer resp2.Body.Close() - - resp3, err := client.Put("/", &struct{ Data string }{}, &struct{ Data string }{}) - assert.Nil(t, err) - defer resp3.Body.Close() - - resp4, err := client.Delete("/", &struct{ Data string }{}, &struct{ Data string }{}) - assert.Nil(t, err) - defer resp4.Body.Close() - }) -} - -func TestCompile(t *testing.T) { - mockey.PatchConvey("success", t, func() { - client := newClient(http.DefaultClient) - mockPost(client, nil) - _, err := client.Compile(nil) - assert.Nil(t, err) - }) - mockey.PatchConvey("failed", t, func() { - client := newClient(http.DefaultClient) - mockPost(client, assert.AnError) - _, err := client.Compile(nil) - assert.NotNil(t, err) - }) -} - -func mockPing(mockErr error) { - mockey.Mock(Ping).To(func(_ *Client) error { - return mockErr - }).Build() -} - -func mockPost(client *Client, mockErr error) { - mockey.Mock(mockey.GetMethod(client, "Post")).To(func(_ *Client, _ string, _, _ interface{}) (*http.Response, error) { - return nil, mockErr - }).Build() -} - -func mockDo(client *Client) { - mockey.Mock(mockey.GetMethod(client.client, "Do")).To(func(_ *http.Client, _ *http.Request) (*http.Response, error) { - return &http.Response{ - Status: "200 OK", - StatusCode: 200, - Body: &bytesReadCloser{bytes: []byte("{\"data\":\"test\"}")}, - }, nil - }).Build() -} diff --git a/pkg/cmd/build/builders/kcl/testdata/crd/foo.yaml b/pkg/cmd/build/builders/kcl/testdata/crd/foo.yaml deleted file mode 100644 index 8ac6e60c..00000000 --- a/pkg/cmd/build/builders/kcl/testdata/crd/foo.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: foos.samplecontroller.k8s.io - # for more information on the below annotation, please see - # https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/2337-k8s.io-group-protection/README.md - annotations: - "api-approved.kubernetes.io": "unapproved, experimental-only; please get an approval from Kubernetes API reviewers if you're trying to develop a CRD in the *.k8s.io or *.kubernetes.io groups" -spec: - group: samplecontroller.k8s.io - versions: - - name: v1alpha1 - served: true - storage: true - schema: - # schema used for validation - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - deploymentName: - type: string - replicas: - type: integer - minimum: 1 - maximum: 10 - status: - type: object - properties: - availableReplicas: - type: integer - names: - kind: Foo - plural: foos - scope: Namespaced diff --git a/pkg/cmd/build/builders/kcl/testdata/kcl.yaml b/pkg/cmd/build/builders/kcl/testdata/kcl.yaml deleted file mode 100644 index b8e7eade..00000000 --- a/pkg/cmd/build/builders/kcl/testdata/kcl.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kcl_cli_configs: - file: - - main.k - disable_none: false - \ No newline at end of file diff --git a/pkg/cmd/build/builders/kcl/testdata/main.k b/pkg/cmd/build/builders/kcl/testdata/main.k deleted file mode 100644 index b3c50408..00000000 --- a/pkg/cmd/build/builders/kcl/testdata/main.k +++ /dev/null @@ -1,13 +0,0 @@ -a = { - "a": "b" - "c": ["1","2","3"] -} - -schema Person: - name: str - age: int - -p = Person { - name: "yym" - age: 18 -} \ No newline at end of file diff --git a/pkg/cmd/build/builders/kcl/testdata/main_topology.k b/pkg/cmd/build/builders/kcl/testdata/main_topology.k deleted file mode 100644 index 8dee9d17..00000000 --- a/pkg/cmd/build/builders/kcl/testdata/main_topology.k +++ /dev/null @@ -1,14 +0,0 @@ -schema App: - name: str - idc: str - cluster: str - zone: str - replicas: int - -app = App { - name: "testapp" - idc: option("idc") - cluster: option("cluster") - zone: option("zone") - replicas: option("replicas") -} \ No newline at end of file diff --git a/pkg/cmd/build/builders/kcl/type.go b/pkg/cmd/build/builders/kcl/type.go deleted file mode 100644 index a5322bbc..00000000 --- a/pkg/cmd/build/builders/kcl/type.go +++ /dev/null @@ -1,35 +0,0 @@ -package kcl - -import ( - kcl "kcl-lang.io/kcl-go" - kclpkg "kcl-lang.io/kcl-go/pkg/kcl" -) - -// CompileResult is the result of a KCL compilation -type CompileResult struct { - Documents []kcl.KCLResult - RawYAMLResult string -} - -// NewCompileResult news a CompileResult by KCLResultList -func NewCompileResult(k *kcl.KCLResultList) *CompileResult { - return &CompileResult{ - Documents: k.Slice(), - RawYAMLResult: k.GetRawYamlResult(), - } -} - -// NewCompileResultByMapList news a CompileResult by map array -func NewCompileResultByMapList(mapList []map[string]interface{}) *CompileResult { - documents := []kcl.KCLResult{} - for _, mapItem := range mapList { - documents = append(documents, kclpkg.NewResult(mapItem)) - } - return &CompileResult{ - Documents: documents, - } -} - -func (c *CompileResult) RawYAML() string { - return c.RawYAMLResult -} diff --git a/pkg/cmd/build/builders/kcl/type_test.go b/pkg/cmd/build/builders/kcl/type_test.go deleted file mode 100644 index 0bb5e716..00000000 --- a/pkg/cmd/build/builders/kcl/type_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package kcl - -import ( - "reflect" - "strings" - "testing" - - kcl "kcl-lang.io/kcl-go" - kclpkg "kcl-lang.io/kcl-go/pkg/kcl" -) - -func TestCompileResult_RawYAML(t *testing.T) { - type fields struct { - Documents []kcl.KCLResult - RawYAMLResult string - } - tests := []struct { - name string - fields fields - want string - }{ - { - name: "t1", - fields: fields{ - Documents: []kcl.KCLResult{kclpkg.NewResult(map[string]string{"a": "b"})}, - RawYAMLResult: "a: b", - }, - want: "a: b", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &CompileResult{ - Documents: tt.fields.Documents, - RawYAMLResult: tt.fields.RawYAMLResult, - } - if got := strings.TrimSpace(c.RawYAML()); got != tt.want { - t.Errorf("CompileResult.RawYAML() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestNewCompileResultByMapList(t *testing.T) { - type args struct { - mapList []map[string]interface{} - } - tests := []struct { - name string - args args - want *CompileResult - }{ - { - name: "t1", - args: args{ - mapList: []map[string]interface{}{{"replicas": 1}}, - }, - want: &CompileResult{ - Documents: []kcl.KCLResult{kclpkg.NewResult(map[string]interface{}{"replicas": 1})}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := NewCompileResultByMapList(tt.args.mapList); !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewCompileResultByMapList() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/cmd/build/builders/kcl/util.go b/pkg/cmd/build/builders/kcl/util.go deleted file mode 100644 index 4a9b4833..00000000 --- a/pkg/cmd/build/builders/kcl/util.go +++ /dev/null @@ -1,48 +0,0 @@ -package kcl - -import ( - "os" - "os/exec" - "path/filepath" - - "kusionstack.io/kusion/pkg/util/io" -) - -const KusionKclPathEnv = "KUSION_KCL_PATH" - -func getKclPath() string { - // 1. try ${KusionKclPathEnv} - if kclPath := os.Getenv(KusionKclPathEnv); kclPath != "" { - return kclPath - } - - // 2.1 try ${appPath}/kclvm/bin/kcl - // 2.2 try ${appPath}/../kclvm/bin/kcl - // 2.3 try ${PWD}/kclvm/bin/kcl - - var kclPathList []string - if appPath, _ := os.Executable(); appPath != "" { - kclPathList = append(kclPathList, - filepath.Join(filepath.Dir(appPath), "kclvm", "bin", "kcl"), - filepath.Join(filepath.Dir(filepath.Dir(appPath)), "kclvm", "bin", "kcl"), - ) - } - if workDir, _ := os.Getwd(); workDir != "" { - kclPathList = append(kclPathList, - filepath.Join(workDir, "kclvm", "bin", "kcl"), - ) - } - for _, kclPath := range kclPathList { - if ok, _ := io.IsFile(kclPath); ok { - return kclPath - } - } - - // 3. try ${PATH}/kcl - - if kclPath, _ := exec.LookPath("kcl"); kclPath != "" { - return kclPath - } - - return "kcl" -} diff --git a/pkg/cmd/build/builders/kcl/util_test.go b/pkg/cmd/build/builders/kcl/util_test.go deleted file mode 100644 index 5e4e6b21..00000000 --- a/pkg/cmd/build/builders/kcl/util_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package kcl - -import ( - "fmt" - "os" - "os/exec" - "testing" - "time" -) - -func TestGetKclPath(t *testing.T) { - os.Setenv(KusionKclPathEnv, "kcl-custom-path") - tAssert(t, getKclPath() == "kcl-custom-path") - - os.Setenv(KusionKclPathEnv, "") - - _ = os.MkdirAll("./kclvm/bin", 0o777) - - kclData := fmt.Sprintf("# kcl-test shell, %d", time.Now().Unix()) - _ = os.WriteFile("./kclvm/bin/kcl", []byte(kclData), 0o777) - defer os.RemoveAll("./kclvm") - - kcl := getKclPath() - kclDataGot, _ := os.ReadFile(kcl) - if len(kclDataGot) > 50 { - kclDataGot = kclDataGot[:50] - } - tAssert(t, kclData == string(kclDataGot), kclData, string(kclDataGot)) - os.RemoveAll("./kclvm") - - if s, _ := exec.LookPath("kcl"); s != "" { - kcl := getKclPath() - tAssert(t, kcl == s, s, kcl) - } -} - -func tAssert(tb testing.TB, condition bool, a ...interface{}) { - tb.Helper() - if !condition { - if msg := fmt.Sprint(a...); msg != "" { - tb.Fatal("Assert failed: " + msg) - } else { - tb.Fatal("Assert failed") - } - } -} diff --git a/pkg/cmd/config/list/cmd_test.go b/pkg/cmd/config/list/cmd_test.go index 1f1a451a..3b20e586 100644 --- a/pkg/cmd/config/list/cmd_test.go +++ b/pkg/cmd/config/list/cmd_test.go @@ -6,7 +6,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/config" ) diff --git a/pkg/cmd/destroy/options.go b/pkg/cmd/destroy/options.go index 9ee4cee0..03b99682 100644 --- a/pkg/cmd/destroy/options.go +++ b/pkg/cmd/destroy/options.go @@ -9,7 +9,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pterm/pterm" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/build" @@ -89,7 +89,7 @@ func (o *Options) Run() error { } // compute changes for preview - i := &apiv1.Intent{Resources: destroyResources} + i := &apiv1.Spec{Resources: destroyResources} changes, err := o.preview(i, proj, stack, storage) if err != nil { return err @@ -137,7 +137,7 @@ func (o *Options) Run() error { } func (o *Options) preview( - planResources *apiv1.Intent, + planResources *apiv1.Spec, proj *apiv1.Project, stack *apiv1.Stack, stateStorage state.Storage, @@ -179,7 +179,7 @@ func (o *Options) preview( return models.NewChanges(proj, stack, rsp.Order), nil } -func (o *Options) destroy(planResources *apiv1.Intent, changes *models.Changes, stateStorage state.Storage) error { +func (o *Options) destroy(planResources *apiv1.Spec, changes *models.Changes, stateStorage state.Storage) error { do := &operation.DestroyOperation{ Operation: models.Operation{ Stack: changes.Stack(), diff --git a/pkg/cmd/destroy/options_test.go b/pkg/cmd/destroy/options_test.go index acbf0adb..dda9a457 100644 --- a/pkg/cmd/destroy/options_test.go +++ b/pkg/cmd/destroy/options_test.go @@ -11,7 +11,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/backend/storages" @@ -98,7 +98,7 @@ func Test_preview(t *testing.T) { o := NewDestroyOptions() stateStorage := statestorages.NewLocalStorage(filepath.Join(o.WorkDir, "state.yaml")) - _, err := o.preview(&apiv1.Intent{Resources: []apiv1.Resource{sa1}}, proj, stack, stateStorage) + _, err := o.preview(&apiv1.Spec{Resources: []apiv1.Resource{sa1}}, proj, stack, stateStorage) assert.Nil(t, err) }) } @@ -196,7 +196,7 @@ func Test_destroy(t *testing.T) { mockOperationDestroy(models.Success) o := NewDestroyOptions() - planResources := &apiv1.Intent{Resources: []apiv1.Resource{sa2}} + planResources := &apiv1.Spec{Resources: []apiv1.Resource{sa2}} order := &models.ChangeOrder{ StepKeys: []string{sa1.ID, sa2.ID}, ChangeSteps: map[string]*models.ChangeStep{ @@ -224,7 +224,7 @@ func Test_destroy(t *testing.T) { mockOperationDestroy(models.Failed) o := NewDestroyOptions() - planResources := &apiv1.Intent{Resources: []apiv1.Resource{sa1}} + planResources := &apiv1.Spec{Resources: []apiv1.Resource{sa1}} order := &models.ChangeOrder{ StepKeys: []string{sa1.ID}, ChangeSteps: map[string]*models.ChangeStep{ diff --git a/pkg/cmd/generate/generate.go b/pkg/cmd/generate/generate.go index 8ba8de3c..2ad4c588 100644 --- a/pkg/cmd/generate/generate.go +++ b/pkg/cmd/generate/generate.go @@ -12,7 +12,7 @@ import ( "k8s.io/cli-runtime/pkg/genericiooptions" "kcl-lang.io/kpm/pkg/api" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/generate/generator" "kusionstack.io/kusion/pkg/cmd/generate/run" @@ -155,15 +155,15 @@ func (o *GenerateOptions) Validate(cmd *cobra.Command, args []string) error { // Run executes the `generate` command. func (o *GenerateOptions) Run() error { - intent, err := GenerateIntentWithSpinner(o.Project, o.Stack, o.Workspace, true) + spec, err := GenerateSpecWithSpinner(o.Project, o.Stack, o.Workspace, true) if err != nil { return err } - return o.SpecStorage.Apply(intent) + return o.SpecStorage.Apply(spec) } -// GenerateIntentWithSpinner calls generator to generate versioned Spec. Add a method wrapper for testing purposes. -func GenerateIntentWithSpinner(project *v1.Project, stack *v1.Stack, workspace *v1.Workspace, noStyle bool) (*v1.Intent, error) { +// GenerateSpecWithSpinner calls generator to generate versioned Spec. Add a method wrapper for testing purposes. +func GenerateSpecWithSpinner(project *v1.Project, stack *v1.Stack, workspace *v1.Workspace, noStyle bool) (*v1.Spec, error) { // Construct generator instance defaultGenerator := &generator.DefaultGenerator{ Project: project, @@ -189,7 +189,7 @@ func GenerateIntentWithSpinner(project *v1.Project, stack *v1.Stack, workspace * // style means color and prompt here. Currently, sp will be nil only when o.NoStyle is true style := !noStyle && sp != nil - intent, err := defaultGenerator.Generate(stack.Path, nil) + spec, err := defaultGenerator.Generate(stack.Path, nil) if err != nil { if style { sp.Fail() @@ -206,10 +206,10 @@ func GenerateIntentWithSpinner(project *v1.Project, stack *v1.Stack, workspace * fmt.Println() } - return intent, nil + return spec, nil } -func IntentFromFile(filePath string) (*v1.Intent, error) { +func SpecFromFile(filePath string) (*v1.Spec, error) { b, err := os.ReadFile(filePath) if err != nil { return nil, err @@ -220,7 +220,7 @@ func IntentFromFile(filePath string) (*v1.Intent, error) { // The use of yaml.v2 and yaml.v3 should be unified in the future. decoder := yamlv3.NewDecoder(bytes.NewBuffer(b)) decoder.KnownFields(true) - i := &v1.Intent{} + i := &v1.Spec{} if err = decoder.Decode(i); err != nil && err != io.EOF { return nil, fmt.Errorf("failed to parse the intent file, please check if the file content is valid") } diff --git a/pkg/cmd/generate/generator/generator.go b/pkg/cmd/generate/generator/generator.go index bbc8530d..5019b0d3 100644 --- a/pkg/cmd/generate/generator/generator.go +++ b/pkg/cmd/generate/generator/generator.go @@ -12,18 +12,19 @@ import ( "kcl-lang.io/kpm/pkg/env" pkg "kcl-lang.io/kpm/pkg/package" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/cmd/build/builders" "kusionstack.io/kusion/pkg/cmd/generate/run" "kusionstack.io/kusion/pkg/util/io" "kusionstack.io/kusion/pkg/util/kfile" ) -// Generator is an interface for things that can generate versioned Intent from +// Generator is an interface for things that can generate versioned Spec from // configuration code under current working directory and given input parameters. type Generator interface { // Generate creates versioned Intent given working directory and set of parameters - Generate(workDir string, params map[string]string) (*v1.Intent, error) + Generate(workDir string, params map[string]string) (*v1.Spec, error) } // DefaultGenerator is the default Generator implementation. @@ -36,7 +37,7 @@ type DefaultGenerator struct { } // Generate versioned Spec with target code runner. -func (g *DefaultGenerator) Generate(workDir string, params map[string]string) (*v1.Intent, error) { +func (g *DefaultGenerator) Generate(workDir string, params map[string]string) (*v1.Spec, error) { // Call code runner to generate raw data if params == nil { params = make(map[string]string, 1) @@ -54,7 +55,7 @@ func (g *DefaultGenerator) Generate(workDir string, params map[string]string) (* // Note: we use the type of MapSlice in yaml.v2 to maintain the order of container // environment variables, thus we unmarshal appConfigs with yaml.v2 rather than yaml.v3. - apps := map[string]v1.AppConfiguration{} + apps := map[string]internalv1.AppConfiguration{} err = yaml.Unmarshal(rawAppConfiguration, apps) if err != nil { return nil, err diff --git a/pkg/cmd/preview/options.go b/pkg/cmd/preview/options.go index ba033fbd..30fbe7e6 100644 --- a/pkg/cmd/preview/options.go +++ b/pkg/cmd/preview/options.go @@ -9,7 +9,7 @@ import ( "github.com/pkg/errors" "github.com/pterm/pterm" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/build" @@ -134,13 +134,12 @@ func (o *Options) Run() error { return err } - // Generate Intent - // Generate Intent - var intent *apiv1.Intent + // Generate Spec + var spec *apiv1.Spec if len(o.IntentFile) != 0 { - intent, err = generate.IntentFromFile(o.IntentFile) + spec, err = generate.SpecFromFile(o.IntentFile) } else { - intent, err = generate.GenerateIntentWithSpinner(currentProject, currentStack, currentWorkspace, true) + spec, err = generate.GenerateSpecWithSpinner(currentProject, currentStack, currentWorkspace, true) } if err != nil { return err @@ -148,7 +147,7 @@ func (o *Options) Run() error { // return immediately if no resource found in stack // todo: if there is no resource, should still do diff job; for now, if output is json format, there is no hint - if intent == nil || len(intent.Resources) == 0 { + if spec == nil || len(spec.Resources) == 0 { if o.Output != jsonOutput { fmt.Println(pretty.GreenBold("\nNo resource found in this stack.")) } @@ -157,7 +156,7 @@ func (o *Options) Run() error { // compute changes for preview storage := bk.StateStorage(currentProject.Name, currentStack.Name, currentWorkspace.Name) - changes, err := Preview(o, storage, intent, currentProject, currentStack) + changes, err := Preview(o, storage, spec, currentProject, currentStack) if err != nil { return err } @@ -222,7 +221,7 @@ func (o *Options) Run() error { func Preview( o *Options, storage state.Storage, - planResources *apiv1.Intent, + planResources *apiv1.Spec, proj *apiv1.Project, stack *apiv1.Stack, ) (*models.Changes, error) { diff --git a/pkg/cmd/preview/options_test.go b/pkg/cmd/preview/options_test.go index eb3af404..04df5c2e 100644 --- a/pkg/cmd/preview/options_test.go +++ b/pkg/cmd/preview/options_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/backend/storages" @@ -50,7 +50,7 @@ func Test_preview(t *testing.T) { defer m.UnPatch() o := NewPreviewOptions() - _, err := Preview(o, stateStorage, &apiv1.Intent{Resources: []apiv1.Resource{sa1, sa2, sa3}}, proj, stack) + _, err := Preview(o, stateStorage, &apiv1.Spec{Resources: []apiv1.Resource{sa1, sa2, sa3}}, proj, stack) assert.Nil(t, err) }) } @@ -228,13 +228,13 @@ func mockDetectProjectAndStack() { } func mockGenerateIntentWithSpinner() { - mockey.Mock(generate.GenerateIntentWithSpinner).To(func( + mockey.Mock(generate.GenerateSpecWithSpinner).To(func( project *apiv1.Project, stack *apiv1.Stack, workspace *apiv1.Workspace, noStyle bool, - ) (*apiv1.Intent, error) { - return &apiv1.Intent{Resources: []apiv1.Resource{sa1, sa2, sa3}}, nil + ) (*apiv1.Spec, error) { + return &apiv1.Spec{Resources: []apiv1.Resource{sa1, sa2, sa3}}, nil }).Build() } diff --git a/pkg/cmd/workspace/create/options_test.go b/pkg/cmd/workspace/create/options_test.go index b6997fb1..ea05f489 100644 --- a/pkg/cmd/workspace/create/options_test.go +++ b/pkg/cmd/workspace/create/options_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/workspace/util" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/cmd/workspace/show/options_test.go b/pkg/cmd/workspace/show/options_test.go index 356eae49..3a8fb66d 100644 --- a/pkg/cmd/workspace/show/options_test.go +++ b/pkg/cmd/workspace/show/options_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/backend" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" ) diff --git a/pkg/cmd/workspace/switch/options_test.go b/pkg/cmd/workspace/switch/options_test.go index a4a56757..877c23a8 100644 --- a/pkg/cmd/workspace/switch/options_test.go +++ b/pkg/cmd/workspace/switch/options_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/workspace/util" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/cmd/workspace/update/options_test.go b/pkg/cmd/workspace/update/options_test.go index 3a5839dc..91e01417 100644 --- a/pkg/cmd/workspace/update/options_test.go +++ b/pkg/cmd/workspace/update/options_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/backend" "kusionstack.io/kusion/pkg/cmd/workspace/util" workspacestorages "kusionstack.io/kusion/pkg/workspace/storages" diff --git a/pkg/cmd/workspace/util/util.go b/pkg/cmd/workspace/util/util.go index 28007d61..9cbe6e7b 100644 --- a/pkg/cmd/workspace/util/util.go +++ b/pkg/cmd/workspace/util/util.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/workspace" "kusionstack.io/kusion/pkg/workspace/storages" ) diff --git a/pkg/config/operator.go b/pkg/config/operator.go index 34728e53..bd8a8b08 100644 --- a/pkg/config/operator.go +++ b/pkg/config/operator.go @@ -12,7 +12,7 @@ import ( "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/util/kfile" ) diff --git a/pkg/config/operator_test.go b/pkg/config/operator_test.go index a64917f6..33bebb30 100644 --- a/pkg/config/operator_test.go +++ b/pkg/config/operator_test.go @@ -8,7 +8,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) var ( diff --git a/pkg/config/registry.go b/pkg/config/registry.go index fe51c669..7ad33baa 100644 --- a/pkg/config/registry.go +++ b/pkg/config/registry.go @@ -1,7 +1,7 @@ package config import ( - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) const ( diff --git a/pkg/config/util.go b/pkg/config/util.go index e784d7fc..f0fa0e7f 100644 --- a/pkg/config/util.go +++ b/pkg/config/util.go @@ -1,7 +1,7 @@ package config import ( - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) // GetConfig returns the structured config stored in the config file. The validation of the config is not checked. diff --git a/pkg/config/util_test.go b/pkg/config/util_test.go index 53773c59..991bead0 100644 --- a/pkg/config/util_test.go +++ b/pkg/config/util_test.go @@ -6,7 +6,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) func mockNewOperator(config *v1.Config) { diff --git a/pkg/config/validation.go b/pkg/config/validation.go index 026c0d39..bf8029f4 100644 --- a/pkg/config/validation.go +++ b/pkg/config/validation.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/backend/storages" ) diff --git a/pkg/config/validation_test.go b/pkg/config/validation_test.go index 691bdcc6..c751fdc4 100644 --- a/pkg/config/validation_test.go +++ b/pkg/config/validation_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) func TestValidateSetCurrentBackend(t *testing.T) { diff --git a/pkg/engine/operation/apply.go b/pkg/engine/operation/apply.go index cac1403e..46161709 100644 --- a/pkg/engine/operation/apply.go +++ b/pkg/engine/operation/apply.go @@ -5,7 +5,7 @@ import ( "fmt" "sync" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" models "kusionstack.io/kusion/pkg/engine/operation/models" @@ -28,7 +28,7 @@ type ApplyResponse struct { State *apiv1.State } -func NewApplyGraph(m *apiv1.Intent, priorState *apiv1.State) (*dag.AcyclicGraph, v1.Status) { +func NewApplyGraph(m *apiv1.Spec, priorState *apiv1.State) (*dag.AcyclicGraph, v1.Status) { intentParser := parser.NewIntentParser(m) g := &dag.AcyclicGraph{} g.Add(&graph.RootNode{}) diff --git a/pkg/engine/operation/apply_test.go b/pkg/engine/operation/apply_test.go index 1e90c07f..af1d01d9 100644 --- a/pkg/engine/operation/apply_test.go +++ b/pkg/engine/operation/apply_test.go @@ -10,7 +10,7 @@ import ( _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/pkg/engine/operation/models" @@ -42,7 +42,7 @@ func Test_ValidateRequest(t *testing.T) { name: "t2", args: args{ request: &models.Request{ - Intent: &apiv1.Intent{Resources: []apiv1.Resource{}}, + Intent: &apiv1.Spec{Resources: []apiv1.Resource{}}, }, }, want: nil, @@ -76,7 +76,7 @@ func TestOperation_Apply(t *testing.T) { } const Jack = "jack" - mf := &apiv1.Intent{Resources: []apiv1.Resource{ + mf := &apiv1.Spec{Resources: []apiv1.Resource{ { ID: Jack, Type: runtime.Kubernetes, diff --git a/pkg/engine/operation/destory.go b/pkg/engine/operation/destory.go index 64beaa42..b948a226 100644 --- a/pkg/engine/operation/destory.go +++ b/pkg/engine/operation/destory.go @@ -3,7 +3,7 @@ package operation import ( "sync" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/pkg/engine/operation/models" diff --git a/pkg/engine/operation/destory_test.go b/pkg/engine/operation/destory_test.go index 86176143..1db22a08 100644 --- a/pkg/engine/operation/destory_test.go +++ b/pkg/engine/operation/destory_test.go @@ -10,7 +10,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/pkg/engine/operation/models" @@ -40,7 +40,7 @@ func TestOperation_Destroy(t *testing.T) { }, DependsOn: nil, } - mf := &apiv1.Intent{Resources: []apiv1.Resource{resourceState}} + mf := &apiv1.Spec{Resources: []apiv1.Resource{resourceState}} o := &DestroyOperation{ models.Operation{ OperationType: models.Destroy, diff --git a/pkg/engine/operation/diff.go b/pkg/engine/operation/diff.go index e983e782..b5c5e2bf 100644 --- a/pkg/engine/operation/diff.go +++ b/pkg/engine/operation/diff.go @@ -3,7 +3,7 @@ package operation import ( "github.com/pkg/errors" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/state" "kusionstack.io/kusion/pkg/log" @@ -48,7 +48,7 @@ func (d *Diff) Diff(request *DiffRequest) (string, error) { return DiffWithRequestResourceAndState(plan, priorState) } -func DiffWithRequestResourceAndState(plan *v1.Intent, priorState *v1.State) (string, error) { +func DiffWithRequestResourceAndState(plan *v1.Spec, priorState *v1.State) (string, error) { planString := json.MustMarshal2String(plan.Resources) var report *dyff.Report var err error diff --git a/pkg/engine/operation/graph/resource_node.go b/pkg/engine/operation/graph/resource_node.go index d99c95bd..8b3313ec 100644 --- a/pkg/engine/operation/graph/resource_node.go +++ b/pkg/engine/operation/graph/resource_node.go @@ -7,7 +7,7 @@ import ( "reflect" "strings" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/runtime" diff --git a/pkg/engine/operation/graph/resource_node_test.go b/pkg/engine/operation/graph/resource_node_test.go index e66c18a2..df9a3e02 100644 --- a/pkg/engine/operation/graph/resource_node_test.go +++ b/pkg/engine/operation/graph/resource_node_test.go @@ -8,7 +8,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/runtime" @@ -30,7 +30,7 @@ func TestResourceNode_Execute(t *testing.T) { const Jack = "jack" const Pony = "pony" const Eric = "eric" - mf := &apiv1.Intent{Resources: []apiv1.Resource{ + mf := &apiv1.Spec{Resources: []apiv1.Resource{ { ID: Pony, Type: runtime.Kubernetes, diff --git a/pkg/engine/operation/models/change.go b/pkg/engine/operation/models/change.go index cbbf1e9f..80745112 100644 --- a/pkg/engine/operation/models/change.go +++ b/pkg/engine/operation/models/change.go @@ -9,7 +9,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pterm/pterm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/util/diff" "kusionstack.io/kusion/pkg/util/pretty" diff --git a/pkg/engine/operation/models/change_test.go b/pkg/engine/operation/models/change_test.go index 1ced1645..c9996092 100644 --- a/pkg/engine/operation/models/change_test.go +++ b/pkg/engine/operation/models/change_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/util/pretty" ) diff --git a/pkg/engine/operation/models/operation_context.go b/pkg/engine/operation/models/operation_context.go index 459123a8..b1de40c0 100644 --- a/pkg/engine/operation/models/operation_context.go +++ b/pkg/engine/operation/models/operation_context.go @@ -7,7 +7,7 @@ import ( "github.com/jinzhu/copier" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/state" "kusionstack.io/kusion/pkg/log" @@ -65,7 +65,7 @@ type Request struct { Project *v1.Project `json:"project"` Stack *v1.Stack `json:"stack"` Operator string `json:"operator"` - Intent *v1.Intent `json:"intent"` + Intent *v1.Spec `json:"intent"` } type OpResult string diff --git a/pkg/engine/operation/parser/delete_resource_parser.go b/pkg/engine/operation/parser/delete_resource_parser.go index 1273afb7..63f46ead 100644 --- a/pkg/engine/operation/parser/delete_resource_parser.go +++ b/pkg/engine/operation/parser/delete_resource_parser.go @@ -3,7 +3,7 @@ package parser import ( "fmt" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" models "kusionstack.io/kusion/pkg/engine/operation/models" diff --git a/pkg/engine/operation/parser/delete_resource_parser_test.go b/pkg/engine/operation/parser/delete_resource_parser_test.go index 4237db82..e5f4fbb7 100644 --- a/pkg/engine/operation/parser/delete_resource_parser_test.go +++ b/pkg/engine/operation/parser/delete_resource_parser_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/third_party/terraform/dag" ) diff --git a/pkg/engine/operation/parser/parser.go b/pkg/engine/operation/parser/parser.go index b7ec3d8f..4b7bc8c0 100644 --- a/pkg/engine/operation/parser/parser.go +++ b/pkg/engine/operation/parser/parser.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/pkg/engine/operation/models" diff --git a/pkg/engine/operation/parser/spec_parser.go b/pkg/engine/operation/parser/spec_parser.go index 4bfd7e7d..0c079390 100644 --- a/pkg/engine/operation/parser/spec_parser.go +++ b/pkg/engine/operation/parser/spec_parser.go @@ -3,7 +3,7 @@ package parser import ( "fmt" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/pkg/engine/operation/models" @@ -13,10 +13,10 @@ import ( ) type IntentParser struct { - intent *apiv1.Intent + intent *apiv1.Spec } -func NewIntentParser(i *apiv1.Intent) *IntentParser { +func NewIntentParser(i *apiv1.Spec) *IntentParser { return &IntentParser{intent: i} } diff --git a/pkg/engine/operation/parser/spec_parser_test.go b/pkg/engine/operation/parser/spec_parser_test.go index 84689920..c77d0524 100644 --- a/pkg/engine/operation/parser/spec_parser_test.go +++ b/pkg/engine/operation/parser/spec_parser_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" "kusionstack.io/kusion/third_party/terraform/dag" ) @@ -13,7 +13,7 @@ func TestSpecParser_Parse(t *testing.T) { const Jack = "jack" const Pony = "pony" const Eric = "eric" - mf := &v1.Intent{Resources: []v1.Resource{ + mf := &v1.Spec{Resources: []v1.Resource{ { ID: Pony, diff --git a/pkg/engine/operation/preview.go b/pkg/engine/operation/preview.go index e171a647..ff80b95c 100644 --- a/pkg/engine/operation/preview.go +++ b/pkg/engine/operation/preview.go @@ -5,7 +5,7 @@ import ( "fmt" "sync" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/graph" models "kusionstack.io/kusion/pkg/engine/operation/models" diff --git a/pkg/engine/operation/preview_test.go b/pkg/engine/operation/preview_test.go index b82dbde6..f314175e 100644 --- a/pkg/engine/operation/preview_test.go +++ b/pkg/engine/operation/preview_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/runtime" @@ -132,7 +132,7 @@ func TestOperation_Preview(t *testing.T) { Stack: s, Project: p, Operator: "fake-operator", - Intent: &apiv1.Intent{ + Intent: &apiv1.Spec{ Resources: []apiv1.Resource{ FakeResourceState, }, @@ -169,7 +169,7 @@ func TestOperation_Preview(t *testing.T) { Stack: s, Project: p, Operator: "fake-operator", - Intent: &apiv1.Intent{ + Intent: &apiv1.Spec{ Resources: []apiv1.Resource{ FakeResourceState2, }, @@ -224,7 +224,7 @@ func TestOperation_Preview(t *testing.T) { Stack: s, Project: p, Operator: "fake-operator", - Intent: &apiv1.Intent{ + Intent: &apiv1.Spec{ Resources: []apiv1.Resource{ { ID: "fake-id", diff --git a/pkg/engine/operation/watch_test.go b/pkg/engine/operation/watch_test.go index bd4fc777..9ce447f1 100644 --- a/pkg/engine/operation/watch_test.go +++ b/pkg/engine/operation/watch_test.go @@ -9,7 +9,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/watch" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/operation/models" "kusionstack.io/kusion/pkg/engine/runtime" @@ -20,7 +20,7 @@ func TestWatchOperation_Watch(t *testing.T) { mockey.PatchConvey("test watch operation: watch", t, func() { req := &WatchRequest{ Request: models.Request{ - Intent: &apiv1.Intent{ + Intent: &apiv1.Spec{ Resources: apiv1.Resources{ { ID: "apps/v1:Deployment:foo:bar", diff --git a/pkg/engine/runtime/init/init.go b/pkg/engine/runtime/init/init.go index 8f7576d2..c1e7e8ce 100644 --- a/pkg/engine/runtime/init/init.go +++ b/pkg/engine/runtime/init/init.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/kubernetes" diff --git a/pkg/engine/runtime/init/init_test.go b/pkg/engine/runtime/init/init_test.go index cb58931c..da8bf6b7 100644 --- a/pkg/engine/runtime/init/init_test.go +++ b/pkg/engine/runtime/init/init_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func TestValidResources(t *testing.T) { diff --git a/pkg/engine/runtime/kubernetes/kubeops/config.go b/pkg/engine/runtime/kubernetes/kubeops/config.go index d90109c3..5b3975da 100644 --- a/pkg/engine/runtime/kubernetes/kubeops/config.go +++ b/pkg/engine/runtime/kubernetes/kubeops/config.go @@ -6,7 +6,7 @@ import ( "k8s.io/client-go/util/homedir" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) const ( diff --git a/pkg/engine/runtime/kubernetes/kubeops/config_test.go b/pkg/engine/runtime/kubernetes/kubeops/config_test.go index c707520b..7b103dc7 100644 --- a/pkg/engine/runtime/kubernetes/kubeops/config_test.go +++ b/pkg/engine/runtime/kubernetes/kubeops/config_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockGetenv(result string) { diff --git a/pkg/engine/runtime/kubernetes/kubernetes_runtime.go b/pkg/engine/runtime/kubernetes/kubernetes_runtime.go index fd0f8178..420e2478 100644 --- a/pkg/engine/runtime/kubernetes/kubernetes_runtime.go +++ b/pkg/engine/runtime/kubernetes/kubernetes_runtime.go @@ -27,7 +27,7 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine" "kusionstack.io/kusion/pkg/engine/printers/convertor" diff --git a/pkg/engine/runtime/kubernetes/kubernetes_runtime_test.go b/pkg/engine/runtime/kubernetes/kubernetes_runtime_test.go index 2e9e89f2..1d697cf1 100644 --- a/pkg/engine/runtime/kubernetes/kubernetes_runtime_test.go +++ b/pkg/engine/runtime/kubernetes/kubernetes_runtime_test.go @@ -13,7 +13,7 @@ import ( "github.com/bytedance/mockey" yamlv3 "gopkg.in/yaml.v3" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/runtime" jsonutil "kusionstack.io/kusion/pkg/util/json" ) diff --git a/pkg/engine/runtime/runtime.go b/pkg/engine/runtime/runtime.go index f5b0fd88..f8bdc70f 100644 --- a/pkg/engine/runtime/runtime.go +++ b/pkg/engine/runtime/runtime.go @@ -5,7 +5,7 @@ import ( "k8s.io/apimachinery/pkg/watch" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" ) diff --git a/pkg/engine/runtime/terraform/install.go b/pkg/engine/runtime/terraform/install.go index dcbef9b5..2ad17655 100644 --- a/pkg/engine/runtime/terraform/install.go +++ b/pkg/engine/runtime/terraform/install.go @@ -11,7 +11,8 @@ import ( "github.com/hashicorp/hc-install/product" "github.com/hashicorp/hc-install/releases" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/util/kfile" ) @@ -22,7 +23,7 @@ var ( ) type CLIInstaller struct { - Intent *apiv1.Intent + Intent *apiv1.Spec } // Check and install the terraform executable binary if it has not been downloaded. diff --git a/pkg/engine/runtime/terraform/install_test.go b/pkg/engine/runtime/terraform/install_test.go index 8f8c61b0..78a1e995 100644 --- a/pkg/engine/runtime/terraform/install_test.go +++ b/pkg/engine/runtime/terraform/install_test.go @@ -6,13 +6,14 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func TestCLIInstaller_CheckAndInstall(t *testing.T) { mockey.PatchConvey("NoResources", t, func() { installer := &CLIInstaller{ - Intent: &v1.Intent{ + Intent: &v1.Spec{ Resources: v1.Resources{}, }, } @@ -22,7 +23,7 @@ func TestCLIInstaller_CheckAndInstall(t *testing.T) { mockey.PatchConvey("NoTerraformResources", t, func() { installer := &CLIInstaller{ - Intent: &v1.Intent{ + Intent: &v1.Spec{ Resources: v1.Resources{ v1.Resource{ Type: v1.Kubernetes, @@ -39,7 +40,7 @@ func TestCLIInstaller_CheckAndInstall(t *testing.T) { return nil }).Build() installer := &CLIInstaller{ - Intent: &v1.Intent{ + Intent: &v1.Spec{ Resources: v1.Resources{ v1.Resource{ Type: v1.Terraform, @@ -59,7 +60,7 @@ func TestCLIInstaller_CheckAndInstall(t *testing.T) { return fmt.Errorf("install timeout") }).Build() installer := &CLIInstaller{ - Intent: &v1.Intent{ + Intent: &v1.Spec{ Resources: v1.Resources{ v1.Resource{ Type: v1.Terraform, @@ -79,7 +80,7 @@ func TestCLIInstaller_CheckAndInstall(t *testing.T) { return nil }).Build() installer := &CLIInstaller{ - Intent: &v1.Intent{ + Intent: &v1.Spec{ Resources: v1.Resources{ v1.Resource{ Type: v1.Terraform, diff --git a/pkg/engine/runtime/terraform/terraform_runtime.go b/pkg/engine/runtime/terraform/terraform_runtime.go index e503aab6..263179a7 100644 --- a/pkg/engine/runtime/terraform/terraform_runtime.go +++ b/pkg/engine/runtime/terraform/terraform_runtime.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/afero" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" v1 "kusionstack.io/kusion/pkg/apis/status/v1" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/terraform/tfops" diff --git a/pkg/engine/runtime/terraform/terraform_runtime_test.go b/pkg/engine/runtime/terraform/terraform_runtime_test.go index 2409fbc1..fa476d27 100644 --- a/pkg/engine/runtime/terraform/terraform_runtime_test.go +++ b/pkg/engine/runtime/terraform/terraform_runtime_test.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/afero" "github.com/stretchr/testify/assert" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/engine/runtime/terraform/tfops" ) diff --git a/pkg/engine/runtime/terraform/tfops/state.go b/pkg/engine/runtime/terraform/tfops/state.go index d0f7ebf0..1ec0efcf 100644 --- a/pkg/engine/runtime/terraform/tfops/state.go +++ b/pkg/engine/runtime/terraform/tfops/state.go @@ -5,7 +5,7 @@ import ( "github.com/zclconf/go-cty/cty" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // StateRepresentation is the top-level representation of the json format of a terraform diff --git a/pkg/engine/runtime/terraform/tfops/state_test.go b/pkg/engine/runtime/terraform/tfops/state_test.go index 8c8c7a18..595c4c00 100644 --- a/pkg/engine/runtime/terraform/tfops/state_test.go +++ b/pkg/engine/runtime/terraform/tfops/state_test.go @@ -5,7 +5,7 @@ import ( "github.com/google/go-cmp/cmp" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) var providerAddr = "registry.terraform.io/hashicorp/local/2.2.3" diff --git a/pkg/engine/runtime/terraform/tfops/workspace.go b/pkg/engine/runtime/terraform/tfops/workspace.go index a23c1bf8..7333fa03 100644 --- a/pkg/engine/runtime/terraform/tfops/workspace.go +++ b/pkg/engine/runtime/terraform/tfops/workspace.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/hcl/v2/hclparse" "github.com/spf13/afero" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/util/io" jsonutil "kusionstack.io/kusion/pkg/util/json" diff --git a/pkg/engine/runtime/terraform/tfops/workspace_test.go b/pkg/engine/runtime/terraform/tfops/workspace_test.go index 7b04ec8d..0d0d1802 100644 --- a/pkg/engine/runtime/terraform/tfops/workspace_test.go +++ b/pkg/engine/runtime/terraform/tfops/workspace_test.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/afero" "github.com/zclconf/go-cty/cty" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" jsonutil "kusionstack.io/kusion/pkg/util/json" ) diff --git a/pkg/engine/spec/storage.go b/pkg/engine/spec/storage.go index 98e2d9a2..27bc9917 100644 --- a/pkg/engine/spec/storage.go +++ b/pkg/engine/spec/storage.go @@ -1,13 +1,13 @@ package spec -import v1 "kusionstack.io/kusion/pkg/apis/core/v1" +import v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" // Storage is an interface that may be implemented by the application // to retrieve or create spec entries from storage. type Storage interface { // Get returns the Spec, if the Spec does not exist, return nil. - Get() (*v1.Intent, error) + Get() (*v1.Spec, error) // Apply updates the spec if already exists, or create a new spec. - Apply(state *v1.Intent) error + Apply(state *v1.Spec) error } diff --git a/pkg/engine/spec/storages/local.go b/pkg/engine/spec/storages/local.go index b0b75346..71c8dfd6 100644 --- a/pkg/engine/spec/storages/local.go +++ b/pkg/engine/spec/storages/local.go @@ -8,7 +8,7 @@ import ( "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" ) @@ -28,7 +28,7 @@ func NewLocalStorage(path string) *LocalStorage { } // Get returns the Spec, if the Spec does not exist, return nil. -func (s *LocalStorage) Get() (*v1.Intent, error) { +func (s *LocalStorage) Get() (*v1.Spec, error) { content, err := os.ReadFile(s.path) if err != nil && !os.IsNotExist(err) { return nil, err @@ -39,7 +39,7 @@ func (s *LocalStorage) Get() (*v1.Intent, error) { return nil, nil } - state := &v1.Intent{} + state := &v1.Spec{} err = yaml.Unmarshal(content, state) if err != nil { return nil, err @@ -48,7 +48,7 @@ func (s *LocalStorage) Get() (*v1.Intent, error) { } // Apply updates the spec if already exists, or create a new spec. -func (s *LocalStorage) Apply(state *v1.Intent) error { +func (s *LocalStorage) Apply(state *v1.Spec) error { if err := os.MkdirAll(filepath.Dir(s.path), os.ModePerm); err != nil { fmt.Println(err) } diff --git a/pkg/engine/spec/storages/oss.go b/pkg/engine/spec/storages/oss.go index faccc336..d50e81ae 100644 --- a/pkg/engine/spec/storages/oss.go +++ b/pkg/engine/spec/storages/oss.go @@ -7,7 +7,7 @@ import ( "github.com/aliyun/aliyun-oss-go-sdk/oss" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" ) @@ -30,7 +30,7 @@ func NewOssStorage(bucket *oss.Bucket, key string) *OssStorage { } // Get returns the Spec, if the Spec does not exist, return nil. -func (s *OssStorage) Get() (*v1.Intent, error) { +func (s *OssStorage) Get() (*v1.Spec, error) { var exist bool body, err := s.bucket.GetObject(s.key) if err != nil { @@ -56,7 +56,7 @@ func (s *OssStorage) Get() (*v1.Intent, error) { return nil, nil } - intent := &v1.Intent{} + intent := &v1.Spec{} err = yaml.Unmarshal(content, intent) if err != nil { return nil, err @@ -65,7 +65,7 @@ func (s *OssStorage) Get() (*v1.Intent, error) { } // Apply updates the spec if already exists, or create a new spec. -func (s *OssStorage) Apply(intent *v1.Intent) error { +func (s *OssStorage) Apply(intent *v1.Spec) error { content, err := yaml.Marshal(intent) if err != nil { return err diff --git a/pkg/engine/spec/storages/s3.go b/pkg/engine/spec/storages/s3.go index 5cf03460..50168e7c 100644 --- a/pkg/engine/spec/storages/s3.go +++ b/pkg/engine/spec/storages/s3.go @@ -9,7 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/spec" ) @@ -34,7 +34,7 @@ func NewS3Storage(s3 *s3.S3, bucket, key string) *S3Storage { } // Get returns the Spec, if the Spec does not exist, return nil. -func (s *S3Storage) Get() (*v1.Intent, error) { +func (s *S3Storage) Get() (*v1.Spec, error) { input := &s3.GetObjectInput{ Bucket: aws.String(s.bucket), Key: &s.key, @@ -60,7 +60,7 @@ func (s *S3Storage) Get() (*v1.Intent, error) { return nil, nil } - intent := &v1.Intent{} + intent := &v1.Spec{} err = yaml.Unmarshal(content, intent) if err != nil { return nil, err @@ -69,7 +69,7 @@ func (s *S3Storage) Get() (*v1.Intent, error) { } // Apply updates the spec if already exists, or create a new spec. -func (s *S3Storage) Apply(intent *v1.Intent) error { +func (s *S3Storage) Apply(intent *v1.Spec) error { content, err := yaml.Marshal(intent) if err != nil { return err diff --git a/pkg/engine/state/storage.go b/pkg/engine/state/storage.go index 173bab38..1ef62943 100644 --- a/pkg/engine/state/storage.go +++ b/pkg/engine/state/storage.go @@ -1,7 +1,7 @@ package state import ( - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // Storage is used to provide the state storage for a set of real resources belonging to a specified stack, diff --git a/pkg/engine/state/storages/local.go b/pkg/engine/state/storages/local.go index 2122e3a0..f7672b36 100644 --- a/pkg/engine/state/storages/local.go +++ b/pkg/engine/state/storages/local.go @@ -8,7 +8,7 @@ import ( "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // LocalStorage is an implementation of state.Storage which uses local filesystem as storage. diff --git a/pkg/engine/state/storages/local_test.go b/pkg/engine/state/storages/local_test.go index fc58ed4f..d39bfa21 100644 --- a/pkg/engine/state/storages/local_test.go +++ b/pkg/engine/state/storages/local_test.go @@ -7,7 +7,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockState() *v1.State { diff --git a/pkg/engine/state/storages/mysql.go b/pkg/engine/state/storages/mysql.go index dcc197c8..9a899fde 100644 --- a/pkg/engine/state/storages/mysql.go +++ b/pkg/engine/state/storages/mysql.go @@ -6,7 +6,7 @@ import ( "gopkg.in/yaml.v3" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // MysqlStorage is an implementation of state.Storage which uses mysql as storage. diff --git a/pkg/engine/state/storages/mysql_test.go b/pkg/engine/state/storages/mysql_test.go index de104681..bdbe1f09 100644 --- a/pkg/engine/state/storages/mysql_test.go +++ b/pkg/engine/state/storages/mysql_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockStateMysqlDO() *StateMysqlDO { diff --git a/pkg/engine/state/storages/oss.go b/pkg/engine/state/storages/oss.go index e3d43993..a957b8dd 100644 --- a/pkg/engine/state/storages/oss.go +++ b/pkg/engine/state/storages/oss.go @@ -7,7 +7,7 @@ import ( "github.com/aliyun/aliyun-oss-go-sdk/oss" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // OssStorage is an implementation of state.Backend which uses oss as storage. diff --git a/pkg/engine/state/storages/oss_test.go b/pkg/engine/state/storages/oss_test.go index f7a92e1a..384ce555 100644 --- a/pkg/engine/state/storages/oss_test.go +++ b/pkg/engine/state/storages/oss_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockOssStorage() *OssStorage { diff --git a/pkg/engine/state/storages/s3.go b/pkg/engine/state/storages/s3.go index 03d7dd8f..3872c5e6 100644 --- a/pkg/engine/state/storages/s3.go +++ b/pkg/engine/state/storages/s3.go @@ -9,7 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // S3Storage is an implementation of state.Storage which uses s3 as storage. diff --git a/pkg/engine/state/storages/s3_test.go b/pkg/engine/state/storages/s3_test.go index e037363e..37cb304e 100644 --- a/pkg/engine/state/storages/s3_test.go +++ b/pkg/engine/state/storages/s3_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockS3Storage() *S3Storage { diff --git a/pkg/modules/generators/app_configurations_generator.go b/pkg/modules/generators/app_configurations_generator.go index 49bca720..fb0a06b4 100644 --- a/pkg/modules/generators/app_configurations_generator.go +++ b/pkg/modules/generators/app_configurations_generator.go @@ -12,7 +12,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "kcl-lang.io/kpm/pkg/package" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/log" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/generators/workload" @@ -24,7 +25,7 @@ type appConfigurationGenerator struct { project string stack string appName string - app *v1.AppConfiguration + app *internalv1.AppConfiguration ws *v1.Workspace dependencies *pkg.Dependencies } @@ -37,7 +38,7 @@ func NewAppConfigurationGenerator( project string, stack string, appName string, - app *v1.AppConfiguration, + app *internalv1.AppConfiguration, ws *v1.Workspace, dependencies *pkg.Dependencies, ) (modules.Generator, error) { @@ -54,7 +55,7 @@ func NewAppConfigurationGenerator( } if app == nil { - return nil, fmt.Errorf("can not find app configuration when generating the Intent") + return nil, fmt.Errorf("can not find app configuration when generating the Spec") } if ws == nil { @@ -79,7 +80,7 @@ func NewAppConfigurationGeneratorFunc( project string, stack string, appName string, - app *v1.AppConfiguration, + app *internalv1.AppConfiguration, ws *v1.Workspace, kpmDependencies *pkg.Dependencies, ) modules.NewGeneratorFunc { @@ -88,7 +89,7 @@ func NewAppConfigurationGeneratorFunc( } } -func (g *appConfigurationGenerator) Generate(spec *v1.Intent) error { +func (g *appConfigurationGenerator) Generate(spec *v1.Spec) error { if spec.Resources == nil { spec.Resources = make(v1.Resources, 0) } @@ -151,7 +152,7 @@ func (g *appConfigurationGenerator) Generate(spec *v1.Intent) error { return nil } -func patchWorkload(workload *v1.Resource, patcher *v1.Patcher) error { +func patchWorkload(workload *v1.Resource, patcher *internalv1.Patcher) error { if patcher == nil { return nil } @@ -252,13 +253,13 @@ func patchWorkload(workload *v1.Resource, patcher *v1.Patcher) error { // moduleConfig represents the configuration of a module, either devConfig or platformConfig can be nil type moduleConfig struct { - devConfig v1.Accessory + devConfig internalv1.Accessory platformConfig v1.GenericConfig } func (g *appConfigurationGenerator) callModules( projectModuleConfigs map[string]v1.GenericConfig, dependencies *pkg.Dependencies, -) (resources []v1.Resource, patchers []v1.Patcher, err error) { +) (resources []v1.Resource, patchers []internalv1.Patcher, err error) { pluginMap := make(map[string]*modules.Plugin) defer func() { for _, plugin := range pluginMap { @@ -325,7 +326,7 @@ func (g *appConfigurationGenerator) callModules( } // parse patcher for _, patcher := range response.Patchers { - temp := &v1.Patcher{} + temp := &internalv1.Patcher{} err = yaml.Unmarshal(patcher, temp) if err != nil { return nil, nil, err @@ -338,7 +339,7 @@ func (g *appConfigurationGenerator) callModules( } func buildModuleConfigIndex( - accessories map[string]v1.Accessory, + accessories map[string]internalv1.Accessory, projectModuleConfigs map[string]v1.GenericConfig, dependencies *pkg.Dependencies, ) (map[string]moduleConfig, error) { @@ -367,7 +368,7 @@ func buildModuleConfigIndex( return indexModuleConfig, nil } -func parseModuleKey(accessory v1.Accessory, dependencies *pkg.Dependencies) (string, error) { +func parseModuleKey(accessory internalv1.Accessory, dependencies *pkg.Dependencies) (string, error) { split := strings.Split(accessory["_type"].(string), ".") moduleName := split[0] // find module namespace and version diff --git a/pkg/modules/generators/app_configurations_generator_test.go b/pkg/modules/generators/app_configurations_generator_test.go index 6620c9a8..4bf8fac7 100644 --- a/pkg/modules/generators/app_configurations_generator_test.go +++ b/pkg/modules/generators/app_configurations_generator_test.go @@ -15,13 +15,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" pkg "kcl-lang.io/kpm/pkg/package" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/proto" jsonutil "kusionstack.io/kusion/pkg/util/json" - - "kusionstack.io/kusion/pkg/apis/core/v1/workload" ) type fakeModule struct{} @@ -92,7 +90,7 @@ func TestAppConfigurationGenerator_Generate_CustomNamespace(t *testing.T) { dependencies: dep, } - spec := &v1.Intent{ + spec := &v1.Spec{ Resources: []v1.Resource{}, } @@ -145,7 +143,7 @@ func TestNewAppConfigurationGeneratorFunc(t *testing.T) { t.Run("Nil app", func(t *testing.T) { g, err := NewAppConfigurationGeneratorFunc("tesstproject", "test", appName, nil, ws, nil)() - assert.EqualError(t, err, "can not find app configuration when generating the Intent") + assert.EqualError(t, err, "can not find app configuration when generating the Spec") assert.Nil(t, g) }) @@ -162,16 +160,16 @@ func TestNewAppConfigurationGeneratorFunc(t *testing.T) { }) } -func buildMockApp() (string, *v1.AppConfiguration) { - return "app1", &v1.AppConfiguration{ - Workload: &workload.Workload{ - Header: workload.Header{ - Type: workload.TypeService, +func buildMockApp() (string, *internalv1.AppConfiguration) { + return "app1", &internalv1.AppConfiguration{ + Workload: &internalv1.Workload{ + Header: internalv1.Header{ + Type: internalv1.TypeService, }, - Service: &workload.Service{ - Base: workload.Base{}, + Service: &internalv1.Service{ + Base: internalv1.Base{}, Type: "Deployment", - Ports: []network.Port{ + Ports: []internalv1.Port{ { Port: 80, Protocol: "TCP", @@ -285,7 +283,7 @@ func Test_patchWorkload(t *testing.T) { } t.Run("Patch labels and annotations", func(t *testing.T) { - patcher := &v1.Patcher{ + patcher := &internalv1.Patcher{ Labels: map[string]string{"newLabel": "newValue"}, Annotations: map[string]string{"newAnnotation": "newValue"}, } @@ -314,7 +312,7 @@ func Test_patchWorkload(t *testing.T) { }) t.Run("Patch environment variables", func(t *testing.T) { - patcher := &v1.Patcher{ + patcher := &internalv1.Patcher{ Environments: []corev1.EnvVar{ { Name: "NEW_ENV", diff --git a/pkg/modules/generators/doc.go b/pkg/modules/generators/doc.go index 0b9da377..2f3f45d6 100644 --- a/pkg/modules/generators/doc.go +++ b/pkg/modules/generators/doc.go @@ -1,5 +1,5 @@ -// Package generators contains all codes about the Intent generator mechanism. -// It is a feature about kusion that can make Kusion more general in generating Intent and decoupled with KCLVM. +// Package generators contains all codes about the Spec generator mechanism. +// It is a feature about kusion that can make Kusion more general in generating Spec and decoupled with KCLVM. // Any generator implements the generator interface can be integrated in Kusion operation workflow. // // This mechanism is very meaningful to Kusion and makes the foundation to support other languages in the feature. diff --git a/pkg/modules/generators/namespace_generator.go b/pkg/modules/generators/namespace_generator.go index efde976d..ef24ec9c 100644 --- a/pkg/modules/generators/namespace_generator.go +++ b/pkg/modules/generators/namespace_generator.go @@ -4,7 +4,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" ) @@ -24,9 +24,9 @@ func NewNamespaceGeneratorFunc(namespace string) modules.NewGeneratorFunc { } } -func (g *namespaceGenerator) Generate(i *apiv1.Intent) error { +func (g *namespaceGenerator) Generate(i *v1.Spec) error { if i.Resources == nil { - i.Resources = make(apiv1.Resources, 0) + i.Resources = make(v1.Resources, 0) } ns := &corev1.Namespace{ @@ -45,5 +45,5 @@ func (g *namespaceGenerator) Generate(i *apiv1.Intent) error { } } - return modules.AppendToIntent(apiv1.Kubernetes, id, i, ns) + return modules.AppendToSpec(v1.Kubernetes, id, i, ns) } diff --git a/pkg/modules/generators/namespace_generator_test.go b/pkg/modules/generators/namespace_generator_test.go index 1a75d32a..cdbc7eda 100644 --- a/pkg/modules/generators/namespace_generator_test.go +++ b/pkg/modules/generators/namespace_generator_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func Test_namespaceGenerator_Generate(t *testing.T) { @@ -13,13 +13,13 @@ func Test_namespaceGenerator_Generate(t *testing.T) { namespace string } type args struct { - intent *apiv1.Intent + Spec *v1.Spec } tests := []struct { name string fields fields args args - want *apiv1.Intent + want *v1.Spec wantErr bool }{ { @@ -28,10 +28,10 @@ func Test_namespaceGenerator_Generate(t *testing.T) { namespace: "fakeNs", }, args: args{ - intent: &apiv1.Intent{}, + Spec: &v1.Spec{}, }, - want: &apiv1.Intent{ - Resources: []apiv1.Resource{ + want: &v1.Spec{ + Resources: []v1.Resource{ { ID: "v1:Namespace:fakeNs", Type: "Kubernetes", @@ -60,10 +60,10 @@ func Test_namespaceGenerator_Generate(t *testing.T) { g := &namespaceGenerator{ namespace: tt.fields.namespace, } - if err := g.Generate(tt.args.intent); (err != nil) != tt.wantErr { + if err := g.Generate(tt.args.Spec); (err != nil) != tt.wantErr { t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr) } - require.Equal(t, tt.want, tt.args.intent) + require.Equal(t, tt.want, tt.args.Spec) }) } } diff --git a/pkg/modules/generators/ordered_resources_generator.go b/pkg/modules/generators/ordered_resources_generator.go index 8b58c45c..87758f3b 100644 --- a/pkg/modules/generators/ordered_resources_generator.go +++ b/pkg/modules/generators/ordered_resources_generator.go @@ -3,7 +3,7 @@ package generators import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/runtime" "kusionstack.io/kusion/pkg/modules" ) @@ -60,9 +60,9 @@ func NewOrderedResourcesGeneratorFunc(multipleOrderedKinds ...[]string) modules. } // Generate inject the dependsOn of resources in a specified order. -func (g *orderedResourcesGenerator) Generate(itt *apiv1.Intent) error { +func (g *orderedResourcesGenerator) Generate(itt *v1.Spec) error { if itt.Resources == nil { - itt.Resources = make(apiv1.Resources, 0) + itt.Resources = make(v1.Resources, 0) } for i := 0; i < len(itt.Resources); i++ { @@ -79,7 +79,7 @@ func (g *orderedResourcesGenerator) Generate(itt *apiv1.Intent) error { return nil } -type resource apiv1.Resource +type resource v1.Resource // kubernetesKind returns the kubernetes kind of the given resource. func (r resource) kubernetesKind() string { @@ -89,7 +89,7 @@ func (r resource) kubernetesKind() string { } // injectDependsOn injects all dependsOn relationships for the given resource and dependent kinds. -func (r *resource) injectDependsOn(orderedKinds []string, rs []apiv1.Resource) { +func (r *resource) injectDependsOn(orderedKinds []string, rs []v1.Resource) { kinds := r.findDependKinds(orderedKinds) for _, kind := range kinds { drs := findDependResources(kind, rs) @@ -98,7 +98,7 @@ func (r *resource) injectDependsOn(orderedKinds []string, rs []apiv1.Resource) { } // appendDependsOn injects dependsOn relationships for the given resource and dependent resources. -func (r *resource) appendDependsOn(dependResources []*apiv1.Resource) { +func (r *resource) appendDependsOn(dependResources []*v1.Resource) { for _, dr := range dependResources { r.DependsOn = append(r.DependsOn, dr.ID) } @@ -118,8 +118,8 @@ func (r *resource) findDependKinds(orderedKinds []string) []string { } // findDependResources returns the dependent resources of the specified kind. -func findDependResources(dependKind string, rs []apiv1.Resource) []*apiv1.Resource { - var dependResources []*apiv1.Resource +func findDependResources(dependKind string, rs []v1.Resource) []*v1.Resource { + var dependResources []*v1.Resource for i := 0; i < len(rs); i++ { if resource(rs[i]).kubernetesKind() == dependKind { dependResources = append(dependResources, &rs[i]) diff --git a/pkg/modules/generators/ordered_resources_generator_test.go b/pkg/modules/generators/ordered_resources_generator_test.go index 00ae0aea..d642117d 100644 --- a/pkg/modules/generators/ordered_resources_generator_test.go +++ b/pkg/modules/generators/ordered_resources_generator_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/engine/runtime" ) @@ -17,10 +17,10 @@ var ( "namespace": "foo", "name": "bar", }, - "intent": map[string]interface{}{ + "Spec": map[string]interface{}{ "replica": 1, "template": map[string]interface{}{ - "intent": map[string]interface{}{ + "Spec": map[string]interface{}{ "containers": []map[string]interface{}{ { "image": "foo.bar.com:v1", @@ -46,9 +46,9 @@ var ( "name": "foo", }, } - genOldSpec = func() *apiv1.Intent { - return &apiv1.Intent{ - Resources: apiv1.Resources{ + genOldSpec = func() *v1.Spec { + return &v1.Spec{ + Resources: v1.Resources{ { ID: "apps/v1:Deployment:foo:bar", Type: runtime.Kubernetes, @@ -67,9 +67,9 @@ var ( }, } } - genNewSpec = func() *apiv1.Intent { - return &apiv1.Intent{ - Resources: apiv1.Resources{ + genNewSpec = func() *v1.Spec { + return &v1.Spec{ + Resources: v1.Resources{ { ID: "apps/v1:Deployment:foo:bar", Type: runtime.Kubernetes, @@ -123,7 +123,7 @@ func TestInjectAllDependsOn(t *testing.T) { dependKinds := []string{"Namespace"} expected := []string{"v1:Namespace:foo"} - actual := resource([]apiv1.Resource(spec.Resources)[0]) + actual := resource([]v1.Resource(spec.Resources)[0]) actual.injectDependsOn(dependKinds, spec.Resources) assert.Equal(t, expected, actual.DependsOn) @@ -166,7 +166,7 @@ func TestFindDependResources(t *testing.T) { dependKind := "Namespace" resources := genOldSpec().Resources - expected := []*apiv1.Resource{ + expected := []*v1.Resource{ { ID: "v1:Namespace:foo", Type: runtime.Kubernetes, diff --git a/pkg/modules/generators/workload/job_generator.go b/pkg/modules/generators/workload/job_generator.go index 8a3c4250..106cb93f 100644 --- a/pkg/modules/generators/workload/job_generator.go +++ b/pkg/modules/generators/workload/job_generator.go @@ -7,8 +7,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" ) @@ -16,8 +16,8 @@ type jobGenerator struct { project string stack string appName string - job *workload.Job - jobConfig apiv1.GenericConfig + job *internalv1.Job + jobConfig v1.GenericConfig namespace string } @@ -27,7 +27,7 @@ func NewJobGenerator(generator *Generator) (modules.Generator, error) { stack: generator.Stack, appName: generator.App, job: generator.Workload.Job, - jobConfig: generator.PlatformConfigs[workload.ModuleJob], + jobConfig: generator.PlatformConfigs[internalv1.ModuleJob], namespace: generator.Namespace, }, nil } @@ -38,14 +38,14 @@ func NewJobGeneratorFunc(generator *Generator) modules.NewGeneratorFunc { } } -func (g *jobGenerator) Generate(spec *apiv1.Intent) error { +func (g *jobGenerator) Generate(spec *v1.Spec) error { job := g.job if job == nil { return nil } if spec.Resources == nil { - spec.Resources = make(apiv1.Resources, 0) + spec.Resources = make(v1.Resources, 0) } if err := completeBaseWorkload(&g.job.Base, g.jobConfig); err != nil { @@ -74,8 +74,8 @@ func (g *jobGenerator) Generate(spec *apiv1.Intent) error { for _, cm := range configMaps { cmObj := cm cmObj.Namespace = g.namespace - if err = modules.AppendToIntent( - apiv1.Kubernetes, + if err = modules.AppendToSpec( + v1.Kubernetes, modules.KubernetesResourceID(cmObj.TypeMeta, cmObj.ObjectMeta), spec, &cmObj, @@ -112,7 +112,7 @@ func (g *jobGenerator) Generate(spec *apiv1.Intent) error { }, Spec: jobSpec, } - return modules.AppendToIntent(apiv1.Kubernetes, modules.KubernetesResourceID(resource.TypeMeta, resource.ObjectMeta), spec, resource) + return modules.AppendToSpec(v1.Kubernetes, modules.KubernetesResourceID(resource.TypeMeta, resource.ObjectMeta), spec, resource) } resource := &batchv1.CronJob{ @@ -128,5 +128,5 @@ func (g *jobGenerator) Generate(spec *apiv1.Intent) error { Schedule: job.Schedule, }, } - return modules.AppendToIntent(apiv1.Kubernetes, modules.KubernetesResourceID(resource.TypeMeta, resource.ObjectMeta), spec, resource) + return modules.AppendToSpec(v1.Kubernetes, modules.KubernetesResourceID(resource.TypeMeta, resource.ObjectMeta), spec, resource) } diff --git a/pkg/modules/generators/workload/job_generator_test.go b/pkg/modules/generators/workload/job_generator_test.go index 14ed922d..ae49b691 100644 --- a/pkg/modules/generators/workload/job_generator_test.go +++ b/pkg/modules/generators/workload/job_generator_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" ) @@ -15,12 +15,12 @@ func TestNewJobGenerator(t *testing.T) { expectedProject := "test" expectedStack := "dev" expectedAppName := "test" - expectedJob := &workload.Job{} - expectedJobConfig := apiv1.GenericConfig{ - "labels": apiv1.GenericConfig{ + expectedJob := &internalv1.Job{} + expectedJobConfig := v1.GenericConfig{ + "labels": v1.GenericConfig{ "Workload-type": "Job", }, - "annotations": apiv1.GenericConfig{ + "annotations": v1.GenericConfig{ "Workload-type": "Job", }, } @@ -29,11 +29,11 @@ func TestNewJobGenerator(t *testing.T) { Stack: expectedStack, App: expectedAppName, Namespace: expectedAppName, - Workload: &workload.Workload{ + Workload: &internalv1.Workload{ Job: expectedJob, }, - PlatformConfigs: map[string]apiv1.GenericConfig{ - workload.ModuleJob: expectedJobConfig, + PlatformConfigs: map[string]v1.GenericConfig{ + internalv1.ModuleJob: expectedJobConfig, }, }) @@ -50,12 +50,12 @@ func TestNewJobGeneratorFunc(t *testing.T) { expectedProject := "test" expectedStack := "dev" expectedAppName := "test" - expectedJob := &workload.Job{} - expectedJobConfig := apiv1.GenericConfig{ - "labels": apiv1.GenericConfig{ + expectedJob := &internalv1.Job{} + expectedJobConfig := v1.GenericConfig{ + "labels": v1.GenericConfig{ "workload-type": "Job", }, - "annotations": apiv1.GenericConfig{ + "annotations": v1.GenericConfig{ "workload-type": "Job", }, } @@ -64,11 +64,11 @@ func TestNewJobGeneratorFunc(t *testing.T) { Stack: expectedStack, App: expectedAppName, Namespace: expectedAppName, - Workload: &workload.Workload{ + Workload: &internalv1.Workload{ Job: expectedJob, }, - PlatformConfigs: map[string]apiv1.GenericConfig{ - workload.ModuleJob: expectedJobConfig, + PlatformConfigs: map[string]v1.GenericConfig{ + internalv1.ModuleJob: expectedJobConfig, }, }) actualGenerator, err := generatorFunc() @@ -88,20 +88,20 @@ func TestJobGenerator_Generate(t *testing.T) { expectedProject string expectedStack string expectedAppName string - expectedJob *workload.Job - expectedJobConfig apiv1.GenericConfig + expectedJob *internalv1.Job + expectedJobConfig v1.GenericConfig }{ { name: "test generate", expectedProject: "test", expectedStack: "dev", expectedAppName: "test", - expectedJob: &workload.Job{}, - expectedJobConfig: apiv1.GenericConfig{ - "labels": apiv1.GenericConfig{ + expectedJob: &internalv1.Job{}, + expectedJobConfig: v1.GenericConfig{ + "labels": v1.GenericConfig{ "workload-type": "Job", }, - "annotations": apiv1.GenericConfig{ + "annotations": v1.GenericConfig{ "workload-type": "Job", }, }, @@ -115,14 +115,14 @@ func TestJobGenerator_Generate(t *testing.T) { Stack: tc.expectedStack, App: tc.expectedAppName, Namespace: tc.expectedAppName, - Workload: &workload.Workload{ + Workload: &internalv1.Workload{ Job: tc.expectedJob, }, - PlatformConfigs: map[string]apiv1.GenericConfig{ - workload.ModuleJob: tc.expectedJobConfig, + PlatformConfigs: map[string]v1.GenericConfig{ + internalv1.ModuleJob: tc.expectedJobConfig, }, }) - spec := &apiv1.Intent{} + spec := &v1.Spec{} err := generator.Generate(spec) assert.NoError(t, err, "Error should be nil") diff --git a/pkg/modules/generators/workload/secret/secret_generator.go b/pkg/modules/generators/workload/secret/secret_generator.go index 47e2279b..20bcdbbb 100644 --- a/pkg/modules/generators/workload/secret/secret_generator.go +++ b/pkg/modules/generators/workload/secret/secret_generator.go @@ -8,12 +8,12 @@ import ( "strings" "golang.org/x/exp/maps" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/secrets" ) @@ -21,8 +21,8 @@ import ( type secretGenerator struct { project string namespace string - secrets map[string]workload.Secret - secretStoreSpec *apiv1.SecretStoreSpec + secrets map[string]internalv1.Secret + secretStoreSpec *v1.SecretStoreSpec } type GeneratorRequest struct { @@ -31,9 +31,9 @@ type GeneratorRequest struct { // Namespace represents the K8s Namespace Namespace string // Workload represents the Workload configuration - Workload *workload.Workload + Workload *internalv1.Workload // SecretStoreSpec contains configuration to describe target secret store. - SecretStoreSpec *apiv1.SecretStoreSpec + SecretStoreSpec *v1.SecretStoreSpec } func NewSecretGenerator(request *GeneratorRequest) (modules.Generator, error) { @@ -41,7 +41,7 @@ func NewSecretGenerator(request *GeneratorRequest) (modules.Generator, error) { return nil, fmt.Errorf("project name must not be empty") } - var secretMap map[string]workload.Secret + var secretMap map[string]internalv1.Secret if request.Workload.Service != nil { secretMap = request.Workload.Service.Secrets } else { @@ -62,9 +62,9 @@ func NewSecretGeneratorFunc(request *GeneratorRequest) modules.NewGeneratorFunc } } -func (g *secretGenerator) Generate(spec *apiv1.Intent) error { +func (g *secretGenerator) Generate(spec *v1.Spec) error { if spec.Resources == nil { - spec.Resources = make(apiv1.Resources, 0) + spec.Resources = make(v1.Resources, 0) } for secretName, secretRef := range g.secrets { @@ -74,8 +74,8 @@ func (g *secretGenerator) Generate(spec *apiv1.Intent) error { } resourceID := modules.KubernetesResourceID(secret.TypeMeta, secret.ObjectMeta) - err = modules.AppendToIntent( - apiv1.Kubernetes, + err = modules.AppendToSpec( + v1.Kubernetes, resourceID, spec, secret, @@ -91,7 +91,7 @@ func (g *secretGenerator) Generate(spec *apiv1.Intent) error { // generateSecret generates target secret based on secret type. Most of these secret types are just semantic wrapper // of native Kubernetes secret types:https://kubernetes.io/docs/concepts/configuration/secret/#secret-types, and more // detailed usage info can be found in public documentation. -func (g *secretGenerator) generateSecret(secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func (g *secretGenerator) generateSecret(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { switch secretRef.Type { case "basic": return g.generateBasic(secretName, secretRef) @@ -110,11 +110,11 @@ func (g *secretGenerator) generateSecret(secretName string, secretRef workload.S // generateBasic generates secret used for basic authentication. The basic secret type // is used for username / password pairs. -func (g *secretGenerator) generateBasic(secretName string, secretRef workload.Secret) (*v1.Secret, error) { - secret := initBasicSecret(g.namespace, secretName, v1.SecretTypeBasicAuth, secretRef.Immutable) - secret.Data = grabData(secretRef.Data, v1.BasicAuthUsernameKey, v1.BasicAuthPasswordKey) +func (g *secretGenerator) generateBasic(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { + secret := initBasicSecret(g.namespace, secretName, corev1.SecretTypeBasicAuth, secretRef.Immutable) + secret.Data = grabData(secretRef.Data, corev1.BasicAuthUsernameKey, corev1.BasicAuthPasswordKey) - for _, key := range []string{v1.BasicAuthUsernameKey, v1.BasicAuthPasswordKey} { + for _, key := range []string{corev1.BasicAuthUsernameKey, corev1.BasicAuthPasswordKey} { if len(secret.Data[key]) == 0 { v := GenerateRandomString(54) secret.Data[key] = []byte(v) @@ -126,8 +126,8 @@ func (g *secretGenerator) generateBasic(secretName string, secretRef workload.Se // generateToken generates secret used for password. Token secrets are useful for generating // a password or secure string used for passwords when the user is already known or not required. -func (g *secretGenerator) generateToken(secretName string, secretRef workload.Secret) (*v1.Secret, error) { - secret := initBasicSecret(g.namespace, secretName, v1.SecretTypeOpaque, secretRef.Immutable) +func (g *secretGenerator) generateToken(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { + secret := initBasicSecret(g.namespace, secretName, corev1.SecretTypeOpaque, secretRef.Immutable) secret.Data = grabData(secretRef.Data, "token") if len(secret.Data["token"]) == 0 { @@ -139,29 +139,29 @@ func (g *secretGenerator) generateToken(secretName string, secretRef workload.Se } // generateOpaque generates secret used for arbitrary user-defined data. -func (g *secretGenerator) generateOpaque(secretName string, secretRef workload.Secret) (*v1.Secret, error) { - secret := initBasicSecret(g.namespace, secretName, v1.SecretTypeOpaque, secretRef.Immutable) +func (g *secretGenerator) generateOpaque(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { + secret := initBasicSecret(g.namespace, secretName, corev1.SecretTypeOpaque, secretRef.Immutable) secret.Data = grabData(secretRef.Data, maps.Keys(secretRef.Data)...) return secret, nil } // generateCertificate generates secret used for storing a certificate and its associated key. // One common use for TLS Secrets is to configure encryption in transit for an Ingress, but -// you can also use it with other resources or directly in your workload. -func (g *secretGenerator) generateCertificate(secretName string, secretRef workload.Secret) (*v1.Secret, error) { - secret := initBasicSecret(g.namespace, secretName, v1.SecretTypeTLS, secretRef.Immutable) - secret.Data = grabData(secretRef.Data, v1.TLSCertKey, v1.TLSPrivateKeyKey) +// you can also use it with other resources or directly in your internalv1. +func (g *secretGenerator) generateCertificate(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { + secret := initBasicSecret(g.namespace, secretName, corev1.SecretTypeTLS, secretRef.Immutable) + secret.Data = grabData(secretRef.Data, corev1.TLSCertKey, corev1.TLSPrivateKeyKey) return secret, nil } // generateSecretWithExternalProvider retrieves target sensitive information from external secret provider and // generates corresponding Kubernetes Secret object. -func (g *secretGenerator) generateSecretWithExternalProvider(secretName string, secretRef workload.Secret) (*v1.Secret, error) { +func (g *secretGenerator) generateSecretWithExternalProvider(secretName string, secretRef internalv1.Secret) (*corev1.Secret, error) { if g.secretStoreSpec == nil { return nil, errors.New("secret store is missing, please add valid secret store spec in workspace") } - secret := initBasicSecret(g.namespace, secretName, v1.SecretTypeOpaque, secretRef.Immutable) + secret := initBasicSecret(g.namespace, secretName, corev1.SecretTypeOpaque, secretRef.Immutable) secret.Data = make(map[string][]byte) var allErrs []error @@ -212,13 +212,13 @@ func grabData(from map[string]string, keys ...string) map[string][]byte { // parseExternalSecretDataRef knows how to parse the remote data ref string, returns the // corresponding ExternalSecretRef object. -func parseExternalSecretDataRef(dataRefStr string) (*apiv1.ExternalSecretRef, error) { +func parseExternalSecretDataRef(dataRefStr string) (*v1.ExternalSecretRef, error) { uri, err := url.Parse(dataRefStr) if err != nil { return nil, err } - ref := &apiv1.ExternalSecretRef{} + ref := &v1.ExternalSecretRef{} if len(uri.Path) > 0 { partialName, property := parsePath(uri.Path) if len(partialName) > 0 { @@ -250,10 +250,10 @@ func parsePath(path string) (partialName string, property string) { return partialName, property } -func initBasicSecret(namespace, name string, secretType v1.SecretType, immutable bool) *v1.Secret { - secret := &v1.Secret{ +func initBasicSecret(namespace, name string, secretType corev1.SecretType, immutable bool) *corev1.Secret { + secret := &corev1.Secret{ TypeMeta: metav1.TypeMeta{ - APIVersion: v1.SchemeGroupVersion.String(), + APIVersion: corev1.SchemeGroupVersion.String(), Kind: "Secret", }, ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/modules/generators/workload/secret/secret_generator_test.go b/pkg/modules/generators/workload/secret/secret_generator_test.go index 47fb2a4e..a2b5423e 100644 --- a/pkg/modules/generators/workload/secret/secret_generator_test.go +++ b/pkg/modules/generators/workload/secret/secret_generator_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/require" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" // ensure we can get correct secret store provider _ "kusionstack.io/kusion/pkg/secrets/providers/register" ) @@ -16,14 +16,14 @@ var testProject = "helloworld" func initGeneratorRequest( project string, - secrets map[string]workload.Secret, - secretStoreSpec *apiv1.SecretStoreSpec, + secrets map[string]internalv1.Secret, + secretStoreSpec *v1.SecretStoreSpec, ) *GeneratorRequest { return &GeneratorRequest{ Project: project, - Workload: &workload.Workload{ - Service: &workload.Service{ - Base: workload.Base{ + Workload: &internalv1.Workload{ + Service: &internalv1.Service{ + Base: internalv1.Base{ Secrets: secrets, }, }, @@ -33,10 +33,10 @@ func initGeneratorRequest( } } -func initSecretStoreSpec(data []apiv1.FakeProviderData) *apiv1.SecretStoreSpec { - return &apiv1.SecretStoreSpec{ - Provider: &apiv1.ProviderSpec{ - Fake: &apiv1.FakeProvider{ +func initSecretStoreSpec(data []v1.FakeProviderData) *v1.SecretStoreSpec { + return &v1.SecretStoreSpec{ + Provider: &v1.ProviderSpec{ + Fake: &v1.FakeProvider{ Data: data, }, }, @@ -106,7 +106,7 @@ func TestGenerateSecret(t *testing.T) { // run all the tests for name, test := range tests { t.Run(name, func(t *testing.T) { - secrets := map[string]workload.Secret{ + secrets := map[string]internalv1.Secret{ name: { Type: test.secretType, Data: test.secretData, @@ -114,7 +114,7 @@ func TestGenerateSecret(t *testing.T) { } context := initGeneratorRequest(testProject, secrets, nil) generator, _ := NewSecretGenerator(context) - err := generator.Generate(&apiv1.Intent{}) + err := generator.Generate(&v1.Spec{}) if test.expectErr == "" { require.NoError(t, err) } else { @@ -131,7 +131,7 @@ func TestGenerateSecretWithExternalRef(t *testing.T) { secretType string secretData map[string]string - providerData []apiv1.FakeProviderData + providerData []v1.FakeProviderData expectErr string }{ @@ -142,7 +142,7 @@ func TestGenerateSecretWithExternalRef(t *testing.T) { "accessKey": "ref://api-auth-info/accessKey?version=1", "secretKey": "ref://api-auth-info/secretKey?version=1", }, - providerData: []apiv1.FakeProviderData{ + providerData: []v1.FakeProviderData{ { Key: "api-auth-info", Value: `{"accessKey":"some sensitive info","secretKey":"*******"}`, @@ -156,7 +156,7 @@ func TestGenerateSecretWithExternalRef(t *testing.T) { secretData: map[string]string{ "accessToken": "ref://token?version=1", }, - providerData: []apiv1.FakeProviderData{ + providerData: []v1.FakeProviderData{ { Key: "token-info", Value: "some sensitive info", @@ -170,7 +170,7 @@ func TestGenerateSecretWithExternalRef(t *testing.T) { // run all the tests for name, test := range tests { t.Run(name, func(t *testing.T) { - secrets := map[string]workload.Secret{ + secrets := map[string]internalv1.Secret{ name: { Type: test.secretType, Data: test.secretData, @@ -179,7 +179,7 @@ func TestGenerateSecretWithExternalRef(t *testing.T) { secretStoreSpec := initSecretStoreSpec(test.providerData) context := initGeneratorRequest(testProject, secrets, secretStoreSpec) generator, _ := NewSecretGenerator(context) - err := generator.Generate(&apiv1.Intent{}) + err := generator.Generate(&v1.Spec{}) if test.expectErr == "" { require.NoError(t, err) } else { @@ -194,7 +194,7 @@ func TestParseExternalSecretDataRef(t *testing.T) { tests := []struct { name string dataRefStr string - want *apiv1.ExternalSecretRef + want *v1.ExternalSecretRef wantErr bool }{ { @@ -206,7 +206,7 @@ func TestParseExternalSecretDataRef(t *testing.T) { { name: "only secret name", dataRefStr: "ref://secret-name", - want: &apiv1.ExternalSecretRef{ + want: &v1.ExternalSecretRef{ Name: "secret-name", }, wantErr: false, @@ -214,7 +214,7 @@ func TestParseExternalSecretDataRef(t *testing.T) { { name: "secret name with version", dataRefStr: "ref://secret-name?version=1", - want: &apiv1.ExternalSecretRef{ + want: &v1.ExternalSecretRef{ Name: "secret-name", Version: "1", }, @@ -223,7 +223,7 @@ func TestParseExternalSecretDataRef(t *testing.T) { { name: "secret name with property and version", dataRefStr: "ref://secret-name/property?version=1", - want: &apiv1.ExternalSecretRef{ + want: &v1.ExternalSecretRef{ Name: "secret-name", Property: "property", Version: "1", @@ -233,7 +233,7 @@ func TestParseExternalSecretDataRef(t *testing.T) { { name: "nested secret name with property and version", dataRefStr: "ref://customer/acme/customer_name?version=1", - want: &apiv1.ExternalSecretRef{ + want: &v1.ExternalSecretRef{ Name: "customer/acme", Property: "customer_name", Version: "1", diff --git a/pkg/modules/generators/workload/service_generator.go b/pkg/modules/generators/workload/service_generator.go index 585f3542..8fc5ea5c 100644 --- a/pkg/modules/generators/workload/service_generator.go +++ b/pkg/modules/generators/workload/service_generator.go @@ -9,9 +9,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "kusionstack.io/kube-api/apps/v1alpha1" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" + apiv1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/workspace" ) @@ -30,7 +29,7 @@ type ServiceGenerator struct { Stack string App string Namespace string - Service *workload.Service + Service *internalv1.Service Config apiv1.GenericConfig } @@ -53,7 +52,7 @@ func NewWorkloadServiceGenerator(request *Generator) (modules.Generator, error) Stack: request.Stack, App: request.App, Service: request.Workload.Service, - Config: request.PlatformConfigs[workload.ModuleService], + Config: request.PlatformConfigs[internalv1.ModuleService], Namespace: request.Namespace, }, nil } @@ -66,7 +65,7 @@ func NewWorkloadServiceGeneratorFunc(workloadGenerator *Generator) modules.NewGe } // Generate generates a Service Workload resource to the given spec. -func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { +func (g *ServiceGenerator) Generate(spec *apiv1.Spec) error { service := g.Service if service == nil { return nil @@ -94,7 +93,7 @@ func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { for _, cm := range configMaps { cmObj := cm cmObj.Namespace = g.Namespace - if err = modules.AppendToIntent( + if err = modules.AppendToSpec( apiv1.Kubernetes, modules.KubernetesResourceID(cmObj.TypeMeta, cmObj.ObjectMeta), spec, @@ -131,10 +130,10 @@ func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { typeMeta := metav1.TypeMeta{} switch service.Type { - case workload.Deployment: + case internalv1.Deployment: typeMeta = metav1.TypeMeta{ APIVersion: appsv1.SchemeGroupVersion.String(), - Kind: string(workload.Deployment), + Kind: string(internalv1.Deployment), } spec := appsv1.DeploymentSpec{ Replicas: service.Replicas, @@ -146,10 +145,10 @@ func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { ObjectMeta: objectMeta, Spec: spec, } - case workload.Collaset: + case internalv1.Collaset: typeMeta = metav1.TypeMeta{ APIVersion: v1alpha1.GroupVersion.String(), - Kind: string(workload.Collaset), + Kind: string(internalv1.Collaset), } resource = &v1alpha1.CollaSet{ TypeMeta: typeMeta, @@ -163,7 +162,7 @@ func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { } // Add the Deployment resource to the spec. - if err = modules.AppendToIntent(apiv1.Kubernetes, modules.KubernetesResourceID(typeMeta, objectMeta), spec, resource); err != nil { + if err = modules.AppendToSpec(apiv1.Kubernetes, modules.KubernetesResourceID(typeMeta, objectMeta), spec, resource); err != nil { return err } @@ -179,7 +178,7 @@ func (g *ServiceGenerator) Generate(spec *apiv1.Intent) error { return nil } -func validatePorts(ports []network.Port) error { +func validatePorts(ports []internalv1.Port) error { portProtocolRecord := make(map[string]struct{}) for _, port := range ports { if err := validatePort(&port); err != nil { @@ -196,20 +195,20 @@ func validatePorts(ports []network.Port) error { return nil } -func validatePort(port *network.Port) error { +func validatePort(port *internalv1.Port) error { if port.Port < 1 || port.Port > 65535 { return ErrInvalidPort } if port.TargetPort < 0 || port.Port > 65535 { return ErrInvalidTargetPort } - if port.Protocol != network.TCP && port.Protocol != network.UDP { + if port.Protocol != internalv1.TCP && port.Protocol != internalv1.UDP { return ErrInvalidProtocol } return nil } -func validate(selectors map[string]string, ports []network.Port) error { +func validate(selectors map[string]string, ports []internalv1.Port) error { if len(selectors) == 0 { return ErrEmptySelectors } @@ -219,7 +218,7 @@ func validate(selectors map[string]string, ports []network.Port) error { return nil } -func complete(ports []network.Port) error { +func complete(ports []internalv1.Port) error { for i := range ports { if ports[i].TargetPort == 0 { ports[i].TargetPort = ports[i].Port @@ -228,20 +227,20 @@ func complete(ports []network.Port) error { return nil } -func completeServiceInput(service *workload.Service, config apiv1.GenericConfig) error { +func completeServiceInput(service *internalv1.Service, config apiv1.GenericConfig) error { if err := completeBaseWorkload(&service.Base, config); err != nil { return err } - serviceTypeStr, err := workspace.GetStringFromGenericConfig(config, workload.ModuleServiceType) - platformServiceType := workload.ServiceType(serviceTypeStr) + serviceTypeStr, err := workspace.GetStringFromGenericConfig(config, internalv1.ModuleServiceType) + platformServiceType := internalv1.ServiceType(serviceTypeStr) if err != nil { return err } // if not set in workspace, use Deployment as default type if platformServiceType == "" { - platformServiceType = workload.Deployment + platformServiceType = internalv1.Deployment } - if platformServiceType != workload.Deployment && platformServiceType != workload.Collaset { + if platformServiceType != internalv1.Deployment && platformServiceType != internalv1.Collaset { return fmt.Errorf("unsupported Service type %s", platformServiceType) } if service.Type == "" { diff --git a/pkg/modules/generators/workload/service_generator_test.go b/pkg/modules/generators/workload/service_generator_test.go index 0ac1eea6..1f2f03f7 100644 --- a/pkg/modules/generators/workload/service_generator_test.go +++ b/pkg/modules/generators/workload/service_generator_test.go @@ -8,11 +8,8 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/container" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" - - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" ) func Test_workloadServiceGenerator_Generate(t *testing.T) { @@ -169,11 +166,11 @@ status: {} project string stack string appName string - service *workload.Service - serviceConfig apiv1.GenericConfig + service *internalv1.Service + serviceConfig v1.GenericConfig } type args struct { - spec *apiv1.Intent + spec *v1.Spec } tests := []struct { @@ -189,12 +186,12 @@ status: {} project: "default", stack: "dev", appName: "foo", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", - Files: map[string]container.FileSpec{ + Files: map[string]internalv1.FileSpec{ "/tmp/example.txt": { Content: "some file contents", Mode: "0777", @@ -204,25 +201,25 @@ status: {} }, Replicas: r2, }, - Ports: []network.Port{ + Ports: []internalv1.Port{ { Port: 80, Protocol: "TCP", }, }, }, - serviceConfig: apiv1.GenericConfig{ + serviceConfig: v1.GenericConfig{ "type": "CollaSet", - "labels": apiv1.GenericConfig{ + "labels": v1.GenericConfig{ "service-workload-type": "CollaSet", }, - "annotations": apiv1.GenericConfig{ + "annotations": v1.GenericConfig{ "service-workload-type": "CollaSet", }, }, }, args: args{ - spec: &apiv1.Intent{}, + spec: &v1.Spec{}, }, wantErr: false, want: []string{cm, cs, csSvc}, @@ -233,12 +230,12 @@ status: {} project: "default", stack: "dev", appName: "foo", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", - Files: map[string]container.FileSpec{ + Files: map[string]internalv1.FileSpec{ "/tmp/example.txt": { Content: "some file contents", Mode: "0777", @@ -247,22 +244,22 @@ status: {} }, }, }, - Ports: []network.Port{ + Ports: []internalv1.Port{ { Port: 80, Protocol: "TCP", }, }, }, - serviceConfig: apiv1.GenericConfig{ + serviceConfig: v1.GenericConfig{ "replicas": 4, - "labels": apiv1.GenericConfig{ + "labels": v1.GenericConfig{ "service-workload-type": "Deployment", }, }, }, args: args{ - spec: &apiv1.Intent{}, + spec: &v1.Spec{}, }, wantErr: false, want: []string{cm, deploy, deploySvc}, @@ -295,16 +292,16 @@ func TestCompleteServiceInput(t *testing.T) { testcases := []struct { name string - service *workload.Service - config apiv1.GenericConfig + service *internalv1.Service + config v1.GenericConfig success bool - completedService *workload.Service + completedService *internalv1.Service }{ { name: "use type in workspace config", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -318,13 +315,13 @@ func TestCompleteServiceInput(t *testing.T) { }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "type": "CollaSet", }, success: true, - completedService: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + completedService: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -342,9 +339,9 @@ func TestCompleteServiceInput(t *testing.T) { }, { name: "use default type", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -360,9 +357,9 @@ func TestCompleteServiceInput(t *testing.T) { }, config: nil, success: true, - completedService: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + completedService: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -380,9 +377,9 @@ func TestCompleteServiceInput(t *testing.T) { }, { name: "invalid field type", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -396,7 +393,7 @@ func TestCompleteServiceInput(t *testing.T) { }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "type": 1, }, success: false, @@ -404,9 +401,9 @@ func TestCompleteServiceInput(t *testing.T) { }, { name: "unsupported type", - service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -420,7 +417,7 @@ func TestCompleteServiceInput(t *testing.T) { }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "type": "unsupported", }, success: false, diff --git a/pkg/modules/generators/workload/workload_generator.go b/pkg/modules/generators/workload/workload_generator.go index 6ab521c6..40514327 100644 --- a/pkg/modules/generators/workload/workload_generator.go +++ b/pkg/modules/generators/workload/workload_generator.go @@ -14,9 +14,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/container" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" "kusionstack.io/kusion/pkg/modules/generators/workload/secret" "kusionstack.io/kusion/pkg/util/net" @@ -33,11 +32,11 @@ type Generator struct { // Namespace represents the K8s Namespace Namespace string // Workload represents the Workload configuration - Workload *workload.Workload + Workload *internalv1.Workload // PlatformConfigs represents the module platform configurations - PlatformConfigs map[string]apiv1.GenericConfig + PlatformConfigs map[string]v1.GenericConfig // SecretStoreSpec contains configuration to describe target secret store. - SecretStoreSpec *apiv1.SecretStoreSpec + SecretStoreSpec *v1.SecretStoreSpec } func NewWorkloadGeneratorFunc(g *Generator) modules.NewGeneratorFunc { @@ -58,23 +57,23 @@ func NewWorkloadGeneratorFunc(g *Generator) modules.NewGeneratorFunc { } } -func (g *Generator) Generate(spec *apiv1.Intent) error { +func (g *Generator) Generate(spec *v1.Spec) error { if spec.Resources == nil { - spec.Resources = make(apiv1.Resources, 0) + spec.Resources = make(v1.Resources, 0) } if g.Workload != nil { var gfs []modules.NewGeneratorFunc switch g.Workload.Header.Type { - case workload.TypeService: + case internalv1.TypeService: gfs = append(gfs, NewWorkloadServiceGeneratorFunc(g), secret.NewSecretGeneratorFunc(&secret.GeneratorRequest{ Project: g.Project, Namespace: g.Namespace, Workload: g.Workload, SecretStoreSpec: g.SecretStoreSpec, })) - case workload.TypeJob: + case internalv1.TypeJob: gfs = append(gfs, NewJobGeneratorFunc(g), secret.NewSecretGeneratorFunc(&secret.GeneratorRequest{ Project: g.Project, Namespace: g.Namespace, @@ -92,7 +91,7 @@ func (g *Generator) Generate(spec *apiv1.Intent) error { } func toOrderedContainers( - appContainers map[string]container.Container, + appContainers map[string]internalv1.Container, uniqueAppName string, ) ([]corev1.Container, []corev1.Volume, []corev1.ConfigMap, error) { // Create a slice of containers based on the App's containers. @@ -103,7 +102,7 @@ func toOrderedContainers( var volumeMounts []corev1.VolumeMount var configMaps []corev1.ConfigMap - if err := modules.ForeachOrdered(appContainers, func(containerName string, c container.Container) error { + if err := modules.ForeachOrdered(appContainers, func(containerName string, c internalv1.Container) error { // Create a slice of env vars based on the container's env vars. var envs []corev1.EnvVar for _, m := range c.Env { @@ -154,7 +153,7 @@ func toOrderedContainers( } // updateContainer updates corev1.Container with passed parameters. -func updateContainer(in *container.Container, out *corev1.Container) error { +func updateContainer(in *internalv1.Container, out *corev1.Container) error { if in.ReadinessProbe != nil { readinessProbe, err := convertKusionProbeToV1Probe(in.ReadinessProbe) if err != nil { @@ -245,7 +244,7 @@ func populateResourceLists(name corev1.ResourceName, spec string) (corev1.Resour } // convertKusionProbeToV1Probe converts Kusion Probe to Kubernetes Probe types. -func convertKusionProbeToV1Probe(p *container.Probe) (*corev1.Probe, error) { +func convertKusionProbeToV1Probe(p *internalv1.Probe) (*corev1.Probe, error) { result := &corev1.Probe{ InitialDelaySeconds: p.InitialDelaySeconds, TimeoutSeconds: p.TimeoutSeconds, @@ -274,7 +273,7 @@ func convertKusionProbeToV1Probe(p *container.Probe) (*corev1.Probe, error) { } // convertKusionLifecycleToV1Lifecycle converts Kusion Lifecycle to Kubernetes Lifecycle types. -func convertKusionLifecycleToV1Lifecycle(l *container.Lifecycle) (*corev1.Lifecycle, error) { +func convertKusionLifecycleToV1Lifecycle(l *internalv1.Lifecycle) (*corev1.Lifecycle, error) { result := &corev1.Lifecycle{} if l.PreStop != nil { preStop, err := lifecycleHandler(l.PreStop) @@ -293,7 +292,7 @@ func convertKusionLifecycleToV1Lifecycle(l *container.Lifecycle) (*corev1.Lifecy return result, nil } -func lifecycleHandler(in *container.LifecycleHandler) (*corev1.LifecycleHandler, error) { +func lifecycleHandler(in *internalv1.LifecycleHandler) (*corev1.LifecycleHandler, error) { result := &corev1.LifecycleHandler{} switch in.Type { case "Http": @@ -350,14 +349,14 @@ func tcpSocketAction(urlstr string) (*corev1.TCPSocketAction, error) { // handleFileCreation handles the creation of the files declared in container.Files // and returns the generated ConfigMap, Volume and VolumeMount. -func handleFileCreation(c container.Container, uniqueAppName, containerName string) ( +func handleFileCreation(c internalv1.Container, uniqueAppName, containerName string) ( volumes []corev1.Volume, volumeMounts []corev1.VolumeMount, configMaps []corev1.ConfigMap, err error, ) { var idx int - err = modules.ForeachOrdered(c.Files, func(k string, v container.FileSpec) error { + err = modules.ForeachOrdered(c.Files, func(k string, v internalv1.FileSpec) error { // The declared file path needs to include the file name. if filepath.Base(k) == "." || filepath.Base(k) == "/" { return fmt.Errorf("the declared file path needs to include the file name") @@ -436,7 +435,7 @@ func handleFileCreation(c container.Container, uniqueAppName, containerName stri // handleDirCreation handles the creation of folder declared in container.Dirs and returns // the generated Volume and VolumeMount. -func handleDirCreation(c container.Container) (volumes []corev1.Volume, volumeMounts []corev1.VolumeMount, err error) { +func handleDirCreation(c internalv1.Container) (volumes []corev1.Volume, volumeMounts []corev1.VolumeMount, err error) { err = modules.ForeachOrdered(c.Dirs, func(mountPath string, v string) error { sec, ok, parseErr := parseSecretReference(v) if parseErr != nil || !ok { @@ -462,8 +461,8 @@ func handleDirCreation(c container.Container) (volumes []corev1.Volume, volumeMo } // completeBaseWorkload uses config from workspace to complete the Workload base config. -func completeBaseWorkload(base *workload.Base, config apiv1.GenericConfig) error { - replicas, err := workspace.GetInt32PointerFromGenericConfig(config, workload.FieldReplicas) +func completeBaseWorkload(base *internalv1.Base, config v1.GenericConfig) error { + replicas, err := workspace.GetInt32PointerFromGenericConfig(config, internalv1.FieldReplicas) if err != nil { return err } @@ -472,7 +471,7 @@ func completeBaseWorkload(base *workload.Base, config apiv1.GenericConfig) error if base.Replicas == nil { base.Replicas = replicas } - labels, err := workspace.GetStringMapFromGenericConfig(config, workload.FieldLabels) + labels, err := workspace.GetStringMapFromGenericConfig(config, internalv1.FieldLabels) if err != nil { return err } @@ -481,7 +480,7 @@ func completeBaseWorkload(base *workload.Base, config apiv1.GenericConfig) error return err } } - annotations, err := workspace.GetStringMapFromGenericConfig(config, workload.FieldAnnotations) + annotations, err := workspace.GetStringMapFromGenericConfig(config, internalv1.FieldAnnotations) if err != nil { return err } diff --git a/pkg/modules/generators/workload/workload_generator_test.go b/pkg/modules/generators/workload/workload_generator_test.go index 9efecedf..522788e8 100644 --- a/pkg/modules/generators/workload/workload_generator_test.go +++ b/pkg/modules/generators/workload/workload_generator_test.go @@ -7,21 +7,18 @@ import ( "github.com/stretchr/testify/assert" "gopkg.in/yaml.v2" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/container" - "kusionstack.io/kusion/pkg/apis/core/v1/workload/network" - - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" - "kusionstack.io/kusion/pkg/apis/core/v1/workload" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" + internalv1 "kusionstack.io/kusion/pkg/apis/internal.kusion.io/v1" "kusionstack.io/kusion/pkg/modules" ) func TestNewWorkloadGeneratorFunc(t *testing.T) { t.Run("NewWorkloadGeneratorFunc should return a valid generator function", func(t *testing.T) { - expectedWorkload := &workload.Workload{} + expectedWorkload := &internalv1.Workload{} expectedAppName := "test" expectedProject := "test" expectedStack := "test" - expectedModuleConfigs := map[string]apiv1.GenericConfig{ + expectedModuleConfigs := map[string]v1.GenericConfig{ "service": { "type": "Deployment", }, @@ -53,17 +50,17 @@ func TestNewWorkloadGeneratorFunc(t *testing.T) { func TestWorkloadGenerator_Generate(t *testing.T) { testCases := []struct { name string - expectedWorkload *workload.Workload + expectedWorkload *internalv1.Workload }{ { name: "Generate should generate the expected service", - expectedWorkload: &workload.Workload{ - Header: workload.Header{ - Type: workload.TypeService, + expectedWorkload: &internalv1.Workload{ + Header: internalv1.Header{ + Type: internalv1.TypeService, }, - Service: &workload.Service{ - Base: workload.Base{}, - Ports: []network.Port{ + Service: &internalv1.Service{ + Base: internalv1.Base{}, + Ports: []internalv1.Port{ { Port: 80, Protocol: "TCP", @@ -74,12 +71,12 @@ func TestWorkloadGenerator_Generate(t *testing.T) { }, { name: "Generate should generate the expected job", - expectedWorkload: &workload.Workload{ - Header: workload.Header{ - Type: workload.TypeJob, + expectedWorkload: &internalv1.Workload{ + Header: internalv1.Header{ + Type: internalv1.TypeJob, }, - Job: &workload.Job{ - Base: workload.Base{}, + Job: &internalv1.Job{ + Base: internalv1.Base{}, Schedule: "* * * * *", }, }, @@ -91,7 +88,7 @@ func TestWorkloadGenerator_Generate(t *testing.T) { expectedProject := "test" expectedStack := "test" expectedAppName := "test" - expectedModuleConfigs := map[string]apiv1.GenericConfig{ + expectedModuleConfigs := map[string]v1.GenericConfig{ "service": { "type": "Deployment", }, @@ -110,7 +107,7 @@ func TestWorkloadGenerator_Generate(t *testing.T) { }) actualGenerator, err := generatorFunc() assert.NoError(t, err, "generator func Error should be nil") - spec := &apiv1.Intent{} + spec := &v1.Spec{} err = actualGenerator.Generate(spec) assert.NoError(t, err, "Error should be nil") assert.NotNil(t, spec.Resources, "Resources should not be nil") @@ -140,23 +137,23 @@ func TestGenerate(t *testing.T) { project string stack string application string - workload *workload.Workload + workload *internalv1.Workload }{ { name: "simple service workload", project: "helloworld", stack: "dev", application: "nginx", - workload: &workload.Workload{ - Header: workload.Header{ - Type: workload.TypeService, + workload: &internalv1.Workload{ + Header: internalv1.Header{ + Type: internalv1.TypeService, }, - Service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + Service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "main": { Image: "nginx:latest", - Files: map[string]container.FileSpec{ + Files: map[string]internalv1.FileSpec{ "/run/secret/password": { ContentFrom: "secret://sec-name/key?mode=0400", Mode: "0644", @@ -165,7 +162,7 @@ func TestGenerate(t *testing.T) { }, }, }, - Type: workload.Deployment, + Type: internalv1.Deployment, }, }, }, @@ -174,19 +171,19 @@ func TestGenerate(t *testing.T) { project: "beep", stack: "test", application: "nginx", - workload: &workload.Workload{ - Header: workload.Header{ - Type: workload.TypeService, + workload: &internalv1.Workload{ + Header: internalv1.Header{ + Type: internalv1.TypeService, }, - Service: &workload.Service{ - Base: workload.Base{ - Containers: map[string]container.Container{ + Service: &internalv1.Service{ + Base: internalv1.Base{ + Containers: map[string]internalv1.Container{ "main": { Image: "nginx:latest", Dirs: map[string]string{ "/var/tmp-secret": "secret://other-sec-name", }, - Files: map[string]container.FileSpec{ + Files: map[string]internalv1.FileSpec{ "/run/secret/password": { ContentFrom: "secret://sec-name/key?mode=0400", Mode: "0644", @@ -195,7 +192,7 @@ func TestGenerate(t *testing.T) { }, }, }, - Type: workload.Deployment, + Type: internalv1.Deployment, }, }, }, @@ -209,7 +206,7 @@ func TestGenerate(t *testing.T) { App: tc.application, Workload: tc.workload, } - spec := &apiv1.Intent{} + spec := &v1.Spec{} err := g.Generate(spec) assert.NoError(t, err, "Error should be nil") }) @@ -218,12 +215,12 @@ func TestGenerate(t *testing.T) { func TestToOrderedContainers(t *testing.T) { t.Run("toOrderedContainers should convert app containers to ordered containers", func(t *testing.T) { - appContainers := make(map[string]container.Container) - appContainers["container1"] = container.Container{ + appContainers := make(map[string]internalv1.Container) + appContainers["container1"] = internalv1.Container{ Image: "image1", Env: make(yaml.MapSlice, 0), } - appContainers["container2"] = container.Container{ + appContainers["container2"] = internalv1.Container{ Image: "image2", Env: yaml.MapSlice{ { @@ -232,9 +229,9 @@ func TestToOrderedContainers(t *testing.T) { }, }, } - appContainers["container3"] = container.Container{ + appContainers["container3"] = internalv1.Container{ Image: "image3", - Files: map[string]container.FileSpec{ + Files: map[string]internalv1.FileSpec{ "/tmp/example1/file.txt": { Content: "some file contents", Mode: "0777", @@ -269,29 +266,29 @@ func TestToOrderedContainers(t *testing.T) { assert.Equal(t, wantedConfigMapData, actualConfigMaps[1].Data, "ConfigMap data mismatch") }) t.Run("toOrderedContainers should convert app containers with probe to ordered containers", func(t *testing.T) { - appContainers := map[string]container.Container{ + appContainers := map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", Resources: map[string]string{ "cpu": "2-4", "memory": "4Gi-8Gi", }, - LivenessProbe: &container.Probe{ - ProbeHandler: &container.ProbeHandler{ - TypeWrapper: container.TypeWrapper{ + LivenessProbe: &internalv1.Probe{ + ProbeHandler: &internalv1.ProbeHandler{ + TypeWrapper: internalv1.TypeWrapper{ Type: "Exec", }, - ExecAction: &container.ExecAction{ + ExecAction: &internalv1.ExecAction{ Command: []string{"/bin/sh", "-c", "echo live"}, }, }, }, - ReadinessProbe: &container.Probe{ - ProbeHandler: &container.ProbeHandler{ - TypeWrapper: container.TypeWrapper{ + ReadinessProbe: &internalv1.Probe{ + ProbeHandler: &internalv1.ProbeHandler{ + TypeWrapper: internalv1.TypeWrapper{ Type: "Http", }, - HTTPGetAction: &container.HTTPGetAction{ + HTTPGetAction: &internalv1.HTTPGetAction{ URL: "http://localhost:8080/readiness", Headers: map[string]string{ "header": "value", @@ -300,12 +297,12 @@ func TestToOrderedContainers(t *testing.T) { }, InitialDelaySeconds: 10, }, - StartupProbe: &container.Probe{ - ProbeHandler: &container.ProbeHandler{ - TypeWrapper: container.TypeWrapper{ + StartupProbe: &internalv1.Probe{ + ProbeHandler: &internalv1.ProbeHandler{ + TypeWrapper: internalv1.TypeWrapper{ Type: "Tcp", }, - TCPSocketAction: &container.TCPSocketAction{ + TCPSocketAction: &internalv1.TCPSocketAction{ URL: "10.0.0.1:8888", }, }, @@ -352,23 +349,23 @@ func TestToOrderedContainers(t *testing.T) { assert.Equal(t, "8888", actualContainers[0].StartupProbe.TCPSocket.Port.String(), "TCPSocket.Port mismatch") }) t.Run("toOrderedContainers should convert app containers with lifecycle to ordered containers", func(t *testing.T) { - appContainers := map[string]container.Container{ + appContainers := map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", - Lifecycle: &container.Lifecycle{ - PreStop: &container.LifecycleHandler{ - TypeWrapper: container.TypeWrapper{ + Lifecycle: &internalv1.Lifecycle{ + PreStop: &internalv1.LifecycleHandler{ + TypeWrapper: internalv1.TypeWrapper{ Type: "Exec", }, - ExecAction: &container.ExecAction{ + ExecAction: &internalv1.ExecAction{ Command: []string{"/bin/sh", "-c", "echo live"}, }, }, - PostStart: &container.LifecycleHandler{ - TypeWrapper: container.TypeWrapper{ + PostStart: &internalv1.LifecycleHandler{ + TypeWrapper: internalv1.TypeWrapper{ Type: "Http", }, - HTTPGetAction: &container.HTTPGetAction{ + HTTPGetAction: &internalv1.HTTPGetAction{ URL: "http://localhost:8080/readiness", Headers: map[string]string{ "header": "value", @@ -406,15 +403,15 @@ func TestCompleteBaseWorkload(t *testing.T) { testcases := []struct { name string - base *workload.Base - config apiv1.GenericConfig + base *internalv1.Base + config v1.GenericConfig success bool - completedBase *workload.Base + completedBase *internalv1.Base }{ { name: "successfully complete base", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -424,19 +421,19 @@ func TestCompleteBaseWorkload(t *testing.T) { "k2": "v2", }, }, - config: apiv1.GenericConfig{ - "labels": apiv1.GenericConfig{ + config: v1.GenericConfig{ + "labels": v1.GenericConfig{ "k1": "v1-ws", "k3": "v3-ws", }, - "annotations": apiv1.GenericConfig{ + "annotations": v1.GenericConfig{ "k1": "v1-ws", }, "replicas": 4, }, success: true, - completedBase: &workload.Base{ - Containers: map[string]container.Container{ + completedBase: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -454,8 +451,8 @@ func TestCompleteBaseWorkload(t *testing.T) { }, { name: "use base replicas", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -468,12 +465,12 @@ func TestCompleteBaseWorkload(t *testing.T) { "k1": "v1", }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "replicas": 4, }, success: true, - completedBase: &workload.Base{ - Containers: map[string]container.Container{ + completedBase: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -489,8 +486,8 @@ func TestCompleteBaseWorkload(t *testing.T) { }, { name: "use platform replicas", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -502,12 +499,12 @@ func TestCompleteBaseWorkload(t *testing.T) { "k1": "v1", }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "replicas": 4, }, success: true, - completedBase: &workload.Base{ - Containers: map[string]container.Container{ + completedBase: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, @@ -523,14 +520,14 @@ func TestCompleteBaseWorkload(t *testing.T) { }, { name: "invalid replicas config", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "replicas": "2", }, success: false, @@ -538,14 +535,14 @@ func TestCompleteBaseWorkload(t *testing.T) { }, { name: "invalid labels config", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "labels": "k1=v1", }, success: false, @@ -553,14 +550,14 @@ func TestCompleteBaseWorkload(t *testing.T) { }, { name: "invalid annotations config", - base: &workload.Base{ - Containers: map[string]container.Container{ + base: &internalv1.Base{ + Containers: map[string]internalv1.Container{ "nginx": { Image: "nginx:v1", }, }, }, - config: apiv1.GenericConfig{ + config: v1.GenericConfig{ "annotations": "k1=v1", }, success: false, diff --git a/pkg/modules/interfaces.go b/pkg/modules/interfaces.go index a0c8fc32..0b2907d3 100644 --- a/pkg/modules/interfaces.go +++ b/pkg/modules/interfaces.go @@ -7,7 +7,7 @@ import ( "github.com/pkg/errors" "google.golang.org/grpc" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/modules/proto" ) @@ -17,7 +17,7 @@ const PluginKey = "module-default" // todo it's for built-in generators and we should consider to convert it to a general Module interface type Generator interface { // Generate performs the intent generate operation. - Generate(intent *v1.Intent) error + Generate(intent *v1.Spec) error } // Module is the interface that we're exposing as a kusion module plugin. diff --git a/pkg/modules/util.go b/pkg/modules/util.go index 602fa5f4..4a35b35d 100644 --- a/pkg/modules/util.go +++ b/pkg/modules/util.go @@ -7,7 +7,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/workspace" ) @@ -27,7 +27,7 @@ func CallGeneratorFuncs(newGenerators ...NewGeneratorFunc) ([]Generator, error) // CallGenerators calls the Generate method of each Generator instance // returned by the given NewGeneratorFuncs. -func CallGenerators(i *apiv1.Intent, newGenerators ...NewGeneratorFunc) error { +func CallGenerators(i *v1.Spec, newGenerators ...NewGeneratorFunc) error { gs, err := CallGeneratorFuncs(newGenerators...) if err != nil { return err @@ -106,11 +106,11 @@ func KusionPathDependency(id, name string) string { return "$kusion_path." + id + "." + name } -// AppendToIntent adds a Kubernetes resource to the Intent resources slice. -func AppendToIntent(resourceType apiv1.Type, resourceID string, i *apiv1.Intent, resource any) error { +// AppendToSpec adds a Kubernetes resource to the Spec resources slice. +func AppendToSpec(resourceType v1.Type, resourceID string, i *v1.Spec, resource any) error { // this function is only used for Kubernetes resources - if resourceType != apiv1.Kubernetes { - return errors.New("AppendToIntent is only used for Kubernetes resources") + if resourceType != v1.Kubernetes { + return errors.New("AppendToSpec is only used for Kubernetes resources") } gvk := resource.(runtime.Object).GetObjectKind().GroupVersionKind().String() @@ -119,13 +119,13 @@ func AppendToIntent(resourceType apiv1.Type, resourceID string, i *apiv1.Intent, if err != nil { return err } - r := apiv1.Resource{ + r := v1.Resource{ ID: resourceID, Type: resourceType, Attributes: unstructured, DependsOn: nil, Extensions: map[string]any{ - apiv1.ResourceExtensionGVK: gvk, + v1.ResourceExtensionGVK: gvk, }, } i.Resources = append(i.Resources, r) @@ -146,7 +146,7 @@ func UniqueAppLabels(projectName, appName string) map[string]string { } // PatchResource patches the resource with the given patch. -func PatchResource[T any](resources map[string][]*apiv1.Resource, gvk string, patchFunc func(*T) error) error { +func PatchResource[T any](resources map[string][]*v1.Resource, gvk string, patchFunc func(*T) error) error { var obj T for _, r := range resources[gvk] { // convert unstructured to typed object @@ -170,18 +170,18 @@ func PatchResource[T any](resources map[string][]*apiv1.Resource, gvk string, pa // AddKubeConfigIf adds kubeConfig from workspace to extensions of Kubernetes type resource in intent. // If there is already has kubeConfig in extensions, use the kubeConfig in extensions. -func AddKubeConfigIf(i *apiv1.Intent, ws *apiv1.Workspace) { +func AddKubeConfigIf(i *v1.Spec, ws *v1.Workspace) { config := workspace.GetKubernetesConfig(ws.Runtimes) if config == nil || config.KubeConfig == "" { return } for n, resource := range i.Resources { - if resource.Type == apiv1.Kubernetes { + if resource.Type == v1.Kubernetes { if resource.Extensions == nil { i.Resources[n].Extensions = make(map[string]any) } - if extensionsKubeConfig, ok := resource.Extensions[apiv1.ResourceExtensionKubeConfig]; !ok || extensionsKubeConfig == "" { - i.Resources[n].Extensions[apiv1.ResourceExtensionKubeConfig] = config.KubeConfig + if extensionsKubeConfig, ok := resource.Extensions[v1.ResourceExtensionKubeConfig]; !ok || extensionsKubeConfig == "" { + i.Resources[n].Extensions[v1.ResourceExtensionKubeConfig] = config.KubeConfig } } } diff --git a/pkg/modules/util_test.go b/pkg/modules/util_test.go index ebeb1226..81e615d0 100644 --- a/pkg/modules/util_test.go +++ b/pkg/modules/util_test.go @@ -5,30 +5,30 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apiv1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) type mockGenerator struct { - GenerateFunc func(intent *apiv1.Intent) error + GenerateFunc func(Spec *v1.Spec) error } -func (m *mockGenerator) Generate(i *apiv1.Intent) error { +func (m *mockGenerator) Generate(i *v1.Spec) error { return m.GenerateFunc(i) } func TestCallGenerators(t *testing.T) { - i := &apiv1.Intent{} + i := &v1.Spec{} var ( generator1 Generator = &mockGenerator{ - GenerateFunc: func(intent *apiv1.Intent) error { + GenerateFunc: func(Spec *v1.Spec) error { return nil }, } generator2 Generator = &mockGenerator{ - GenerateFunc: func(intent *apiv1.Intent) error { + GenerateFunc: func(Spec *v1.Spec) error { return assert.AnError }, } @@ -106,12 +106,12 @@ func TestMergeMaps(t *testing.T) { } func TestKubernetesResourceID(t *testing.T) { - typeMeta := v1.TypeMeta{ + typeMeta := metav1.TypeMeta{ APIVersion: "apps/v1", Kind: "Deployment", } - objectMeta := v1.ObjectMeta{ + objectMeta := metav1.ObjectMeta{ Namespace: "example", Name: "my-deployment", } @@ -120,9 +120,9 @@ func TestKubernetesResourceID(t *testing.T) { assert.Equal(t, "apps/v1:Deployment:example:my-deployment", id) } -func TestAppendToIntent(t *testing.T) { - i := &apiv1.Intent{} - resource := &apiv1.Resource{ +func TestAppendToSpec(t *testing.T) { + i := &v1.Spec{} + resource := &v1.Resource{ ID: "v1:Namespace:fake-project", Type: "Kubernetes", Attributes: map[string]interface{}{ @@ -140,23 +140,23 @@ func TestAppendToIntent(t *testing.T) { } ns := &corev1.Namespace{ - TypeMeta: v1.TypeMeta{ + TypeMeta: metav1.TypeMeta{ Kind: "Namespace", APIVersion: "v1", }, - ObjectMeta: v1.ObjectMeta{ + ObjectMeta: metav1.ObjectMeta{ Name: "fake-project", }, } - err := AppendToIntent(apiv1.Kubernetes, resource.ID, i, ns) + err := AppendToSpec(v1.Kubernetes, resource.ID, i, ns) assert.NoError(t, err) assert.Len(t, i.Resources, 1) assert.Equal(t, resource.ID, i.Resources[0].ID) assert.Equal(t, resource.Type, i.Resources[0].Type) assert.Equal(t, resource.Attributes, i.Resources[0].Attributes) - assert.Equal(t, ns.GroupVersionKind().String(), i.Resources[0].Extensions[apiv1.ResourceExtensionGVK]) + assert.Equal(t, ns.GroupVersionKind().String(), i.Resources[0].Extensions[v1.ResourceExtensionGVK]) } func TestUniqueAppName(t *testing.T) { @@ -185,7 +185,7 @@ func TestUniqueAppLabels(t *testing.T) { } func TestPatchResource(t *testing.T) { - resources := map[string][]*apiv1.Resource{ + resources := map[string][]*v1.Resource{ "/v1, Kind=Namespace": { { ID: "v1:Namespace:default", @@ -223,16 +223,16 @@ func TestPatchResource(t *testing.T) { func TestAddKubeConfigIf(t *testing.T) { testcases := []struct { - name string - ws *apiv1.Workspace - i *apiv1.Intent - expectedIntent *apiv1.Intent + name string + ws *v1.Workspace + i *v1.Spec + expectedSpec *v1.Spec }{ { name: "empty workspace runtime config", - ws: &apiv1.Workspace{Name: "dev"}, - i: &apiv1.Intent{ - Resources: apiv1.Resources{ + ws: &v1.Workspace{Name: "dev"}, + i: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -243,8 +243,8 @@ func TestAddKubeConfigIf(t *testing.T) { }, }, }, - expectedIntent: &apiv1.Intent{ - Resources: apiv1.Resources{ + expectedSpec: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -258,14 +258,14 @@ func TestAddKubeConfigIf(t *testing.T) { }, { name: "empty kubeConfig in workspace", - ws: &apiv1.Workspace{ + ws: &v1.Workspace{ Name: "dev", - Runtimes: &apiv1.RuntimeConfigs{ - Kubernetes: &apiv1.KubernetesConfig{}, + Runtimes: &v1.RuntimeConfigs{ + Kubernetes: &v1.KubernetesConfig{}, }, }, - i: &apiv1.Intent{ - Resources: apiv1.Resources{ + i: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -276,8 +276,8 @@ func TestAddKubeConfigIf(t *testing.T) { }, }, }, - expectedIntent: &apiv1.Intent{ - Resources: apiv1.Resources{ + expectedSpec: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -291,16 +291,16 @@ func TestAddKubeConfigIf(t *testing.T) { }, { name: "add kubeConfig", - ws: &apiv1.Workspace{ + ws: &v1.Workspace{ Name: "dev", - Runtimes: &apiv1.RuntimeConfigs{ - Kubernetes: &apiv1.KubernetesConfig{ + Runtimes: &v1.RuntimeConfigs{ + Kubernetes: &v1.KubernetesConfig{ KubeConfig: "/etc/kubeConfig.yaml", }, }, }, - i: &apiv1.Intent{ - Resources: apiv1.Resources{ + i: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -349,8 +349,8 @@ func TestAddKubeConfigIf(t *testing.T) { }, }, }, - expectedIntent: &apiv1.Intent{ - Resources: apiv1.Resources{ + expectedSpec: &v1.Spec{ + Resources: v1.Resources{ { ID: "mock-id-1", Type: "Kubernetes", @@ -408,7 +408,7 @@ func TestAddKubeConfigIf(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { AddKubeConfigIf(tc.i, tc.ws) - assert.Equal(t, *tc.expectedIntent, *tc.i) + assert.Equal(t, *tc.expectedSpec, *tc.i) }) } } diff --git a/pkg/project/paths.go b/pkg/project/paths.go index 6fc3e6b9..928f2c92 100644 --- a/pkg/project/paths.go +++ b/pkg/project/paths.go @@ -11,7 +11,7 @@ import ( yamlv3 "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/util/sets" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/log" ) diff --git a/pkg/project/paths_test.go b/pkg/project/paths_test.go index 777f049f..3044fefd 100644 --- a/pkg/project/paths_test.go +++ b/pkg/project/paths_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/util/json" ) diff --git a/pkg/secrets/interfaces.go b/pkg/secrets/interfaces.go index 0184bd4a..488299d4 100644 --- a/pkg/secrets/interfaces.go +++ b/pkg/secrets/interfaces.go @@ -3,7 +3,7 @@ package secrets import ( "context" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // SecretStore provides the interface to interact with various cloud secret manager. diff --git a/pkg/secrets/providers.go b/pkg/secrets/providers.go index bb998e5a..46bad127 100644 --- a/pkg/secrets/providers.go +++ b/pkg/secrets/providers.go @@ -7,7 +7,7 @@ import ( "golang.org/x/exp/maps" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/log" ) diff --git a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go index 55d9f6e6..fb40fd41 100644 --- a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go +++ b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" "github.com/aliyun/aliyun-secretsmanager-client-go/sdk" diff --git a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go index aa180644..6f044135 100644 --- a/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go +++ b/pkg/secrets/providers/alicloud/secretsmanager/secretsmanager_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets/providers/alicloud/secretsmanager/fake" ) diff --git a/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go b/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go index 91ae2b6d..95f96d19 100644 --- a/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go +++ b/pkg/secrets/providers/aws/secretsmanager/secretsmanager.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" "github.com/tidwall/gjson" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" "kusionstack.io/kusion/pkg/secrets/providers/aws/auth" ) diff --git a/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go b/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go index ecc77b68..783ba193 100644 --- a/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go +++ b/pkg/secrets/providers/aws/secretsmanager/secretsmanager_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets/providers/aws/secretsmanager/fake" ) diff --git a/pkg/secrets/providers/azure/keyvault/keyvault.go b/pkg/secrets/providers/azure/keyvault/keyvault.go index 8b35ea6f..250875d5 100644 --- a/pkg/secrets/providers/azure/keyvault/keyvault.go +++ b/pkg/secrets/providers/azure/keyvault/keyvault.go @@ -13,7 +13,7 @@ import ( "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/tidwall/gjson" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" ) diff --git a/pkg/secrets/providers/azure/keyvault/keyvault_test.go b/pkg/secrets/providers/azure/keyvault/keyvault_test.go index 0f74b526..be956509 100644 --- a/pkg/secrets/providers/azure/keyvault/keyvault_test.go +++ b/pkg/secrets/providers/azure/keyvault/keyvault_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets/providers/azure/keyvault/fake" ) diff --git a/pkg/secrets/providers/fake/fake.go b/pkg/secrets/providers/fake/fake.go index b9cd7d35..3f005302 100644 --- a/pkg/secrets/providers/fake/fake.go +++ b/pkg/secrets/providers/fake/fake.go @@ -6,7 +6,7 @@ import ( "github.com/tidwall/gjson" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" ) diff --git a/pkg/secrets/providers/fake/fake_test.go b/pkg/secrets/providers/fake/fake_test.go index b82af163..1fc3af9c 100644 --- a/pkg/secrets/providers/fake/fake_test.go +++ b/pkg/secrets/providers/fake/fake_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" ) diff --git a/pkg/secrets/providers/hashivault/vault.go b/pkg/secrets/providers/hashivault/vault.go index da666132..901fc65e 100644 --- a/pkg/secrets/providers/hashivault/vault.go +++ b/pkg/secrets/providers/hashivault/vault.go @@ -13,7 +13,7 @@ import ( vault "github.com/hashicorp/vault/api" "github.com/tidwall/gjson" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets" ) diff --git a/pkg/secrets/providers/hashivault/vault_test.go b/pkg/secrets/providers/hashivault/vault_test.go index 3f954c3f..20067753 100644 --- a/pkg/secrets/providers/hashivault/vault_test.go +++ b/pkg/secrets/providers/hashivault/vault_test.go @@ -10,7 +10,7 @@ import ( "github.com/google/go-cmp/cmp" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" "kusionstack.io/kusion/pkg/secrets/providers/hashivault/fake" ) diff --git a/pkg/secrets/providers_test.go b/pkg/secrets/providers_test.go index 29cec9db..cd2e5fc2 100644 --- a/pkg/secrets/providers_test.go +++ b/pkg/secrets/providers_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - "kusionstack.io/kusion/pkg/apis/core/v1" + "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // FakeSecretStore is the fake implementation of SecretStore. diff --git a/pkg/workspace/storage.go b/pkg/workspace/storage.go index 95b4f7ff..cde29f59 100644 --- a/pkg/workspace/storage.go +++ b/pkg/workspace/storage.go @@ -1,7 +1,7 @@ package workspace import ( - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // Storage is used to provide the storage service for multiple workspaces. diff --git a/pkg/workspace/storages/local.go b/pkg/workspace/storages/local.go index 14497018..1cdb81e9 100644 --- a/pkg/workspace/storages/local.go +++ b/pkg/workspace/storages/local.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // LocalStorage is an implementation of workspace.Storage which uses local filesystem as storage. diff --git a/pkg/workspace/storages/local_test.go b/pkg/workspace/storages/local_test.go index 452fccb0..4a0bc92f 100644 --- a/pkg/workspace/storages/local_test.go +++ b/pkg/workspace/storages/local_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func testDataFolder(path string) string { diff --git a/pkg/workspace/storages/mysql.go b/pkg/workspace/storages/mysql.go index 4dc5f488..126744fd 100644 --- a/pkg/workspace/storages/mysql.go +++ b/pkg/workspace/storages/mysql.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // MysqlStorage is an implementation of workspace.Storage which uses mysql as storage. diff --git a/pkg/workspace/storages/mysql_test.go b/pkg/workspace/storages/mysql_test.go index 5d231b46..ae7e2c9d 100644 --- a/pkg/workspace/storages/mysql_test.go +++ b/pkg/workspace/storages/mysql_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "gorm.io/gorm" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockMysqlStorage() *MysqlStorage { diff --git a/pkg/workspace/storages/oss.go b/pkg/workspace/storages/oss.go index c521b75c..8d7d4522 100644 --- a/pkg/workspace/storages/oss.go +++ b/pkg/workspace/storages/oss.go @@ -8,7 +8,7 @@ import ( "github.com/aliyun/aliyun-oss-go-sdk/oss" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // OssStorage is an implementation of workspace.Storage which uses oss as storage. diff --git a/pkg/workspace/storages/oss_test.go b/pkg/workspace/storages/oss_test.go index 66d4014b..60d91bd1 100644 --- a/pkg/workspace/storages/oss_test.go +++ b/pkg/workspace/storages/oss_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockOssStorage(meta *workspacesMetaData) *OssStorage { diff --git a/pkg/workspace/storages/s3.go b/pkg/workspace/storages/s3.go index 6d141fae..5a1999e7 100644 --- a/pkg/workspace/storages/s3.go +++ b/pkg/workspace/storages/s3.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "gopkg.in/yaml.v3" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) // S3Storage is an implementation of workspace.Storage which uses s3 as storage. diff --git a/pkg/workspace/storages/s3_test.go b/pkg/workspace/storages/s3_test.go index a85af09a..0a485671 100644 --- a/pkg/workspace/storages/s3_test.go +++ b/pkg/workspace/storages/s3_test.go @@ -9,7 +9,7 @@ import ( "github.com/bytedance/mockey" "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockS3Storage(meta *workspacesMetaData) *S3Storage { diff --git a/pkg/workspace/util.go b/pkg/workspace/util.go index 3b37f513..11786751 100644 --- a/pkg/workspace/util.go +++ b/pkg/workspace/util.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) var ErrEmptyProjectName = errors.New("empty project name") diff --git a/pkg/workspace/util_test.go b/pkg/workspace/util_test.go index 9aa3d528..f2c41f41 100644 --- a/pkg/workspace/util_test.go +++ b/pkg/workspace/util_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockGenericConfig() v1.GenericConfig { diff --git a/pkg/workspace/validation.go b/pkg/workspace/validation.go index c9fee468..47a492e2 100644 --- a/pkg/workspace/validation.go +++ b/pkg/workspace/validation.go @@ -6,7 +6,7 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) var ( diff --git a/pkg/workspace/validation_test.go b/pkg/workspace/validation_test.go index 8c3bad01..9cb3c1a9 100644 --- a/pkg/workspace/validation_test.go +++ b/pkg/workspace/validation_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - v1 "kusionstack.io/kusion/pkg/apis/core/v1" + v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1" ) func mockValidWorkspace(name string) *v1.Workspace {