Loading .gitlab-ci.yml +214 −2 Changes for .gitlab-ci.yml: 214 added lines, 2 removed lines. Original line number Diff line number Diff line workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main")' - if: '$CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS' when: never - when: always image: python:3.12-slim stages: - lint - test - report variables: ANSIBLE_CONFIG: ansible/ansible.cfg Loading @@ -23,6 +32,10 @@ cache: - ansible-galaxy collection install -r ansible/requirements.yml secret-scan: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint image: alpine:latest before_script: Loading @@ -39,18 +52,30 @@ secret-scan: fi yamllint: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint extends: .ansible_setup script: - yamllint . ansible-lint: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint extends: .ansible_setup script: - ansible-lint -c .ansible-lint ansible/playbooks ansible/roles ansible/role-template - ansible-lint -c .ansible-lint ansible/playbooks ansible/roles ansible/role-template ansible/tests/test_platform_bootstrap.yml syntax-check: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: test extends: .ansible_setup script: Loading @@ -61,7 +86,194 @@ syntax-check: ansible-playbook -i inventory/r2.example.yml --syntax-check "$playbook" done - ANSIBLE_ROLES_PATH=roles ansible-playbook -i localhost, tests/test_platform_bootstrap.yml python-smoke: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: test script: - python3 -m py_compile ansible/roles/oop-platform/files/fm_partners.py ansible/roles/oop-platform/files/tfsdk_bootstrap.py ansible/tests/r2_e2e/*.py ci/*.py - sh -n ci/run_platform_lab.sh - python3 -m unittest discover -s ansible/tests -p test_tfsdk_bootstrap.py platform-smoke-checks: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] variables: TMPDIR: "$CI_PROJECT_DIR/.cache/smoke-tests" PYTHONDONTWRITEBYTECODE: "1" script: - mkdir -p "$TMPDIR" - pip install -r ci/requirements-smoke.txt - python -m pytest --confcutdir=ansible/tests/unit -q -p no:cacheprovider ansible/tests/unit --basetemp="$TMPDIR/pytest" - python -m pytest --collect-only -q -p no:cacheprovider ansible/tests/r2_e2e # Read-only opt-in check of an already deployed platform, through its public URLs. platform-smoke: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] timeout: 10 minutes variables: TMPDIR: "$CI_PROJECT_DIR/.cache/smoke-install" PYTHONDONTWRITEBYTECODE: "1" rules: - if: '$RUN_PLATFORM_SMOKE == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never script: - mkdir -p "$TMPDIR" - pip install -r ci/requirements-smoke.txt - python ci/platform_smoke.py --inventory "$OOP_SMOKE_INVENTORY" artifacts: when: always paths: - .cache/platform-smoke/result.json reports: junit: .cache/platform-smoke/junit.xml expire_in: 1 week # Disposable core platform: create -> existing deploy -> existing health -> delete. # Requires a trusted DinD-capable runner with shared TLS client certificates. platform-lab: stage: test image: docker:29.5.1-cli@sha256:b40b3737eb3bf588d25bb856d3564dd3f9fdb32ac2fc19ebe85cc58d761692a5 services: - name: docker:29.5.1-dind@sha256:eed377f3ce14afda560e742c5b3ae446df1ce00a16e1beab2ac6c78c1477fe85 alias: docker variables: HEALTHCHECK_TCP_PORT: "2376" cache: [] timeout: 40 minutes variables: OOP_LAB_REPORT_DIR: .cache/platform-lab/container FF_NETWORK_PER_BUILD: "true" DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: /certs DOCKER_TLS_VERIFY: "1" DOCKER_CERT_PATH: /certs/client rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' when: on_success allow_failure: false variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$CI_COMMIT_BRANCH == "test/platform-lab"' when: manual allow_failure: false - if: '$RUN_PLATFORM_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never before_script: - apk add --no-cache python3 script: - sh ci/run_platform_lab.sh "${OOP_LAB_PROFILE:-ci/lab/profile.health.json}" "$OOP_LAB_REPORT_DIR" artifacts: when: always paths: - $OOP_LAB_REPORT_DIR/result.json - $OOP_LAB_REPORT_DIR/junit.xml - $OOP_LAB_REPORT_DIR/chart.json - $OOP_LAB_REPORT_DIR/candidate.json - $OOP_LAB_REPORT_DIR/feature-matrix.json - $OOP_LAB_REPORT_DIR/feature-matrix.md - $OOP_LAB_REPORT_DIR/wrapper-junit.xml - $OOP_LAB_REPORT_DIR/pods.txt - $OOP_LAB_REPORT_DIR/events.txt - $OOP_LAB_REPORT_DIR/health/result.json - $OOP_LAB_REPORT_DIR/health/junit.xml - $OOP_LAB_REPORT_DIR/health/acceptance/ reports: junit: - $OOP_LAB_REPORT_DIR/junit.xml - $OOP_LAB_REPORT_DIR/wrapper-junit.xml expire_in: 90 days # Same lab and lifecycle, using a chart archive instead of a container manifest. platform-lab-helm: extends: platform-lab variables: OOP_LAB_PACKAGE_TYPE: HELM OOP_LAB_REPORT_DIR: .cache/platform-lab/helm rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$RUN_PLATFORM_HELM_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never # Actual provider compatibility, extending the same container application lab. platform-lab-network: extends: platform-lab variables: OOP_LAB_NETWORK_PROVIDER: EURECOM OOP_LAB_REPORT_DIR: .cache/platform-lab/network rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$RUN_PLATFORM_NETWORK_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never # Consolidation consumes real job artifacts; it adds no approval or input form. release-feature-report: stage: report image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] when: always needs: - {job: platform-lab, artifacts: true, optional: true} - {job: platform-lab-helm, artifacts: true, optional: true} - {job: platform-lab-network, artifacts: true, optional: true} rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' - when: never script: - python ci/merge_feature_reports.py .cache/platform-lab .cache/release-features artifacts: when: always expose_as: Observed release features paths: - .cache/release-features/feature-matrix.md - .cache/release-features/feature-matrix.json expire_in: 90 days # Explicit live mode leaves all default component tests and deployment jobs alone. sdk-live-acceptance: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 tags: [sdk-lab] interruptible: false timeout: 30 minutes resource_group: dedicated-sdk-lab environment: name: sdk-acceptance action: verify cache: [] variables: TMPDIR: "$CI_PROJECT_DIR/.cache/sdk-tmp" PYTHONDONTWRITEBYTECODE: "1" rules: - if: '$RUN_SDK_ACCEPTANCE == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never before_script: - mkdir -p "$TMPDIR" - pip install pytest==8.3.2 requests==2.33.0 - python ci/install_kubectl.py - export PATH="$CI_PROJECT_DIR/.cache/bin:$PATH" - kubectl version --client script: - python3 -m py_compile ansible/roles/oop-platform/files/fm_partners.py ansible/tests/r2_e2e/*.py - python ci/sdk_live.py artifacts: when: always paths: - .cache/sdk-live/qualification.json - .cache/sdk-e2e/*/run.json reports: junit: .cache/sdk-live/junit.xml expire_in: 90 days README.md +53 −0 Changes for README.md: 53 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -39,3 +39,56 @@ Sergio Giménez <sergio.gimenez@i2cat.net> ## License Apache 2.0. See `LICENSE` and `NOTICE` for attribution requirements. ## Single SRM / TF-SDK bootstrap The existing `oop-platform` role accepts `oop_platform_bootstrap` as one operator declaration. It emits the complete bootstrap and matching read-only credential mounts through the Release 2 chart: ```yaml oop_platform_bootstrap: version: openop.srm.bootstrap/v1 control_paths: - ref: athens adapter_type: kubernetes kubeconfig_secret: name: athens-credentials key: config infrastructure: kube_context: athens namespace: applications - ref: local-workloads adapter_type: kubernetes infrastructure: in_cluster: true namespace: applications zones: [] # Add the real declared topology and bindings. ``` For in-cluster workloads, configure the existing `workloads.namespaces` RBAC setting explicitly. Declaring a control path does not grant permissions. Create the referenced Secrets in the SRM namespace through the existing operator credential process. The role never reads their values or implements a secret resolver. It derives file paths from refs, keeping each control path separate, and strips deployment-only Secret metadata from emitted bootstrap. The SDK identity is derived by SRM from each ref, not repeated in infrastructure. The deployment controller's kubeconfig remains separate from SDK credentials. Remove `controlPaths` from extra chart values. When using `oop_platform_bootstrap`, also remove manually supplied `topology` and `controlPathCredentials`; competing sources fail before deployment. Existing empty defaults preserve health-only deployments. The paired chart provides `/var/run/openop-tfsdk` for private execution files. Use matching SDK 2.0.0rc3, SRM and chart revisions; upgrade or roll back the set together. Bootstrap generation is not a backend-health or credential-validity check. Offline producer tests run in the existing Python CI job. The real-role check also runs locally and in the existing syntax-check job, without cluster access: ```sh python -m unittest discover -s ansible/tests -p test_tfsdk_bootstrap.py ANSIBLE_ROLES_PATH=ansible/roles ansible-playbook -i localhost, ansible/tests/test_platform_bootstrap.yml ``` ansible/inventory/r2-sdk-lab.example.yml 0 → 100644 +62 −0 Changes for ansible/inventory/r2-sdk-lab.example.yml: 62 added lines, 0 removed lines. Original line number Diff line number Diff line --- # Separate, single-operator lab. Copy to r2-sdk-lab.local.yml and fill the pins. # No production inventory, federation, shared workload namespace or floating SDK install. all: children: oop_platform_operators: hosts: sdk_lab: ansible_connection: local ansible_python_interpreter: "{{ ansible_playbook_python }}" oop_platform_kubeconfig: ~/.kube/oop-sdk-lab.yaml oop_platform_kube_context: oop-sdk-lab oop_platform_namespace: oop-e2e-platform oop_platform_public_host: sdk-lab.example.test oop_platform_federation_id: sdk-lab oop_platform_country_code: GR oop_platform_mcc: "202" oop_platform_mncs: ["01"] oop_platform_federation_clients: [] oop_platform_portal_enabled: false oop_platform_chart_version: 52a7b0d942af88d004a0781e365b0a6db7c66e2c oop_platform_fm_image_tag: REPLACE_WITH_REVIEWED_FM_TAG oop_platform_oeg_image_tag: REPLACE_WITH_REVIEWED_OEG_TAG oop_platform_srm_image_tag: REPLACE_WITH_REVIEWED_SRM_TAG e2e_temp_dir: "{{ playbook_dir }}/../../../.cache/sdk-e2e-tmp" oop_platform_bootstrap: version: openop.srm.bootstrap/v1 platform_instance_id: sdk-lab control_paths: - ref: sdk-lab-k8s adapter_family: compute adapter_type: kubernetes adapter_contract_version: v1 infrastructure: namespace: oop-e2e-workloads in_cluster: true endpoint_host: sdk-lab.example.test zones: - ref: sdk-lab-zone name: SDK lab kind: resource state: active domains: - ref: sdk-lab-compute name: SDK lab compute kind: compute state: active capabilities: - ref: sdk-lab-workload name: SDK lab workload kind: workload state: active control_path_bindings: - ref: sdk-lab-workload-binding control_path_ref: sdk-lab-k8s is_default: true state: active oop_platform_extra_values: srm: workloads: namespaces: - oop-e2e-workloads ansible/inventory/r2-smoke.example.yml 0 → 100644 +13 −0 Changes for ansible/inventory/r2-smoke.example.yml: 13 added lines, 0 removed lines. Original line number Diff line number Diff line --- # HTTP-only view of an already deployed platform. Copy to r2-smoke.local.yml. # Public URLs must be reachable from the machine/container running the command. # No SSH credentials, kubeconfig or application image is needed for this scenario. all: children: oop_platform_operators: hosts: local_lab: oop_platform_public_host: 127.0.0.1 oop_platform_scheme: http oop_platform_oeg_node_port: 32263 oop_platform_fm_node_port: 30989 ansible/inventory/r2.example.yml +9 −14 Changes for ansible/inventory/r2.example.yml: 9 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -42,8 +42,8 @@ all: # No Release 2 portal image is published yet: build one, or turn the portal off. oop_platform_portal_enabled: false # The Release 2 charts are on this branch until oop/deploy/helm!15 merges; # helm develop still has the Release 1 (MongoDB) charts. oop_platform_chart_version: refactor/helm-2.0 # Pin the reviewed Release 2 chart, including single-bootstrap mounts. oop_platform_chart_version: 52a7b0d942af88d004a0781e365b0a6db7c66e2c # Plain HTTP between the operators: test networks only. oop_platform_allow_insecure_partner_endpoints: true Loading @@ -68,32 +68,27 @@ all: # deployed by Helm into namespace oop-apps of the operator's own cluster. oop_platform_extra_values: srm: srmcontroller: workloads: namespaces: [oop-apps] controlPaths: - control_path_ref: k8s-local adapter: kubernetes config: namespace: oop-apps topology: | oop_platform_bootstrap: version: openop.srm.bootstrap/v1 platform_instance_id: {{ oop_platform_federation_id }} platform_instance_id: "{{ oop_platform_federation_id }}" control_paths: - ref: k8s-local adapter_family: compute adapter_type: kubernetes adapter_contract_version: v1 infrastructure: in_cluster: true namespace: oop-apps zones: - ref: {{ oop_platform_federation_id }}-zone name: {{ srm_zone_name }} - ref: "{{ oop_platform_federation_id }}-zone" name: "{{ srm_zone_name }}" kind: resource state: active domains: - ref: {{ oop_platform_federation_id }}-compute name: {{ srm_zone_name }} compute - ref: "{{ oop_platform_federation_id }}-compute" name: "{{ srm_zone_name }} compute" kind: compute state: active capabilities: Loading Loading
.gitlab-ci.yml +214 −2 Changes for .gitlab-ci.yml: 214 added lines, 2 removed lines. Original line number Diff line number Diff line workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "main")' - if: '$CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS' when: never - when: always image: python:3.12-slim stages: - lint - test - report variables: ANSIBLE_CONFIG: ansible/ansible.cfg Loading @@ -23,6 +32,10 @@ cache: - ansible-galaxy collection install -r ansible/requirements.yml secret-scan: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint image: alpine:latest before_script: Loading @@ -39,18 +52,30 @@ secret-scan: fi yamllint: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint extends: .ansible_setup script: - yamllint . ansible-lint: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: lint extends: .ansible_setup script: - ansible-lint -c .ansible-lint ansible/playbooks ansible/roles ansible/role-template - ansible-lint -c .ansible-lint ansible/playbooks ansible/roles ansible/role-template ansible/tests/test_platform_bootstrap.yml syntax-check: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: test extends: .ansible_setup script: Loading @@ -61,7 +86,194 @@ syntax-check: ansible-playbook -i inventory/r2.example.yml --syntax-check "$playbook" done - ANSIBLE_ROLES_PATH=roles ansible-playbook -i localhost, tests/test_platform_bootstrap.yml python-smoke: rules: - if: '$RUN_SDK_ACCEPTANCE == "1"' when: never - when: on_success stage: test script: - python3 -m py_compile ansible/roles/oop-platform/files/fm_partners.py ansible/roles/oop-platform/files/tfsdk_bootstrap.py ansible/tests/r2_e2e/*.py ci/*.py - sh -n ci/run_platform_lab.sh - python3 -m unittest discover -s ansible/tests -p test_tfsdk_bootstrap.py platform-smoke-checks: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] variables: TMPDIR: "$CI_PROJECT_DIR/.cache/smoke-tests" PYTHONDONTWRITEBYTECODE: "1" script: - mkdir -p "$TMPDIR" - pip install -r ci/requirements-smoke.txt - python -m pytest --confcutdir=ansible/tests/unit -q -p no:cacheprovider ansible/tests/unit --basetemp="$TMPDIR/pytest" - python -m pytest --collect-only -q -p no:cacheprovider ansible/tests/r2_e2e # Read-only opt-in check of an already deployed platform, through its public URLs. platform-smoke: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] timeout: 10 minutes variables: TMPDIR: "$CI_PROJECT_DIR/.cache/smoke-install" PYTHONDONTWRITEBYTECODE: "1" rules: - if: '$RUN_PLATFORM_SMOKE == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never script: - mkdir -p "$TMPDIR" - pip install -r ci/requirements-smoke.txt - python ci/platform_smoke.py --inventory "$OOP_SMOKE_INVENTORY" artifacts: when: always paths: - .cache/platform-smoke/result.json reports: junit: .cache/platform-smoke/junit.xml expire_in: 1 week # Disposable core platform: create -> existing deploy -> existing health -> delete. # Requires a trusted DinD-capable runner with shared TLS client certificates. platform-lab: stage: test image: docker:29.5.1-cli@sha256:b40b3737eb3bf588d25bb856d3564dd3f9fdb32ac2fc19ebe85cc58d761692a5 services: - name: docker:29.5.1-dind@sha256:eed377f3ce14afda560e742c5b3ae446df1ce00a16e1beab2ac6c78c1477fe85 alias: docker variables: HEALTHCHECK_TCP_PORT: "2376" cache: [] timeout: 40 minutes variables: OOP_LAB_REPORT_DIR: .cache/platform-lab/container FF_NETWORK_PER_BUILD: "true" DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: /certs DOCKER_TLS_VERIFY: "1" DOCKER_CERT_PATH: /certs/client rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' when: on_success allow_failure: false variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$CI_COMMIT_BRANCH == "test/platform-lab"' when: manual allow_failure: false - if: '$RUN_PLATFORM_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never before_script: - apk add --no-cache python3 script: - sh ci/run_platform_lab.sh "${OOP_LAB_PROFILE:-ci/lab/profile.health.json}" "$OOP_LAB_REPORT_DIR" artifacts: when: always paths: - $OOP_LAB_REPORT_DIR/result.json - $OOP_LAB_REPORT_DIR/junit.xml - $OOP_LAB_REPORT_DIR/chart.json - $OOP_LAB_REPORT_DIR/candidate.json - $OOP_LAB_REPORT_DIR/feature-matrix.json - $OOP_LAB_REPORT_DIR/feature-matrix.md - $OOP_LAB_REPORT_DIR/wrapper-junit.xml - $OOP_LAB_REPORT_DIR/pods.txt - $OOP_LAB_REPORT_DIR/events.txt - $OOP_LAB_REPORT_DIR/health/result.json - $OOP_LAB_REPORT_DIR/health/junit.xml - $OOP_LAB_REPORT_DIR/health/acceptance/ reports: junit: - $OOP_LAB_REPORT_DIR/junit.xml - $OOP_LAB_REPORT_DIR/wrapper-junit.xml expire_in: 90 days # Same lab and lifecycle, using a chart archive instead of a container manifest. platform-lab-helm: extends: platform-lab variables: OOP_LAB_PACKAGE_TYPE: HELM OOP_LAB_REPORT_DIR: .cache/platform-lab/helm rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$RUN_PLATFORM_HELM_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never # Actual provider compatibility, extending the same container application lab. platform-lab-network: extends: platform-lab variables: OOP_LAB_NETWORK_PROVIDER: EURECOM OOP_LAB_REPORT_DIR: .cache/platform-lab/network rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' variables: OOP_LAB_PROFILE: ci/lab/profile.release-2.0.json OOP_LAB_REFRESH_CANDIDATE: "1" - if: '$RUN_PLATFORM_NETWORK_LAB == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never # Consolidation consumes real job artifacts; it adds no approval or input form. release-feature-report: stage: report image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 cache: [] when: always needs: - {job: platform-lab, artifacts: true, optional: true} - {job: platform-lab-helm, artifacts: true, optional: true} - {job: platform-lab-network, artifacts: true, optional: true} rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "test/platform-application-checkpoints" || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "test/platform-application-checkpoints"' - when: never script: - python ci/merge_feature_reports.py .cache/platform-lab .cache/release-features artifacts: when: always expose_as: Observed release features paths: - .cache/release-features/feature-matrix.md - .cache/release-features/feature-matrix.json expire_in: 90 days # Explicit live mode leaves all default component tests and deployment jobs alone. sdk-live-acceptance: stage: test image: python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 tags: [sdk-lab] interruptible: false timeout: 30 minutes resource_group: dedicated-sdk-lab environment: name: sdk-acceptance action: verify cache: [] variables: TMPDIR: "$CI_PROJECT_DIR/.cache/sdk-tmp" PYTHONDONTWRITEBYTECODE: "1" rules: - if: '$RUN_SDK_ACCEPTANCE == "1" && $CI_COMMIT_REF_PROTECTED == "true"' - when: never before_script: - mkdir -p "$TMPDIR" - pip install pytest==8.3.2 requests==2.33.0 - python ci/install_kubectl.py - export PATH="$CI_PROJECT_DIR/.cache/bin:$PATH" - kubectl version --client script: - python3 -m py_compile ansible/roles/oop-platform/files/fm_partners.py ansible/tests/r2_e2e/*.py - python ci/sdk_live.py artifacts: when: always paths: - .cache/sdk-live/qualification.json - .cache/sdk-e2e/*/run.json reports: junit: .cache/sdk-live/junit.xml expire_in: 90 days
README.md +53 −0 Changes for README.md: 53 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -39,3 +39,56 @@ Sergio Giménez <sergio.gimenez@i2cat.net> ## License Apache 2.0. See `LICENSE` and `NOTICE` for attribution requirements. ## Single SRM / TF-SDK bootstrap The existing `oop-platform` role accepts `oop_platform_bootstrap` as one operator declaration. It emits the complete bootstrap and matching read-only credential mounts through the Release 2 chart: ```yaml oop_platform_bootstrap: version: openop.srm.bootstrap/v1 control_paths: - ref: athens adapter_type: kubernetes kubeconfig_secret: name: athens-credentials key: config infrastructure: kube_context: athens namespace: applications - ref: local-workloads adapter_type: kubernetes infrastructure: in_cluster: true namespace: applications zones: [] # Add the real declared topology and bindings. ``` For in-cluster workloads, configure the existing `workloads.namespaces` RBAC setting explicitly. Declaring a control path does not grant permissions. Create the referenced Secrets in the SRM namespace through the existing operator credential process. The role never reads their values or implements a secret resolver. It derives file paths from refs, keeping each control path separate, and strips deployment-only Secret metadata from emitted bootstrap. The SDK identity is derived by SRM from each ref, not repeated in infrastructure. The deployment controller's kubeconfig remains separate from SDK credentials. Remove `controlPaths` from extra chart values. When using `oop_platform_bootstrap`, also remove manually supplied `topology` and `controlPathCredentials`; competing sources fail before deployment. Existing empty defaults preserve health-only deployments. The paired chart provides `/var/run/openop-tfsdk` for private execution files. Use matching SDK 2.0.0rc3, SRM and chart revisions; upgrade or roll back the set together. Bootstrap generation is not a backend-health or credential-validity check. Offline producer tests run in the existing Python CI job. The real-role check also runs locally and in the existing syntax-check job, without cluster access: ```sh python -m unittest discover -s ansible/tests -p test_tfsdk_bootstrap.py ANSIBLE_ROLES_PATH=ansible/roles ansible-playbook -i localhost, ansible/tests/test_platform_bootstrap.yml ```
ansible/inventory/r2-sdk-lab.example.yml 0 → 100644 +62 −0 Changes for ansible/inventory/r2-sdk-lab.example.yml: 62 added lines, 0 removed lines. Original line number Diff line number Diff line --- # Separate, single-operator lab. Copy to r2-sdk-lab.local.yml and fill the pins. # No production inventory, federation, shared workload namespace or floating SDK install. all: children: oop_platform_operators: hosts: sdk_lab: ansible_connection: local ansible_python_interpreter: "{{ ansible_playbook_python }}" oop_platform_kubeconfig: ~/.kube/oop-sdk-lab.yaml oop_platform_kube_context: oop-sdk-lab oop_platform_namespace: oop-e2e-platform oop_platform_public_host: sdk-lab.example.test oop_platform_federation_id: sdk-lab oop_platform_country_code: GR oop_platform_mcc: "202" oop_platform_mncs: ["01"] oop_platform_federation_clients: [] oop_platform_portal_enabled: false oop_platform_chart_version: 52a7b0d942af88d004a0781e365b0a6db7c66e2c oop_platform_fm_image_tag: REPLACE_WITH_REVIEWED_FM_TAG oop_platform_oeg_image_tag: REPLACE_WITH_REVIEWED_OEG_TAG oop_platform_srm_image_tag: REPLACE_WITH_REVIEWED_SRM_TAG e2e_temp_dir: "{{ playbook_dir }}/../../../.cache/sdk-e2e-tmp" oop_platform_bootstrap: version: openop.srm.bootstrap/v1 platform_instance_id: sdk-lab control_paths: - ref: sdk-lab-k8s adapter_family: compute adapter_type: kubernetes adapter_contract_version: v1 infrastructure: namespace: oop-e2e-workloads in_cluster: true endpoint_host: sdk-lab.example.test zones: - ref: sdk-lab-zone name: SDK lab kind: resource state: active domains: - ref: sdk-lab-compute name: SDK lab compute kind: compute state: active capabilities: - ref: sdk-lab-workload name: SDK lab workload kind: workload state: active control_path_bindings: - ref: sdk-lab-workload-binding control_path_ref: sdk-lab-k8s is_default: true state: active oop_platform_extra_values: srm: workloads: namespaces: - oop-e2e-workloads
ansible/inventory/r2-smoke.example.yml 0 → 100644 +13 −0 Changes for ansible/inventory/r2-smoke.example.yml: 13 added lines, 0 removed lines. Original line number Diff line number Diff line --- # HTTP-only view of an already deployed platform. Copy to r2-smoke.local.yml. # Public URLs must be reachable from the machine/container running the command. # No SSH credentials, kubeconfig or application image is needed for this scenario. all: children: oop_platform_operators: hosts: local_lab: oop_platform_public_host: 127.0.0.1 oop_platform_scheme: http oop_platform_oeg_node_port: 32263 oop_platform_fm_node_port: 30989
ansible/inventory/r2.example.yml +9 −14 Changes for ansible/inventory/r2.example.yml: 9 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -42,8 +42,8 @@ all: # No Release 2 portal image is published yet: build one, or turn the portal off. oop_platform_portal_enabled: false # The Release 2 charts are on this branch until oop/deploy/helm!15 merges; # helm develop still has the Release 1 (MongoDB) charts. oop_platform_chart_version: refactor/helm-2.0 # Pin the reviewed Release 2 chart, including single-bootstrap mounts. oop_platform_chart_version: 52a7b0d942af88d004a0781e365b0a6db7c66e2c # Plain HTTP between the operators: test networks only. oop_platform_allow_insecure_partner_endpoints: true Loading @@ -68,32 +68,27 @@ all: # deployed by Helm into namespace oop-apps of the operator's own cluster. oop_platform_extra_values: srm: srmcontroller: workloads: namespaces: [oop-apps] controlPaths: - control_path_ref: k8s-local adapter: kubernetes config: namespace: oop-apps topology: | oop_platform_bootstrap: version: openop.srm.bootstrap/v1 platform_instance_id: {{ oop_platform_federation_id }} platform_instance_id: "{{ oop_platform_federation_id }}" control_paths: - ref: k8s-local adapter_family: compute adapter_type: kubernetes adapter_contract_version: v1 infrastructure: in_cluster: true namespace: oop-apps zones: - ref: {{ oop_platform_federation_id }}-zone name: {{ srm_zone_name }} - ref: "{{ oop_platform_federation_id }}-zone" name: "{{ srm_zone_name }}" kind: resource state: active domains: - ref: {{ oop_platform_federation_id }}-compute name: {{ srm_zone_name }} compute - ref: "{{ oop_platform_federation_id }}-compute" name: "{{ srm_zone_name }} compute" kind: compute state: active capabilities: Loading