@@ -41,6 +41,7 @@ type ENIReconciler struct {
4141 NonCachingClient client.Client
4242 Log logr.Logger
4343 EC2 * ec2.EC2
44+ Tags map [string ]string
4445}
4546
4647// +kubebuilder:rbac:groups=aws.k8s.logmein.com,resources=enis,verbs=get;list;watch;create;update;patch;delete
@@ -74,6 +75,13 @@ func (r *ENIReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
7475 if eni .Spec .SecondaryPrivateIPAddressCount > 0 {
7576 input .SecondaryPrivateIpAddressCount = aws .Int64 (eni .Spec .SecondaryPrivateIPAddressCount )
7677 }
78+
79+ tags := ec2.TagSpecification {
80+ ResourceType : aws .String ("network-interface" ),
81+ }
82+ tags .Tags = convertMapToTags (r .Tags )
83+ input .TagSpecifications = []* ec2.TagSpecification {& tags }
84+
7785 resp , err := r .EC2 .CreateNetworkInterface (input )
7886 if err != nil {
7987 return ctrl.Result {}, err
@@ -200,6 +208,12 @@ func (r *ENIReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
200208 return ctrl.Result {RequeueAfter : 3 * time .Second }, err
201209 }
202210 }
211+
212+ // reconcile tags
213+ if err := r .reconcileTags (ctx , & eni , eniInfo .TagSet ); err != nil {
214+ return ctrl.Result {}, err
215+ }
216+
203217 eni .Status .Attachment = eni .Spec .Attachment
204218 return ctrl.Result {}, r .Update (ctx , & eni )
205219 } else if containsString (eni .ObjectMeta .Finalizers , finalizerName ) {
@@ -356,3 +370,59 @@ func (r *ENIReconciler) SetupWithManager(mgr ctrl.Manager) error {
356370 For (& awsv1alpha1.ENI {}).
357371 Complete (r )
358372}
373+
374+ // combineDefaultAndDefinedTags combines the default tags defined in the controller
375+ // with the tags defined in the ENI spec. Tags defined in the ENI spec override
376+ // default tags in case of key conflicts.
377+ func (r ENIReconciler ) combineDefaultAndDefinedTags (eni * awsv1alpha1.ENI ) []* ec2.Tag {
378+ var tags []* ec2.Tag
379+ tags = convertMapToTags (r .Tags )
380+ tags = append (tags , convertMapToTags (* eni .Spec .Tags )... )
381+ return tags
382+ }
383+
384+ func (r * ENIReconciler ) reconcileTags (ctx context.Context , eni * awsv1alpha1.ENI , existingTags []* ec2.Tag ) error {
385+ resources := []* string {aws .String (eni .Status .NetworkInterfaceID )}
386+
387+ // create tags that are defined in the spec but not present yet
388+ var tagsToCreate []* ec2.Tag
389+ for k , v := range * eni .Spec .Tags {
390+ create := true
391+ for _ , tag := range existingTags {
392+ if aws .StringValue (tag .Key ) == k && aws .StringValue (tag .Value ) == v {
393+ create = false
394+ break
395+ }
396+ }
397+ if create {
398+ tagsToCreate = append (tagsToCreate , & ec2.Tag {Key : aws .String (k ), Value : aws .String (v )})
399+ }
400+ }
401+
402+ if len (tagsToCreate ) > 0 {
403+ if _ , err := r .EC2 .CreateTagsWithContext (ctx , & ec2.CreateTagsInput {
404+ Resources : resources ,
405+ Tags : tagsToCreate ,
406+ }); err != nil {
407+ return err
408+ }
409+ }
410+
411+ // remove tags that are not defined in the spec and are not default ones
412+ var tagsToRemove []* ec2.Tag
413+ for _ , tag := range existingTags {
414+ if ! isTagPresent (r .combineDefaultAndDefinedTags (eni ), tag ) {
415+ tagsToRemove = append (tagsToRemove , tag )
416+ }
417+ }
418+
419+ if len (tagsToRemove ) > 0 {
420+ _ , err := r .EC2 .DeleteTagsWithContext (ctx , & ec2.DeleteTagsInput {
421+ Resources : resources ,
422+ Tags : tagsToRemove ,
423+ })
424+ return err
425+ }
426+
427+ return nil
428+ }
0 commit comments