Skip to content
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
11 changes: 3 additions & 8 deletions scripts/release-operator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ phase_operator() {
local changelog="$chart_dir/CHANGELOG.md"
local values_yaml="$chart_dir/values.yaml"
local helpers_tpl="$chart_dir/templates/_helpers.tpl"
local test_file="$ROOT_DIR/test/datadog-operator/operator_deployment_test.go"

# Get current appVersion for replacement references
local prev_version
Expand Down Expand Up @@ -313,20 +312,16 @@ phase_operator() {
add_changelog_entry "$changelog" "$OPERATOR_CHART_VERSION" \
"* Update Datadog Operator chart for ${OPERATOR_VERSION}."

# Step 8: Update test assertion
step "Updating operator_deployment_test.go image assertion"
sed_i "s|operator:${prev_version}|operator:${OPERATOR_VERSION}|g" "$test_file"

# Step 9: Run helm-docs
# Step 8: Run helm-docs
step "Running helm-docs..."
run_helm_docs

# Step 10: Update test baselines
# Step 9: Update test baselines
step "Updating test baselines (make update-test-baselines-operator)..."
(cd "$ROOT_DIR" && make update-test-baselines-operator)
success "Test baselines updated"

# Step 11: Update clusterrole.yaml from upstream RBAC
# Step 10: Update clusterrole.yaml from upstream RBAC
step "Updating clusterrole.yaml from upstream v${OPERATOR_VERSION}..."
update_clusterrole "$OPERATOR_VERSION"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ spec:
serviceAccountName: datadog-operator
containers:
- name: datadog-operator
image: "registry.datadoghq.com/operator:1.30.0"
image: "registry.datadoghq.com/operator"
imagePullPolicy: IfNotPresent
env:
- name: WATCH_NAMESPACE
Expand Down
13 changes: 12 additions & 1 deletion test/datadog-operator/baseline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,18 @@ func Test_baseline_manifests(t *testing.T) {
}

func verifyOperatorDeployment(t *testing.T, baselineManifestPath, manifest string) {
utils.VerifyBaseline(t, baselineManifestPath, manifest, appsv1.Deployment{}, appsv1.Deployment{})
// The image tag and the "app.kubernetes.io/version" label (sourced from
// Chart.AppVersion) both change with every Operator release and aren't
// part of the chart structure this baseline is meant to protect, so
// they're stripped before comparing.
utils.VerifyBaseline(t, baselineManifestPath, manifest, appsv1.Deployment{}, appsv1.Deployment{}, stripReleaseVersion)
}

func stripReleaseVersion(d *appsv1.Deployment) {
for i, c := range d.Spec.Template.Spec.Containers {
d.Spec.Template.Spec.Containers[i].Image = utils.ImageRepository(c.Image)
}
delete(d.Labels, "app.kubernetes.io/version")
}

func verifyDatadogAgent(t *testing.T, baselineManifestPath, manifest string) {
Expand Down
7 changes: 6 additions & 1 deletion test/datadog-operator/operator_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,12 @@ func verifyDeployment(t *testing.T, manifest string) {
assert.Equal(t, 1, len(deployment.Spec.Template.Spec.Containers))
operatorContainer := deployment.Spec.Template.Spec.Containers[0]
assert.Equal(t, v1.PullPolicy("IfNotPresent"), operatorContainer.ImagePullPolicy)
assert.Equal(t, "registry.datadoghq.com/operator:1.30.0", operatorContainer.Image)
// The default image tag should always track the chart's own appVersion,
// exposed on the Deployment via the "app.kubernetes.io/version" label -
// this catches a release bump that updates one but not the other.
version := deployment.Labels["app.kubernetes.io/version"]
assert.NotEmpty(t, version, "app.kubernetes.io/version label should be set")
assert.Equal(t, "registry.datadoghq.com/operator:"+version, operatorContainer.Image)
assert.NotContains(t, operatorContainer.Args, "-webhookEnabled=false")
assert.NotContains(t, operatorContainer.Args, "-webhookEnabled=true")
assert.NotContains(t, operatorContainer.Args, "-supportExtendedDaemonset=false")
Expand Down
28 changes: 28 additions & 0 deletions test/utils/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package utils

import "strings"

// ImageRepository returns the repository portion of a container image
// reference, with any tag and/or digest stripped.
//
// It only looks for the tag separator (":") after the last "/", so a
// registry host with a port (e.g. "myregistry:5000/operator:1.2.3") isn't
// mistaken for a tag. The digest separator ("@") is stripped first so a
// digest-only reference (no tag, e.g. "operator@sha256:...") isn't mistaken
// for one either.
func ImageRepository(image string) string {
repo := image
if i := strings.Index(repo, "@"); i >= 0 {
repo = repo[:i]
}
if i := strings.LastIndex(repo, "/"); i >= 0 {
host, rest := repo[:i], repo[i:]
if j := strings.Index(rest, ":"); j >= 0 {
rest = rest[:j]
}
repo = host + rest
} else if j := strings.Index(repo, ":"); j >= 0 {
repo = repo[:j]
}
return repo
}
55 changes: 55 additions & 0 deletions test/utils/image_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package utils

import "testing"

func TestImageRepository(t *testing.T) {
tests := []struct {
name string
image string
want string
}{
{
name: "repository with tag",
image: "registry.datadoghq.com/operator:1.30.0-rc.2",
want: "registry.datadoghq.com/operator",
},
{
name: "repository without tag",
image: "registry.datadoghq.com/operator",
want: "registry.datadoghq.com/operator",
},
{
name: "repository with tag and digest",
image: "registry.datadoghq.com/operator:1.18.0@sha256:0000",
want: "registry.datadoghq.com/operator",
},
{
name: "registry host with a port",
image: "myregistry:5000/operator:1.2.3",
want: "myregistry:5000/operator",
},
{
name: "registry host with a port, no tag",
image: "myregistry:5000/operator",
want: "myregistry:5000/operator",
},
{
name: "no registry host, just repo and tag",
image: "operator:1.2.3",
want: "operator",
},
{
name: "repository with digest, no tag",
image: "registry.datadoghq.com/operator@sha256:0000",
want: "registry.datadoghq.com/operator",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ImageRepository(tt.image); got != tt.want {
t.Errorf("ImageRepository(%q) = %q, want %q", tt.image, got, tt.want)
}
})
}
}
23 changes: 17 additions & 6 deletions test/utils/verify_baseline.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@ import (
"github.com/stretchr/testify/assert"
)

func VerifyBaseline[T any](t *testing.T, baselineManifestPath, manifest string, baseline, actual T) {
// Normalizer mutates a loaded manifest in place before it's compared, e.g. to
// strip out fields that are expected to vary independently of chart
// structure (see stripReleaseVersion in test/datadog-operator/baseline_test.go).
type Normalizer[T any] func(*T)

func VerifyBaseline[T any](t *testing.T, baselineManifestPath, manifest string, baseline, actual T, normalizers ...Normalizer[T]) {
common.Unmarshal(t, manifest, &actual)
common.LoadFromFile(t, baselineManifestPath, &baseline)

for _, normalize := range normalizers {
normalize(&actual)
normalize(&baseline)
}

// Exclude "helm.sh/chart" label from comparison to avoid
// updating baselines on every unrelated chart changes.
ops := make(cmp.Options, 0)
ops = append(ops, cmpopts.IgnoreMapEntries(func(k, v string) bool {
return k == "helm.sh/chart"
}))
ops := cmp.Options{
cmpopts.IgnoreMapEntries(func(k, v string) bool {
return k == "helm.sh/chart"
}),
}

assert.True(t, cmp.Equal(baseline, actual, ops), cmp.Diff(baseline, actual))
assert.True(t, cmp.Equal(baseline, actual, ops), cmp.Diff(baseline, actual, ops))
}
Loading