Skip to content

Commit 1d8e188

Browse files
committed
Tag PowerVS Cluster Resources
1 parent 126acb0 commit 1d8e188

File tree

3 files changed

+411
-40
lines changed

3 files changed

+411
-40
lines changed

cloud/scope/powervs_cluster.go

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
cosSession "github.com/IBM/ibm-cos-sdk-go/aws/session"
3535
"github.com/IBM/ibm-cos-sdk-go/service/s3"
3636
tgapiv1 "github.com/IBM/networking-go-sdk/transitgatewayapisv1"
37+
"github.com/IBM/platform-services-go-sdk/globaltaggingv1"
3738
"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
3839
"github.com/IBM/platform-services-go-sdk/resourcemanagerv2"
3940
"github.com/IBM/vpc-go-sdk/vpcv1"
@@ -51,6 +52,7 @@ import (
5152
infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
5253
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/authenticator"
5354
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/cos"
55+
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/globaltagging"
5456
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/powervs"
5557
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/resourcecontroller"
5658
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/resourcemanager"
@@ -80,6 +82,7 @@ const (
8082
// vpcSubnetIPAddressCount is the total IP Addresses for the subnet.
8183
// Support for custom address prefixes will be added at a later time. Currently, we use the ip count for subnet creation.
8284
vpcSubnetIPAddressCount int64 = 256
85+
tagKey = "powervs.cluster.x-k8s.io-resource-owner:"
8386
)
8487

8588
// PowerVSClusterScopeParams defines the input parameters used to create a new PowerVSClusterScope.
@@ -102,6 +105,7 @@ type ClientFactory struct {
102105
TransitGatewayFactory func() (transitgateway.TransitGateway, error)
103106
ResourceControllerFactory func() (resourcecontroller.ResourceController, error)
104107
ResourceManagerFactory func() (resourcemanager.ResourceManager, error)
108+
GlobalTaggingFactory func() (globaltagging.GlobalTagging, error)
105109
}
106110

107111
// PowerVSClusterScope defines a scope defined around a Power VS Cluster.
@@ -110,6 +114,7 @@ type PowerVSClusterScope struct {
110114
patchHelper *patch.Helper
111115

112116
IBMPowerVSClient powervs.PowerVS
117+
GlobalTaggingClient globaltagging.GlobalTagging
113118
IBMVPCClient vpc.Vpc
114119
TransitGatewayClient transitgateway.TransitGateway
115120
ResourceClient resourcecontroller.ResourceController
@@ -253,6 +258,18 @@ func NewPowerVSClusterScope(params PowerVSClusterScopeParams) (*PowerVSClusterSc
253258
Authenticator: auth,
254259
}
255260

261+
// Create Global Tagging client.
262+
gtOptions := globaltagging.ServiceOptions{
263+
GlobalTaggingV1Options: &globaltaggingv1.GlobalTaggingV1Options{
264+
Authenticator: auth,
265+
},
266+
}
267+
268+
globalTaggingClient, err := params.getGlobalTaggingClient(gtOptions)
269+
if err != nil {
270+
return nil, fmt.Errorf("failed to create global tagging client: %w", err)
271+
}
272+
256273
rmClient, err := params.getResourceManagerClient(rcManagerOptions)
257274
if err != nil {
258275
return nil, fmt.Errorf("failed to create resource manager client: %w", err)
@@ -267,6 +284,7 @@ func NewPowerVSClusterScope(params PowerVSClusterScopeParams) (*PowerVSClusterSc
267284
IBMPowerVSClient: powerVSClient,
268285
IBMVPCClient: vpcClient,
269286
TransitGatewayClient: tgClient,
287+
GlobalTaggingClient: globalTaggingClient,
270288
ResourceClient: resourceClient,
271289
ResourceManagerClient: rmClient,
272290
}
@@ -294,6 +312,18 @@ func (params PowerVSClusterScopeParams) getPowerVSClient(options powervs.Service
294312
return powervs.NewService(options)
295313
}
296314

315+
func (params PowerVSClusterScopeParams) getGlobalTaggingClient(gtOptions globaltagging.ServiceOptions) (globaltagging.GlobalTagging, error) {
316+
if params.GlobalTaggingFactory != nil {
317+
return params.GlobalTaggingFactory()
318+
}
319+
320+
if gtEndpoint := endpoints.FetchEndpoints(string(endpoints.GlobalTagging), params.ServiceEndpoint); gtEndpoint != "" {
321+
params.Logger.V(3).Info("Overriding the default global tagging endpoint", "GlobaTaggingEndpoint", gtEndpoint)
322+
gtOptions.URL = gtEndpoint
323+
}
324+
return globaltagging.NewService(gtOptions)
325+
}
326+
297327
func (params PowerVSClusterScopeParams) getVPCClient() (vpc.Vpc, error) {
298328
if params.Logger.V(DEBUGLEVEL).Enabled() {
299329
core.SetLoggingLevel(core.LevelDebug)
@@ -859,10 +889,13 @@ func (s *PowerVSClusterScope) createServiceInstance(ctx context.Context) (*resou
859889
if zone == nil {
860890
return nil, fmt.Errorf("PowerVS zone is not set")
861891
}
892+
893+
tag := tagKey + s.Name()
862894
serviceInstance, _, err := s.ResourceClient.CreateResourceInstance(&resourcecontrollerv2.CreateResourceInstanceOptions{
863895
Name: s.GetServiceName(infrav1beta2.ResourceTypeServiceInstance),
864896
Target: zone,
865897
ResourceGroup: &resourceGroupID,
898+
Tags: append(make([]string, 0), tag),
866899
ResourcePlanID: ptr.To(resourcecontroller.PowerVSResourcePlanID),
867900
})
868901
if err != nil {
@@ -1084,6 +1117,24 @@ func (s *PowerVSClusterScope) createDHCPServer(ctx context.Context) (*string, er
10841117
return dhcpServer.ID, nil
10851118
}
10861119

1120+
// TagResource will attach a user Tag to a resource.
1121+
func (s *PowerVSClusterScope) TagResource(tagName string, resourceCRN *string) error {
1122+
tagOptions := &globaltaggingv1.AttachTagOptions{}
1123+
tagOptions.SetResources([]globaltaggingv1.Resource{
1124+
{
1125+
ResourceID: resourceCRN,
1126+
},
1127+
})
1128+
1129+
tagOptions.SetTagName(tagName)
1130+
tagOptions.SetTagType(globaltaggingv1.AttachTagOptionsTagTypeUserConst)
1131+
if _, _, err := s.GlobalTaggingClient.AttachTag(tagOptions); err != nil {
1132+
return fmt.Errorf("failure tagging resource: %w", err)
1133+
}
1134+
1135+
return nil
1136+
}
1137+
10871138
// ReconcileVPC reconciles VPC.
10881139
func (s *PowerVSClusterScope) ReconcileVPC(ctx context.Context) (bool, error) {
10891140
log := ctrl.LoggerFrom(ctx)
@@ -1124,7 +1175,7 @@ func (s *PowerVSClusterScope) ReconcileVPC(ctx context.Context) (bool, error) {
11241175

11251176
// create VPC
11261177
log.Info("Creating a VPC")
1127-
vpcID, err = s.createVPC()
1178+
vpcID, err = s.createVPC(ctx)
11281179
if err != nil {
11291180
return false, fmt.Errorf("failed to create VPC: %w", err)
11301181
}
@@ -1168,7 +1219,8 @@ func (s *PowerVSClusterScope) getVPCByName() (*vpcv1.VPC, error) {
11681219
}
11691220

11701221
// createVPC creates VPC.
1171-
func (s *PowerVSClusterScope) createVPC() (*string, error) {
1222+
func (s *PowerVSClusterScope) createVPC(ctx context.Context) (*string, error) {
1223+
log := ctrl.LoggerFrom(ctx)
11721224
resourceGroupID := s.GetResourceGroupID()
11731225
if resourceGroupID == "" {
11741226
return nil, fmt.Errorf("failed to fetch resource group ID for resource group %v, ID is empty", s.ResourceGroup())
@@ -1184,6 +1236,11 @@ func (s *PowerVSClusterScope) createVPC() (*string, error) {
11841236
return nil, err
11851237
}
11861238

1239+
tag := tagKey + s.Name()
1240+
if err = s.TagResource(tag, vpcDetails.CRN); err != nil {
1241+
log.Error(err, "failed to tag vpc")
1242+
}
1243+
11871244
// set security group for vpc
11881245
options := &vpcv1.CreateSecurityGroupRuleOptions{}
11891246
options.SetSecurityGroupID(*vpcDetails.DefaultSecurityGroup.ID)
@@ -1270,7 +1327,7 @@ func (s *PowerVSClusterScope) ReconcileVPCSubnets(ctx context.Context) (bool, er
12701327
subnet.Zone = &vpcZones[index%len(vpcZones)]
12711328
}
12721329
log.Info("Creating VPC subnet")
1273-
subnetID, err = s.createVPCSubnet(subnet)
1330+
subnetID, err = s.createVPCSubnet(ctx, subnet)
12741331
if err != nil {
12751332
return false, fmt.Errorf("error creating VPC subnet: %w", err)
12761333
}
@@ -1299,7 +1356,8 @@ func (s *PowerVSClusterScope) checkVPCSubnet(ctx context.Context, subnetName str
12991356
}
13001357

13011358
// createVPCSubnet creates a VPC subnet.
1302-
func (s *PowerVSClusterScope) createVPCSubnet(subnet infrav1beta2.Subnet) (*string, error) {
1359+
func (s *PowerVSClusterScope) createVPCSubnet(ctx context.Context, subnet infrav1beta2.Subnet) (*string, error) {
1360+
log := ctrl.LoggerFrom(ctx)
13031361
// TODO(karthik-k-n): consider moving to clusterscope
13041362
// fetch resource group id
13051363
resourceGroupID := s.GetResourceGroupID()
@@ -1338,6 +1396,12 @@ func (s *PowerVSClusterScope) createVPCSubnet(subnet infrav1beta2.Subnet) (*stri
13381396
if subnetDetails == nil {
13391397
return nil, fmt.Errorf("created VPC subnet is nil")
13401398
}
1399+
1400+
tag := tagKey + s.Name()
1401+
err = s.TagResource(tag, subnetDetails.CRN)
1402+
if err != nil {
1403+
log.Error(err, "failed to tag subnet")
1404+
}
13411405
return subnetDetails.ID, nil
13421406
}
13431407

@@ -1560,7 +1624,12 @@ func (s *PowerVSClusterScope) createVPCSecurityGroup(ctx context.Context, spec i
15601624
if err != nil {
15611625
return nil, fmt.Errorf("error creating VPC security group: %w", err)
15621626
}
1563-
// To-Do: Add tags to VPC security group, need to implement the client for "github.com/IBM/platform-services-go-sdk/globaltaggingv1".
1627+
1628+
tag := tagKey + s.Name()
1629+
err = s.TagResource(tag, securityGroup.CRN)
1630+
if err != nil {
1631+
log.Error(err, "failed to tag security group")
1632+
}
15641633
return securityGroup.ID, nil
15651634
}
15661635

@@ -1987,6 +2056,7 @@ func (s *PowerVSClusterScope) createTransitGatewayConnections(ctx context.Contex
19872056

19882057
// createTransitGateway creates transit gateway and sets the transit gateway status.
19892058
func (s *PowerVSClusterScope) createTransitGateway(ctx context.Context) error {
2059+
log := ctrl.LoggerFrom(ctx)
19902060
// fetch resource group id
19912061
resourceGroupID := s.GetResourceGroupID()
19922062
if resourceGroupID == "" {
@@ -2023,6 +2093,12 @@ func (s *PowerVSClusterScope) createTransitGateway(ctx context.Context) error {
20232093
return err
20242094
}
20252095

2096+
tag := tagKey + s.Name()
2097+
err = s.TagResource(tag, tg.Crn)
2098+
if err != nil {
2099+
log.Error(err, "failed to tag transitGateway")
2100+
}
2101+
20262102
s.SetTransitGatewayStatus(tg.ID, ptr.To(true))
20272103

20282104
vpcCRN, err := s.fetchVPCCRN()
@@ -2243,6 +2319,12 @@ func (s *PowerVSClusterScope) createLoadBalancer(ctx context.Context, lb infrav1
22432319
if err != nil {
22442320
return nil, fmt.Errorf("failed to create load balancer: %w", err)
22452321
}
2322+
2323+
tag := tagKey + s.Name()
2324+
if err = s.TagResource(tag, loadBalancer.CRN); err != nil {
2325+
log.Error(err, "failed to tag load balancer")
2326+
}
2327+
22462328
lbState := infrav1beta2.VPCLoadBalancerState(*loadBalancer.ProvisioningStatus)
22472329
return &infrav1beta2.VPCLoadBalancerStatus{
22482330
ID: loadBalancer.ID,
@@ -2398,12 +2480,14 @@ func (s *PowerVSClusterScope) createCOSServiceInstance() (*resourcecontrollerv2.
23982480
return nil, fmt.Errorf("failed to fetch resource group ID for resource group %v, ID is empty", s.ResourceGroup())
23992481
}
24002482

2483+
tag := tagKey + s.Name()
24012484
target := "Global"
24022485
// create service instance
24032486
serviceInstance, _, err := s.ResourceClient.CreateResourceInstance(&resourcecontrollerv2.CreateResourceInstanceOptions{
24042487
Name: s.GetServiceName(infrav1beta2.ResourceTypeCOSInstance),
24052488
Target: &target,
24062489
ResourceGroup: &resourceGroupID,
2490+
Tags: append(make([]string, 0), tag),
24072491
ResourcePlanID: ptr.To(resourcecontroller.CosResourcePlanID),
24082492
})
24092493
if err != nil {

0 commit comments

Comments
 (0)