@@ -68,6 +68,17 @@ const DefaultNetworkLoadBalancerListenerProtocol = "TCP"
68
68
// https://docs.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm#nsg_limits
69
69
const MaxNsgPerVnic = 5
70
70
71
+ const (
72
+ OkeSystemTagNamesapce = "orcl-containerengine"
73
+ // MaxDefinedTagPerLB is the maximum number of defined tags that be can be associated with the resource
74
+ //https://docs.oracle.com/en-us/iaas/Content/Tagging/Concepts/taggingoverview.htm#limits
75
+ MaxDefinedTagPerLB = 64
76
+ resourceTrackingFeatureFlagName = "CPO_ENABLE_RESOURCE_ATTRIBUTION"
77
+ )
78
+
79
+ var MaxDefinedTagPerLBErr = fmt .Errorf ("max limit of defined tags for lb is reached. skip adding tags. sending metric" )
80
+ var enableOkeSystemTags = false
81
+
71
82
const (
72
83
// Fallback value if annotation on service is not set
73
84
lbDefaultShape = "100Mbps"
@@ -373,6 +384,11 @@ func (clb *CloudLoadBalancerProvider) createLoadBalancer(ctx context.Context, sp
373
384
FreeformTags : spec .FreeformTags ,
374
385
DefinedTags : spec .DefinedTags ,
375
386
}
387
+ // do not block creation if the defined tag limit is reached. defer LB to tracked by backfilling
388
+ if len (details .DefinedTags ) > MaxDefinedTagPerLB {
389
+ logger .Warnf ("the number of defined tags in the LB create request is beyond the limit. removing the resource tracking tags from the details.." )
390
+ delete (details .DefinedTags , OkeSystemTagNamesapce )
391
+ }
376
392
377
393
if spec .Shape == flexible {
378
394
details .ShapeDetails = & client.GenericShapeDetails {
@@ -714,6 +730,19 @@ func (cp *CloudProvider) EnsureLoadBalancer(ctx context.Context, clusterName str
714
730
715
731
if ! lbExists {
716
732
lbStatus , newLBOCID , err := lbProvider .createLoadBalancer (ctx , spec )
733
+ if err != nil && client .IsSystemTagNotFoundOrNotAuthorisedError (logger , err ) {
734
+ logger .Warn ("LB creation failed due to error in adding system tags. sending metric & retrying without system tags" )
735
+
736
+ // send resource track tagging failure metrics
737
+ errorType = util .SystemTagErrTypePrefix + util .GetError (err )
738
+ lbMetricDimension = util .GetMetricDimensionForComponent (errorType , util .LoadBalancerType )
739
+ dimensionsMap [metrics .ComponentDimension ] = lbMetricDimension
740
+ metrics .SendMetricData (cp .metricPusher , getMetric (loadBalancerType , Create ), time .Since (startTime ).Seconds (), dimensionsMap )
741
+
742
+ // retry create without resource tracking system tags
743
+ delete (spec .DefinedTags , OkeSystemTagNamesapce )
744
+ lbStatus , newLBOCID , err = lbProvider .createLoadBalancer (ctx , spec )
745
+ }
717
746
if err != nil {
718
747
logger .With (zap .Error (err )).Error ("Failed to provision LoadBalancer" )
719
748
errorType = util .GetError (err )
@@ -884,7 +913,7 @@ func (cp *CloudProvider) getLoadBalancerSubnets(ctx context.Context, logger *zap
884
913
885
914
func (clb * CloudLoadBalancerProvider ) updateLoadBalancer (ctx context.Context , lb * client.GenericLoadBalancer , spec * LBSpec ) error {
886
915
lbID := * lb .Id
887
-
916
+ start := time . Now ()
888
917
logger := clb .logger .With ("loadBalancerID" , lbID , "compartmentID" , clb .config .CompartmentID , "loadBalancerType" , getLoadBalancerType (spec .service ), "serviceName" , spec .service .Name )
889
918
890
919
var actualPublicReservedIP * string
@@ -983,6 +1012,24 @@ func (clb *CloudLoadBalancerProvider) updateLoadBalancer(ctx context.Context, lb
983
1012
return errors .Errorf ("The Load Balancer service reserved IP cannot be updated after the Load Balancer is created." )
984
1013
}
985
1014
}
1015
+
1016
+ dimensionsMap := make (map [string ]string )
1017
+ var errType string
1018
+ if enableOkeSystemTags && ! doesLbHaveOkeSystemTags (lb , spec ) {
1019
+ logger .Info ("detected loadbalancer without oke system tags. proceeding to add" )
1020
+ err = clb .addLoadBalancerOkeSystemTags (ctx , lb , spec )
1021
+ if err != nil {
1022
+ // fail open if the update request fails
1023
+ logger .With (zap .Error (err )).Warn ("updateLoadBalancer didn't succeed. unable to add oke system tags" )
1024
+ errType = util .SystemTagErrTypePrefix + util .GetError (err )
1025
+ if errors .Is (err , MaxDefinedTagPerLBErr ) {
1026
+ errType = util .ErrTagLimitReached
1027
+ }
1028
+ dimensionsMap [metrics .ComponentDimension ] = util .GetMetricDimensionForComponent (errType , util .LoadBalancerType )
1029
+ dimensionsMap [metrics .ResourceOCIDDimension ] = * lb .Id
1030
+ metrics .SendMetricData (clb .metricPusher , getMetric (spec .Type , Update ), time .Since (start ).Seconds (), dimensionsMap )
1031
+ }
1032
+ }
986
1033
return nil
987
1034
}
988
1035
@@ -1648,6 +1695,56 @@ func (clb *CloudLoadBalancerProvider) updateLoadBalancerNetworkSecurityGroups(ct
1648
1695
return nil
1649
1696
}
1650
1697
1698
+ func doesLbHaveOkeSystemTags (lb * client.GenericLoadBalancer , spec * LBSpec ) bool {
1699
+ if lb .SystemTags == nil || spec .SystemTags == nil {
1700
+ return false
1701
+ }
1702
+ if okeSystemTag , okeSystemTagNsExists := lb .SystemTags [OkeSystemTagNamesapce ]; okeSystemTagNsExists {
1703
+ return reflect .DeepEqual (okeSystemTag , spec .SystemTags [OkeSystemTagNamesapce ])
1704
+ }
1705
+ return false
1706
+ }
1707
+ func (clb * CloudLoadBalancerProvider ) addLoadBalancerOkeSystemTags (ctx context.Context , lb * client.GenericLoadBalancer , spec * LBSpec ) error {
1708
+ lbDefinedTagsRequest := make (map [string ]map [string ]interface {})
1709
+
1710
+ if spec .SystemTags == nil {
1711
+ return fmt .Errorf ("oke system tag is not found in LB spec. ignoring.." )
1712
+ }
1713
+ if _ , exists := spec .SystemTags [OkeSystemTagNamesapce ]; ! exists {
1714
+ return fmt .Errorf ("oke system tag namespace is not found in LB spec" )
1715
+ }
1716
+
1717
+ if lb .DefinedTags != nil {
1718
+ lbDefinedTagsRequest = lb .DefinedTags
1719
+ }
1720
+
1721
+ // no overwriting customer tags as customer can not have a tag namespace with prefix 'orcl-'
1722
+ // system tags are passed as defined tags in the request
1723
+ lbDefinedTagsRequest [OkeSystemTagNamesapce ] = spec .SystemTags [OkeSystemTagNamesapce ]
1724
+
1725
+ // update fails if the number of defined tags is more than the service limit i.e 64
1726
+ if len (lbDefinedTagsRequest ) > MaxDefinedTagPerLB {
1727
+ return MaxDefinedTagPerLBErr
1728
+ }
1729
+
1730
+ lbUpdateDetails := & client.GenericUpdateLoadBalancerDetails {
1731
+ FreeformTags : lb .FreeformTags ,
1732
+ DefinedTags : lbDefinedTagsRequest ,
1733
+ }
1734
+ wrID , err := clb .lbClient .UpdateLoadBalancer (ctx , * lb .Id , lbUpdateDetails )
1735
+ if err != nil {
1736
+ return errors .Wrap (err , "UpdateLoadBalancer request failed" )
1737
+ }
1738
+ _ , err = clb .lbClient .AwaitWorkRequest (ctx , wrID )
1739
+ if err != nil {
1740
+ return errors .Wrap (err , "failed to await updateloadbalancer work request" )
1741
+ }
1742
+
1743
+ logger := clb .logger .With ("opc-workrequest-id" , wrID , "loadBalancerID" , lb .Id )
1744
+ logger .Info ("UpdateLoadBalancer request to add oke system tags completed successfully" )
1745
+ return nil
1746
+ }
1747
+
1651
1748
// Given an OCI load balancer, return a LoadBalancerStatus
1652
1749
func loadBalancerToStatus (lb * client.GenericLoadBalancer ) (* v1.LoadBalancerStatus , error ) {
1653
1750
if len (lb .IpAddresses ) == 0 {
0 commit comments