diff --git a/references/cli/common.go b/references/cli/common.go index 3505cb620..d8ab3e052 100644 --- a/references/cli/common.go +++ b/references/cli/common.go @@ -44,6 +44,8 @@ const ( FlagProvider = "provider" // FlagGit command flag to specify which git repository the configuration(HCL) is stored in FlagGit = "git" + // FlagLocal command flag to specify the local path of Terraform module or resource HCL file + FlagLocal = "local" // FlagPath command flag to specify which path the configuration(HCL) is stored in the Git repository FlagPath = "path" // FlagNamespace command flag to specify which namespace to use diff --git a/references/cli/def.go b/references/cli/def.go index 59f2db247..2d65bfbe8 100644 --- a/references/cli/def.go +++ b/references/cli/def.go @@ -21,6 +21,7 @@ import ( "bytes" "context" "fmt" + "io/ioutil" "os" "os/exec" "path" @@ -167,8 +168,10 @@ func NewDefinitionInitCommand(c common.Args) *cobra.Command { "> vela def init my-def -i --output ./my-def.cue\n" + "# Command below initiate a ComponentDefinition named my-webservice with the template parsed from ./template.yaml.\n" + "> vela def init my-webservice -i --template-yaml ./template.yaml\n" + - "# Command below initiate a typed ComponentDefinition named vswitch from Alibaba Cloud.\n" + - "> vela def init vswitch --type component --provider alibaba --desc xxx --git https://github.com/kubevela-contrib/terraform-modules.git --path alibaba/vswitch", + "# Initiate a Terraform ComponentDefinition named vswitch from Github for Alibaba Cloud.\n" + + "> vela def init vswitch --type component --provider alibaba --desc xxx --git https://github.com/kubevela-contrib/terraform-modules.git --path alibaba/vswitch\n" + + "# Initiate a Terraform ComponentDefinition named redis from local file for AWS.\n" + + "> vela def init redis --type component --provider aws --desc \"Terraform configuration for AWS Redis\" --local redis.tf", Args: cobra.ExactValidArgs(1), RunE: func(cmd *cobra.Command, args []string) error { var defStr string @@ -280,6 +283,7 @@ func NewDefinitionInitCommand(c common.Args) *cobra.Command { cmd.Flags().BoolP(FlagInteractive, "i", false, "Specify whether use interactive process to help generate definitions.") cmd.Flags().StringP(FlagProvider, "p", "", "Specify which provider the cloud resource definition belongs to. Only `alibaba`, `aws`, `azure` are supported.") cmd.Flags().StringP(FlagGit, "", "", "Specify which git repository the configuration(HCL) is stored in. Valid when --provider/-p is set.") + cmd.Flags().StringP(FlagLocal, "", "", "Specify the local path of the configuration(HCL) file. Valid when --provider/-p is set.") cmd.Flags().StringP(FlagPath, "", "", "Specify which path the configuration(HCL) is stored in the Git repository. Valid when --git is set.") return cmd } @@ -290,18 +294,42 @@ func generateTerraformTypedComponentDefinition(cmd *cobra.Command, name, kind, p } switch provider { - case "aws", "azure", "alibaba": + case "aws", "azure", "alibaba", "tencent": + var terraform *commontype.Terraform + git, err := cmd.Flags().GetString(FlagGit) if err != nil { return "", errors.Wrapf(err, "failed to get `%s`", FlagGit) } - if !strings.HasPrefix(git, "https://") || !strings.HasSuffix(git, ".git") { - return "", errors.Errorf("invalid git url: %s", git) + local, err := cmd.Flags().GetString(FlagLocal) + if err != nil { + return "", errors.Wrapf(err, "failed to get `%s`", FlagLocal) + } + if git != "" && local != "" { + return "", errors.New("only one of --git and --local can be set") } gitPath, err := cmd.Flags().GetString(FlagPath) if err != nil { return "", errors.Wrapf(err, "failed to get `%s`", FlagPath) } + if git != "" { + if !strings.HasPrefix(git, "https://") || !strings.HasSuffix(git, ".git") { + return "", errors.Errorf("invalid git url: %s", git) + } + terraform = &commontype.Terraform{ + Configuration: git, + Type: "remote", + Path: gitPath, + } + } else if local != "" { + hcl, err := ioutil.ReadFile(filepath.Clean(local)) + if err != nil { + return "", errors.Wrapf(err, "failed to read Terraform configuration from file %s", local) + } + terraform = &commontype.Terraform{ + Configuration: string(hcl), + } + } def := v1beta1.ComponentDefinition{ TypeMeta: metav1.TypeMeta{ APIVersion: "core.oam.dev/v1beta1", @@ -325,11 +353,7 @@ func generateTerraformTypedComponentDefinition(cmd *cobra.Command, name, kind, p }, }, Schematic: &commontype.Schematic{ - Terraform: &commontype.Terraform{ - Configuration: git, - Type: "remote", - Path: gitPath, - }, + Terraform: terraform, }, }, } diff --git a/references/cli/def_test.go b/references/cli/def_test.go index 7cdcb9a4a..43170bbdd 100644 --- a/references/cli/def_test.go +++ b/references/cli/def_test.go @@ -215,6 +215,10 @@ func TestNewDefinitionInitCommand4Terraform(t *testing.T) { name: "normal", args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "xxx", "--git", "https://github.com/kubevela-contrib/terraform-modules.git", "--path", "alibaba/vswitch"}, }, + { + name: "normal from local", + args: []string{"vswitch", "-t", "component", "--provider", "tencent", "--desc", "xxx", "--local", "test-data/redis.tf"}, + }, { name: "print in a file", args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "xxx", "--git", "https://github.com/kubevela-contrib/terraform-modules.git", "--path", "alibaba/vswitch", "--output", defFileName}, @@ -255,6 +259,16 @@ status: {}`, args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "test", "--git", "xxx"}, errMsg: "invalid git url", }, + { + name: "git and local could be set at the same time", + args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "test", "--git", "xxx", "--local", "yyy"}, + errMsg: "only one of --git and --local can be set", + }, + { + name: "local file doesn't exist", + args: []string{"vswitch", "-t", "component", "--provider", "tencent", "--desc", "xxx", "--local", "test-data/redis2.tf"}, + errMsg: "failed to read Terraform configuration from file", + }, } for _, tc := range testcases { diff --git a/references/cli/test-data/redis.tf b/references/cli/test-data/redis.tf new file mode 100644 index 000000000..454dbefaf --- /dev/null +++ b/references/cli/test-data/redis.tf @@ -0,0 +1,58 @@ +terraform { + required_providers { + tencentcloud = { + source = "tencentcloudstack/tencentcloud" + } + } +} + +resource "tencentcloud_redis_instance" "main" { + type_id = 8 + availability_zone = var.availability_zone + name = var.instance_name + password = var.user_password + mem_size = var.mem_size + port = var.port +} + +output "DB_IP" { + value = tencentcloud_redis_instance.main.ip +} + +output "DB_PASSWORD" { + value = var.user_password +} + +output "DB_PORT" { + value = var.port +} + +variable "availability_zone" { + description = "The available zone ID of an instance to be created." + type = string + default = "ap-chengdu-1" +} + +variable "instance_name" { + description = "redis instance name" + type = string + default = "sample" +} + +variable "user_password" { + description = "redis instance password" + type = string + default = "IEfewjf2342rfwfwYYfaked" +} + +variable "mem_size" { + description = "redis instance memory size" + type = number + default = 1024 +} + +variable "port" { + description = "The port used to access a redis instance." + type = number + default = 6379 +}