forked from openshift/compliance-operator
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fed54b4
commit 57368e4
Showing
4 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# The base version determines the index that the build will be included in, but | ||
# not exactly. It is based on semantics of | ||
# https://docs.engineering.redhat.com/display/CFC/Delivery | ||
# 4.10 means that we will be included in 4.10+ indexes | ||
BASE_OCP_VERSION="4.10" | ||
# We use the stable channel because the Compliance Operator adheres to Tier | ||
# 3 operator lifecycle management | ||
# https://docs.google.com/document/d/18BPe68jhk16-4eYGT6zV-iSNLrFVsuPdVIos24kWaaE/edit | ||
CHANNEL="stable" | ||
ANNOTATIONS_CONTENT=$(cat << EOM | ||
annotations: | ||
com.redhat.openshift.versions: "v${BASE_OCP_VERSION}" | ||
operators.operatorframework.io.bundle.channel.default.v1: '${CHANNEL}' | ||
operators.operatorframework.io.bundle.channels.v1: '${CHANNEL}' | ||
operators.operatorframework.io.bundle.manifests.v1: manifests/ | ||
operators.operatorframework.io.bundle.mediatype.v1: registry+v1 | ||
operators.operatorframework.io.bundle.metadata.v1: metadata/ | ||
operators.operatorframework.io.bundle.package.v1: compliance-operator | ||
EOM | ||
) | ||
echo "$ANNOTATIONS_CONTENT" > ./metadata/annotations.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
#!/usr/bin/env python3 | ||
# The syntax str | None was added in 3.10 | ||
# Remove when UBI9 moves to python 3.10+ | ||
from __future__ import annotations | ||
|
||
import argparse | ||
import base64 | ||
import io | ||
import os | ||
import sys | ||
import json | ||
|
||
from ruamel.yaml import YAML | ||
|
||
|
||
yaml = YAML() | ||
yaml.preserve_quotes = True | ||
|
||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument("manifest_directory", type=str, | ||
help="Path to operator manifest directory.") | ||
parser.add_argument("version", type=str, | ||
help="Version string of the product to update in the manifest.") | ||
args = parser.parse_args() | ||
|
||
|
||
def main() -> None: | ||
build_manifest_file_path = get_manifest_file_path_from_directory(args.manifest_directory) | ||
if not build_manifest_file_path: | ||
print(f"Failed to find manifest in {args.manifest_directory}") | ||
sys.exit(1) | ||
|
||
print(f"Success to find manifest in {build_manifest_file_path}") | ||
with open(build_manifest_file_path) as f: | ||
manifest = yaml.load(f) | ||
print(f"Successfully loaded {build_manifest_file_path} from build.") | ||
|
||
add_required_annotations(manifest) | ||
replace_version(manifest) | ||
replace_icon(manifest) | ||
replace_images(manifest) | ||
remove_related_images(manifest) | ||
write_manifest(manifest) | ||
print(f"Successfully updated CSV manifest for {args.version}.") | ||
|
||
|
||
|
||
def get_manifest_file_path_from_directory(d: str) -> str|None: | ||
for filename in os.listdir(d): | ||
if filename.endswith('clusterserviceversion.yaml'): | ||
return os.path.join(d, filename) | ||
|
||
def add_required_annotations(m: dict) -> None: | ||
""" | ||
Adds required annotations to the CSV file content represented as a dictionary. | ||
Errors out if 'metadata' or 'annotations' does not exist. | ||
:param m: A dictionary representing the operator CSV manifest. | ||
""" | ||
required_annotations = { | ||
"features.operators.openshift.io/disconnected": "true", | ||
"features.operators.openshift.io/fips-compliant": "true", | ||
"features.operators.openshift.io/proxy-aware": "true", | ||
"features.operators.openshift.io/tls-profiles": "false", | ||
"features.operators.openshift.io/token-auth-aws": "false", | ||
"features.operators.openshift.io/token-auth-azure": "false", | ||
"features.operators.openshift.io/token-auth-gcp": "false" | ||
} | ||
|
||
if 'metadata' not in m: | ||
sys.exit("Error: 'metadata' does not exist in the CSV content.") | ||
|
||
if 'annotations' not in m['metadata']: | ||
sys.exit("Error: 'annotations' does not exist within 'metadata' in the CSV content.") | ||
|
||
for key, value in required_annotations.items(): | ||
m['metadata']['annotations'][key] = value | ||
|
||
print("Successfully added required annotations.") | ||
|
||
def replace_version(m: dict) -> None: | ||
manifest_version = m['spec']['version'] | ||
print(f"Updating version references from {manifest_version}", | ||
f"to {args.version} in manifest.") | ||
m['metadata']['name'] = m['metadata']['name'].replace(manifest_version, args.version) | ||
m['metadata']['annotations']['olm.skipRange'] = m['metadata']['annotations']['olm.skipRange'].replace(manifest_version, args.version) | ||
m['spec']['replaces'] = 'compliance-operator.v' + manifest_version | ||
m['spec']['version'] = args.version | ||
print(f"Successfully updated the operator version references from", | ||
f"{manifest_version} to {args.version} in manifest.") | ||
|
||
|
||
def replace_icon(m: dict) -> None: | ||
"""Replace the upstream icon with a Red Hat branded image. | ||
Perform an in-place update of the icon data on the manifest. | ||
manifest(dict): A dictionary representing the operator CSV manifest | ||
""" | ||
icon_path = "icons/icon.png" | ||
with io.open(icon_path, "rb") as f: | ||
base64_encoded_icon = base64.b64encode(f.read()) | ||
icons = [{"base64data": base64_encoded_icon.decode(), "mediatype": "image/png"}] | ||
m['spec']['icon'] = icons | ||
print(f"Successfully updated the operator image to use icon in {icon_path}.") | ||
|
||
|
||
def replace_images(m: dict) -> None: | ||
|
||
CO_OPERATOR_IMAGE_PULLSPEC = "quay.io/redhat-user-workloads/ocp-isc-tenant/compliance-operator" | ||
CO_CONTENT_IMAGE_PULLSPEC = "quay.io/redhat-user-workloads/ocp-isc-tenant/cac-content-fork" | ||
CO_OPENSCAP_IMAGE_PULLSPEC = "quay.io/redhat-user-workloads/ocp-isc-tenant/compliance-operator-openscap" | ||
CO_MUST_GATHER_IMAGE_PULLSPEC = "quay.io/redhat-user-workloads/ocp-isc-tenant/compliance-operator-must-gather" | ||
|
||
m['spec']['install']['spec']['deployments'][0]['spec']['template']['spec']['containers'][0]['image'] = CO_OPERATOR_IMAGE_PULLSPEC | ||
|
||
container_env = m['spec']['install']['spec']['deployments'][0]['spec']['template']['spec']['containers'][0]['env'] | ||
for e in container_env: | ||
if e['name'] == "RELATED_IMAGE_OPERATOR": | ||
e['value'] = CO_OPERATOR_IMAGE_PULLSPEC | ||
if e['name'] == "RELATED_IMAGE_PROFILE": | ||
e['value'] = CO_CONTENT_IMAGE_PULLSPEC | ||
if e['name'] == "RELATED_IMAGE_OPENSCAP": | ||
e['value'] = CO_OPENSCAP_IMAGE_PULLSPEC | ||
if e['name'] == "RELATED_IMAGE_MUST_GATHER": | ||
e['value'] = CO_MUST_GATHER_IMAGE_PULLSPEC | ||
|
||
# Decode alm-examples | ||
alm_examples_json = json.loads(m['metadata']['annotations']['alm-examples']) | ||
|
||
# Iterate through each item in the list and update the contentImage field | ||
for item in alm_examples_json: | ||
if 'spec' in item and 'contentImage' in item['spec']: | ||
item['spec']['contentImage'] = CO_CONTENT_IMAGE_PULLSPEC | ||
# Update nested scans if present | ||
if 'spec' in item and 'scans' in item['spec']: | ||
for scan in item['spec']['scans']: | ||
if 'contentImage' in scan: | ||
scan['contentImage'] = CO_CONTENT_IMAGE_PULLSPEC | ||
|
||
# Encode alm-examples back to JSON string | ||
m['metadata']['annotations']['alm-examples'] = json.dumps(alm_examples_json, indent=2) | ||
print("Successfully updated the operator image to use the new image.") | ||
|
||
|
||
def remove_related_images(m: dict) -> None: | ||
# Remove relatedImages entirely from the CSV. OSBS will look for container | ||
# images in the manifest and populate them as relatedImages when the bundle | ||
# image is built, so that we don't have to. See | ||
# https://osbs.readthedocs.io/en/latest/users.html#pullspec-locations for | ||
# more information on how OSBS does this. | ||
del m['spec']['relatedImages'] | ||
print("Removed relatedImages from operator manifest.") | ||
|
||
|
||
def write_manifest(m: dict) -> None: | ||
old_csv_filename = get_manifest_file_path_from_directory('manifests') | ||
if not old_csv_filename: | ||
print(f"Failed to find manifest in {args.manifest_directory}") | ||
sys.exit(1) | ||
|
||
new_csv_filename = os.path.join('manifests', f"compliance-operator.v{args.version}.clusterserviceversion.yaml") | ||
os.rename(old_csv_filename, new_csv_filename) | ||
print(f"Successfully moved {old_csv_filename} to {new_csv_filename}.") | ||
with open(new_csv_filename, 'w') as f: | ||
yaml.dump(m, f) | ||
print(f"Successfully wrote updated manifest to {new_csv_filename}.") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as builder-runner | ||
RUN microdnf install -y python3 python3-pip | ||
RUN pip3 install --upgrade pip && pip3 install ruamel.yaml==0.17.9 | ||
|
||
# Use a new stage to enable caching of the package installations for local development | ||
FROM builder-runner as builder | ||
|
||
ARG CO_VERSION="1.6.1" | ||
|
||
COPY ./bundle-hack . | ||
COPY ./bundle/icons ./icons | ||
COPY ./bundle/manifests ./manifests | ||
COPY ./bundle/metadata ./metadata | ||
|
||
RUN ./update_csv.py ./manifests ${CO_VERSION} | ||
RUN ./update_bundle_annotations.sh | ||
|
||
FROM scratch | ||
|
||
LABEL name=openshift-compliance-operator-bundle | ||
LABEL version=${CO_VERSION} | ||
LABEL summary='OpenShift Compliance Operator' | ||
LABEL maintainer='Infrastructure Security and Compliance Team <isc-team@redhat.com>' | ||
|
||
LABEL io.k8s.display-name='Compliance Operator' | ||
LABEL io.k8s.description='OpenShift Compliance Operator' | ||
|
||
LABEL com.redhat.component=openshift-compliance-operator-bundle-container | ||
LABEL com.redhat.delivery.appregistry=false | ||
LABEL com.redhat.delivery.operator.bundle=true | ||
LABEL com.redhat.openshift.versions="v4.10" | ||
|
||
|
||
LABEL io.openshift.maintainer.product='OpenShift Container Platform' | ||
LABEL io.openshift.tags=openshift,security,compliance,openscap | ||
|
||
LABEL operators.operatorframework.io.bundle.channel.default.v1=stable | ||
LABEL operators.operatorframework.io.bundle.channels.v1=stable | ||
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ | ||
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 | ||
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ | ||
LABEL operators.operatorframework.io.bundle.package.v1=compliance-operator | ||
LABEL License=GPLv2+ | ||
|
||
# Copy files to locations specified by labels. | ||
COPY --from=builder /manifests /manifests/ | ||
COPY --from=builder /metadata /metadata/ | ||
COPY bundle/tests/scorecard /tests/scorecard | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.