Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Check for well-known CloudInit userdata keys #308

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ type CloudInitMetadata struct {
PublicKeys string `yaml:"public-keys,omitempty"`
}

// CloudInitUserDataSecretKeys are the Secret keys that in v1a1 we'd check for the userdata.
// Specifically, CAPBK uses "value" for its key, while "user-data" is the preferred key nowadays.
// The 'value' key lookup will eventually be deprecated.
var CloudInitUserDataSecretKeys = []string{"user-data", "value"}

func BootStrapCloudInit(
vmCtx context.VirtualMachineContextA2,
config *types.VirtualMachineConfigInfo,
Expand Down Expand Up @@ -59,11 +64,8 @@ func BootStrapCloudInit(
}
userdata = data
} else if raw := cloudInitSpec.RawCloudConfig; raw != nil {
// Check for the 'user-data' key as per official contract and API documentation.
// Additionally, to support the cluster bootstrap data supplied by CAPBK's secret,
// we check for a 'value' key when 'user-data' is not supplied.
// The 'value' key lookup will eventually be deprecated.
for _, key := range []string{raw.Key, "user-data", "value"} {
keys := []string{raw.Key}
for _, key := range append(keys, CloudInitUserDataSecretKeys...) {
if data := bsArgs.BootstrapData.Data[key]; data != "" {
userdata = data
break
Expand Down
28 changes: 22 additions & 6 deletions pkg/vmprovider/providers/vsphere2/vmprovider_vm_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func getSecretData(
vmCtx context.VirtualMachineContextA2,
k8sClient ctrlclient.Client,
secretName, secretKey string,
configMapFallback bool) (map[string]string, error) {
configMapFallback, isCloudInitSecret bool) (map[string]string, error) {

var data map[string]string

Expand Down Expand Up @@ -141,7 +141,23 @@ func getSecretData(
}

if secretKey != "" {
if _, ok := data[secretKey]; !ok {
secretKeys := []string{secretKey}
if isCloudInitSecret {
// Hack: the v1a1 bootstrap did not have a Key field so for CloudInit we'd check
// for a few well-known keys. Check for the existence of those other keys when
// dealing with a CloudInit Secret so existing v1a1 users continue to work.
secretKeys = append(secretKeys, vmlifecycle.CloudInitUserDataSecretKeys...)
}

found := false
for _, k := range secretKeys {
if _, ok := data[k]; ok {
found = true
break
}
}

if !found {
err := fmt.Errorf("required key %q not found in Secret %s", secretKey, secretName)
conditions.MarkFalse(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady, "RequiredKeyNotFound", err.Error())
return nil, err
Expand Down Expand Up @@ -180,7 +196,7 @@ func GetVirtualMachineBootstrap(
cloudConfigSecretData = &out
} else if raw := v.RawCloudConfig; raw != nil {
var err error
data, err = getSecretData(vmCtx, k8sClient, raw.Name, raw.Key, true)
data, err = getSecretData(vmCtx, k8sClient, raw.Name, raw.Key, true, true)
if err != nil {
reason, msg := errToConditionReasonAndMessage(err)
conditions.MarkFalse(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady, reason, msg)
Expand All @@ -192,7 +208,7 @@ func GetVirtualMachineBootstrap(
_ = cooked // TODO Add support for in-line sysprep
} else if raw := v.RawSysprep; raw != nil {
var err error
data, err = getSecretData(vmCtx, k8sClient, raw.Name, raw.Key, true)
data, err = getSecretData(vmCtx, k8sClient, raw.Name, raw.Key, true, false)
if err != nil {
reason, msg := errToConditionReasonAndMessage(err)
conditions.MarkFalse(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady, reason, msg)
Expand All @@ -206,7 +222,7 @@ func GetVirtualMachineBootstrap(

if vApp.RawProperties != "" {
var err error
vAppData, err = getSecretData(vmCtx, k8sClient, vApp.RawProperties, "", true)
vAppData, err = getSecretData(vmCtx, k8sClient, vApp.RawProperties, "", true, false)
if err != nil {
reason, msg := errToConditionReasonAndMessage(err)
conditions.MarkFalse(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady, reason, msg)
Expand All @@ -223,7 +239,7 @@ func GetVirtualMachineBootstrap(
if data, ok := vAppExData[from.Name]; !ok {
// Do the easy thing here and carry along each Secret's entire data. We could instead
// shoehorn this in the vAppData with a concat key using an invalid k8s name delimiter.
fromData, err := getSecretData(vmCtx, k8sClient, from.Name, from.Key, false)
fromData, err := getSecretData(vmCtx, k8sClient, from.Name, from.Key, false, false)
if err != nil {
reason, msg := errToConditionReasonAndMessage(err)
conditions.MarkFalse(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady, reason, msg)
Expand Down
28 changes: 28 additions & 0 deletions pkg/vmprovider/providers/vsphere2/vmprovider_vm_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,34 @@ func vmUtilTests() {
})
})

When("Secret key fallback for CloudInit", func() {
const value = "should-fallback-to-this-key"

BeforeEach(func() {
cloudInitSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: dataName,
Namespace: vmCtx.VM.Namespace,
},
Data: map[string][]byte{
"value": []byte(value),
},
}

initObjects = append(initObjects, bootstrapCM, cloudInitSecret)

vmCtx.VM.Spec.Bootstrap.CloudInit.RawCloudConfig = &common.SecretKeySelector{}
vmCtx.VM.Spec.Bootstrap.CloudInit.RawCloudConfig.Name = dataName
vmCtx.VM.Spec.Bootstrap.CloudInit.RawCloudConfig.Key = "user-data"
})

It("returns success", func() {
bsData, err := vsphere.GetVirtualMachineBootstrap(vmCtx, k8sClient)
Expect(err).ToNot(HaveOccurred())
Expect(bsData.Data).To(HaveKeyWithValue("value", value))
Expect(conditions.IsTrue(vmCtx.VM, vmopv1.VirtualMachineConditionBootstrapReady)).To(BeTrue())
})
})
})

When("Bootstrap via Sysprep", func() {
Expand Down
Loading