Skip to content

Commit de57c7b

Browse files
committed
Provide user data secrets to ignition template
1 parent d655057 commit de57c7b

4 files changed

Lines changed: 60 additions & 6 deletions

File tree

api/cloudscale/provider/v1beta1/cloudscaleprovider_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@ type CloudscaleMachineProviderSpec struct {
2929
// The Jsonnet template has access to the following variables:
3030
// - std.extVar('context').machine: the Machine object. The name can be accessed via std.extVar('context').machine.metadata.name for example.
3131
// - std.extVar('context').data: all keys from the UserDataSecret. For example, std.extVar('context').data.foo will access the value of the key foo.
32+
// - std.extVar('context').secrets: all secrets matching UserDataSecretSelector. For example, std.extVar('context').secrets[0].metadata.name will access the name of the first secret.
33+
// Also see UserDataSecretSelector.
3234
// +optional
3335
UserDataSecret *corev1.LocalObjectReference `json:"userDataSecret,omitempty"`
36+
// UserDataSecretSelector allows passing secrets with the matching selector into the user data Jsonnet context.
37+
// Only secrets in the same namespace as the controller are considered.
38+
// +optional
39+
// `null` means no secrets are passed.
40+
// And empty selector means all secrets in the namespace are passed.
41+
UserDataSecretSelector *metav1.LabelSelector `json:"userDataSecretSelector,omitempty"`
42+
3443
// TokenSecret is a reference to the secret with the cloudscale API token.
3544
// The secret must contain a key named token.
3645
// If no token is provided, the operator will try to use the default token from CLOUDSCALE_API_TOKEN.

api/cloudscale/provider/v1beta1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/machine/actuator.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
machinecontroller "github.com/openshift/machine-api-operator/pkg/controller/machine"
1414
corev1 "k8s.io/api/core/v1"
1515
"k8s.io/apimachinery/pkg/api/equality"
16+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617
"k8s.io/utils/ptr"
1718
"sigs.k8s.io/controller-runtime/pkg/client"
1819
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -477,7 +478,23 @@ func (a *Actuator) loadAndRenderUserDataSecret(ctx context.Context, mctx *machin
477478
data[k] = string(v)
478479
}
479480

480-
jvm, err := jsonnetVMWithContext(mctx.machine, data)
481+
var userDataSecrets corev1.SecretList
482+
if mctx.spec.UserDataSecretSelector != nil {
483+
sel, err := metav1.LabelSelectorAsSelector(mctx.spec.UserDataSecretSelector)
484+
if err != nil {
485+
return "", fmt.Errorf("failed to parse UserDataSecretSelector: %w", err)
486+
}
487+
if err := a.k8sClient.List(
488+
ctx,
489+
&userDataSecrets,
490+
client.InNamespace(mctx.machine.Namespace),
491+
client.MatchingLabelsSelector{Selector: sel},
492+
); err != nil {
493+
return "", fmt.Errorf("failed to list secrets in namespace %q: %w", mctx.machine.Namespace, err)
494+
}
495+
}
496+
497+
jvm, err := jsonnetVMWithContext(mctx.machine, data, userDataSecrets)
481498
if err != nil {
482499
return "", fmt.Errorf("userData: failed to create jsonnet VM: %w", err)
483500
}
@@ -494,10 +511,11 @@ func (a *Actuator) loadAndRenderUserDataSecret(ctx context.Context, mctx *machin
494511
return compacted.String(), nil
495512
}
496513

497-
func jsonnetVMWithContext(machine *machinev1beta1.Machine, data map[string]string) (*jsonnet.VM, error) {
514+
func jsonnetVMWithContext(machine *machinev1beta1.Machine, data map[string]string, userDataSecrets corev1.SecretList) (*jsonnet.VM, error) {
498515
jcr, err := json.Marshal(map[string]any{
499516
"machine": machine,
500517
"data": data,
518+
"secrets": userDataSecrets.Items,
501519
})
502520
if err != nil {
503521
return nil, fmt.Errorf("unable to marshal jsonnet context: %w", err)

pkg/machine/actuator_test.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,30 @@ func Test_Actuator_Create_ComplexMachineE2E(t *testing.T) {
4242
},
4343
},
4444
}
45+
appUserDataSecret := &corev1.Secret{
46+
ObjectMeta: metav1.ObjectMeta{
47+
Name: "user-data-managed",
48+
Labels: map[string]string{
49+
"test.com/user-data-secret": "",
50+
},
51+
},
52+
Data: map[string][]byte{
53+
"userData": []byte("{}"),
54+
},
55+
}
56+
unrelatedSecret := &corev1.Secret{
57+
ObjectMeta: metav1.ObjectMeta{
58+
Name: "unrelated-secret",
59+
},
60+
Data: map[string][]byte{
61+
"foo": []byte("bar"),
62+
},
63+
}
4564
providerSpec := csv1beta1.CloudscaleMachineProviderSpec{
46-
UserDataSecret: &corev1.LocalObjectReference{Name: "app-user-data"},
65+
UserDataSecret: &corev1.LocalObjectReference{Name: "app-user-data"},
66+
UserDataSecretSelector: &metav1.LabelSelector{
67+
MatchLabels: appUserDataSecret.Labels,
68+
},
4769
TokenSecret: &corev1.LocalObjectReference{Name: "cloudscale-token"},
4870
BaseDomain: "cluster.example.com",
4971
Zone: "rma1",
@@ -81,11 +103,11 @@ func Test_Actuator_Create_ComplexMachineE2E(t *testing.T) {
81103
},
82104
Data: map[string][]byte{
83105
"ignitionCA": []byte("CADATA"),
84-
"userData": []byte("{ca: std.extVar('context').data.ignitionCA}"),
106+
"userData": []byte("{ca: std.extVar('context').data.ignitionCA, udsecrets: std.map(function(s) s.metadata.name,std.extVar('context').secrets)}"),
85107
},
86108
}
87109

88-
c := newFakeClient(t, machine, tokenSecret, userDataSecret)
110+
c := newFakeClient(t, machine, tokenSecret, userDataSecret, appUserDataSecret, unrelatedSecret)
89111
ss := csmock.NewMockServerService(ctrl)
90112
sgs := csmock.NewMockServerGroupService(ctrl)
91113
actuator := newActuator(c, ss, sgs)
@@ -145,7 +167,7 @@ func Test_Actuator_Create_ComplexMachineE2E(t *testing.T) {
145167
SSHKeys: []string{},
146168
UseIPV6: providerSpec.UseIPV6,
147169
ServerGroups: []string{"created-server-group-uuid"},
148-
UserData: "{\"ca\":\"CADATA\"}",
170+
UserData: "{\"ca\":\"CADATA\",\"udsecrets\":[\"user-data-managed\"]}",
149171
}),
150172
).DoAndReturn(cloudscaleServerFromServerRequest(func(s *cloudscale.Server) {
151173
s.UUID = "created-server-uuid"

0 commit comments

Comments
 (0)