@@ -16,30 +16,116 @@ limitations under the License.
16
16
17
17
package cloud
18
18
19
+ import (
20
+ infrav1 "github.com/aws/cluster-api-provider-cloudstack/api/v1beta1"
21
+ "strings"
22
+ )
23
+
19
24
type TagIface interface {
20
- AddNetworkTags (string , map [string ]string ) error
21
- GetNetworkTags (string ) (map [string ]string , error )
22
- DeleteNetworkTags (string , map [string ]string ) error
25
+ AddClusterTag (ResourceType , string , * infrav1.CloudStackCluster , bool ) error
26
+ DeleteClusterTag (ResourceType , string , * infrav1.CloudStackCluster ) error
27
+ DeleteCreatedByCAPCTag (ResourceType , string ) error
28
+ DoClusterTagsAllowDisposal (ResourceType , string ) (bool , error )
29
+ AddTags (ResourceType , string , map [string ]string ) error
30
+ GetTags (ResourceType , string ) (map [string ]string , error )
31
+ DeleteTags (ResourceType , string , map [string ]string ) error
23
32
}
24
33
34
+ type ResourceType string
35
+
25
36
const (
26
- clusterTagNamePrefix = "CAPC_cluster_"
27
- createdByCapcTagName = "created_by_CAPC"
28
- resourceTypeNetwork = "network"
37
+ clusterTagNamePrefix = "CAPC_cluster_"
38
+ createdByCAPCTagName = "created_by_CAPC"
39
+ ResourceTypeNetwork ResourceType = "Network"
40
+ ResourceTypeIPAddress ResourceType = "PublicIpAddress"
29
41
)
30
42
31
- // TagNetwork adds tags to a network by network id.
32
- func (c * client ) AddNetworkTags (networkID string , tags map [string ]string ) error {
33
- p := c .cs .Resourcetags .NewCreateTagsParams ([]string {networkID }, resourceTypeNetwork , tags )
43
+ // AddClusterTag adds cluster-related tags to a resource. One tag indicates that the resource is used by a given
44
+ // cluster. The other tag, if applied, indicates that CAPC created the resource and may dispose of it later.
45
+ func (c * client ) AddClusterTag (resourceType ResourceType , resourceID string , csCluster * infrav1.CloudStackCluster , addCreatedByCAPCTag bool ) error {
46
+ clusterTagName := generateClusterTagName (csCluster )
47
+ newTags := map [string ]string {}
48
+
49
+ existingTags , err := c .GetTags (resourceType , resourceID )
50
+ if err != nil {
51
+ return err
52
+ }
53
+
54
+ if existingTags [clusterTagName ] == "" {
55
+ newTags [clusterTagName ] = "1"
56
+ }
57
+
58
+ if addCreatedByCAPCTag && existingTags [createdByCAPCTagName ] == "" {
59
+ newTags [createdByCAPCTagName ] = "1"
60
+ }
61
+
62
+ if len (newTags ) > 0 {
63
+ return c .AddTags (resourceType , resourceID , newTags )
64
+ }
65
+
66
+ return nil
67
+ }
68
+
69
+ // DeleteClusterTag deletes the tag that associates the resource with a given cluster.
70
+ func (c * client ) DeleteClusterTag (resourceType ResourceType , resourceID string , csCluster * infrav1.CloudStackCluster ) error {
71
+ tags , err := c .GetTags (resourceType , resourceID )
72
+ if err != nil {
73
+ return err
74
+ }
75
+
76
+ clusterTagName := generateClusterTagName (csCluster )
77
+ if tagValue := tags [clusterTagName ]; tagValue != "" {
78
+ return c .DeleteTags (resourceType , resourceID , map [string ]string {clusterTagName : tagValue })
79
+ }
80
+
81
+ return nil
82
+ }
83
+
84
+ // DeleteCreatedByCAPCTag deletes the tag that indicates that the resource was created by CAPC. This is useful when a
85
+ // resource is disassociated instead of deleted. That way the tag won't cause confusion if the resource is reused later.
86
+ func (c * client ) DeleteCreatedByCAPCTag (resourceType ResourceType , resourceID string ) error {
87
+ tags , err := c .GetTags (resourceType , resourceID )
88
+ if err != nil {
89
+ return err
90
+ }
91
+
92
+ if tagValue := tags [createdByCAPCTagName ]; tagValue != "" {
93
+ return c .DeleteTags (resourceType , resourceID , map [string ]string {createdByCAPCTagName : tagValue })
94
+ }
95
+
96
+ return nil
97
+ }
98
+
99
+ // DoClusterTagsAllowDisposal checks to see if the resource is in a state that makes it eligible for disposal. CAPC can
100
+ // dispose of a resource if the tags show it was created by CAPC and isn't being used by any clusters.
101
+ func (c * client ) DoClusterTagsAllowDisposal (resourceType ResourceType , resourceID string ) (bool , error ) {
102
+ tags , err := c .GetTags (resourceType , resourceID )
103
+ if err != nil {
104
+ return false , err
105
+ }
106
+
107
+ var clusterTagCount int
108
+ for tagName := range tags {
109
+ if strings .HasPrefix (tagName , clusterTagNamePrefix ) {
110
+ clusterTagCount ++
111
+ }
112
+ }
113
+
114
+ return clusterTagCount == 0 && tags [createdByCAPCTagName ] != "" , nil
115
+ }
116
+
117
+ // AddTags adds arbitrary tags to a resource.
118
+ func (c * client ) AddTags (resourceType ResourceType , resourceID string , tags map [string ]string ) error {
119
+ p := c .cs .Resourcetags .NewCreateTagsParams ([]string {resourceID }, string (resourceType ), tags )
34
120
_ , err := c .cs .Resourcetags .CreateTags (p )
35
121
return err
36
122
}
37
123
38
- // GetNetworkTags gets tags by network id .
39
- func (c * client ) GetNetworkTags ( networkID string ) (map [string ]string , error ) {
124
+ // GetTags gets all of a resource's tags .
125
+ func (c * client ) GetTags ( resourceType ResourceType , resourceID string ) (map [string ]string , error ) {
40
126
p := c .cs .Resourcetags .NewListTagsParams ()
41
- p .SetResourceid (networkID )
42
- p .SetResourcetype (resourceTypeNetwork )
127
+ p .SetResourceid (resourceID )
128
+ p .SetResourcetype (string ( resourceType ) )
43
129
listTagResponse , err := c .cs .Resourcetags .ListTags (p )
44
130
if err != nil {
45
131
return nil , err
@@ -51,10 +137,15 @@ func (c *client) GetNetworkTags(networkID string) (map[string]string, error) {
51
137
return tags , nil
52
138
}
53
139
54
- // DeleteNetworkTags deletes matching tags from a network
55
- func (c * client ) DeleteNetworkTags (networkID string , tagsToDelete map [string ]string ) error {
56
- p := c .cs .Resourcetags .NewDeleteTagsParams ([]string {networkID }, resourceTypeNetwork )
140
+ // DeleteTags deletes the given tags from a resource. If the tags don't exist, or if the values don't match, it will
141
+ // result in an error.
142
+ func (c * client ) DeleteTags (resourceType ResourceType , resourceID string , tagsToDelete map [string ]string ) error {
143
+ p := c .cs .Resourcetags .NewDeleteTagsParams ([]string {resourceID }, string (resourceType ))
57
144
p .SetTags (tagsToDelete )
58
145
_ , err := c .cs .Resourcetags .DeleteTags (p )
59
146
return err
60
147
}
148
+
149
+ func generateClusterTagName (csCluster * infrav1.CloudStackCluster ) string {
150
+ return clusterTagNamePrefix + string (csCluster .UID )
151
+ }
0 commit comments