Skip to content

Commit

Permalink
Move parts of ICC config to a new secret
Browse files Browse the repository at this point in the history
The assisted service needs to get the same configuration to embed IPA
into their images. Right now they embed CBO and ICC code to achieve
that. When we change anything on the CBO side (e.g. add ironic-proxy or
drop inspector), they need to update their code on all supported
releases.

This change adds a new secret with some of the IRONIC_* variables. It is
used for ICC itself and will be used by the assisted service instead of
CBO code directly.
  • Loading branch information
dtantsur committed Feb 22, 2024
1 parent 03222f4 commit 82659b1
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 29 deletions.
65 changes: 48 additions & 17 deletions provisioning/image_customization.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const (
deployISOFile = imageSharedDir + "/ironic-python-agent.iso"
deployInitrdEnvVar = "DEPLOY_INITRD"
deployInitrdFile = imageSharedDir + "/ironic-python-agent.initramfs"
imageCustomizationConfigName = "metal3-image-customization-config"
)

var (
Expand Down Expand Up @@ -107,26 +108,23 @@ func createImageCustomizationContainer(images *Images, info *ProvisioningInfo, i
imageVolumeMount,
},
ImagePullPolicy: "IfNotPresent",
Env: append(envVars, corev1.EnvVar{
Name: deployISOEnvVar,
Value: deployISOFile,
},
corev1.EnvVar{
Name: deployInitrdEnvVar,
Value: deployInitrdFile,
},
corev1.EnvVar{
Name: ironicBaseUrl,
Value: getUrlFromIP(ironicIPs, baremetalIronicPort),
EnvFrom: []corev1.EnvFromSource{
{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: imageCustomizationConfigName,
},
},
},
},
Env: append(envVars,
corev1.EnvVar{
Name: ironicInspectorBaseUrl,
// TODO(dtantsur): when inspector is gone, we may be able to stop passing this URL
Value: getUrlFromIP(inspectorIPs, baremetalIronicInspectorPort),
Name: deployISOEnvVar,
Value: deployISOFile,
},
corev1.EnvVar{
Name: ironicAgentImage,
Value: images.IronicAgent,
Name: deployInitrdEnvVar,
Value: deployInitrdFile,
},
corev1.EnvVar{
Name: containerRegistriesEnvVar,
Expand All @@ -136,7 +134,6 @@ func createImageCustomizationContainer(images *Images, info *ProvisioningInfo, i
Name: ipOptions,
Value: info.NetworkStack.IpOption(),
},
buildSSHKeyEnvVar(info.SSHKey),
pullSecret),
Ports: []corev1.ContainerPort{
{
Expand Down Expand Up @@ -242,12 +239,46 @@ func newImageCustomizationDeployment(info *ProvisioningInfo, ironicIPs []string,
}
}

func newImageCustomizationConfig(info *ProvisioningInfo, ironicIPs []string, inspectorIPs []string) *corev1.Secret {
return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: imageCustomizationConfigName,
Namespace: info.Namespace,
Annotations: map[string]string{},
Labels: map[string]string{
"k8s-app": metal3AppName,
cboLabelName: imageCustomizationService,
},
},
Type: corev1.SecretTypeOpaque,
StringData: map[string]string{
ironicAgentImage: info.Images.IronicAgent,
ironicBaseUrl: getUrlFromIP(ironicIPs, baremetalIronicPort),
// TODO(dtantsur): when inspector is gone, we may be able to stop passing this URL
ironicInspectorBaseUrl: getUrlFromIP(inspectorIPs, baremetalIronicInspectorPort),
sshKeyEnvVar: info.SSHKey,
},
}
}

func EnsureImageCustomizationDeployment(info *ProvisioningInfo) (updated bool, err error) {
ironicIPs, inspectorIPs, err := GetIronicIPs(info)
if err != nil {
return false, fmt.Errorf("unable to determine Ironic's IP to pass to the machine-image-customization-controller: %w", err)
}

configSecret := newImageCustomizationConfig(info, ironicIPs, inspectorIPs)
err = controllerutil.SetControllerReference(info.ProvConfig, configSecret, info.Scheme)
if err != nil {
err = fmt.Errorf("unable to set controllerReference on machine-image-customization config: %w", err)
return
}
_, _, err = resourceapply.ApplySecret(
context.Background(), info.Client.CoreV1(), info.EventRecorder, configSecret)
if err != nil {
return false, fmt.Errorf("failed to create the image customization config: %w", err)
}

imageCustomizationDeployment := newImageCustomizationDeployment(info, ironicIPs, inspectorIPs)
expectedGeneration := resourcemerge.ExpectedDeploymentGeneration(imageCustomizationDeployment, info.ProvConfig.Status.Generations)
err = controllerutil.SetControllerReference(info.ProvConfig, imageCustomizationDeployment, info.Scheme)
Expand Down
37 changes: 25 additions & 12 deletions provisioning/image_customization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,34 @@ func TestNewImageCustomizationContainer(t *testing.T) {
{Name: "NO_PROXY", Value: ".example.com,192.168.0.2,192.168.0.2"},
{Name: "DEPLOY_ISO", Value: "/shared/html/images/ironic-python-agent.iso"},
{Name: "DEPLOY_INITRD", Value: "/shared/html/images/ironic-python-agent.initramfs"},
{Name: "IRONIC_BASE_URL", Value: "https://192.168.0.2:6385"},
{Name: "IRONIC_INSPECTOR_BASE_URL", Value: "https://192.168.0.2:5050"},
{Name: "IRONIC_AGENT_IMAGE", Value: "registry.ci.openshift.org/openshift:ironic-agent"},
{Name: "REGISTRIES_CONF_PATH", Value: "/etc/containers/registries.conf"},
{Name: "IP_OPTIONS", Value: "ip=dhcp"},
{Name: "IRONIC_RAMDISK_SSH_KEY", Value: "sshkey"},
pullSecret,
},
}
secret1 := map[string]string{
"IRONIC_BASE_URL": "https://192.168.0.2:6385",
"IRONIC_INSPECTOR_BASE_URL": "https://192.168.0.2:5050",
"IRONIC_AGENT_IMAGE": "registry.ci.openshift.org/openshift:ironic-agent",
"IRONIC_RAMDISK_SSH_KEY": "sshkey",
}

container2 := corev1.Container{
Name: "image-customization-controller",
Env: []corev1.EnvVar{
{Name: "DEPLOY_ISO", Value: "/shared/html/images/ironic-python-agent.iso"},
{Name: "DEPLOY_INITRD", Value: "/shared/html/images/ironic-python-agent.initramfs"},
{Name: "IRONIC_BASE_URL", Value: "https://192.168.0.2:6385"},
{Name: "IRONIC_INSPECTOR_BASE_URL", Value: "https://192.168.0.3:5050"},
{Name: "IRONIC_AGENT_IMAGE", Value: "registry.ci.openshift.org/openshift:ironic-agent"},
{Name: "REGISTRIES_CONF_PATH", Value: "/etc/containers/registries.conf"},
{Name: "IP_OPTIONS", Value: "ip=dhcp"},
{Name: "IRONIC_RAMDISK_SSH_KEY", Value: "sshkey"},
pullSecret,
},
}
secret2 := map[string]string{
"IRONIC_BASE_URL": "https://192.168.0.2:6385",
"IRONIC_INSPECTOR_BASE_URL": "https://192.168.0.3:5050",
"IRONIC_AGENT_IMAGE": "registry.ci.openshift.org/openshift:ironic-agent",
"IRONIC_RAMDISK_SSH_KEY": "sshkey",
}

container3 := corev1.Container{
Name: "image-customization-controller",
Expand All @@ -88,48 +92,55 @@ func TestNewImageCustomizationContainer(t *testing.T) {
{Name: "NO_PROXY", Value: ".example.com,192.168.0.2,2001:db8::2"},
{Name: "DEPLOY_ISO", Value: "/shared/html/images/ironic-python-agent.iso"},
{Name: "DEPLOY_INITRD", Value: "/shared/html/images/ironic-python-agent.initramfs"},
{Name: "IRONIC_BASE_URL", Value: "https://192.168.0.2:6385,https://[2001:db8::2]:6385"},
{Name: "IRONIC_INSPECTOR_BASE_URL", Value: ""},
{Name: "IRONIC_AGENT_IMAGE", Value: "registry.ci.openshift.org/openshift:ironic-agent"},
{Name: "REGISTRIES_CONF_PATH", Value: "/etc/containers/registries.conf"},
{Name: "IP_OPTIONS", Value: "ip=dhcp"},
{Name: "IRONIC_RAMDISK_SSH_KEY", Value: "sshkey"},
pullSecret,
},
}
secret3 := map[string]string{
"IRONIC_BASE_URL": "https://192.168.0.2:6385,https://[2001:db8::2]:6385",
"IRONIC_INSPECTOR_BASE_URL": "",
"IRONIC_AGENT_IMAGE": "registry.ci.openshift.org/openshift:ironic-agent",
"IRONIC_RAMDISK_SSH_KEY": "sshkey",
}

tCases := []struct {
name string
ironicIPs []string
inspectorIPs []string
proxy *v1.Proxy
expectedContainer corev1.Container
expectedSecret map[string]string
}{
{
name: "image customization container with proxy",
ironicIPs: []string{ironicIP},
inspectorIPs: []string{ironicIP},
proxy: testProxy,
expectedContainer: container1,
expectedSecret: secret1,
},
{
name: "image customization container without proxy",
ironicIPs: []string{ironicIP},
inspectorIPs: []string{"192.168.0.3"},
proxy: nil,
expectedContainer: container2,
expectedSecret: secret2,
},
{
name: "image customization container with proxy",
ironicIPs: []string{ironicIP, ironicIP6},
proxy: testProxy,
expectedContainer: container3,
expectedSecret: secret3,
},
}
for _, tc := range tCases {
t.Run(tc.name, func(t *testing.T) {
t.Logf("Testing tc : %s", tc.name)
info := &ProvisioningInfo{
Images: &images,
SSHKey: "sshkey",
NetworkStack: NetworkStackV4,
Proxy: tc.proxy,
Expand All @@ -138,6 +149,8 @@ func TestNewImageCustomizationContainer(t *testing.T) {
for e := range actualContainer.Env {
assert.EqualValues(t, tc.expectedContainer.Env[e], actualContainer.Env[e])
}
actualSecret := newImageCustomizationConfig(info, tc.ironicIPs, tc.inspectorIPs)
assert.Equal(t, tc.expectedSecret, actualSecret.StringData)
})
}
}
Expand Down

0 comments on commit 82659b1

Please sign in to comment.