Skip to content

feat: Support organization account and other accounts sharing #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .web-docs/components/builder/cvm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can
- `vpc_endpoint` (string) - The endpoint you want to reach the cloud endpoint,
if tce cloud you should set a tce vpc 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`.

Expand Down Expand Up @@ -99,6 +102,12 @@ a [communicator](/packer/docs/templates/legacy_json_templates/communicator) can
- `image_share_accounts` ([]string) - accounts that will be shared to
after your image created.

- `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_tags` (map[string]string) - Key/value pair tags that will be applied to the resulting image.

<!-- End of code generated from the comments of the TencentCloudImageConfig struct in builder/tencentcloud/cvm/image_config.go; -->
Expand Down
36 changes: 28 additions & 8 deletions builder/tencentcloud/cvm/access_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (

"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
"github.com/mitchellh/go-homedir"
cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
org "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization/v20210331"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
)

Expand Down Expand Up @@ -91,6 +93,9 @@ type TencentCloudAccessConfig struct {
// The endpoint you want to reach the cloud endpoint,
// if tce cloud you should set a tce vpc endpoint.
VpcEndpoint string `mapstructure:"vpc_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
Expand Down Expand Up @@ -131,28 +136,38 @@ type TencentCloudAccessRole struct {
SessionDuration int `mapstructure:"session_duration" required:"false"`
}

func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, error) {
func (cf *TencentCloudAccessConfig) Client() (map[string]interface{}, error) {
var (
err error
cvm_client *cvm.Client
vpc_client *vpc.Client
org_client *org.Client
cam_client *cam.Client
resp *cvm.DescribeZonesResponse
)

if err = cf.validateRegion(); err != nil {
return nil, nil, err
return nil, err
}

if cf.Zone == "" {
return nil, nil, fmt.Errorf("parameter zone must be set")
return nil, fmt.Errorf("parameter zone must be set")
}

if cvm_client, err = NewCvmClient(cf); err != nil {
return nil, nil, err
return nil, err
}

if vpc_client, err = NewVpcClient(cf); err != nil {
return nil, nil, err
return nil, err
}

if org_client, err = NewOrgClient(cf); err != nil {
return nil, err
}

if cam_client, err = NewCamClient(cf); err != nil {
return nil, err
}

ctx := context.TODO()
Expand All @@ -162,16 +177,21 @@ func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, error) {
return e
})
if err != nil {
return nil, nil, err
return nil, err
}

for _, zone := range resp.Response.ZoneSet {
if cf.Zone == *zone.Zone {
return cvm_client, vpc_client, nil
clientMap := map[string]interface{}{}
clientMap["cvm_client"] = cvm_client
clientMap["vpc_client"] = vpc_client
clientMap["org_client"] = org_client
clientMap["cam_client"] = cam_client
return clientMap, nil
}
}

return nil, nil, fmt.Errorf("unknown zone: %s", cf.Zone)
return nil, fmt.Errorf("unknown zone: %s", cf.Zone)
}

func (cf *TencentCloudAccessConfig) Prepare(ctx *interpolate.Context) []error {
Expand Down
15 changes: 11 additions & 4 deletions builder/tencentcloud/cvm/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ 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"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
)

const BuilderId = "tencent.cloud"
Expand Down Expand Up @@ -75,15 +79,17 @@ 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, 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("cvm_client", clientMap["cvm_client"].(*vm.Client))
state.Put("vpc_client", clientMap["vpc_client"].(*vpc.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)

Expand Down Expand Up @@ -148,6 +154,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
&stepCreateImage{},
&stepShareImage{
b.config.ImageShareAccounts,
b.config.IsShareOrgMembers,
},
&stepCopyImage{
DesinationRegions: b.config.ImageCopyRegions,
Expand All @@ -169,7 +176,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")},
}

Expand Down
4 changes: 4 additions & 0 deletions builder/tencentcloud/cvm/builder.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions builder/tencentcloud/cvm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
)
Expand All @@ -20,6 +22,8 @@ type TencentCloudClient struct {
vpcConn *vpc.Client
cvmConn *cvm.Client
stsConn *sts.Client
orgConn *org.Client
camConn *cam.Client
}

func (me *TencentCloudClient) UseVpcClient(cpf *profile.ClientProfile) *vpc.Client {
Expand All @@ -43,6 +47,27 @@ func (me *TencentCloudClient) UseCvmClient(cpf *profile.ClientProfile) *cvm.Clie
return me.cvmConn
}

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
}

func (me *TencentCloudClient) UseStsClient() *sts.Client {
if me.stsConn != nil {
return me.stsConn
Expand Down
31 changes: 31 additions & 0 deletions builder/tencentcloud/cvm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
)
Expand Down Expand Up @@ -143,6 +145,35 @@ func NewVpcClient(cf *TencentCloudAccessConfig) (client *vpc.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))
Expand Down
6 changes: 6 additions & 0 deletions builder/tencentcloud/cvm/image_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ type TencentCloudImageConfig struct {
// accounts that will be shared to
// after your image created.
ImageShareAccounts []string `mapstructure:"image_share_accounts" 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"`
// Key/value pair tags that will be applied to the resulting image.
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
skipValidation bool
Expand Down
Loading