Commit 201649f6 authored by Konstantinos Togias's avatar Konstantinos Togias
Browse files

Merge branch 'master' into 'develop'

Synchronize the Release 2.0.0 E2E baseline into develop

See merge request !10
parents f5901b6a 5bcfda5a
Loading
Loading
Loading
Loading
Loading
+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
@@ -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:
@@ -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:
@@ -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
+53 −0
Changes for README.md: 53 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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
```
+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
+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
+9 −14
Changes for ansible/inventory/r2.example.yml: 9 added lines, 14 removed lines.
Original line number Diff line number Diff line
@@ -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

@@ -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