Skip to content

Commit

Permalink
Get instance tags from infrastructure object
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-demicev committed Apr 21, 2021
1 parent 638f9f3 commit e7aaa5d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
33 changes: 28 additions & 5 deletions pkg/actuators/machine/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws/awserr"
configv1 "github.com/openshift/api/config/v1"
machinev1 "github.com/openshift/machine-api-operator/pkg/apis/machine/v1beta1"
mapierrors "github.com/openshift/machine-api-operator/pkg/controller/machine"
"github.com/openshift/machine-api-operator/pkg/metrics"
Expand All @@ -23,7 +24,7 @@ import (
awsclient "sigs.k8s.io/cluster-api-provider-aws/pkg/client"
)

// Scan machine tags, and return a deduped tags list
// Scan machine tags, and return a deduped tags list. The first found value gets precedence.
func removeDuplicatedTags(tags []*ec2.Tag) []*ec2.Tag {
m := make(map[string]bool)
result := []*ec2.Tag{}
Expand Down Expand Up @@ -272,7 +273,7 @@ func getBlockDeviceMappings(machine runtimeclient.ObjectKey, blockDeviceMappingS
return blockDeviceMappings, nil
}

func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsproviderv1.AWSMachineProviderConfig, userData []byte, client awsclient.Client) (*ec2.Instance, error) {
func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsproviderv1.AWSMachineProviderConfig, userData []byte, client awsclient.Client, infra *configv1.Infrastructure) (*ec2.Instance, error) {
machineKey := runtimeclient.ObjectKey{
Name: machine.Name,
Namespace: machine.Namespace,
Expand Down Expand Up @@ -315,7 +316,7 @@ func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsprovid
return nil, mapierrors.InvalidMachineConfiguration("Unable to get cluster ID for machine: %q", machine.Name)
}
// Add tags to the created machine
tagList := buildTagList(machine.Name, clusterID, machineProviderConfig.Tags)
tagList := buildTagList(machine.Name, clusterID, machineProviderConfig.Tags, infra)

tagInstance := &ec2.TagSpecification{
ResourceType: aws.String("instance"),
Expand Down Expand Up @@ -410,9 +411,13 @@ func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsprovid
return runResult.Instances[0], nil
}

func buildTagList(machineName string, clusterID string, machineTags []awsproviderv1.TagSpecification) []*ec2.Tag {
// buildTagList compile a list of ec2 tags from machine provider spec and infrastructure object platform spec
func buildTagList(machineName string, clusterID string, machineTags []awsproviderv1.TagSpecification, infra *configv1.Infrastructure) []*ec2.Tag {
rawTagList := []*ec2.Tag{}
for _, tag := range machineTags {

mergedTags := mergeInfrastructureAndMachineSpecTags(machineTags, infra)

for _, tag := range mergedTags {
// AWS tags are case sensitive, so we don't need to worry about other casing of "Name"
if !strings.HasPrefix(tag.Name, "kubernetes.io/cluster/") && tag.Name != "Name" {
rawTagList = append(rawTagList, &ec2.Tag{Key: aws.String(tag.Name), Value: aws.String(tag.Value)})
Expand All @@ -422,9 +427,27 @@ func buildTagList(machineName string, clusterID string, machineTags []awsprovide
{Key: aws.String("kubernetes.io/cluster/" + clusterID), Value: aws.String("owned")},
{Key: aws.String("Name"), Value: aws.String(machineName)},
}...)

return removeDuplicatedTags(rawTagList)
}

// mergeInfrastructureAndMachineSpecTags merge list of tags from machine provider spec and Infrastructure object platform spec.
// Machine tags have precedence over Infrastructure
func mergeInfrastructureAndMachineSpecTags(machineSpecTags []awsproviderv1.TagSpecification, infra *configv1.Infrastructure) []awsproviderv1.TagSpecification {
if infra == nil || infra.Status.PlatformStatus == nil || infra.Status.PlatformStatus.AWS == nil || infra.Status.PlatformStatus.AWS.ResourceTags == nil {
return machineSpecTags
}

mergedList := []awsproviderv1.TagSpecification{}
mergedList = append(mergedList, machineSpecTags...)

for _, tag := range infra.Status.PlatformStatus.AWS.ResourceTags {
mergedList = append(mergedList, awsproviderv1.TagSpecification{Name: tag.Key, Value: tag.Value})
}

return mergedList
}

type instanceList []*ec2.Instance

func (il instanceList) Len() int {
Expand Down
12 changes: 11 additions & 1 deletion pkg/actuators/machine/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
configv1 "github.com/openshift/api/config/v1"
machinecontroller "github.com/openshift/machine-api-operator/pkg/controller/machine"
"github.com/openshift/machine-api-operator/pkg/metrics"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
errorutil "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/klog/v2"
awsclient "sigs.k8s.io/cluster-api-provider-aws/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client"

awsproviderv1 "sigs.k8s.io/cluster-api-provider-aws/pkg/apis/awsprovider/v1beta1"
)
Expand Down Expand Up @@ -64,7 +67,14 @@ func (r *Reconciler) create() error {
return fmt.Errorf("failed to get user data: %w", err)
}

instance, err := launchInstance(r.machine, r.providerSpec, userData, r.awsClient)
infra := &configv1.Infrastructure{}
infraName := client.ObjectKey{Name: awsclient.GlobalInfrastuctureName}

if err := r.client.Get(r.Context, infraName, infra); err != nil {
return err
}

instance, err := launchInstance(r.machine, r.providerSpec, userData, r.awsClient, infra)
if err != nil {
klog.Errorf("%s: error creating machine: %v", r.machine.Name, err)
conditionFailed := conditionFailed()
Expand Down
6 changes: 3 additions & 3 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ const (
// AwsCredsSecretAccessKey is secret key containing AWS Secret Key
AwsCredsSecretAccessKey = "aws_secret_access_key"

// globalInfrastuctureName default name for infrastructure object
globalInfrastuctureName = "cluster"
// GlobalInfrastuctureName default name for infrastructure object
GlobalInfrastuctureName = "cluster"

// KubeCloudConfigNamespace is the namespace where the kube cloud config ConfigMap is located
KubeCloudConfigNamespace = "openshift-config-managed"
Expand Down Expand Up @@ -283,7 +283,7 @@ var addProviderVersionToUserAgent = request.NamedHandler{

func resolveEndpoints(awsConfig *aws.Config, ctrlRuntimeClient client.Client, region string) error {
infra := &configv1.Infrastructure{}
infraName := client.ObjectKey{Name: globalInfrastuctureName}
infraName := client.ObjectKey{Name: GlobalInfrastuctureName}

if err := ctrlRuntimeClient.Get(context.Background(), infraName, infra); err != nil {
return err
Expand Down

0 comments on commit e7aaa5d

Please sign in to comment.