@@ -6,12 +6,11 @@ package cvm
66import (
77 "context"
88 "fmt"
9- "strings"
109
1110 "github.com/hashicorp/packer-plugin-sdk/multistep"
1211 "github.com/hashicorp/packer-plugin-sdk/uuid"
12+
1313 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
14- cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
1514 vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
1615)
1716
@@ -25,74 +24,35 @@ type stepConfigSubnet struct {
2524
2625func (s * stepConfigSubnet ) Run (ctx context.Context , state multistep.StateBag ) multistep.StepAction {
2726 vpcClient := state .Get ("vpc_client" ).(* vpc.Client )
28- cvmClient := state .Get ("cvm_client" ).(* cvm.Client )
2927 vpcId := state .Get ("vpc_id" ).(string )
30- instanceType := state .Get ("config" ).(* Config ).InstanceType
31-
32- zones := []string {s .Zone }
33- // 根据机型自动选择可用区
34- if len (s .Zone ) == 0 {
35- Say (state , fmt .Sprintf ("Try to get available zones for instance: %s" , instanceType ), "" )
36- req := cvm .NewDescribeZoneInstanceConfigInfosRequest ()
37- req .Filters = []* cvm.Filter {
38- {
39- Name : common .StringPtr ("instance-type" ),
40- Values : common .StringPtrs ([]string {instanceType }),
41- },
42- {
43- Name : common .StringPtr ("instance-charge-type" ),
44- Values : common .StringPtrs ([]string {"POSTPAID_BY_HOUR" }),
45- },
46- }
47- var resp * cvm.DescribeZoneInstanceConfigInfosResponse
48- err := Retry (ctx , func (ctx context.Context ) error {
49- var e error
50- resp , e = cvmClient .DescribeZoneInstanceConfigInfos (req )
51- return e
52- })
53- if err != nil {
54- return Halt (state , err , "Failed to get available zones instance config" )
55- }
56- if len (resp .Response .InstanceTypeQuotaSet ) > 0 {
57- zones = make ([]string , 0 )
58- Say (state , fmt .Sprintf ("length:%d" , len (resp .Response .InstanceTypeQuotaSet )), "" )
59- for _ , z := range resp .Response .InstanceTypeQuotaSet {
60- zones = append (zones , * z .Zone )
61- }
62- Say (state , fmt .Sprintf ("Found zones: %s" , strings .Join (zones , "," )), "" )
63- } else {
64- Say (state , fmt .Sprintf ("The instance type %s isn't available in this region." +
65- "\n You can change to other regions." , instanceType ), "" )
66- state .Put ("error" , fmt .Errorf ("The instance type %s isn't available in this region." +
67- "\n You can change to other regions." , instanceType ))
68- return multistep .ActionHalt
69- }
70- }
7128
7229 // 如果指定了子网ID或子网名称,则尝试使用已有子网
7330 if len (s .SubnetId ) != 0 || len (s .SubnetName ) != 0 {
7431 Say (state , fmt .Sprintf ("Trying to use existing subnet id: %s, name: %s" , s .SubnetId , s .SubnetName ), "" )
7532 req := vpc .NewDescribeSubnetsRequest ()
33+ req .Filters = []* vpc.Filter {
34+ {
35+ Name : common .StringPtr ("vpc-id" ),
36+ Values : common .StringPtrs ([]string {vpcId }),
37+ },
38+ }
39+ // 搜索指定所有可用区或所有可用区中符合条件的subnet
40+ if s .Zone != "" {
41+ req .Filters = append (req .Filters ,
42+ & vpc.Filter {
43+ Name : common .StringPtr ("zone" ),
44+ Values : common .StringPtrs ([]string {s .Zone }),
45+ })
46+ }
7647 // 空字符串作为参数会报错
7748 if s .SubnetId != "" {
7849 req .SubnetIds = []* string {& s .SubnetId }
79- }
80- if len (s .SubnetName ) != 0 {
81- // s.zones列表长度不能超过5,取最后五个
82- if len (zones ) > 5 {
83- zones = zones [len (zones )- 5 :]
84- }
85- // 搜索机型在售所有可用区内符合subnet名称的subnet
86- req .Filters = []* vpc.Filter {
87- {
50+ } else if len (s .SubnetName ) != 0 {
51+ req .Filters = append (req .Filters ,
52+ & vpc.Filter {
8853 Name : common .StringPtr ("subnet-name" ),
8954 Values : common .StringPtrs ([]string {s .SubnetName }),
90- },
91- {
92- Name : common .StringPtr ("zone" ),
93- Values : common .StringPtrs (zones ),
94- },
95- }
55+ })
9656 }
9757 var resp * vpc.DescribeSubnetsResponse
9858 err := Retry (ctx , func (ctx context.Context ) error {
@@ -104,12 +64,6 @@ func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) mu
10464 return Halt (state , err , "Failed to get subnet info" )
10565 }
10666 if * resp .Response .TotalCount > 0 {
107- for _ , subnet := range resp .Response .SubnetSet {
108- if * subnet .VpcId != vpcId {
109- return Halt (state , fmt .Errorf ("the specified subnet(%s) does not belong to the specified vpc(%s)" ,
110- * subnet .SubnetId , vpcId ), "" )
111- }
112- }
11367 state .Put ("subnets" , resp .Response .SubnetSet )
11468 Message (state , fmt .Sprintf ("%d subnets in total." , * resp .Response .TotalCount ), "Subnet found" )
11569 return multistep .ActionContinue
@@ -120,34 +74,29 @@ func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) mu
12074 // 遍历候选可用区,在对应可用区内创建subnet并将subnet收集起来便于后续销毁
12175 // 此时subnetname一定为空,使用随机生成的名称
12276 s .SubnetName = fmt .Sprintf ("packer_%s" , uuid .TimeOrderedUUID ()[:8 ])
123- for _ , zone := range zones {
124- Say (state , s .SubnetName , "Trying to create a new subnet" )
125- req := vpc .NewCreateSubnetRequest ()
126- req .VpcId = & vpcId
127- req .SubnetName = & s .SubnetName
128- req .CidrBlock = & s .SubnetCidrBlock
129- req .Zone = & zone
130- var resp * vpc.CreateSubnetResponse
131- err := Retry (ctx , func (ctx context.Context ) error {
132- var e error
133- resp , e = vpcClient .CreateSubnet (req )
134- return e
135- })
136- if err != nil {
137- Say (state , s .SubnetName , "Failed to create subnet" )
138- continue
139- }
140-
141- // 创建成功后都将subnet收集起来,便于后续销毁
142- s .createdSubnet = resp .Response .Subnet
143- Message (state , fmt .Sprintf ("subnet created: %s in zone: %s" , * s .createdSubnet .SubnetId , * s .createdSubnet .Zone ), "Subnet created" )
144-
145- // 由于cidr冲突,不能用同一个cidr创建多个subnet,所以创建成功后直接继续
146- state .Put ("subnets" , []* vpc.Subnet {s .createdSubnet })
147- return multistep .ActionContinue
77+ Say (state , s .SubnetName , "Trying to create a new subnet" )
78+ req := vpc .NewCreateSubnetRequest ()
79+ req .VpcId = & vpcId
80+ req .SubnetName = & s .SubnetName
81+ req .CidrBlock = & s .SubnetCidrBlock
82+ req .Zone = & s .Zone
83+ var resp * vpc.CreateSubnetResponse
84+ err := Retry (ctx , func (ctx context.Context ) error {
85+ var e error
86+ resp , e = vpcClient .CreateSubnet (req )
87+ return e
88+ })
89+ if err != nil {
90+ return Halt (state , err , "Failed to create subnet" )
14891 }
14992
150- return Halt (state , fmt .Errorf ("cannot create subnet" ), "no available subnet" )
93+ // 创建成功后都将subnet收集起来,便于后续销毁
94+ s .createdSubnet = resp .Response .Subnet
95+ Message (state , fmt .Sprintf ("subnet created: %s in zone: %s" , * s .createdSubnet .SubnetId , * s .createdSubnet .Zone ), "Subnet created" )
96+
97+ // 由于cidr冲突,不能用同一个cidr创建多个subnet,所以创建成功后直接继续
98+ state .Put ("subnets" , []* vpc.Subnet {s .createdSubnet })
99+ return multistep .ActionContinue
151100}
152101
153102func (s * stepConfigSubnet ) Cleanup (state multistep.StateBag ) {
0 commit comments