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

feat: applicationset volumes and volumemounts spec #1563

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
6 changes: 6 additions & 0 deletions api/v1beta1/argocd_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ type ArgoCDApplicationSet struct {

// Custom labels to pods deployed by the operator
Labels map[string]string `json:"labels,omitempty"`

// Volumes adds volumes to the Argo CD ApplicationSet Controller container.
Volumes []corev1.Volume `json:"volumes,omitempty"`

// VolumeMounts adds volumeMounts to the Argo CD ApplicationSet Controller container.
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
}

func (a *ArgoCDApplicationSet) IsEnabled() bool {
Expand Down
14 changes: 14 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.

1,655 changes: 1,655 additions & 0 deletions bundle/manifests/argoproj.io_argocds.yaml

Large diffs are not rendered by default.

1,655 changes: 1,655 additions & 0 deletions config/crd/bases/argoproj.io_argocds.yaml

Large diffs are not rendered by default.

72 changes: 43 additions & 29 deletions controllers/argocd/applicationset.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD,
if sa != nil {
podSpec.ServiceAccountName = sa.ObjectMeta.Name
}
podSpec.Volumes = []corev1.Volume{

serverVolumes := []corev1.Volume{
{
Name: "ssh-known-hosts",
VolumeSource: corev1.VolumeSource{
Expand Down Expand Up @@ -228,6 +229,10 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD,
},
},
}
if cr.Spec.ApplicationSet.Volumes != nil {
serverVolumes = append(serverVolumes, cr.Spec.ApplicationSet.Volumes...)
}
podSpec.Volumes = serverVolumes
addSCMGitlabVolumeMount := false
if scmRootCAConfigMapName := getSCMRootCAConfigMapName(cr); scmRootCAConfigMapName != "" {
cm := newConfigMapWithName(scmRootCAConfigMapName, cr)
Expand Down Expand Up @@ -322,35 +327,50 @@ func (r *ReconcileArgoCD) applicationSetContainer(cr *argoproj.ArgoCD, addSCMGit
// Environment specified in the CR take precedence over everything else
appSetEnv = argoutil.EnvMerge(appSetEnv, proxyEnvVars(), false)

// Default VolumeMounts for ApplicationSetController
serverVolumeMounts := []corev1.VolumeMount{
{
Name: "ssh-known-hosts",
MountPath: "/app/config/ssh",
},
{
Name: "tls-certs",
MountPath: "/app/config/tls",
},
{
Name: "gpg-keys",
MountPath: "/app/config/gpg/source",
},
{
Name: "gpg-keyring",
MountPath: "/app/config/gpg/keys",
},
{
Name: "tmp",
MountPath: "/tmp",
},
}

// Optional extra VolumeMounts for ApplicationSetController
if cr.Spec.ApplicationSet.VolumeMounts != nil {
serverVolumeMounts = append(serverVolumeMounts, cr.Spec.ApplicationSet.VolumeMounts...)
}

if addSCMGitlabVolumeMount {
serverVolumeMounts = append(serverVolumeMounts, corev1.VolumeMount{
Name: "appset-gitlab-scm-tls-cert",
MountPath: ApplicationSetGitlabSCMTlsMountPath,
})
}

container := corev1.Container{
Command: r.getArgoApplicationSetCommand(cr),
Env: appSetEnv,
Image: getApplicationSetContainerImage(cr),
ImagePullPolicy: corev1.PullAlways,
Name: "argocd-applicationset-controller",
Resources: getApplicationSetResources(cr),
VolumeMounts: []corev1.VolumeMount{
{
Name: "ssh-known-hosts",
MountPath: "/app/config/ssh",
},
{
Name: "tls-certs",
MountPath: "/app/config/tls",
},
{
Name: "gpg-keys",
MountPath: "/app/config/gpg/source",
},
{
Name: "gpg-keyring",
MountPath: "/app/config/gpg/keys",
},
{
Name: "tmp",
MountPath: "/tmp",
},
},
VolumeMounts: serverVolumeMounts,
Ports: []corev1.ContainerPort{
{
ContainerPort: 7000,
Expand All @@ -375,12 +395,6 @@ func (r *ReconcileArgoCD) applicationSetContainer(cr *argoproj.ArgoCD, addSCMGit
},
},
}
if addSCMGitlabVolumeMount {
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
Name: "appset-gitlab-scm-tls-cert",
MountPath: ApplicationSetGitlabSCMTlsMountPath,
})
}
return container
}

Expand Down
99 changes: 95 additions & 4 deletions controllers/argocd/applicationset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ func TestReconcileApplicationSet_CreateDeployments(t *testing.T) {
deployment))

// Ensure the created Deployment has the expected properties
checkExpectedDeploymentValues(t, r, deployment, &sa, a)
checkExpectedDeploymentValues(t, r, deployment, &sa, nil, nil, a)
}

func checkExpectedDeploymentValues(t *testing.T, r *ReconcileArgoCD, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, a *argoproj.ArgoCD) {
func checkExpectedDeploymentValues(t *testing.T, r *ReconcileArgoCD, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, extraVolumes *[]corev1.Volume, extraVolumeMounts *[]corev1.VolumeMount, a *argoproj.ArgoCD) {
assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name)
appsetAssertExpectedLabels(t, &deployment.ObjectMeta)

Expand Down Expand Up @@ -174,10 +174,46 @@ func checkExpectedDeploymentValues(t *testing.T, r *ReconcileArgoCD, deployment
})
}

if extraVolumes != nil {
volumes = append(volumes, *extraVolumes...)
}

if diff := cmp.Diff(volumes, deployment.Spec.Template.Spec.Volumes); diff != "" {
t.Fatalf("failed to reconcile applicationset-controller deployment volumes:\n%s", diff)
}

volumeMounts := []corev1.VolumeMount{
{
Name: "ssh-known-hosts",
MountPath: "/app/config/ssh",
},
{
Name: "tls-certs",
MountPath: "/app/config/tls",
},
{
Name: "gpg-keys",
MountPath: "/app/config/gpg/source",
},
{
Name: "gpg-keyring",
MountPath: "/app/config/gpg/keys",
},
{
Name: "tmp",
MountPath: "/tmp",
},
}

if extraVolumeMounts != nil {
volumeMounts = append(volumeMounts, *extraVolumeMounts...)
}

// Verify VolumeMounts
if diff := cmp.Diff(volumeMounts, deployment.Spec.Template.Spec.Containers[0].VolumeMounts); diff != "" {
t.Fatalf("failed to reconcile applicationset-controller deployment volume mounts:\n%s", diff)
}

expectedSelector := &metav1.LabelSelector{
MatchLabels: map[string]string{
common.ArgoCDKeyName: deployment.Name,
Expand Down Expand Up @@ -249,6 +285,61 @@ func TestReconcileApplicationSetProxyConfiguration(t *testing.T) {

}

func TestReconcileApplicationSetVolumes(t *testing.T) {
logf.SetLogger(ZapLogger(true))

extraVolumes := []corev1.Volume{
{
Name: "example-volume",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
}

extraVolumeMounts := []corev1.VolumeMount{
{
Name: "example-volume",
MountPath: "/mnt/data",
},
}

a := makeTestArgoCD()
a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{
Volumes: extraVolumes,
VolumeMounts: extraVolumeMounts,
}

resObjs := []client.Object{a}
subresObjs := []client.Object{a}
runtimeObjs := []runtime.Object{}
sch := makeTestReconcilerScheme(argoproj.AddToScheme)
cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs)
r := makeTestReconciler(cl, sch)

sa := corev1.ServiceAccount{}

// Reconcile the ApplicationSet deployment
assert.NoError(t, r.reconcileApplicationSetDeployment(a, &sa))

// Get the deployment after reconciliation
deployment := &appsv1.Deployment{}
err := r.Client.Get(
context.TODO(),
types.NamespacedName{
Name: "argocd-applicationset-controller",
Namespace: a.Namespace,
},
deployment,
)
if err != nil {
t.Fatalf("failed to get deployment: %v", err)
}

// Ensure the created Deployment has the expected properties
checkExpectedDeploymentValues(t, r, deployment, &sa, &extraVolumes, &extraVolumeMounts, a)
}

func TestReconcileApplicationSet_UpdateExistingDeployments(t *testing.T) {
logf.SetLogger(ZapLogger(true))
a := makeTestArgoCD()
Expand Down Expand Up @@ -294,7 +385,7 @@ func TestReconcileApplicationSet_UpdateExistingDeployments(t *testing.T) {
deployment))

// Ensure the updated Deployment has the expected properties
checkExpectedDeploymentValues(t, r, deployment, &sa, a)
checkExpectedDeploymentValues(t, r, deployment, &sa, nil, nil, a)

}

Expand Down Expand Up @@ -454,7 +545,7 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) {

specImage := deployment.Spec.Template.Spec.Containers[0].Image
assert.Equal(t, test.expectedContainerImage, specImage)
checkExpectedDeploymentValues(t, r, deployment, &sa, a)
checkExpectedDeploymentValues(t, r, deployment, &sa, nil, nil, a)
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ metadata:
capabilities: Deep Insights
categories: Integration & Delivery
certified: "false"
createdAt: "2024-10-16T08:53:24Z"
createdAt: "2024-10-14T02:57:43Z"
description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
operators.operatorframework.io/builder: operator-sdk-v1.35.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
Expand Down
Loading
Loading