Skip to content

Commit

Permalink
MGMT-16508: Add API to AgentServiceConfig CRD to allow pass of CA cer…
Browse files Browse the repository at this point in the history
…tificates for image pull.

This PR introduces a new field to the AgentServiceConfig CRD `imagePullCAConfigMap` which is a LocalObjectReference to a config map containing CA certificates
These certificates are to be used by the image service for the purpose of verifying the CA of HTTPS connections used for pulling images.

If `imagePullCAConfigMap` has an influence over a volume definition for "additional-ca-bundle" in the StatefulSet for assisted-image-service.
Any certificates defined within the data section of the map are to be stored in "/additional-ca-bundle"

This code sets up the Volume for this and maps to either an empty directory or maps the content of the ConfigMap.

This will ensure that the CA's will be available for use by the image service.
  • Loading branch information
paul-maidment committed Jan 15, 2024
1 parent 2f45852 commit 2adc972
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 0 deletions.
6 changes: 6 additions & 0 deletions api/v1beta1/agentserviceconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ type AgentServiceConfigSpec struct {
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="List of container registries without authentication"
// +optional
UnauthenticatedRegistries []string `json:"unauthenticatedRegistries,omitempty"`
// ImagePullCAConfigMapRef is a reference to a config map containing a certificate authority certificate
// this is an optional certificate to allow a customer to add a certificate authority for a HTTPS source of images
// this certificate will be used by the assisted-image-service when pulling OS images.
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image pull CA config map reference"
// +optional
ImagePullCAConfigMapRef *corev1.LocalObjectReference `json:"imagePullCAConfigMapRef,omitempty"`
}

// ConditionType related to our reconcile loop in addition to all the reasons
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down
24 changes: 24 additions & 0 deletions config/crd/resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down Expand Up @@ -2147,6 +2159,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ spec:
in -image-service'
displayName: Expose IPXE HTTP route
path: iPXEHTTPRoute
- description: ImagePullCAConfigMapRef is a reference to a config map containing
a certificate authority certificate this is an optional certificate to allow
a customer to add a certificate authority for a HTTPS source of images this
certificate will be used by the assisted-image-service when pulling OS images.
displayName: Image pull CA config map reference
path: imagePullCAConfigMapRef
- description: ImageStorage defines the spec of the PersistentVolumeClaim to
be created for each replica of the image service. If a PersistentVolumeClaim
is provided 2GiB per OSImage entry is required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,18 @@ spec:
- enabled
- disabled
type: string
imagePullCAConfigMapRef:
description: ImagePullCAConfigMapRef is a reference to a config map
containing a certificate authority certificate this is an optional
certificate to allow a customer to add a certificate authority for
a HTTPS source of images this certificate will be used by the assisted-image-service
when pulling OS images.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
imageStorage:
description: ImageStorage defines the spec of the PersistentVolumeClaim
to be created for each replica of the image service. If a PersistentVolumeClaim
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ spec:
in -image-service'
displayName: Expose IPXE HTTP route
path: iPXEHTTPRoute
- description: ImagePullCAConfigMapRef is a reference to a config map containing
a certificate authority certificate this is an optional certificate to allow
a customer to add a certificate authority for a HTTPS source of images this
certificate will be used by the assisted-image-service when pulling OS images.
displayName: Image pull CA config map reference
path: imagePullCAConfigMapRef
- description: ImageStorage defines the spec of the PersistentVolumeClaim to
be created for each replica of the image service. If a PersistentVolumeClaim
is provided 2GiB per OSImage entry is required
Expand Down
22 changes: 22 additions & 0 deletions internal/controller/controllers/agentserviceconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,7 @@ func newImageServiceStatefulSet(ctx context.Context, log logrus.FieldLogger, asc
{Name: "tls-certs", MountPath: "/etc/image-service/certs"},
{Name: "service-cabundle", MountPath: "/etc/image-service/ca-bundle"},
{Name: "image-service-data", MountPath: "/data"},
{Name: "additional-ca-bundle", MountPath: "/additional-ca-bundle"},
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
Expand Down Expand Up @@ -1261,6 +1262,27 @@ func newImageServiceStatefulSet(ctx context.Context, log logrus.FieldLogger, asc
},
})

if asc.spec.ImagePullCAConfigMapRef != nil {
volumeSource := &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: asc.spec.ImagePullCAConfigMapRef.Name,
},
}
volumes = ensureVolume(volumes, corev1.Volume{
Name: "additional-ca-bundle",
VolumeSource: corev1.VolumeSource{
ConfigMap: volumeSource,
},
})
} else {
volumes = ensureVolume(volumes, corev1.Volume{
Name: "additional-ca-bundle",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
})
}

if asc.spec.ImageStorage != nil {
var found bool
for i, claim := range statefulSet.Spec.VolumeClaimTemplates {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,64 @@ var _ = Describe("reconcileImageServiceStatefulSet", func() {
Expect(*ss.Spec.Replicas).To(Equal(int32(1)))
})

It("Volume claim for ImagePullCAConfigMapRef", func() {

By("Register CA Config map and reference in asc.Spec.ImagePullCAConfigMapRef", func() {
// Register some certificate authority certs.
imagePullCAConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "imagePullConfigMap",
Namespace: testNamespace,
},
Data: map[string]string{
"CA1.pem": "-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIUASRIJ1X9QHbJ/+daV+IjQdS1NIowDQYJKoZIhvcNAQEL\nBQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE\nCgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yNDAxMDkxMzA0MzFaFw0zNDAxMDYx\nMzA0MzFaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa\nBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQC+Z9BqGKzPINWCSMdeTX52gLDoeTU3q4fH8QyHSO3hNo/eKtaE\nrHOqnsn/ntcsjFwX9Wfwxt1B73uqXkqWWCsH2QKGsw36gPJmSc6ZuqP7oUTApx0U\nOktdxOm96MouqN5OAXoPvzH5dFytJyW3TWpKJ3jP9ZWJrqmp4YcgnU+U6Vlen4iy\nN0NciJtdVDDsWoWqh0zg0YOHJpd43c7aQ0PFoPp4QEj4j29I7X91UmRP67dA8kSw\n2mPcZZFDkKY9fA0TuF1a3Dvx7yssvQoAC9F+jZYgBsTcFNGcc2roJVA8RwcdVZQ3\nbTwA0nLql5EDLdXHSthJiXHPhp6niOTsJx4bAgMBAAGjUzBRMB0GA1UdDgQWBBQr\nbklK4KlO6lgMM5MpVxqWcpWhxzAfBgNVHSMEGDAWgBQrbklK4KlO6lgMM5MpVxqW\ncpWhxzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAEF3pv541h\nXKwDMqHShbpvqEqnhN74c6zc6b8nnIohRK5rNkEkIEf2ikJ6Pdik2te4IHEoA4V9\nHqtpKUtgNqge6GAw/p3kOB4C6eObZYZTaJ4ZiQ5UvO6R7w5MvFkjQH5hFO+fjhQv\n8whWWO7HRlt/Hll/VF3JNVALtIv2SGi51WHFqwe+ERKl0kGKWH8PyY4X6XflHQfa\n1FDev/NRnOVjRcXipsaZwRXcjRUiRX1KuOixlc8Reul8RdrL1Mt7lpl8+e/hqhoO\n2O5thhnTuV/mID3zE+5J8w6UcCdeZo4VDNWdZqPzrI/ymSgARVwUu0MFeYfCbMmB\neEpiSixb6YRM\n-----END CERTIFICATE-----\n",
"CA2.pem": "-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIUSS+V3nF9Pb7SGXTKq0Ggca5Ed6owDQYJKoZIhvcNAQEL\nBQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE\nCgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yNDAxMDkxMzA1MjZaFw0zNDAxMDYx\nMzA1MjZaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa\nBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDK7E8quzVQkdBcRFeNJNVLgnERkTWGaacbTlFYVJi04BRENc4i\nWc/4zvt+VxLeGLFUA6fLGtNjiPhaqw5Tg7IjRd8t6Ho0+xODdADP3phg1bPZN2VL\neWpuNiszngk9CAZ8s2qWDFyY6FoNk3zykH4G69vyXS2DXjlX+y7MJpjuTsHqBhNS\nfg4oJNy/XtIm4eeGVa3o3A23qZkpI3JeZAdPEjsSwxYzsD93dMmZKbqZ0UkU9sbF\nVMbuwPOEde1eBAdIdg2K51SGwL84RUGsMUCcS2ASqED9wdEcFQfCbg8MtdwdUkT8\nNXsw3MuehcRXksLfMntg97mJJ7v3wJLahlcdAgMBAAGjUzBRMB0GA1UdDgQWBBQA\nP+6zc3wM6V0dVswyGh0sOsEkCzAfBgNVHSMEGDAWgBQAP+6zc3wM6V0dVswyGh0s\nOsEkCzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCWQXTdQOvX\neE+9PZye/xhxxGrjNlyrhzUk3+uVR0bFgoucakF7qfIFph/EPCfY7jR14Gwnlaty\nhZ/bpH4yh3Y6gAXztGkfyZW39x4MBKyUuD49ZW6BKz8daWR3TVBWU9yJLE53aJUD\nYLVSeglquQOjnfclL+0jE8mYCld6K9mxYrIjig58JQ24NcHMfpzcRgf5qYMpY2nj\ni5aXTd8D2FBs5a2/5rGQDG/9tN8YKPoFpg7V+UnBH9yaVL7LkTZUjZVzy8sGLpZ2\nXz2WeZ9oFpBEi+dYMtLnwkHwc5IOCsj6aK5/TTQlW8AyUO9iSUpShrADoANQzNsY\ni7xTDV88P0fU\n-----END CERTIFICATE-----\n",
},
}

// Reference the config map containing the certs.
asc.Spec.ImagePullCAConfigMapRef = &corev1.LocalObjectReference{
Name: imagePullCAConfigMap.Name,
}
ascr = newTestReconciler(asc, imagePullCAConfigMap)
ascc = initASC(ascr, asc)
Expect(reconcileImageServiceStatefulSet(ctx, log, ascc)).To(Succeed())
})

By("Verify additional certs volume added", func() {
imageServiceStatefulSet := &appsv1.StatefulSet{}
Expect(ascr.Client.Get(ctx, types.NamespacedName{Name: imageServiceName, Namespace: testNamespace}, imageServiceStatefulSet)).To(Succeed())
foundVolume := false
for _, v := range imageServiceStatefulSet.Spec.Template.Spec.Volumes {
if v.Name == "additional-ca-bundle" {
foundVolume = true
Expect(v.VolumeSource.EmptyDir).To(BeNil())
break
}
}
Expect(foundVolume).To(BeTrue())
})

By("Remove ImagePullCAConfigMapRef", func() {
asc.Spec.ImagePullCAConfigMapRef = nil
reconcileUntilDone(5)
})

By("Verify additional certs volume removed", func() {
imageServiceStatefulSet := &appsv1.StatefulSet{}
Expect(ascr.Client.Get(ctx, types.NamespacedName{Name: imageServiceName, Namespace: testNamespace}, imageServiceStatefulSet)).To(Succeed())
foundVolume := false
for _, v := range imageServiceStatefulSet.Spec.Template.Spec.Volumes {
if v.Name == "additional-ca-bundle" {
foundVolume = true
Expect(v.VolumeSource.EmptyDir).NotTo(BeNil())
break
}
}
Expect(foundVolume).To(BeTrue())
})
})

It("removes empty dir volume and adds volume claim template when image storage is added", func() {
asc.Spec.ImageStorage = nil
ascc = initASC(ascr, asc)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2adc972

Please sign in to comment.