in pkg/providers/v1/aws.go [3558:3639]
func (c *Cloud) ensureSecurityGroup(name string, description string, additionalTags map[string]string) (string, error) {
groupID := ""
attempt := 0
for {
attempt++
// Note that we do _not_ add our tag filters; group-name + vpc-id is the EC2 primary key.
// However, we do check that it matches our tags.
// If it doesn't have any tags, we tag it; this is how we recover if we failed to tag before.
// If it has a different cluster's tags, that is an error.
// This shouldn't happen because name is expected to be globally unique (UUID derived)
request := &ec2.DescribeSecurityGroupsInput{}
request.Filters = []*ec2.Filter{
newEc2Filter("group-name", name),
newEc2Filter("vpc-id", c.vpcID),
}
securityGroups, err := c.ec2.DescribeSecurityGroups(request)
if err != nil {
return "", err
}
if len(securityGroups) >= 1 {
if len(securityGroups) > 1 {
klog.Warningf("Found multiple security groups with name: %q", name)
}
err := c.tagging.readRepairClusterTags(
c.ec2, aws.StringValue(securityGroups[0].GroupId),
ResourceLifecycleOwned, nil, securityGroups[0].Tags)
if err != nil {
return "", err
}
return aws.StringValue(securityGroups[0].GroupId), nil
}
createRequest := &ec2.CreateSecurityGroupInput{}
createRequest.VpcId = &c.vpcID
createRequest.GroupName = &name
createRequest.Description = &description
tags := c.tagging.buildTags(ResourceLifecycleOwned, additionalTags)
var awsTags []*ec2.Tag
for k, v := range tags {
tag := &ec2.Tag{
Key: aws.String(k),
Value: aws.String(v),
}
awsTags = append(awsTags, tag)
}
createRequest.TagSpecifications = []*ec2.TagSpecification{
{
ResourceType: aws.String(ec2.ResourceTypeSecurityGroup),
Tags: awsTags,
},
}
createResponse, err := c.ec2.CreateSecurityGroup(createRequest)
if err != nil {
ignore := false
switch err := err.(type) {
case awserr.Error:
if err.Code() == "InvalidGroup.Duplicate" && attempt < MaxReadThenCreateRetries {
klog.V(2).Infof("Got InvalidGroup.Duplicate while creating security group (race?); will retry")
ignore = true
}
}
if !ignore {
klog.Errorf("Error creating security group: %q", err)
return "", err
}
time.Sleep(1 * time.Second)
} else {
groupID = aws.StringValue(createResponse.GroupId)
break
}
}
if groupID == "" {
return "", fmt.Errorf("created security group, but id was not returned: %s", name)
}
return groupID, nil
}