Skip to content
This repository was archived by the owner on Jun 23, 2020. It is now read-only.

Commit 287ea2d

Browse files
committed
add env var for default tag values
1 parent a6396dd commit 287ea2d

File tree

5 files changed

+95
-69
lines changed

5 files changed

+95
-69
lines changed

pkg/oci/client/config_validate.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ func validateAuthConfig(c Config, fldPath *field.Path) field.ErrorList {
6262
// ValidateConfig validates the OCI Volume Provisioner config file.
6363
func ValidateConfig(c *Config) field.ErrorList {
6464
allErrs := field.ErrorList{}
65-
if c.ClusterName == "" {
66-
allErrs = append(allErrs, field.Required(field.NewPath("clusterName"), ""))
67-
}
68-
6965
allErrs = append(allErrs, validateAuthConfig(*c, field.NewPath("auth"))...)
7066
return allErrs
7167
}

pkg/oci/client/config_validate_test.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ func TestValidateConfig(t *testing.T) {
3737
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
3838
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
3939
},
40-
ClusterName: "test",
4140
},
4241
errs: field.ErrorList{},
4342
}, {
@@ -49,7 +48,6 @@ func TestValidateConfig(t *testing.T) {
4948
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
5049
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
5150
},
52-
ClusterName: "test",
5351
},
5452
errs: field.ErrorList{
5553
&field.Error{Type: field.ErrorTypeRequired, Field: "auth.region", BadValue: ""},
@@ -63,7 +61,6 @@ func TestValidateConfig(t *testing.T) {
6361
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
6462
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
6563
},
66-
ClusterName: "test",
6764
},
6865
errs: field.ErrorList{
6966
&field.Error{Type: field.ErrorTypeRequired, Field: "auth.tenancy", BadValue: ""},
@@ -77,7 +74,6 @@ func TestValidateConfig(t *testing.T) {
7774
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
7875
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
7976
},
80-
ClusterName: "test",
8177
},
8278
errs: field.ErrorList{
8379
&field.Error{Type: field.ErrorTypeRequired, Field: "auth.user", BadValue: ""},
@@ -91,7 +87,6 @@ func TestValidateConfig(t *testing.T) {
9187
UserOCID: "ocid1.user.oc1..aaaaaaaai77mql2xerv7cn6wu3nhxang3y4jk56vo5bn5l5lysl34avnui3q",
9288
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
9389
},
94-
ClusterName: "test",
9590
},
9691
errs: field.ErrorList{
9792
&field.Error{Type: field.ErrorTypeRequired, Field: "auth.key", BadValue: ""},
@@ -105,30 +100,14 @@ func TestValidateConfig(t *testing.T) {
105100
UserOCID: "ocid1.user.oc1..aaaaaaaai77mql2xerv7cn6wu3nhxang3y4jk56vo5bn5l5lysl34avnui3q",
106101
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
107102
},
108-
ClusterName: "test",
109103
},
110104
errs: field.ErrorList{
111105
&field.Error{Type: field.ErrorTypeRequired, Field: "auth.fingerprint", BadValue: ""},
112106
},
113-
}, {
114-
name: "missing_clusterName",
115-
in: &Config{
116-
Auth: AuthConfig{
117-
Region: "us-phoenix-1",
118-
TenancyOCID: "ocid1.tenancy.oc1..aaaaaaaatyn7scrtwtqedvgrxgr2xunzeo6uanvyhzxqblctwkrpisvke4kq",
119-
UserOCID: "ocid1.user.oc1..aaaaaaaai77mql2xerv7cn6wu3nhxang3y4jk56vo5bn5l5lysl34avnui3q",
120-
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
121-
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
122-
},
123-
},
124-
errs: field.ErrorList{
125-
&field.Error{Type: field.ErrorTypeRequired, Field: "clusterName", BadValue: ""},
126-
},
127107
}, {
128108
name: "valid with instance principals enabled",
129109
in: &Config{
130110
UseInstancePrincipals: true,
131-
ClusterName: "test",
132111
},
133112
errs: field.ErrorList{},
134113
}, {
@@ -142,7 +121,6 @@ func TestValidateConfig(t *testing.T) {
142121
PrivateKey: "-----BEGIN RSA PRIVATE KEY----- (etc)",
143122
Fingerprint: "8c:bf:17:7b:5f:e0:7d:13:75:11:d6:39:0d:e2:84:74",
144123
},
145-
ClusterName: "test",
146124
UseInstancePrincipals: true,
147125
},
148126
errs: field.ErrorList{

pkg/provisioner/block/block.go

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ import (
3838
)
3939

4040
const (
41-
ociVolumeID = "ociVolumeID"
42-
ociVolumeBackupID = "volume.beta.kubernetes.io/oci-volume-source"
43-
ociTagAnnotation = "oraclecloud.com/additional-tags"
41+
ociVolumeID = "ociVolumeID"
42+
ociVolumeBackupID = "volume.beta.kubernetes.io/oci-volume-source"
43+
ociTagAnnotation = "oraclecloud.com/additional-tags"
44+
45+
defaultTagsEnvVar = "OCI_DEFAULT_TAGS"
4446
volumePrefixEnvVarName = "OCI_VOLUME_NAME_PREFIX"
4547
fsType = "fsType"
4648
)
4749

4850
// blockProvisioner is the internal provisioner for OCI block volumes
4951
type blockProvisioner struct {
50-
clusterName string
5152
client client.ProvisionerClient
5253
metadata instancemeta.Interface
5354
volumeRoundingEnabled bool
@@ -57,9 +58,8 @@ type blockProvisioner struct {
5758
var _ plugin.ProvisionerPlugin = &blockProvisioner{}
5859

5960
// NewBlockProvisioner creates a new instance of the block storage provisioner
60-
func NewBlockProvisioner(client client.ProvisionerClient, metadata instancemeta.Interface, volumeRoundingEnabled bool, minVolumeSize resource.Quantity, clusterName string) plugin.ProvisionerPlugin {
61+
func NewBlockProvisioner(client client.ProvisionerClient, metadata instancemeta.Interface, volumeRoundingEnabled bool, minVolumeSize resource.Quantity) plugin.ProvisionerPlugin {
6162
return &blockProvisioner{
62-
clusterName: clusterName,
6363
client: client,
6464
metadata: metadata,
6565
volumeRoundingEnabled: volumeRoundingEnabled,
@@ -83,10 +83,6 @@ func roundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64 {
8383
return (volumeSizeBytes + allocationUnitBytes - 1) / allocationUnitBytes
8484
}
8585

86-
func (block *blockProvisioner) clusterTag() string {
87-
return fmt.Sprintf("kubernetes.io/cluster/%s", block.clusterName)
88-
}
89-
9086
// Provision creates an OCI block volume
9187
func (block *blockProvisioner) Provision(options controller.VolumeOptions, ad *identity.AvailabilityDomain) (*v1.PersistentVolume, error) {
9288
for _, accessMode := range options.PVC.Spec.AccessModes {
@@ -188,42 +184,69 @@ func (block *blockProvisioner) Provision(options controller.VolumeOptions, ad *i
188184
}
189185

190186
func getTags(annotations map[string]string) (defined map[string]map[string]interface{}, freeform map[string]string, err error) {
191-
if annotations == nil {
192-
return
187+
defaultDefinedTags, defaultFreeformTags, err := parseTags(os.Getenv(defaultTagsEnvVar))
188+
if err != nil {
189+
return nil, nil, err
190+
}
191+
192+
definedTags, freeformTags, err := parseTags(annotations[ociTagAnnotation])
193+
if err != nil {
194+
return nil, nil, err
195+
}
196+
197+
// merge annotation tags with default tags
198+
for namespace, tags := range definedTags {
199+
if _, ok := defaultDefinedTags[namespace]; !ok {
200+
defaultDefinedTags[namespace] = map[string]interface{}{}
201+
}
202+
203+
for tag, value := range tags {
204+
defaultDefinedTags[namespace][tag] = value
205+
}
206+
}
207+
208+
for tag, value := range freeformTags {
209+
defaultFreeformTags[tag] = value
193210
}
194211

212+
return defaultDefinedTags, defaultFreeformTags, nil
213+
}
214+
215+
func parseTags(tagStr string) (defined map[string]map[string]interface{}, freeform map[string]string, err error) {
216+
195217
defined = map[string]map[string]interface{}{}
196218
freeform = map[string]string{}
197219

198-
tagStr, ok := annotations[ociTagAnnotation]
199-
if ok {
200-
for _, tag := range strings.Split(tagStr, ",") {
201-
parts := strings.Split(tag, "=")
202-
if len(parts) != 2 {
203-
return nil, nil, fmt.Errorf("tag format must follow (<namespace>.)<tagkey>=<value>: %q", tag)
204-
}
220+
if tagStr == "" {
221+
return
222+
}
205223

206-
key, value := parts[0], parts[1]
207-
208-
keyParts := strings.Split(key, ".")
209-
if len(keyParts) == 1 {
210-
freeform[key] = value
211-
} else if len(keyParts) == 2 {
212-
namespace, key := keyParts[0], keyParts[1]
213-
namespaceTags, ok := defined[namespace]
214-
if !ok {
215-
namespaceTags = map[string]interface{}{}
216-
defined[namespace] = namespaceTags
217-
}
218-
219-
namespaceTags[key] = value
220-
} else {
221-
return nil, nil, fmt.Errorf("tag format must follow (<namespace>.)<tagkey>=<value>: %q", tag)
224+
for _, tag := range strings.Split(tagStr, ",") {
225+
parts := strings.Split(tag, "=")
226+
if len(parts) != 2 {
227+
return nil, nil, fmt.Errorf("tag format must follow (<namespace>.)<tagkey>=<value>: %q", tag)
228+
}
229+
230+
key, value := parts[0], parts[1]
231+
232+
keyParts := strings.Split(key, ".")
233+
if len(keyParts) == 1 {
234+
freeform[key] = value
235+
} else if len(keyParts) == 2 {
236+
namespace, key := keyParts[0], keyParts[1]
237+
namespaceTags, ok := defined[namespace]
238+
if !ok {
239+
namespaceTags = map[string]interface{}{}
240+
defined[namespace] = namespaceTags
222241
}
242+
243+
namespaceTags[key] = value
244+
} else {
245+
return nil, nil, fmt.Errorf("tag format must follow (<namespace>.)<tagkey>=<value>: %q", tag)
223246
}
224247
}
225248

226-
return defined, freeform, nil
249+
return
227250
}
228251

229252
// Delete destroys a OCI volume created by Provision

pkg/provisioner/block/block_test.go

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package block
1717
import (
1818
"context"
1919
"fmt"
20+
"os"
2021
"reflect"
2122
"testing"
2223
"time"
@@ -164,7 +165,7 @@ func TestVolumeRoundingLogic(t *testing.T) {
164165
CompartmentOCID: "",
165166
Region: "phx",
166167
})
167-
block := NewBlockProvisioner(NewClientProvisioner(nil), metadata, tt.enabled, tt.minVolumeSize, "test")
168+
block := NewBlockProvisioner(NewClientProvisioner(nil), metadata, tt.enabled, tt.minVolumeSize)
168169
provisionedVolume, err := block.Provision(volumeOptions, &defaultAD)
169170
if err != nil {
170171
t.Fatalf("Expected no error but got %s", err)
@@ -184,32 +185,60 @@ func TestVolumeRoundingLogic(t *testing.T) {
184185

185186
func TestGetTags(t *testing.T) {
186187
testCases := map[string]struct {
188+
setup func()
187189
annotations map[string]string
188190
expectedDefinedTags map[string]map[string]interface{}
189191
expectedFreeformTags map[string]string
190192
}{
191-
"valid tags": {
193+
"valid tags only default": {
194+
setup: func() {
195+
os.Setenv(defaultTagsEnvVar, "namespace1.default=test,default=test")
196+
},
197+
annotations: map[string]string{},
198+
expectedDefinedTags: map[string]map[string]interface{}{
199+
"namespace1": map[string]interface{}{
200+
"default": "test",
201+
},
202+
},
203+
expectedFreeformTags: map[string]string{
204+
"default": "test",
205+
},
206+
},
207+
"valid tags with default": {
208+
setup: func() {
209+
os.Setenv(defaultTagsEnvVar, "namespace1.default=test,default=test")
210+
},
192211
annotations: map[string]string{
193212
ociTagAnnotation: "namespace1.test=foo,namespace2.test=bar,bar=baz,namespace1.test2=bar,foo=bar",
194213
},
195214
expectedDefinedTags: map[string]map[string]interface{}{
196215
"namespace1": map[string]interface{}{
197-
"test": "foo",
198-
"test2": "bar",
216+
"test": "foo",
217+
"test2": "bar",
218+
"default": "test",
199219
},
200220
"namespace2": map[string]interface{}{
201221
"test": "bar",
202222
},
203223
},
204224
expectedFreeformTags: map[string]string{
205-
"bar": "baz",
206-
"foo": "bar",
225+
"bar": "baz",
226+
"foo": "bar",
227+
"default": "test",
207228
},
208229
},
209230
}
210231

211232
for name, tc := range testCases {
212233
t.Run(name, func(t *testing.T) {
234+
defer func() {
235+
os.Setenv(defaultTagsEnvVar, "")
236+
}()
237+
238+
if tc.setup != nil {
239+
tc.setup()
240+
}
241+
213242
defined, freeform, err := getTags(tc.annotations)
214243
if err != nil {
215244
t.Fatal(err)

pkg/provisioner/core/provisioner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func NewOCIProvisioner(kubeClient kubernetes.Interface, nodeInformer informersv1
7777
glog.Fatalf("Unable to create volume provisioner client: %v", err)
7878
}
7979

80-
blockProvisioner := block.NewBlockProvisioner(client, instancemeta.New(), volumeRoundingEnabled, minVolumeSize, cfg.ClusterName)
80+
blockProvisioner := block.NewBlockProvisioner(client, instancemeta.New(), volumeRoundingEnabled, minVolumeSize)
8181

8282
return &OCIProvisioner{
8383
client: client,

0 commit comments

Comments
 (0)