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
2 changes: 1 addition & 1 deletion .ci-operator.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build_root_image:
name: boilerplate
namespace: openshift
tag: image-v8.3.3
tag: image-v8.3.4
2 changes: 0 additions & 2 deletions OWNERS_ALIASES
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ aliases:
srep-team-leads:
- rafael-azevedo
- iamkirkbater
- rogbas
- dustman9000
- bng0y
- bmeng
- typeid
sre-group-leads:
Expand Down
2 changes: 1 addition & 1 deletion boilerplate/_data/backing-image-tag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
image-v8.3.3
image-v8.3.4
2 changes: 1 addition & 1 deletion boilerplate/_data/last-boilerplate-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b1b2a7f89ab7147bf8782b1fd1554126c567f2d4
0dad0e7f84f4617c8173534edf865c819d0be537
11 changes: 11 additions & 0 deletions boilerplate/openshift/golang-osd-e2e/e2e-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ objects:
template:
spec:
restartPolicy: Never
volumes:
- name: ${OPERATOR_NAME}-sc
secret:
secretName: ${OPERATOR_NAME}-sc
optional: true
containers:
- name: osde2e
image: quay.io/redhat-services-prod/osde2e-cicada-tenant/osde2e:latest
Expand All @@ -56,6 +61,12 @@ objects:
- --skip-must-gather
- --configs
- ${OSDE2E_CONFIGS}
- --secret-locations
- "/etc/external-secrets"
volumeMounts:
- name: ${OPERATOR_NAME}-sc
readOnly: true
mountPath: "/etc/external-secrets"
resources:
requests:
cpu: "300m"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.19 AS builder
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.21 AS builder
ARG SAAS_OPERATOR_DIR
COPY ${SAAS_OPERATOR_DIR} manifests
RUN initializer --permissive
Expand Down
2 changes: 0 additions & 2 deletions boilerplate/openshift/golang-osd-operator/OWNERS_ALIASES
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ aliases:
srep-team-leads:
- rafael-azevedo
- iamkirkbater
- rogbas
- dustman9000
- bng0y
- bmeng
- typeid
sre-group-leads:
Expand Down
81 changes: 76 additions & 5 deletions boilerplate/openshift/golang-osd-operator/olm_pko_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
appstudio.openshift.io/application: {operator_name}
appstudio.openshift.io/component: {operator_name}-pko
pipelines.appstudio.openshift.io/type: build
name: {operator_name}-pko-on-{event}
name: {operator_name}-pko-on-{event_name}
namespace: {operator_name}-tenant
spec:
params:
Expand Down Expand Up @@ -162,7 +162,6 @@
package-operator.run/phase: cleanup-deploy
package-operator.run/collision-protection: IfNoController
spec:
ttlSecondsAfterFinished: 100
template:
metadata:
annotations:
Expand Down Expand Up @@ -202,6 +201,8 @@
parameters:
- name: CHANNEL
required: false
- name: OPERATOR_IMAGE
required: true
- name: PKO_IMAGE
required: true
- name: IMAGE_TAG
Expand Down Expand Up @@ -238,6 +239,8 @@
package-operator.run/collision-protection: IfNoController
spec:
image: ${{PKO_IMAGE}}:${{IMAGE_TAG}}
config:
image: ${{OPERATOR_IMAGE}}:${{IMAGE_TAG}}
"""

def get_remotes() -> list[str]:
Expand Down Expand Up @@ -621,16 +624,80 @@ def write_pko_dockerfile():
)
)

def extract_deployment_selector() -> str | None:
"""
Extract the clusterDeploymentSelector from hack/olm-registry/olm-artifacts-template.yaml.
Returns:
A YAML string containing the clusterDeploymentSelector, or None if file doesn't exist
or selector cannot be extracted.
"""
olm_template_path = Path("./hack/olm-registry/olm-artifacts-template.yaml")

if not olm_template_path.exists():
return None

try:
with open(olm_template_path, "r") as f:
content = yaml.safe_load(f)

# Navigate through the structure to find clusterDeploymentSelector
# Expected structure: .objects[0].spec.clusterDeploymentSelector
if not isinstance(content, dict):
return None

objects = content.get("objects", [])
if not objects or not isinstance(objects, list):
return None

# Look through objects to find one with clusterDeploymentSelector
for obj in objects:
if not isinstance(obj, dict):
continue
spec = obj.get("spec", {})
if "clusterDeploymentSelector" in spec:
# Convert the selector back to YAML format with proper indentation
selector = spec["clusterDeploymentSelector"]
# Dump with proper indentation for inserting into template
selector_yaml = yaml.dump(selector, default_flow_style=False, sort_keys=False)
# Indent each line by 6 spaces (to match template indentation)
indented_lines = [" " + line for line in selector_yaml.splitlines()]
return "\n".join(indented_lines)

return None

except (IOError, OSError, yaml.YAMLError) as e:
print(f"Warning: Could not read or parse {olm_template_path}: {e}", file=sys.stderr)
return None


def write_clusterpackage_template():
"""Write the ClusterPackage template to hack/pko/clusterpackage.yaml."""
operator_name = get_operator_name()
pko_hack_folder = Path("./hack/pko")
pko_hack_folder.mkdir(parents=True, exist_ok=True)


# Try to extract deployment selector from existing OLM template
deployment_selector = extract_deployment_selector()

clusterpackage_file = pko_hack_folder / "clusterpackage.yaml"
print(f"Writing ClusterPackage template to {clusterpackage_file}")
with open(clusterpackage_file, "w") as f:
f.write(CLUSTERPACKAGE_TEMPLATE.format(operator_name=operator_name))

if deployment_selector:
print("✓ Using clusterDeploymentSelector from hack/olm-registry/olm-artifacts-template.yaml")
# Create template with extracted selector
template_with_selector = CLUSTERPACKAGE_TEMPLATE.replace(
" clusterDeploymentSelector:\n matchLabels:\n api.openshift.com/managed: \"true\"",
f" clusterDeploymentSelector:\n{deployment_selector}"
)
with open(clusterpackage_file, "w") as f:
f.write(template_with_selector.format(operator_name=operator_name))
print(f"Please review this file and ensure the deployment targets match your expectation")
else:
print("⚠ Using default clusterDeploymentSelector (hack/olm-registry/olm-artifacts-template.yaml not found)")
print(f"Please review this file and ensure the deployment targets match your expectation")
with open(clusterpackage_file, "w") as f:
f.write(CLUSTERPACKAGE_TEMPLATE.format(operator_name=operator_name))


def write_tekton_pipelines():
Expand Down Expand Up @@ -658,6 +725,7 @@ def write_tekton_pipelines():
github_url = operator_upstream,
cancel_in_progress = "false",
event = "push",
event_name = "push",
image_tag = "{{revision}}",
additional_params = "",
default_branch = default_branch,
Expand All @@ -677,6 +745,7 @@ def write_tekton_pipelines():
github_url = operator_upstream,
cancel_in_progress = "true",
event = "pull_request",
event_name = "pull-request",
image_tag = "on-pr-{{revision}}",
additional_params = pr_additional_params,
default_branch = default_branch,
Expand Down Expand Up @@ -852,6 +921,8 @@ def main():
write_clusterpackage_template()
except Exception as e:
print(f"Warning: Could not generate ClusterPackage template: {e}", file=sys.stderr)
print("\n")
print("⚠ IMPORTANT: Review *all* generated files for validity ⚠")


if __name__ == "__main__":
Expand Down
21 changes: 16 additions & 5 deletions boilerplate/openshift/golang-osd-operator/standard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,17 @@ endif
go-build: ## Build binary
${GOENV} go build ${GOBUILDFLAGS} -o build/_output/bin/$(OPERATOR_NAME) .

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.23
SETUP_ENVTEST = setup-envtest
ENVTEST_K8S_VERSION = 1.28.0
SETUP_ENVTEST_VERSION = release-0.23
GOPATH ?= $(shell go env GOPATH)
SETUP_ENVTEST = $(GOPATH)/bin/setup-envtest

.PHONY: setup-envtest
setup-envtest:
$(eval KUBEBUILDER_ASSETS := "$(shell $(SETUP_ENVTEST) use $(ENVTEST_K8S_VERSION) -p path --bin-dir /tmp/envtest/bin)")
@if [ ! -f "$(SETUP_ENVTEST)" ]; then \
echo "Installing setup-envtest..."; \
GOBIN=$(GOPATH)/bin go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(SETUP_ENVTEST_VERSION); \
fi

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
Expand All @@ -267,7 +271,14 @@ go-test: setup-envtest
exit 1; \
fi

${GOENV} KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) go test $(TESTOPTS) $(TESTTARGETS)
@echo "Setting up kubebuilder test assets..."; \
if ! ASSETS_PATH=$$($(SETUP_ENVTEST) use $(ENVTEST_K8S_VERSION) --arch amd64 --os linux --bin-dir /tmp/envtest-binaries -p path 2>&1); then \
echo "ERROR: Could not obtain kubebuilder test assets"; \
echo "Output: $$ASSETS_PATH"; \
exit 1; \
fi; \
echo "Using test assets: $$ASSETS_PATH"; \
${GOENV} KUBEBUILDER_ASSETS="$$ASSETS_PATH" go test $(TESTOPTS) $(TESTTARGETS)

.PHONY: python-venv
python-venv:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,18 +610,104 @@ def test_write_tekton_pipelines(self):
# Verify it uses master for boilerplate
self.assertIn('value: master', pr_content)

def test_write_clusterpackage_template(self):
"""Test ClusterPackage template generation."""
def test_write_clusterpackage_template_default(self):
"""Test ClusterPackage template generation with default selector."""
migration.write_clusterpackage_template()

clusterpackage_file = Path(self.temp_dir) / 'hack' / 'pko' / 'clusterpackage.yaml'
self.assertTrue(clusterpackage_file.exists())

content = clusterpackage_file.read_text()
self.assertIn('kind: Template', content)
self.assertIn('kind: SelectorSyncSet', content)
self.assertIn('kind: ClusterPackage', content)
self.assertIn('test-operator', content)
# Should use default selector
self.assertIn('api.openshift.com/managed: "true"', content)

def test_write_clusterpackage_template_from_olm_template(self):
"""Test ClusterPackage template generation using existing OLM template."""
# Create hack/olm-registry directory with template
olm_registry_dir = Path(self.temp_dir) / 'hack' / 'olm-registry'
olm_registry_dir.mkdir(parents=True)

# Create OLM template with custom selector
olm_template = olm_registry_dir / 'olm-artifacts-template.yaml'
olm_template.write_text("""apiVersion: v1
kind: Template
metadata:
name: selectorsyncset-template
objects:
- apiVersion: hive.openshift.io/v1
kind: SelectorSyncSet
metadata:
name: test-operator
spec:
clusterDeploymentSelector:
matchExpressions:
- key: api.openshift.com/fedramp
operator: In
values:
- "true"
resourceApplyMode: Sync
resources: []
""")

migration.write_clusterpackage_template()

clusterpackage_file = Path(self.temp_dir) / 'hack' / 'pko' / 'clusterpackage.yaml'
self.assertTrue(clusterpackage_file.exists())

content = clusterpackage_file.read_text()
# Should use custom selector from OLM template
self.assertIn('matchExpressions', content)
self.assertIn('api.openshift.com/fedramp', content)
# Should NOT use default selector
self.assertNotIn('api.openshift.com/managed', content)

def test_extract_deployment_selector_file_not_found(self):
"""Test extract_deployment_selector when file doesn't exist."""
result = migration.extract_deployment_selector()
self.assertIsNone(result)

def test_extract_deployment_selector_valid_file(self):
"""Test extract_deployment_selector with valid OLM template."""
# Create hack/olm-registry directory
olm_registry_dir = Path(self.temp_dir) / 'hack' / 'olm-registry'
olm_registry_dir.mkdir(parents=True)

# Create OLM template
olm_template = olm_registry_dir / 'olm-artifacts-template.yaml'
olm_template.write_text("""apiVersion: v1
kind: Template
objects:
- apiVersion: hive.openshift.io/v1
kind: SelectorSyncSet
spec:
clusterDeploymentSelector:
matchLabels:
custom-label: "custom-value"
resources: []
""")

result = migration.extract_deployment_selector()
self.assertIsNotNone(result)
self.assertIn('matchLabels', result)
self.assertIn('custom-label', result)
self.assertIn('custom-value', result)

def test_extract_deployment_selector_invalid_yaml(self):
"""Test extract_deployment_selector with invalid YAML."""
# Create hack/olm-registry directory
olm_registry_dir = Path(self.temp_dir) / 'hack' / 'olm-registry'
olm_registry_dir.mkdir(parents=True)

# Create invalid YAML file
olm_template = olm_registry_dir / 'olm-artifacts-template.yaml'
olm_template.write_text("invalid: yaml: broken: [")

result = migration.extract_deployment_selector()
self.assertIsNone(result)


class TestIntegration(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM quay.io/redhat-services-prod/openshift/boilerplate:image-v8.3.3 AS builder
FROM quay.io/redhat-services-prod/openshift/boilerplate:image-v8.3.4 AS builder
COPY go.mod /
COPY go.sum /
RUN go mod download
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.olm-registry
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.19 AS builder
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.21 AS builder
ARG SAAS_OPERATOR_DIR
COPY ${SAAS_OPERATOR_DIR} manifests
RUN initializer --permissive
Expand Down
11 changes: 11 additions & 0 deletions test/e2e/e2e-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ objects:
template:
spec:
restartPolicy: Never
volumes:
- name: osd-metrics-exporter-sc
secret:
secretName: osd-metrics-exporter-sc
optional: true
containers:
- name: osde2e
image: quay.io/redhat-services-prod/osde2e-cicada-tenant/osde2e:latest
Expand All @@ -56,6 +61,12 @@ objects:
- --skip-must-gather
- --configs
- ${OSDE2E_CONFIGS}
- --secret-locations
- "/etc/external-secrets"
volumeMounts:
- name: osd-metrics-exporter-sc
readOnly: true
mountPath: "/etc/external-secrets"
resources:
requests:
cpu: "300m"
Expand Down