packer-cn/builder/tencentcloud/cvm/step_config_security_group.go
ZhiQiang Fan 1c7b23357d fix: correctly remove tencentcloud temporary keypair
Tencent Cloud key pair cannot be removed if it is in a image, so
when user doesn't specify any log in method, such as ssh_password,
temporary key pair will be created and used, which eventually will
always fail.

This patch detach temporary key pair before creating image, so in
cleanup step, it can be deleted correctly.

Note that if user specifies a private key pair, we do not detach it,
because user might want to use it when creating new instances from this
image.
2019-06-23 23:23:48 +08:00

125 lines
3.6 KiB
Go

package cvm
import (
"context"
"time"
"fmt"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/pkg/errors"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
)
type stepConfigSecurityGroup struct {
SecurityGroupId string
SecurityGroupName string
Description string
isCreate bool
}
func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
vpcClient := state.Get("vpc_client").(*vpc.Client)
ui := state.Get("ui").(packer.Ui)
if len(s.SecurityGroupId) != 0 { // use existing security group
req := vpc.NewDescribeSecurityGroupsRequest()
req.SecurityGroupIds = []*string{&s.SecurityGroupId}
resp, err := vpcClient.DescribeSecurityGroups(req)
if err != nil {
ui.Error(fmt.Sprintf("query security group failed: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
}
if *resp.Response.TotalCount > 0 {
state.Put("security_group_id", s.SecurityGroupId)
s.isCreate = false
return multistep.ActionContinue
}
message := fmt.Sprintf("the specified security group(%s) does not exist", s.SecurityGroupId)
ui.Error(message)
state.Put("error", errors.New(message))
return multistep.ActionHalt
}
// create a new security group
req := vpc.NewCreateSecurityGroupRequest()
req.GroupName = &s.SecurityGroupName
req.GroupDescription = &s.Description
resp, err := vpcClient.CreateSecurityGroup(req)
if err != nil {
ui.Error(fmt.Sprintf("create security group failed: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
}
s.SecurityGroupId = *resp.Response.SecurityGroup.SecurityGroupId
state.Put("security_group_id", s.SecurityGroupId)
s.isCreate = true
// bind security group ingress police
pReq := vpc.NewCreateSecurityGroupPoliciesRequest()
ACCEPT := "ACCEPT"
DEFAULT_CIDR := "0.0.0.0/0"
pReq.SecurityGroupId = &s.SecurityGroupId
pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{
Ingress: []*vpc.SecurityGroupPolicy{
{
CidrBlock: &DEFAULT_CIDR,
Action: &ACCEPT,
},
},
}
_, err = vpcClient.CreateSecurityGroupPolicies(pReq)
if err != nil {
ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
}
// bind security group engress police
pReq = vpc.NewCreateSecurityGroupPoliciesRequest()
pReq.SecurityGroupId = &s.SecurityGroupId
pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{
Egress: []*vpc.SecurityGroupPolicy{
{
CidrBlock: &DEFAULT_CIDR,
Action: &ACCEPT,
},
},
}
_, err = vpcClient.CreateSecurityGroupPolicies(pReq)
if err != nil {
ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error()))
state.Put("error", err)
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) {
if !s.isCreate {
return
}
ctx := context.TODO()
vpcClient := state.Get("vpc_client").(*vpc.Client)
ui := state.Get("ui").(packer.Ui)
MessageClean(state, "Security Group")
req := vpc.NewDeleteSecurityGroupRequest()
req.SecurityGroupId = &s.SecurityGroupId
err := retry.Config{
Tries: 60,
RetryDelay: (&retry.Backoff{InitialBackoff: 5 * time.Second, MaxBackoff: 5 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := vpcClient.DeleteSecurityGroup(req)
return err
})
if err != nil {
ui.Error(fmt.Sprintf("delete security group(%s) failed: %s, you need to delete it by hand",
s.SecurityGroupId, err.Error()))
return
}
}