Skip to content
Open
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 @@ -62,6 +62,10 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep
}
})

if hcp.Spec.AdditionalTrustBundle != nil {
podspec.DeploymentAddAWSCABundleVolume(hcp.Spec.AdditionalTrustBundle, deployment, cpContext.ReleaseImageProvider.GetImage(podspec.CPOImageName))
}

// Set replicas based on whether termination handler is needed
// If the disable annotation is present, scale to 0 replicas
deployment.Spec.Replicas = ptr.To[int32](1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ import (
assets "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/assets"
controlplanecomponent "github.com/openshift/hypershift/support/controlplane-component"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type fakeReleaseProvider struct{}

func (f *fakeReleaseProvider) GetImage(key string) string { return "test-cpo-image" }
func (f *fakeReleaseProvider) ImageExist(key string) (string, bool) { return "", false }
func (f *fakeReleaseProvider) Version() string { return "4.17.0" }
func (f *fakeReleaseProvider) ComponentVersions() (map[string]string, error) {
return nil, nil
}
func (f *fakeReleaseProvider) ComponentImages() map[string]string { return nil }

func TestAdaptDeployment(t *testing.T) {
testCases := []struct {
name string
Expand Down Expand Up @@ -181,3 +192,91 @@ func TestGetTerminationHandlerQueueURL(t *testing.T) {
})
}
}

func TestAdaptDeploymentAWSCABundle(t *testing.T) {
testCases := []struct {
name string
additionalTrust *corev1.LocalObjectReference
expectCABundle bool
}{
{
name: "When additional trust bundle is set it should add combined CA bundle with init container",
additionalTrust: &corev1.LocalObjectReference{Name: "user-ca-bundle"},
expectCABundle: true,
},
{
name: "When no additional trust bundle is set it should not add CA bundle resources",
additionalTrust: nil,
expectCABundle: false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewGomegaWithT(t)

hcp := &hyperv1.HostedControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Namespace: "clusters-test-cluster",
},
Spec: hyperv1.HostedControlPlaneSpec{
InfraID: "test-infra-id",
Platform: hyperv1.PlatformSpec{
Type: hyperv1.AWSPlatform,
AWS: &hyperv1.AWSPlatformSpec{
Region: "us-east-1",
},
},
AdditionalTrustBundle: tc.additionalTrust,
},
}

cpContext := controlplanecomponent.WorkloadContext{
Context: t.Context(),
HCP: hcp,
ReleaseImageProvider: &fakeReleaseProvider{},
}

deployment, err := assets.LoadDeploymentManifest(ComponentName)
g.Expect(err).ToNot(HaveOccurred())

err = adaptDeployment(cpContext, deployment)
g.Expect(err).ToNot(HaveOccurred())

volumes := deployment.Spec.Template.Spec.Volumes
initContainers := deployment.Spec.Template.Spec.InitContainers
container := deployment.Spec.Template.Spec.Containers[0]

if tc.expectCABundle {
g.Expect(volumes).To(ContainElement(SatisfyAll(
HaveField("Name", "user-ca-bundle"),
HaveField("VolumeSource.ConfigMap.Name", "user-ca-bundle"),
)))
g.Expect(volumes).To(ContainElement(SatisfyAll(
HaveField("Name", "aws-ca-bundle"),
HaveField("VolumeSource.EmptyDir", Not(BeNil())),
)))
g.Expect(initContainers).To(ContainElement(SatisfyAll(
HaveField("Name", "setup-aws-ca-bundle"),
HaveField("Image", "test-cpo-image"),
)))
g.Expect(container.VolumeMounts).To(ContainElement(SatisfyAll(
HaveField("Name", "aws-ca-bundle"),
HaveField("MountPath", "/etc/pki/ca-trust/extracted/hypershift"),
HaveField("ReadOnly", true),
)))
g.Expect(container.Env).To(ContainElement(SatisfyAll(
HaveField("Name", "AWS_CA_BUNDLE"),
HaveField("Value", "/etc/pki/ca-trust/extracted/hypershift/combined-ca-bundle.pem"),
)))
} else {
g.Expect(volumes).ToNot(ContainElement(HaveField("Name", "user-ca-bundle")))
g.Expect(volumes).ToNot(ContainElement(HaveField("Name", "aws-ca-bundle")))
g.Expect(initContainers).ToNot(ContainElement(HaveField("Name", "setup-aws-ca-bundle")))
g.Expect(container.VolumeMounts).ToNot(ContainElement(HaveField("Name", "aws-ca-bundle")))
g.Expect(container.Env).ToNot(ContainElement(HaveField("Name", "AWS_CA_BUNDLE")))
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package capiprovider

import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
component "github.com/openshift/hypershift/support/controlplane-component"
"github.com/openshift/hypershift/support/k8sutil"
"github.com/openshift/hypershift/support/podspec"
"github.com/openshift/hypershift/support/proxy"

appsv1 "k8s.io/api/apps/v1"
Expand All @@ -20,6 +22,10 @@ func (capi *CAPIProviderOptions) adaptDeployment(cpContext component.WorkloadCon

proxy.SetEnvVars(&deployment.Spec.Template.Spec.Containers[0].Env)

if cpContext.HCP.Spec.Platform.Type == hyperv1.AWSPlatform && cpContext.HCP.Spec.AdditionalTrustBundle != nil {
podspec.DeploymentAddAWSCABundleVolume(cpContext.HCP.Spec.AdditionalTrustBundle, deployment, cpContext.ReleaseImageProvider.GetImage(podspec.CPOImageName))
}

if deployment.Annotations == nil {
deployment.Annotations = make(map[string]string)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,130 @@ func TestAdaptDeployment_WithNilAnnotations(t *testing.T) {
g.Expect(deployment.Annotations).ToNot(BeNil())
g.Expect(deployment.Annotations[k8sutil.HostedClusterAnnotation]).To(Equal("test-namespace/test-cluster"))
}

type fakeReleaseProvider struct{}

func (f *fakeReleaseProvider) GetImage(key string) string { return "test-cpo-image" }
func (f *fakeReleaseProvider) ImageExist(key string) (string, bool) { return "", false }
func (f *fakeReleaseProvider) Version() string { return "4.17.0" }
func (f *fakeReleaseProvider) ComponentVersions() (map[string]string, error) {
return nil, nil
}
func (f *fakeReleaseProvider) ComponentImages() map[string]string { return nil }

func TestAdaptDeploymentAWSCABundle(t *testing.T) {
testCases := []struct {
name string
platformType hyperv1.PlatformType
additionalTrust *corev1.LocalObjectReference
expectCABundle bool
}{
{
name: "When AWS platform with additional trust bundle it should add combined CA bundle",
platformType: hyperv1.AWSPlatform,
additionalTrust: &corev1.LocalObjectReference{Name: "user-ca-bundle"},
expectCABundle: true,
},
{
name: "When AWS platform without additional trust bundle it should not add CA bundle",
platformType: hyperv1.AWSPlatform,
additionalTrust: nil,
expectCABundle: false,
},
{
name: "When non-AWS platform with additional trust bundle it should not add CA bundle",
platformType: hyperv1.KubevirtPlatform,
additionalTrust: &corev1.LocalObjectReference{Name: "user-ca-bundle"},
expectCABundle: false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)

hcp := &hyperv1.HostedControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Namespace: "clusters-test-cluster",
Annotations: map[string]string{
"hypershift.openshift.io/cluster": "clusters/test-cluster",
},
},
Spec: hyperv1.HostedControlPlaneSpec{
Platform: hyperv1.PlatformSpec{
Type: tc.platformType,
},
AdditionalTrustBundle: tc.additionalTrust,
},
}

deploymentSpec := &appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "manager",
Image: "test-image",
},
},
},
},
}

capi := &CAPIProviderOptions{
deploymentSpec: deploymentSpec,
}

cpContext := component.WorkloadContext{
Context: t.Context(),
HCP: hcp,
ReleaseImageProvider: &fakeReleaseProvider{},
}

deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: ComponentName,
Namespace: hcp.Namespace,
},
}

err := capi.adaptDeployment(cpContext, deployment)
g.Expect(err).ToNot(HaveOccurred())

volumes := deployment.Spec.Template.Spec.Volumes
initContainers := deployment.Spec.Template.Spec.InitContainers
container := deployment.Spec.Template.Spec.Containers[0]

if tc.expectCABundle {
g.Expect(volumes).To(ContainElement(SatisfyAll(
HaveField("Name", "user-ca-bundle"),
HaveField("VolumeSource.ConfigMap.Name", "user-ca-bundle"),
)))
g.Expect(volumes).To(ContainElement(SatisfyAll(
HaveField("Name", "aws-ca-bundle"),
HaveField("VolumeSource.EmptyDir", Not(BeNil())),
)))
g.Expect(initContainers).To(ContainElement(SatisfyAll(
HaveField("Name", "setup-aws-ca-bundle"),
HaveField("Image", "test-cpo-image"),
)))
g.Expect(container.VolumeMounts).To(ContainElement(SatisfyAll(
HaveField("Name", "aws-ca-bundle"),
HaveField("MountPath", "/etc/pki/ca-trust/extracted/hypershift"),
HaveField("ReadOnly", true),
)))
g.Expect(container.Env).To(ContainElement(SatisfyAll(
HaveField("Name", "AWS_CA_BUNDLE"),
HaveField("Value", "/etc/pki/ca-trust/extracted/hypershift/combined-ca-bundle.pem"),
)))
} else {
g.Expect(volumes).ToNot(ContainElement(HaveField("Name", "user-ca-bundle")))
g.Expect(volumes).ToNot(ContainElement(HaveField("Name", "aws-ca-bundle")))
g.Expect(initContainers).ToNot(ContainElement(HaveField("Name", "setup-aws-ca-bundle")))
g.Expect(container.VolumeMounts).ToNot(ContainElement(HaveField("Name", "aws-ca-bundle")))
g.Expect(container.Env).ToNot(ContainElement(HaveField("Name", "AWS_CA_BUNDLE")))
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (c *awsOptions) NeedsManagementKASAccess() bool {

func NewComponent() component.ControlPlaneComponent {
return component.NewDeploymentComponent(ComponentName, &awsOptions{}).
WithAdaptFunction(adaptDeployment).
WithPredicate(predicate).
WithManifestAdapter(
"config.yaml",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package aws

import (
component "github.com/openshift/hypershift/support/controlplane-component"
"github.com/openshift/hypershift/support/podspec"

appsv1 "k8s.io/api/apps/v1"
)

func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Deployment) error {
if cpContext.HCP.Spec.AdditionalTrustBundle != nil {
podspec.DeploymentAddAWSCABundleVolume(cpContext.HCP.Spec.AdditionalTrustBundle, deployment, cpContext.ReleaseImageProvider.GetImage(podspec.CPOImageName))
}
return nil
}
Loading
Loading