diff --git a/.web-docs/components/builder/cvm/README.md b/.web-docs/components/builder/cvm/README.md index c7f60fd..e0a7ff1 100644 --- a/.web-docs/components/builder/cvm/README.md +++ b/.web-docs/components/builder/cvm/README.md @@ -62,6 +62,9 @@ a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can - `tag_endpoint` (string) - The endpoint you want to reach the cloud endpoint, if tce cloud you should set a tce tag endpoint. +- `org_endpoint` (string) - The endpoint you want to reach the cloud endpoint, + if tce cloud you should set a tce organization endpoint. + - `security_token` (string) - STS access token, can be set through template or by exporting as environment variable such as `export TENCENTCLOUD_SECURITY_TOKEN=value`. @@ -108,6 +111,14 @@ a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can - `skip_create_image` (bool) - Skip creating an image. When set to true, you don't need to enter target image information, share, copy, etc. The default value is false. +- `is_share_org_members` (bool) - After creating the image, + whether to share it with other accounts in the organization + where the current account is located. + The image can be copied to a maximum of 50 accounts, + with ImageShareAccounts being the priority. + +- `image_family` (string) - Image family. Example value: business-daily-update. + diff --git a/builder/tencentcloud/cvm/access_config.go b/builder/tencentcloud/cvm/access_config.go index cecf859..f599269 100644 --- a/builder/tencentcloud/cvm/access_config.go +++ b/builder/tencentcloud/cvm/access_config.go @@ -12,9 +12,6 @@ import ( "strconv" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" - tag "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag/v20180813" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" ) const ( @@ -85,6 +82,9 @@ type TencentCloudAccessConfig struct { // The endpoint you want to reach the cloud endpoint, // if tce cloud you should set a tce tag endpoint. TagEndpoint string `mapstructure:"tag_endpoint" required:"false"` + // The endpoint you want to reach the cloud endpoint, + // if tce cloud you should set a tce organization endpoint. + OrgEndpoint string `mapstructure:"org_endpoint" required:"false"` // The region validation can be skipped if this value is true, the default // value is false. skipValidation bool @@ -125,31 +125,42 @@ type TencentCloudAccessRole struct { SessionDuration int `mapstructure:"session_duration" required:"false"` } -func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, *tag.Client, error) { +func (cf *TencentCloudAccessConfig) Client() (map[string]interface{}, error) { var ( - err error - cvm_client *cvm.Client - vpc_client *vpc.Client - tag_client *tag.Client + err error + // cvm_client *cvm.Client + // vpc_client *vpc.Client + // tag_client *tag.Client + // org_client *org.Client + // cam_client *cam.Client ) if err = cf.validateRegion(); err != nil { - return nil, nil, nil, err + return nil, err + } + + clientMap := map[string]interface{}{} + if clientMap["cvm_client"], err = NewCvmClient(cf); err != nil { + return nil, err + } + + if clientMap["vpc_client"], err = NewVpcClient(cf); err != nil { + return nil, err } - if cvm_client, err = NewCvmClient(cf); err != nil { - return nil, nil, nil, err + if clientMap["tag_client"], err = NewTagClient(cf); err != nil { + return nil, err } - if vpc_client, err = NewVpcClient(cf); err != nil { - return nil, nil, nil, err + if clientMap["org_client"], err = NewOrgClient(cf); err != nil { + return nil, err } - if tag_client, err = NewTagClient(cf); err != nil { - return nil, nil, nil, err + if clientMap["cam_client"], err = NewCamClient(cf); err != nil { + return nil, err } - return cvm_client, vpc_client, tag_client, nil + return clientMap, nil } func (cf *TencentCloudAccessConfig) Prepare(ctx *interpolate.Context) []error { diff --git a/builder/tencentcloud/cvm/builder.go b/builder/tencentcloud/cvm/builder.go index 6718d3e..d814e8f 100644 --- a/builder/tencentcloud/cvm/builder.go +++ b/builder/tencentcloud/cvm/builder.go @@ -17,6 +17,11 @@ import ( packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/template/config" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" + vm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + org "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization/v20210331" + tag "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag/v20180813" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" ) const BuilderId = "tencent.cloud" @@ -75,16 +80,18 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { } func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) { - cvmClient, vpcClient, tagClient, err := b.config.Client() + clientMap, err := b.config.Client() if err != nil { return nil, err } state := new(multistep.BasicStateBag) state.Put("config", &b.config) - state.Put("cvm_client", cvmClient) - state.Put("vpc_client", vpcClient) - state.Put("tag_client", tagClient) + state.Put("cvm_client", clientMap["cvm_client"].(*vm.Client)) + state.Put("vpc_client", clientMap["vpc_client"].(*vpc.Client)) + state.Put("tag_client", clientMap["tag_client"].(*tag.Client)) + state.Put("org_client", clientMap["org_client"].(*org.Client)) + state.Put("cam_client", clientMap["cam_client"].(*cam.Client)) state.Put("hook", hook) state.Put("ui", ui) @@ -155,6 +162,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) }, &stepShareImage{ b.config.ImageShareAccounts, + b.config.IsShareOrgMembers, }, &stepCopyImage{ DestinationRegions: b.config.ImageCopyRegions, @@ -177,7 +185,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) artifact := &Artifact{ TencentCloudImages: state.Get("tencentcloudimages").(map[string]string), BuilderIdValue: BuilderId, - Client: cvmClient, + Client: clientMap["cvm_client"].(*vm.Client), StateData: map[string]interface{}{"generated_data": state.Get("generated_data")}, } diff --git a/builder/tencentcloud/cvm/builder.hcl2spec.go b/builder/tencentcloud/cvm/builder.hcl2spec.go index 976a1d6..ba1cd00 100644 --- a/builder/tencentcloud/cvm/builder.hcl2spec.go +++ b/builder/tencentcloud/cvm/builder.hcl2spec.go @@ -25,6 +25,7 @@ type FlatConfig struct { CvmEndpoint *string `mapstructure:"cvm_endpoint" required:"false" cty:"cvm_endpoint" hcl:"cvm_endpoint"` VpcEndpoint *string `mapstructure:"vpc_endpoint" required:"false" cty:"vpc_endpoint" hcl:"vpc_endpoint"` TagEndpoint *string `mapstructure:"tag_endpoint" required:"false" cty:"tag_endpoint" hcl:"tag_endpoint"` + OrgEndpoint *string `mapstructure:"org_endpoint" required:"false" cty:"org_endpoint" hcl:"org_endpoint"` SecurityToken *string `mapstructure:"security_token" required:"false" cty:"security_token" hcl:"security_token"` AssumeRole *FlatTencentCloudAccessRole `mapstructure:"assume_role" required:"false" cty:"assume_role" hcl:"assume_role"` Profile *string `mapstructure:"profile" required:"false" cty:"profile" hcl:"profile"` @@ -38,6 +39,8 @@ type FlatConfig struct { ImageTags map[string]string `mapstructure:"image_tags" required:"false" cty:"image_tags" hcl:"image_tags"` SnapshotTags map[string]string `mapstructure:"snapshot_tags" required:"false" cty:"snapshot_tags" hcl:"snapshot_tags"` SkipCreateImage *bool `mapstructure:"skip_create_image" required:"false" cty:"skip_create_image" hcl:"skip_create_image"` + IsShareOrgMembers *bool `mapstructure:"is_share_org_members" required:"false" cty:"is_share_org_members" hcl:"is_share_org_members"` + ImageFamily *string `mapstructure:"image_family" required:"false" cty:"image_family" hcl:"image_family"` AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"` SourceImageId *string `mapstructure:"source_image_id" required:"false" cty:"source_image_id" hcl:"source_image_id"` SourceImageName *string `mapstructure:"source_image_name" required:"false" cty:"source_image_name" hcl:"source_image_name"` @@ -145,6 +148,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "cvm_endpoint": &hcldec.AttrSpec{Name: "cvm_endpoint", Type: cty.String, Required: false}, "vpc_endpoint": &hcldec.AttrSpec{Name: "vpc_endpoint", Type: cty.String, Required: false}, "tag_endpoint": &hcldec.AttrSpec{Name: "tag_endpoint", Type: cty.String, Required: false}, + "org_endpoint": &hcldec.AttrSpec{Name: "org_endpoint", Type: cty.String, Required: false}, "security_token": &hcldec.AttrSpec{Name: "security_token", Type: cty.String, Required: false}, "assume_role": &hcldec.BlockSpec{TypeName: "assume_role", Nested: hcldec.ObjectSpec((*FlatTencentCloudAccessRole)(nil).HCL2Spec())}, "profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false}, @@ -158,6 +162,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "image_tags": &hcldec.AttrSpec{Name: "image_tags", Type: cty.Map(cty.String), Required: false}, "snapshot_tags": &hcldec.AttrSpec{Name: "snapshot_tags", Type: cty.Map(cty.String), Required: false}, "skip_create_image": &hcldec.AttrSpec{Name: "skip_create_image", Type: cty.Bool, Required: false}, + "is_share_org_members": &hcldec.AttrSpec{Name: "is_share_org_members", Type: cty.Bool, Required: false}, + "image_family": &hcldec.AttrSpec{Name: "image_family", Type: cty.String, Required: false}, "associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false}, "source_image_id": &hcldec.AttrSpec{Name: "source_image_id", Type: cty.String, Required: false}, "source_image_name": &hcldec.AttrSpec{Name: "source_image_name", Type: cty.String, Required: false}, diff --git a/builder/tencentcloud/cvm/client.go b/builder/tencentcloud/cvm/client.go index 1d83edc..f738cf2 100644 --- a/builder/tencentcloud/cvm/client.go +++ b/builder/tencentcloud/cvm/client.go @@ -4,9 +4,11 @@ package cvm import ( + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + org "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization/v20210331" sts "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts/v20180813" tag "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag/v20180813" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" @@ -22,6 +24,8 @@ type TencentCloudClient struct { cvmConn *cvm.Client stsConn *sts.Client tagConn *tag.Client + orgConn *org.Client + camConn *cam.Client } func (me *TencentCloudClient) UseVpcClient(cpf *profile.ClientProfile) *vpc.Client { @@ -65,3 +69,24 @@ func (me *TencentCloudClient) UseTagClient(cpf *profile.ClientProfile) *tag.Clie return me.tagConn } + +func (me *TencentCloudClient) UseOrgClient(cpf *profile.ClientProfile) *org.Client { + if me.orgConn != nil { + return me.orgConn + } + + me.orgConn, _ = org.NewClient(me.Credential, me.Region, cpf) + + return me.orgConn +} + +func (me *TencentCloudClient) UseCamClient() *cam.Client { + if me.camConn != nil { + return me.camConn + } + + cpf := me.ClientProfile + me.camConn, _ = cam.NewClient(me.Credential, me.Region, cpf) + + return me.camConn +} diff --git a/builder/tencentcloud/cvm/common.go b/builder/tencentcloud/cvm/common.go index ff514ab..adda19c 100644 --- a/builder/tencentcloud/cvm/common.go +++ b/builder/tencentcloud/cvm/common.go @@ -14,10 +14,12 @@ import ( "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/retry" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + org "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization/v20210331" sts "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts/v20180813" tag "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag/v20180813" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" @@ -181,6 +183,35 @@ func NewTagClient(cf *TencentCloudAccessConfig) (client *tag.Client, err error) return } +// NewVpcClient returns a new organization client +func NewOrgClient(cf *TencentCloudAccessConfig) (client *org.Client, err error) { + apiV3Conn, err := packerConfigClient(cf) + if err != nil { + return nil, err + } + + orgClientProfile, err := newClientProfile(cf.OrgEndpoint) + if err != nil { + return nil, err + } + + client = apiV3Conn.UseOrgClient(orgClientProfile) + + return +} + +// NewCamClient returns a new cam client +func NewCamClient(cf *TencentCloudAccessConfig) (client *cam.Client, err error) { + apiV3Conn, err := packerConfigClient(cf) + if err != nil { + return nil, err + } + + client = apiV3Conn.UseCamClient() + + return +} + // CheckResourceIdFormat check resource id format func CheckResourceIdFormat(resource string, id string) bool { regex := regexp.MustCompile(fmt.Sprintf("%s-[0-9a-z]{8}$", resource)) diff --git a/builder/tencentcloud/cvm/image_config.go b/builder/tencentcloud/cvm/image_config.go index 75a948d..63a9b14 100644 --- a/builder/tencentcloud/cvm/image_config.go +++ b/builder/tencentcloud/cvm/image_config.go @@ -37,6 +37,14 @@ type TencentCloudImageConfig struct { skipValidation bool // Skip creating an image. When set to true, you don't need to enter target image information, share, copy, etc. The default value is false. SkipCreateImage bool `mapstructure:"skip_create_image" required:"false"` + // After creating the image, + // whether to share it with other accounts in the organization + // where the current account is located. + // The image can be copied to a maximum of 50 accounts, + // with ImageShareAccounts being the priority. + IsShareOrgMembers bool `mapstructure:"is_share_org_members" required:"false"` + // Image family. Example value: business-daily-update. + ImageFamily string `mapstructure:"image_family" required:"false"` } func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error { diff --git a/builder/tencentcloud/cvm/step_create_image.go b/builder/tencentcloud/cvm/step_create_image.go index 3fd164a..bb82340 100644 --- a/builder/tencentcloud/cvm/step_create_image.go +++ b/builder/tencentcloud/cvm/step_create_image.go @@ -35,6 +35,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul req := cvm.NewCreateImageRequest() req.ImageName = &config.ImageName req.ImageDescription = &config.ImageDescription + req.ImageFamily = &config.ImageFamily req.InstanceId = instance.InstanceId // TODO: We should allow user to specify which data disk should be diff --git a/builder/tencentcloud/cvm/step_share_image.go b/builder/tencentcloud/cvm/step_share_image.go index 821555b..e4f8350 100644 --- a/builder/tencentcloud/cvm/step_share_image.go +++ b/builder/tencentcloud/cvm/step_share_image.go @@ -6,19 +6,23 @@ package cvm import ( "context" "fmt" + "strconv" "strings" "github.com/hashicorp/packer-plugin-sdk/multistep" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + organization "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization/v20210331" ) type stepShareImage struct { - ShareAccounts []string + ShareAccounts []string + IsShareOrgMembers bool } func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - if len(s.ShareAccounts) == 0 { + if len(s.ShareAccounts) == 0 && !s.IsShareOrgMembers { return multistep.ActionContinue } @@ -30,10 +34,23 @@ func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) mult req := cvm.NewModifyImageSharePermissionRequest() req.ImageId = imageId req.Permission = common.StringPtr("SHARE") - accounts := make([]*string, 0, len(s.ShareAccounts)) + accounts := []*string{} for _, account := range s.ShareAccounts { accounts = append(accounts, common.StringPtr(account)) } + + if s.IsShareOrgMembers { + accountList, err := s.getOrgAccounts(ctx, state) + if err != nil { + return Halt(state, err, "Failed to get org accounts") + } + accounts = append(accounts, accountList...) + } + + if len(accounts) == 0 { + return multistep.ActionContinue + } + req.AccountIds = accounts err := Retry(ctx, func(ctx context.Context) error { _, e := client.ModifyImageSharePermission(req) @@ -48,6 +65,81 @@ func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) mult return multistep.ActionContinue } +func (s *stepShareImage) getOrgAccounts(ctx context.Context, state multistep.StateBag) ([]*string, error) { + + currentAccount, err := s.getUserId(ctx, state) + if err != nil { + return nil, err + } + + req := organization.NewDescribeOrganizationMembersRequest() + resp := organization.NewDescribeOrganizationMembersResponse() + + var limit uint64 = 50 + var offset uint64 = 0 + + req.Limit = &limit + req.Offset = &offset + + accounts := []*string{} + for { + client := state.Get("org_client").(*organization.Client) + err := Retry(ctx, func(ctx context.Context) error { + var e error + resp, e = client.DescribeOrganizationMembers(req) + return e + }) + if err != nil { + return nil, nil + } + if resp.Response == nil { + return nil, nil + } + items := resp.Response.Items + for _, v := range items { + if v.MemberUin != nil { + if strconv.FormatInt(*v.MemberUin, 10) == currentAccount { + continue + } + accounts = append(accounts, common.StringPtr(strconv.Itoa(int(*v.MemberUin)))) + } + } + + if len(items) < int(limit) { + break + } + + offset += limit + } + + return accounts, nil +} + +func (s *stepShareImage) getUserId(ctx context.Context, state multistep.StateBag) (string, error) { + req := cam.NewGetUserAppIdRequest() + resp := cam.NewGetUserAppIdResponse() + + client := state.Get("cam_client").(*cam.Client) + err := Retry(ctx, func(ctx context.Context) error { + var e error + resp, e = client.GetUserAppId(req) + return e + }) + if err != nil { + return "", err + } + + if resp.Response == nil { + return "", nil + } + + if resp.Response.Uin != nil { + return *resp.Response.Uin, nil + } + + return "", nil +} + func (s *stepShareImage) Cleanup(state multistep.StateBag) { _, cancelled := state.GetOk(multistep.StateCancelled) _, halted := state.GetOk(multistep.StateHalted) diff --git a/datasource/tencentcloud/image/data.go b/datasource/tencentcloud/image/data.go index d096cc2..bdec647 100644 --- a/datasource/tencentcloud/image/data.go +++ b/datasource/tencentcloud/image/data.go @@ -105,11 +105,13 @@ func (d *Datasource) Execute() (cty.Value, error) { } func (d *Datasource) ResolveImageByFilters() (*cvm.Image, error) { - client, _, _, err := d.config.Client() + clientMap, err := d.config.Client() if err != nil { return nil, err } + cvmClient := clientMap["cvm_client"].(*cvm.Client) + req := cvm.NewDescribeImagesRequest() var filters []*cvm.Filter @@ -127,7 +129,7 @@ func (d *Datasource) ResolveImageByFilters() (*cvm.Image, error) { var resp *cvm.DescribeImagesResponse err = buildCvm.Retry(ctx, func(ctx context.Context) error { var e error - resp, e = client.DescribeImages(req) + resp, e = cvmClient.DescribeImages(req) return e }) if err != nil { @@ -150,11 +152,13 @@ func (d *Datasource) ResolveImageByFilters() (*cvm.Image, error) { } func (d *Datasource) ResolveImageByImageFamily() (*cvm.Image, error) { - client, _, _, err := d.config.Client() + clientMap, err := d.config.Client() if err != nil { return nil, err } + cvmClient := clientMap["cvm_client"].(*cvm.Client) + var resp *cvm.DescribeImageFromFamilyResponse req := cvm.NewDescribeImageFromFamilyRequest() req.ImageFamily = &d.config.ImageFamily @@ -162,7 +166,7 @@ func (d *Datasource) ResolveImageByImageFamily() (*cvm.Image, error) { ctx := context.TODO() err = buildCvm.Retry(ctx, func(ctx context.Context) error { var e error - resp, e = client.DescribeImageFromFamily(req) + resp, e = cvmClient.DescribeImageFromFamily(req) return e }) diff --git a/datasource/tencentcloud/image/data.hcl2spec.go b/datasource/tencentcloud/image/data.hcl2spec.go index 7327099..f870f0d 100644 --- a/datasource/tencentcloud/image/data.hcl2spec.go +++ b/datasource/tencentcloud/image/data.hcl2spec.go @@ -25,6 +25,7 @@ type FlatConfig struct { CvmEndpoint *string `mapstructure:"cvm_endpoint" required:"false" cty:"cvm_endpoint" hcl:"cvm_endpoint"` VpcEndpoint *string `mapstructure:"vpc_endpoint" required:"false" cty:"vpc_endpoint" hcl:"vpc_endpoint"` TagEndpoint *string `mapstructure:"tag_endpoint" required:"false" cty:"tag_endpoint" hcl:"tag_endpoint"` + OrgEndpoint *string `mapstructure:"org_endpoint" required:"false" cty:"org_endpoint" hcl:"org_endpoint"` SecurityToken *string `mapstructure:"security_token" required:"false" cty:"security_token" hcl:"security_token"` AssumeRole *cvm.FlatTencentCloudAccessRole `mapstructure:"assume_role" required:"false" cty:"assume_role" hcl:"assume_role"` Profile *string `mapstructure:"profile" required:"false" cty:"profile" hcl:"profile"` @@ -60,6 +61,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "cvm_endpoint": &hcldec.AttrSpec{Name: "cvm_endpoint", Type: cty.String, Required: false}, "vpc_endpoint": &hcldec.AttrSpec{Name: "vpc_endpoint", Type: cty.String, Required: false}, "tag_endpoint": &hcldec.AttrSpec{Name: "tag_endpoint", Type: cty.String, Required: false}, + "org_endpoint": &hcldec.AttrSpec{Name: "org_endpoint", Type: cty.String, Required: false}, "security_token": &hcldec.AttrSpec{Name: "security_token", Type: cty.String, Required: false}, "assume_role": &hcldec.BlockSpec{TypeName: "assume_role", Nested: hcldec.ObjectSpec((*cvm.FlatTencentCloudAccessRole)(nil).HCL2Spec())}, "profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false}, diff --git a/docs-partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx b/docs-partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx index 7bb930b..8c15fe1 100644 --- a/docs-partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx +++ b/docs-partials/builder/tencentcloud/cvm/TencentCloudAccessConfig-not-required.mdx @@ -9,6 +9,9 @@ - `tag_endpoint` (string) - The endpoint you want to reach the cloud endpoint, if tce cloud you should set a tce tag endpoint. +- `org_endpoint` (string) - The endpoint you want to reach the cloud endpoint, + if tce cloud you should set a tce organization endpoint. + - `security_token` (string) - STS access token, can be set through template or by exporting as environment variable such as `export TENCENTCLOUD_SECURITY_TOKEN=value`. diff --git a/docs-partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx b/docs-partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx index 21a382c..8859424 100644 --- a/docs-partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx +++ b/docs-partials/builder/tencentcloud/cvm/TencentCloudImageConfig-not-required.mdx @@ -19,4 +19,12 @@ - `skip_create_image` (bool) - Skip creating an image. When set to true, you don't need to enter target image information, share, copy, etc. The default value is false. +- `is_share_org_members` (bool) - After creating the image, + whether to share it with other accounts in the organization + where the current account is located. + The image can be copied to a maximum of 50 accounts, + with ImageShareAccounts being the priority. + +- `image_family` (string) - Image family. Example value: business-daily-update. + diff --git a/go.mod b/go.mod index 6c5fad9..ca56c5d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/hashicorp/hcl/v2 v2.19.1 github.com/hashicorp/packer-plugin-sdk v0.5.2 github.com/pkg/errors v0.9.1 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1175 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1200 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.1072 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts v1.0.797 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.1175 @@ -16,6 +16,8 @@ require ( require ( github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.1200 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization v1.0.1200 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect ) diff --git a/go.sum b/go.sum index 104dac7..f9e0ff2 100644 --- a/go.sum +++ b/go.sum @@ -306,12 +306,18 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.1200 h1:vONBPPPZR83iIJGnrIBjIrFj1Lba8p3tBmwmveabLlo= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.1200/go.mod h1:g1HW2Y5P+yi9XH2dL136gEMKogKcNRLoZ4hq9767D48= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.797/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1072/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1175 h1:w0z4dtrinCY3R4aHnw9vcq80XWEIEKXv6c3p779ueRo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1175/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1200 h1:n6elge0PuoOtHt67BhlQka5Y7ChPbCtp23zYDFw56V0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1200/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.1072 h1:BO6eEqw2CxeP73AnOfkq99mJAPccP+w3exmVuBDMvAc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.1072/go.mod h1:Ot4h9BuqIbyOPotq8cIT3vCCMDdn6LXkc37jU2teHnQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization v1.0.1200 h1:hYOvCfgPKpH2OS6+6ZOT+h21CfduIbGfz7RE+Ey1H14= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization v1.0.1200/go.mod h1:qYzdOsPWtOJ18uQ/4QupBTF98ariELEH4dx93GiBeuY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts v1.0.797 h1:Z9rTZBoR4arEXA9gYLu8AQnMInG1scb+WnlIWczLH2A= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts v1.0.797/go.mod h1:IugQh1ZI86ZeEUBYf+u/REwTeKZcneP449FPU8BbLxA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.1175 h1:Yw7azOzlQqh6/Zyk5JCLH69LJ7nE2jkilGXU+3vIqUM=