Skip to content

Commit

Permalink
feat(overrides): add JSON patch for deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewbelu committed Dec 12, 2024
1 parent 3f90b47 commit a7daf9b
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 4 deletions.
3 changes: 2 additions & 1 deletion api/v1beta1/temporalcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ type DeploymentOverride struct {
*ObjectMetaOverride `json:"metadata,omitempty"`
// Specification of the desired behavior of the Deployment.
// +optional
Spec *DeploymentOverrideSpec `json:"spec,omitempty"`
Spec *DeploymentOverrideSpec `json:"spec,omitempty"`
JsonPatch *apiextensionsv1.JSON `json:"jsonPatch,omitempty"`

Check failure on line 178 in api/v1beta1/temporalcluster_types.go

View workflow job for this annotation

GitHub Actions / Lint files

var-naming: struct field JsonPatch should be JSONPatch (revive)
}

// DeploymentOverrideSpec provides the ability to override a Deployment Spec.
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.

16 changes: 16 additions & 0 deletions config/crd/bases/temporal.io_temporalclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -2910,6 +2912,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3075,6 +3079,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3246,6 +3252,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3411,6 +3419,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3549,6 +3559,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3637,6 +3649,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down Expand Up @@ -3829,6 +3843,8 @@ spec:
deployment:
description: Override configuration for the temporal service Deployment.
properties:
jsonPatch:
x-kubernetes-preserve-unknown-fields: true
metadata:
description: |-
ObjectMetaOverride provides the ability to override an object metadata.
Expand Down
16 changes: 14 additions & 2 deletions docs/api/v1beta1.md
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,18 @@ DeploymentOverrideSpec
</table>
</td>
</tr>
<tr>
<td>
<code>jsonPatch</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1#JSON">
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON
</a>
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -2388,7 +2400,7 @@ map[string]string
<td>
<code>override</code><br>
<em>
<a href="https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.ServiceMonitorSpec">
<a href="https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.ServiceMonitorSpec">
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1.ServiceMonitorSpec
</a>
</em>
Expand All @@ -2403,7 +2415,7 @@ All fields can be overwritten except &ldquo;endpoints&rdquo;, &ldquo;selector&rd
<td>
<code>metricRelabelings</code><br>
<em>
<a href="https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.RelabelConfig">
<a href="https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.RelabelConfig">
[]github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1.RelabelConfig
</a>
</em>
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/alexandrevilain/controller-tools v0.3.0
github.com/cert-manager/cert-manager v1.16.1
github.com/elliotchance/orderedmap/v2 v2.4.0
github.com/evanphx/json-patch/v5 v5.9.0
github.com/go-logr/logr v1.4.2
github.com/gocql/gocql v1.7.0
github.com/google/uuid v1.6.0
Expand Down Expand Up @@ -53,7 +54,6 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
Expand Down
19 changes: 19 additions & 0 deletions pkg/kubernetes/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/alexandrevilain/temporal-operator/api/v1beta1"
"github.com/alexandrevilain/temporal-operator/internal/metadata"
jsonpatch "github.com/evanphx/json-patch/v5"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/strategicpatch"
Expand Down Expand Up @@ -110,6 +111,24 @@ func ApplyDeploymentOverrides(deployment *appsv1.Deployment, override *v1beta1.D
}
}

if override.JsonPatch != nil {
patch, err := jsonpatch.DecodePatch(override.JsonPatch.Raw)
if err != nil {
return fmt.Errorf("can't decode json patch: %w", err)
}

original, err := json.Marshal(deployment)
if err != nil {
return fmt.Errorf("can't marshal deployment spec: %w", err)
}

patched, err := patch.Apply(original)
if err != nil {
return fmt.Errorf("can't apply json patch: %w", err)
}
return json.Unmarshal(patched, &deployment)
}

return nil
}

Expand Down
160 changes: 160 additions & 0 deletions pkg/kubernetes/overrides_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,166 @@ func TestApplyDeploymentOverrides(t *testing.T) {
},
},
},
"add env var to existing env": {
original: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "test",
Env: []corev1.EnvVar{
{
Name: "a",
ValueFrom: &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "test",
},
},
},
},
},
},
},
},
},
},
},
override: &v1beta1.DeploymentOverride{
JsonPatch: &apiextensionsv1.JSON{
Raw: []byte(`[{"op":"add", "path":"/spec/template/spec/containers/0/env/-", "value":{"name":"b","value":"c"}}]`),
},
},
expected: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "test",
Env: []corev1.EnvVar{
{
Name: "a",
ValueFrom: &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "test",
},
},
},
},
{
Name: "b",
Value: "c",
},
},
},
},
},
},
},
},
},
"add secret volume to existing volumes": {
original: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "test",
VolumeMounts: []corev1.VolumeMount{
{
Name: "a",
ReadOnly: true,
MountPath: "/a",
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "a",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "test",
},
},
},
},
},
},
},
},
},
override: &v1beta1.DeploymentOverride{
JsonPatch: &apiextensionsv1.JSON{
Raw: []byte(`[
{"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts/-", "value": {"name": "b", "readOnly": true, "mountPath": "/b"}},
{"op": "add", "path": "/spec/template/spec/volumes/-", "value": {"name": "b", "secret": {"secretName": "test"}}}
]`),
},
},
expected: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "test",
VolumeMounts: []corev1.VolumeMount{
{
Name: "a",
ReadOnly: true,
MountPath: "/a",
},
{
Name: "b",
ReadOnly: true,
MountPath: "/b",
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "a",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "test",
},
},
},
},
{
Name: "b",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "test",
},
},
},
},
},
},
},
},
},
}

for name, test := range tests {
Expand Down
Loading

0 comments on commit a7daf9b

Please sign in to comment.