From ed89a024ecb4e3c533e2ce68bd20fb70b074cd4b Mon Sep 17 00:00:00 2001 From: Paul Wright <5154224+pwright@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:35:58 +0000 Subject: [PATCH] minimal doc changes for v3 (#5615) * broker link * add operator docs * operatorhub screenshot * fix operator docs * update --- ...oc-exporting-importing-using-rest-api.adoc | 2 +- operator/docs/README.adoc | 17 + operator/docs/antora.yml | 6 + operator/docs/local-test-playbook.yml | 27 ++ .../apicurioregistry_kafkasql_plain_cr.yaml | 9 + .../apicurioregistry_kafkasql_scram_cr.yaml | 14 + .../apicurioregistry_kafkasql_tls_cr.yaml | 13 + .../examples/apicurioregistry_mem_cr.yaml | 8 + .../examples/apicurioregistry_sql_cr.yaml | 12 + ...apicurioregistry_kafkasql_keycloak_cr.yaml | 19 + .../apicurioregistry_mem_keycloak_cr.yaml | 16 + .../apicurioregistry_sql_keycloak_cr.yaml | 23 + .../ROOT/examples/keycloak/keycloak.yaml | 12 + .../keycloak/keycloak_http_ingress.yaml | 18 + .../keycloak/keycloak_http_route.yaml | 15 + .../keycloak/keycloak_http_service.yaml | 19 + .../examples/keycloak/keycloak_realm.yaml | 63 +++ .../keycloak/keycloak_realm_import.yaml | 61 +++ .../ROOT/examples/templates/https/README.md | 21 + ...keycloak-certmanager-letsencrypt-edge.yaml | 374 ++++++++++++++++ .../registry-keycloak-default-edge.yaml | 259 +++++++++++ .../https/registry-certmanager-edge.yaml | 235 ++++++++++ ...anager-letsencrypt-custom-domain-edge.yaml | 264 ++++++++++++ ...registry-certmanager-letsencrypt-edge.yaml | 248 +++++++++++ .../registry-certmanager-passthrough.yaml | 236 ++++++++++ .../https/registry-default-edge.yaml | 211 +++++++++ .../templates/registry-simple-postgresql.yaml | 139 ++++++ .../ROOT/images/operator-hub-search-ar.png | Bin 0 -> 136386 bytes .../ROOT/images/operator-hub-search-sr.png | Bin 0 -> 110536 bytes operator/docs/modules/ROOT/nav.adoc | 7 + .../assembly-operator-configuration.adoc | 19 + .../pages/assembly-operator-installation.adoc | 23 + .../pages/assembly-operator-quickstart.adoc | 30 ++ .../pages/assembly-registry-maintenance.adoc | 27 ++ .../ROOT/pages/assembly-registry-storage.adoc | 36 ++ operator/docs/modules/ROOT/pages/index.adoc | 21 + .../partials/con-persistence-options.adoc | 45 ++ .../ROOT/partials/con-registry-intro.adoc | 12 + .../partials/con-registry-operator-intro.adoc | 14 + .../ROOT/partials/proc-install-kafka.adoc | 46 ++ .../partials/proc-install-olm-kubernetes.adoc | 16 + .../ROOT/partials/proc-install-olm-sr.adoc | 55 +++ .../partials/proc-install-postgresql.adoc | 72 ++++ .../proc-manage-environment-variables.adoc | 65 +++ .../proc-persistence-kafkasql-plain.adoc | 106 +++++ .../proc-persistence-kafkasql-scram.adoc | 174 ++++++++ .../proc-persistence-kafkasql-tls.adoc | 174 ++++++++ .../ROOT/partials/proc-persistence-mem.adoc | 27 ++ .../ROOT/partials/proc-persistence-sql.adoc | 38 ++ .../proc-registry-https-in-cluster.adoc | 85 ++++ .../proc-registry-https-outside-cluster.adoc | 56 +++ ...istry-operator-distribution-bundle-ar.adoc | 8 + .../proc-registry-operator-quickstart-ar.adoc | 26 ++ .../proc-registry-operator-quickstart-sr.adoc | 38 ++ .../partials/proc-registry-quickstart-ar.adoc | 35 ++ .../partials/proc-registry-quickstart-sr.adoc | 55 +++ .../proc-registry-security-keycloak.adoc | 104 +++++ .../partials/proc-registry-sql-backup.adoc | 37 ++ .../partials/proc-registry-sql-restore.adoc | 25 ++ .../modules/ROOT/partials/ref-get-help.adoc | 12 + .../partials/ref-liveness-and-readiness.adoc | 55 +++ .../ROOT/partials/ref-registry-cr-spec.adoc | 363 ++++++++++++++++ .../ROOT/partials/ref-registry-cr-status.adoc | 77 ++++ .../ROOT/partials/ref-registry-cr.adoc | 59 +++ .../ROOT/partials/ref-registry-labels.adoc | 55 +++ .../ref-registry-managed-resources.adoc | 49 +++ .../ref-registry-operator-prerequisites.adoc | 18 + .../ref-registry-pod-template-spec.adoc | 76 ++++ .../ROOT/partials/shared/all-attributes.adoc | 2 + .../partials/shared/attributes-links.adoc | 18 + .../ROOT/partials/shared/attributes.adoc | 81 ++++ operator/docs/resources/licenses/licenses.csv | 72 ++++ .../tips-for-creating-asciidoc-content.adoc | 403 ++++++++++++++++++ 73 files changed, 5156 insertions(+), 1 deletion(-) create mode 100644 operator/docs/README.adoc create mode 100644 operator/docs/antora.yml create mode 100644 operator/docs/local-test-playbook.yml create mode 100644 operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_plain_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_scram_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_tls_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/apicurioregistry_sql_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_kafkasql_keycloak_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_mem_keycloak_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_sql_keycloak_cr.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak_http_ingress.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak_http_route.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak_http_service.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak_realm.yaml create mode 100644 operator/docs/modules/ROOT/examples/keycloak/keycloak_realm_import.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/README.md create mode 100644 operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-certmanager-letsencrypt-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-default-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-custom-domain-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-passthrough.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/https/registry-default-edge.yaml create mode 100644 operator/docs/modules/ROOT/examples/templates/registry-simple-postgresql.yaml create mode 100644 operator/docs/modules/ROOT/images/operator-hub-search-ar.png create mode 100644 operator/docs/modules/ROOT/images/operator-hub-search-sr.png create mode 100644 operator/docs/modules/ROOT/nav.adoc create mode 100644 operator/docs/modules/ROOT/pages/assembly-operator-configuration.adoc create mode 100644 operator/docs/modules/ROOT/pages/assembly-operator-installation.adoc create mode 100644 operator/docs/modules/ROOT/pages/assembly-operator-quickstart.adoc create mode 100644 operator/docs/modules/ROOT/pages/assembly-registry-maintenance.adoc create mode 100644 operator/docs/modules/ROOT/pages/assembly-registry-storage.adoc create mode 100644 operator/docs/modules/ROOT/pages/index.adoc create mode 100644 operator/docs/modules/ROOT/partials/con-persistence-options.adoc create mode 100644 operator/docs/modules/ROOT/partials/con-registry-intro.adoc create mode 100644 operator/docs/modules/ROOT/partials/con-registry-operator-intro.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-install-kafka.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-install-olm-kubernetes.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-install-olm-sr.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-install-postgresql.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-manage-environment-variables.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-plain.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-scram.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-tls.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-persistence-mem.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-persistence-sql.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-https-in-cluster.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-https-outside-cluster.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-operator-distribution-bundle-ar.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-ar.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-sr.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-quickstart-ar.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-quickstart-sr.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-security-keycloak.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-sql-backup.adoc create mode 100644 operator/docs/modules/ROOT/partials/proc-registry-sql-restore.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-get-help.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-liveness-and-readiness.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-cr-spec.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-cr-status.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-cr.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-labels.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-managed-resources.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-operator-prerequisites.adoc create mode 100644 operator/docs/modules/ROOT/partials/ref-registry-pod-template-spec.adoc create mode 100644 operator/docs/modules/ROOT/partials/shared/all-attributes.adoc create mode 100644 operator/docs/modules/ROOT/partials/shared/attributes-links.adoc create mode 100644 operator/docs/modules/ROOT/partials/shared/attributes.adoc create mode 100644 operator/docs/resources/licenses/licenses.csv create mode 100644 operator/docs/tips-for-creating-asciidoc-content.adoc diff --git a/docs/modules/ROOT/partials/getting-started/proc-exporting-importing-using-rest-api.adoc b/docs/modules/ROOT/partials/getting-started/proc-exporting-importing-using-rest-api.adoc index 2d7a32ea35..c14db5b95a 100644 --- a/docs/modules/ROOT/partials/getting-started/proc-exporting-importing-using-rest-api.adoc +++ b/docs/modules/ROOT/partials/getting-started/proc-exporting-importing-using-rest-api.adoc @@ -55,4 +55,4 @@ endif::[] [role="_additional-resources"] .Additional resources * For more details, see the `admin` endpoint in the {registry-rest-api}. -* For details on export tools for migrating from {registry} version 1.x to 2.x, see link:https://github.com/Apicurio/apicurio-registry/tree/main/utils/exportV1[Apicurio Registry export utility for 1.x versions]. +//* For details on export tools for migrating from {registry} version 1.x to 2.x, see link:https://github.com/Apicurio/apicurio-registry/tree/main/utils/exportV1[Apicurio Registry export utility for 1.x versions]. diff --git a/operator/docs/README.adoc b/operator/docs/README.adoc new file mode 100644 index 0000000000..567aed47fe --- /dev/null +++ b/operator/docs/README.adoc @@ -0,0 +1,17 @@ +== Apicurio Registry Operator Documentation + +The Apicurio Registry Operator documentation is created using https://asciidoc.org/[AsciiDoc] and https://antora.org/[Antora] site generator. + +You can perform a local build of the documentation for test purposes using the `antora` tool (https://antora.org/): + +. Install the `antora` tool using the following steps: https://docs.antora.org/antora/2.3/install-and-run-quickstart/ +. In the `apicurio-registry-operator/docs` directory, enter the following command: ++ +---- +$ antora local-test-playbook.yml +---- ++ +. Change to the `./target/dist/apicurio-registry-operator` directory. +. Open the generated `index.html` file in your browser. + +NOTE: See `docs/modules/ROOT/partials/shared/attributes.adoc` for configurable parameters. \ No newline at end of file diff --git a/operator/docs/antora.yml b/operator/docs/antora.yml new file mode 100644 index 0000000000..4c8be45719 --- /dev/null +++ b/operator/docs/antora.yml @@ -0,0 +1,6 @@ +name: apicurio-registry-operator +title: Apicurio Registry Operator +version: '3.0.0-dev-v1.x' +start_ROOT: ROOT:index.adoc +nav: + - modules/ROOT/nav.adoc diff --git a/operator/docs/local-test-playbook.yml b/operator/docs/local-test-playbook.yml new file mode 100644 index 0000000000..0e726b3a91 --- /dev/null +++ b/operator/docs/local-test-playbook.yml @@ -0,0 +1,27 @@ +site: + title: Apicurio Registry Operator PREVIEW + url: https://www.apicur.io/registry/docs + start_page: apicurio-registry-operator::index.adoc +content: + edit_url: https://github.com/Apicurio/apicurio-registry/tree/main/docs + sources: + - url: ../../ + branches: HEAD + start_path: operator/docs + +ui: + bundle: + url: https://raw.githubusercontent.com/Apicurio/apicurio-docs-ui/main/dist/ui-bundle.zip + snapshot: true + +runtime: + cache_dir: ./target/antora-cache + +output: + dir: ./target/dist + +asciidoc: + attributes: + plantuml-server-url: https://www.plantuml.com/plantuml + plantuml-fetch-diagram: true + mod-loc: partial$ diff --git a/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_plain_cr.yaml b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_plain_cr.yaml new file mode 100644 index 0000000000..038e295a48 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_plain_cr.yaml @@ -0,0 +1,9 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-kafkasql +spec: + configuration: + persistence: "kafkasql" + kafkasql: + bootstrapServers: "my-cluster-kafka-bootstrap.registry-example-kafkasql-plain.svc:9092" diff --git a/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_scram_cr.yaml b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_scram_cr.yaml new file mode 100644 index 0000000000..0e4c9fd113 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_scram_cr.yaml @@ -0,0 +1,14 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-kafkasql-scram +spec: + configuration: + persistence: "kafkasql" + kafkasql: + bootstrapServers: "my-cluster-kafka-bootstrap.registry-example-kafkasql-scram.svc:9093" + security: + scram: + truststoreSecretName: my-cluster-cluster-ca-cert + user: my-user + passwordSecretName: my-user diff --git a/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_tls_cr.yaml b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_tls_cr.yaml new file mode 100644 index 0000000000..0fc4b58f88 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/apicurioregistry_kafkasql_tls_cr.yaml @@ -0,0 +1,13 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-kafkasql-tls +spec: + configuration: + persistence: "kafkasql" + kafkasql: + bootstrapServers: "my-cluster-kafka-bootstrap.registry-example-kafkasql-tls.svc:9093" + security: + tls: + keystoreSecretName: my-user + truststoreSecretName: my-cluster-cluster-ca-cert diff --git a/operator/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml b/operator/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml new file mode 100644 index 0000000000..84b999e16e --- /dev/null +++ b/operator/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml @@ -0,0 +1,8 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-mem +spec: + configuration: + persistence: "mem" # Optional (default value) + # NOTE: No additional configuration required for *dev* deployment diff --git a/operator/docs/modules/ROOT/examples/apicurioregistry_sql_cr.yaml b/operator/docs/modules/ROOT/examples/apicurioregistry_sql_cr.yaml new file mode 100644 index 0000000000..86fc3dc44d --- /dev/null +++ b/operator/docs/modules/ROOT/examples/apicurioregistry_sql_cr.yaml @@ -0,0 +1,12 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-sql +spec: + configuration: + persistence: "sql" + sql: + dataSource: + url: "jdbc:postgresql://..svc:5432/" + userName: "postgres" + password: "" # Optional diff --git a/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_kafkasql_keycloak_cr.yaml b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_kafkasql_keycloak_cr.yaml new file mode 100644 index 0000000000..f9c2205b79 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_kafkasql_keycloak_cr.yaml @@ -0,0 +1,19 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-kafkasql-keycloak +spec: + configuration: + security: + keycloak: + url: "http://keycloak-http-.apps." + # ^ Required + # Use an HTTP URL in development. + realm: "registry" + # apiClientId: "registry-client-api" + # ^ Optional (default value) + # uiClientId: "registry-client-ui" + # ^ Optional (default value) + persistence: 'kafkasql' + kafkasql: + bootstrapServers: '-kafka-bootstrap..svc:9092' diff --git a/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_mem_keycloak_cr.yaml b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_mem_keycloak_cr.yaml new file mode 100644 index 0000000000..770a32a1fe --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_mem_keycloak_cr.yaml @@ -0,0 +1,16 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-keycloak +spec: + configuration: + security: + keycloak: + url: "http://keycloak-http-.apps." + # ^ Required + # Use an HTTP URL in development. + realm: "registry" + # apiClientId: "registry-client-api" + # ^ Optional (default value) + # uiClientId: "registry-client-ui" + # ^ Optional (default value) diff --git a/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_sql_keycloak_cr.yaml b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_sql_keycloak_cr.yaml new file mode 100644 index 0000000000..c794188ec2 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/apicurioregistry_sql_keycloak_cr.yaml @@ -0,0 +1,23 @@ +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry-sql-keycloak +spec: + configuration: + persistence: "sql" + sql: + dataSource: + url: "jdbc:postgresql://..svc:5432/" + userName: "postgres" + password: "" + # ^ Optional + security: + keycloak: + url: "http://keycloak-http-.apps." + # ^ Required + # Use an HTTP URL in development. + realm: "registry" + # apiClientId: "registry-client-api" + # ^ Optional (default value) + # uiClientId: "registry-client-ui" + # ^ Optional (default value) diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak.yaml new file mode 100644 index 0000000000..203abfec1b --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak.yaml @@ -0,0 +1,12 @@ +apiVersion: keycloak.org/v1alpha1 +kind: Keycloak +metadata: + name: example-keycloak + labels: + app: sso +spec: + instances: 1 + externalAccess: + enabled: True + podDisruptionBudget: + enabled: True diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_ingress.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_ingress.yaml new file mode 100644 index 0000000000..e916da0a4a --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_ingress.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: keycloak-http + labels: + app: keycloak +spec: + rules: + - host: KEYCLOAK_HTTP_HOST + http: + paths: + - path: / + pathType: ImplementationSpecific + backend: + service: + name: keycloak-http + port: + number: 8080 \ No newline at end of file diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_route.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_route.yaml new file mode 100644 index 0000000000..e0fb23bc34 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_route.yaml @@ -0,0 +1,15 @@ +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: keycloak-http + labels: + app: keycloak +spec: + path: / + to: + kind: Service + name: keycloak-http + weight: 100 + port: + targetPort: keycloak-http + wildcardPolicy: None diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_service.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_service.yaml new file mode 100644 index 0000000000..242aa47a72 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak_http_service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: keycloak-http + labels: + app: keycloak +spec: + ports: + - name: keycloak-http + protocol: TCP + port: 8080 + targetPort: 8080 + selector: + app: keycloak + component: keycloak + type: ClusterIP + sessionAffinity: None +status: + loadBalancer: {} diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm.yaml new file mode 100644 index 0000000000..511fbc9b5a --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm.yaml @@ -0,0 +1,63 @@ +apiVersion: keycloak.org/v1alpha1 +kind: KeycloakRealm +metadata: + name: registry-keycloakrealm + labels: + app: sso +spec: + instanceSelector: + matchLabels: + app: sso + realm: + displayName: Registry + enabled: true + id: registry + realm: registry + sslRequired: none + roles: + realm: + - name: sr-admin + - name: sr-developer + - name: sr-readonly + clients: + - clientId: registry-client-ui + implicitFlowEnabled: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + publicClient: true + - clientId: registry-client-api + implicitFlowEnabled: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + publicClient: true + users: + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-admin + username: registry-admin + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-developer + username: registry-developer + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-readonly + username: registry-user diff --git a/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm_import.yaml b/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm_import.yaml new file mode 100644 index 0000000000..65cf1697b4 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/keycloak/keycloak_realm_import.yaml @@ -0,0 +1,61 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: KeycloakRealmImport +metadata: + name: registry-keycloakrealm + labels: + app: keycloak +spec: + keycloakCRName: example-keycloak + realm: + displayName: Registry + enabled: true + id: registry + realm: registry + sslRequired: none + roles: + realm: + - name: sr-admin + - name: sr-developer + - name: sr-readonly + clients: + - clientId: registry-client-ui + implicitFlowEnabled: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + publicClient: true + - clientId: registry-client-api + implicitFlowEnabled: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + publicClient: true + users: + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-admin + username: registry-admin + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-developer + username: registry-developer + - credentials: + - temporary: false + type: password + value: changeme + enabled: true + realmRoles: + - sr-readonly + username: registry-user diff --git a/operator/docs/modules/ROOT/examples/templates/https/README.md b/operator/docs/modules/ROOT/examples/templates/https/README.md new file mode 100644 index 0000000000..07a630426c --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/README.md @@ -0,0 +1,21 @@ +This collection of OpenShift templates provides examples of how to configure Red Hat Integration - Service Registry to use HTTPS. Each template contains comments with instructions and details. + +We suggest you read the examples in the following order of increasing complexity: + +Edge termination: + +- registry-default-edge +- registry-certmanager-edge +- registry-certmanager-letsencrypt-edge +- registry-certmanager-letsencrypt-custom-domain-edge + +Passthrough termination: + +- registry-certmanager-passthrough + +In addition, there is a collection of examples on how to configure Red Hat Single Sign-On (Keycloak) to use HTTPS, and integrate it with Service Registry: + +- registry-keycloak-default-edge +- registry-keycloak-certmanager-letsencrypt-edge + +You can merge multiple examples together to configure HTTPS for both Service Registry and Red Hat Single Sign-On. diff --git a/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-certmanager-letsencrypt-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-certmanager-letsencrypt-edge.yaml new file mode 100644 index 0000000000..61b3615aba --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-certmanager-letsencrypt-edge.yaml @@ -0,0 +1,374 @@ +# This example template deploys Registry, and a Red Hat Single Sign-On (Keycloak) instance with an edge-terminated HTTPS route, +# and with a Let's Encrypt certificate using cert-manager operator. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-keycloak-certmanager-letsencrypt-edge +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - Red Hat Single Sign-On Operator +# - cert-manager Operator for Red Hat OpenShift +# +# 3. Apply the template: +# +# oc process -f registry-keycloak-certmanager-letsencrypt-edge.yaml \ +# -p NAMESPACE=registry-keycloak-certmanager-letsencrypt-edge \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-keycloak-certmanager-letsencrypt-edge --timeout=120s +# +# 4. Registry will not be available, until you have created a truststore secret with the Keycloak certificate: +# +# oc get secret registry-keycloak-certmanager-letsencrypt-edge-keycloak-tls-secret -o jsonpath="{.data['tls\.crt']}" | base64 -d > tls.crt +# echo "y" | keytool -import -alias IngressCertificate -file tls.crt -keystore tls.truststore -storepass password +# oc create secret generic keycloak-truststore-secret --from-file=tls.truststore +# +# IMPORTANT NOTES: +# +# 1. Before you apply the template, make sure the ingress/route hostname will be shorter than 64 characters, due to this limitation +# https://community.letsencrypt.org/t/a-certificate-for-a-63-character-domain/78870 . +# +# The resulting hostname will be: +# +# - keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} +# +# You can choose a shorter namespace name, or edit the Ingress below to make the prefix even shorter. +# Alternatively, you can use your custom domain as the Common Name (CN) field in the certificate +# (equivalent to the first item in the dnsNames list) if it's shorter than 64 characters, +# and include the full ingress/route hostname in the Subject Alt Names (SAN) field. +# See the `registry-certmanager-letsencrypt-custom-domain-edge.yaml` example. +# +# 2. By default, this template uses the staging Let's Encrypt issuer, suitable for testing (see https://letsencrypt.org/docs/rate-limits). +# You can try the letsencrypt-production-cluster-issuer instead. In this case, you don't have to create and provide +# a truststore to the Registry, since the certificate is accepted by default. +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-template +labels: + template: registry-keycloak-certmanager-letsencrypt-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-keycloak-certmanager-letsencrypt-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-keycloak-certmanager-letsencrypt-edge-postgres + template: + metadata: + labels: + app: registry-keycloak-certmanager-letsencrypt-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-keycloak-certmanager-letsencrypt-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-keycloak-certmanager-letsencrypt-edge-postgres + # Keycloak + - apiVersion: keycloak.org/v1alpha1 + kind: Keycloak + metadata: + labels: + app: sso + name: registry-keycloak-certmanager-letsencrypt-edge-keycloak + namespace: ${NAMESPACE} + spec: + externalAccess: + enabled: false + instances: 1 + - apiVersion: keycloak.org/v1alpha1 + kind: KeycloakRealm + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-keycloakrealm + namespace: ${NAMESPACE} + spec: + instanceSelector: + matchLabels: + app: sso + realm: + clients: + - clientId: registry-client-ui + directAccessGrantsEnabled: false + implicitFlowEnabled: true + publicClient: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + - clientId: registry-client-api + directAccessGrantsEnabled: false + implicitFlowEnabled: true + publicClient: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + displayName: Registry + enabled: true + id: registry + realm: registry + roles: + realm: + - name: sr-admin + - name: sr-developer + - name: sr-readonly + sslRequired: none + users: + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-admin + username: registry-admin + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-developer + username: registry-developer + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-readonly + username: registry-user + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-keycloak-certmanager-letsencrypt-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: QUARKUS_OIDC_TLS_TRUST_STORE_FILE + value: /mnt/truststore/tls.truststore + - name: QUARKUS_OIDC_TLS_TRUST_STORE_PASSWORD + value: password + - name: ROLE_BASED_AUTHZ_ENABLED + value: "true" + security: + keycloak: + url: https://keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}/auth + realm: registry + deployment: + podTemplateSpecPreview: + spec: + containers: + - name: registry + volumeMounts: + - mountPath: /mnt/truststore + name: truststore + readOnly: true + volumes: + - name: truststore + secret: + secretName: keycloak-truststore-secret + # cert-manager + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-staging-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-edge-staging-key-secret + server: https://acme-staging-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-production-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-edge-production-key-secret + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + - apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-keycloak-ingress-certificate + namespace: ${NAMESPACE} + spec: + secretName: registry-keycloak-certmanager-letsencrypt-edge-keycloak-tls-secret + duration: 17520h # 2*365*24h ~= 2 years + isCA: false + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + dnsNames: + - keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + issuerRef: + # Using a staging Let's encrypt issuer for testing: + name: letsencrypt-staging-cluster-issuer + # See https://letsencrypt.org/docs/rate-limits + # name: letsencrypt-production-cluster-issuer + kind: ClusterIssuer + # Keycloak HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-keycloak-ingress + namespace: ${NAMESPACE} + annotations: + haproxy.router.openshift.io/balance: source + route.openshift.io/termination: reencrypt + labels: + app: keycloak + spec: + tls: + - hosts: + - keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-keycloak-certmanager-letsencrypt-edge-keycloak-tls-secret + rules: + - host: keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: keycloak + port: + name: keycloak + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-keycloak-certmanager-letsencrypt-edge-keycloak-metrics-rewrite-ingress + namespace: ${NAMESPACE} + annotations: + haproxy.router.openshift.io/balance: source + haproxy.router.openshift.io/rewrite-target: /auth/realms/master + route.openshift.io/termination: reencrypt + labels: + app: keycloak + spec: + tls: + - hosts: + - keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-keycloak-certmanager-letsencrypt-edge-keycloak-tls-secret + rules: + - host: keycloak.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: /auth/realms/master/metrics + pathType: Prefix + backend: + service: + name: keycloak + port: + name: keycloak +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-default-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-default-edge.yaml new file mode 100644 index 0000000000..596023eaee --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/keycloak/registry-keycloak-default-edge.yaml @@ -0,0 +1,259 @@ +# This example template deploys Registry, and a Red Hat Single Sign-On (Keycloak) instance with an edge-terminated HTTPS route. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-keycloak-default-edge +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - Red Hat Single Sign-On Operator +# +# 3. Prepare a truststore with certificates for the Keycloak URL. In this example, +# I'm using the default ingress router certificates on my OpenShift cluster: +# +# oc get secret -n openshift-ingress --field-selector=type=kubernetes.io/tls | grep -v metrics +# +# will list something like: +# +# NAME TYPE DATA AGE +# 0b9c209b-0566-4e3b-a2e2-c93e27e90eb2-ingress kubernetes.io/tls 2 20m +# +# oc get secret -n openshift-ingress 0b9c209b-0566-4e3b-a2e2-c93e27e90eb2-ingress -o jsonpath="{.data['tls\.crt']}" | base64 -d > tls.crt +# echo "y" | keytool -import -alias IngressCertificate -file tls.crt -keystore tls.truststore -storepass password +# oc create secret generic keycloak-truststore-secret --from-file=tls.truststore +# +# 4. Apply the template: +# +# oc process -f registry-keycloak-default-edge.yaml \ +# -p NAMESPACE=registry-keycloak-default-edge \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-keycloak-default-edge --timeout=120s +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-keycloak-default-edge-template +labels: + template: registry-keycloak-default-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-keycloak-default-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-keycloak-default-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-keycloak-default-edge-postgres + template: + metadata: + labels: + app: registry-keycloak-default-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-keycloak-default-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-keycloak-default-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-keycloak-default-edge-postgres + # Keycloak + - apiVersion: keycloak.org/v1alpha1 + kind: Keycloak + metadata: + labels: + app: sso + name: registry-keycloak-default-edge-keycloak + namespace: ${NAMESPACE} + spec: + externalAccess: + enabled: true + instances: 1 + - apiVersion: keycloak.org/v1alpha1 + kind: KeycloakRealm + metadata: + name: registry-keycloak-default-edge-keycloakrealm + namespace: ${NAMESPACE} + spec: + instanceSelector: + matchLabels: + app: sso + realm: + clients: + - clientId: registry-client-ui + directAccessGrantsEnabled: false + implicitFlowEnabled: true + publicClient: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + - clientId: registry-client-api + directAccessGrantsEnabled: false + implicitFlowEnabled: true + publicClient: true + redirectUris: + - '*' + standardFlowEnabled: true + webOrigins: + - '*' + displayName: Registry + enabled: true + id: registry + realm: registry + roles: + realm: + - name: sr-admin + - name: sr-developer + - name: sr-readonly + sslRequired: none + users: + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-admin + username: registry-admin + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-developer + username: registry-developer + - credentials: + - type: password + value: changeme + enabled: true + realmRoles: + - sr-readonly + username: registry-user + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-keycloak-default-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-keycloak-default-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: QUARKUS_OIDC_TLS_TRUST_STORE_FILE + value: /mnt/truststore/tls.truststore + - name: QUARKUS_OIDC_TLS_TRUST_STORE_PASSWORD + value: password + - name: ROLE_BASED_AUTHZ_ENABLED + value: "true" + security: + keycloak: + url: https://keycloak-${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}/auth + realm: registry + deployment: + podTemplateSpecPreview: + spec: + containers: + - name: registry + volumeMounts: + - mountPath: /mnt/truststore + name: truststore + readOnly: true + volumes: + - name: truststore + secret: + secretName: keycloak-truststore-secret +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-edge.yaml new file mode 100644 index 0000000000..9adb19ec11 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-edge.yaml @@ -0,0 +1,235 @@ +# This example template deploys Registry with an edge-terminated HTTPS route, with a self-signed certificate using cert-manager operator. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-certmanager-edge +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - cert-manager Operator for Red Hat OpenShift +# +# 3. Apply the template: +# +# oc process -f registry-certmanager-edge.yaml \ +# -p NAMESPACE=registry-certmanager-edge \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-certmanager-edge --timeout=120s +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-certmanager-edge-template +labels: + template: registry-certmanager-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-certmanager-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-certmanager-edge-postgres + template: + metadata: + labels: + app: registry-certmanager-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-certmanager-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-certmanager-edge-postgres + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-certmanager-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-certmanager-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: CORS_ALLOWED_ORIGINS + value: >- + http://registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}, + https://registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + deployment: + managedResources: + disableIngress: true + # cert-manager + # Self-signed cluster issuer for the "root CA certificate" + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: selfsigned-cluster-issuer + spec: + selfSigned: { } + # Create the "root CA certificate" + - apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: selfsigned-ca + namespace: ${NAMESPACE} + spec: + secretName: ca-root-secret + duration: 17520h # 2*365*24h ~= 2 years + isCA: true + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + commonName: selfsigned-ca + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: selfsigned-cluster-issuer + # Issuer for Ingress + - apiVersion: cert-manager.io/v1 + kind: Issuer + metadata: + name: selfsigned-ca-issuer + namespace: ${NAMESPACE} + spec: + ca: + secretName: ca-root-secret + # HTTP Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-edge-http-ingress + namespace: ${NAMESPACE} + spec: + rules: + - host: >- + registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-edge-service + port: + number: 8080 + # HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-edge-https-ingress + namespace: ${NAMESPACE} + annotations: + cert-manager.io/issuer: selfsigned-ca-issuer + spec: + tls: + - hosts: + - registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-certmanager-edge-tls-secret + rules: + - host: registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-edge-service + port: + number: 8080 +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-custom-domain-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-custom-domain-edge.yaml new file mode 100644 index 0000000000..739460f0c7 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-custom-domain-edge.yaml @@ -0,0 +1,264 @@ +# This example template deploys Registry with an edge-terminated HTTPS route, with a custom domain +# and Let's Encrypt certificate using cert-manager operator. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project test +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - cert-manager Operator for Red Hat OpenShift +# +# 3. Provision a custom domain, and add a CNAME DNS record referencing the ${INGRESS_ROUTER_CANONICAL_HOSTNAME} +# (see the bottom of the file) of your cluster: +# +# Name TTL Type Data +# test 300 CNAME router-default.apps.apicur.eastus.aroapp.io +# +# Wait for the DNS changes to propagate. +# +# 4. Apply the template: +# +# oc process -f registry-certmanager-letsencrypt-custom-domain-edge.yaml \ +# -p NAMESPACE=test \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# -p CUSTOM_DOMAIN=test.jsenko.net \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-certmanager-letsencrypt-custom-domain-edge --timeout=120s +# +# It may take a few minutes until the certificate has been issued. +# +# IMPORTANT NOTES: +# +# 1. Before you apply the template, make sure the ingress/route hostname will be shorter than 64 characters, due to this limitation +# https://community.letsencrypt.org/t/a-certificate-for-a-63-character-domain/78870 . +# +# 2. By default, this template uses the staging Let's Encrypt issuer, suitable for testing (see https://letsencrypt.org/docs/rate-limits/). +# You can try the letsencrypt-production-cluster-issuer instead. +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge-template +labels: + template: registry-certmanager-letsencrypt-custom-domain-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-letsencrypt-custom-domain-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-certmanager-letsencrypt-custom-domain-edge-postgres + template: + metadata: + labels: + app: registry-certmanager-letsencrypt-custom-domain-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-letsencrypt-custom-domain-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-certmanager-letsencrypt-custom-domain-edge-postgres + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-certmanager-letsencrypt-custom-domain-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: CORS_ALLOWED_ORIGINS + value: >- + https://${CUSTOM_DOMAIN}, + http://registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}, + https://registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + deployment: + managedResources: + disableIngress: true + # cert-manager + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-staging-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-custom-domain-edge-staging-key-secret + server: https://acme-staging-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-production-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-custom-domain-edge-production-key-secret + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + # HTTP Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge-http-ingress + namespace: ${NAMESPACE} + spec: + rules: + - host: >- + registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-letsencrypt-custom-domain-edge-service + port: + number: 8080 + # HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-letsencrypt-custom-domain-edge-https-ingress + namespace: ${NAMESPACE} + annotations: + # Use a staging Let's encrypt issuer for testing: + cert-manager.io/cluster-issuer: letsencrypt-staging-cluster-issuer + # See https://letsencrypt.org/docs/rate-limits + # cert-manager.io/cluster-issuer: letsencrypt-production-cluster-issuer + spec: + tls: + - hosts: + - ${CUSTOM_DOMAIN} + - registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-certmanager-letsencrypt-custom-domain-edge-tls-secret + rules: + - host: ${CUSTOM_DOMAIN} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-letsencrypt-custom-domain-edge-service + port: + number: 8080 + # This rule is optional + - host: registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-letsencrypt-custom-domain-edge-service + port: + number: 8080 +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true + - name: CUSTOM_DOMAIN + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-edge.yaml new file mode 100644 index 0000000000..5d13016dd5 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-letsencrypt-edge.yaml @@ -0,0 +1,248 @@ +# This example template deploys Registry with an edge-terminated HTTPS route, with a Let's Encrypt certificate using cert-manager operator. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project test +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - cert-manager Operator for Red Hat OpenShift +# +# 3. Apply the template: +# +# oc process -f registry-certmanager-letsencrypt-edge.yaml \ +# -p NAMESPACE=test \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-certmanager-letsencrypt-edge --timeout=120s +# +# It may take a few minutes until the certificate has been issued. +# +# IMPORTANT NOTES: +# +# 1. Before you apply the template, make sure the ingress/route hostname will be shorter than 64 characters, due to this limitation +# https://community.letsencrypt.org/t/a-certificate-for-a-63-character-domain/78870 . +# +# The resulting hostname will be: +# +# registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} +# +# You can choose a shorter namespace name, or edit the Ingress below to make the prefix even shorter. +# Alternatively, you can use your custom domain as the Common Name (CN) field in the certificate +# if it's shorter than 64 characters, and include the full ingress/route hostname in the Subject Alt Names (SAN) field. +# See the `registry-certmanager-letsencrypt-custom-domain-edge.yaml` example. +# +# 2. By default, this template uses the staging Let's Encrypt issuer, suitable for testing (see https://letsencrypt.org/docs/rate-limits/). +# You can try the letsencrypt-production-cluster-issuer instead. +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-certmanager-letsencrypt-edge-template +labels: + template: registry-certmanager-letsencrypt-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-certmanager-letsencrypt-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-letsencrypt-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-certmanager-letsencrypt-edge-postgres + template: + metadata: + labels: + app: registry-certmanager-letsencrypt-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-certmanager-letsencrypt-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-letsencrypt-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-certmanager-letsencrypt-edge-postgres + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-certmanager-letsencrypt-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-certmanager-letsencrypt-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: CORS_ALLOWED_ORIGINS + value: >- + http://registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}, + https://registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + deployment: + managedResources: + disableIngress: true + # cert-manager + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-staging-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-edge-staging-key-secret + server: https://acme-staging-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-production-cluster-issuer + spec: + acme: + privateKeySecretRef: + name: registry-certmanager-letsencrypt-edge-production-key-secret + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: openshift-default + # HTTP Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-letsencrypt-edge-http-ingress + namespace: ${NAMESPACE} + spec: + rules: + - host: >- + registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-letsencrypt-edge-service + port: + number: 8080 + # HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-letsencrypt-edge-https-ingress + namespace: ${NAMESPACE} + annotations: + # Use a staging Let's encrypt issuer for testing: + cert-manager.io/cluster-issuer: letsencrypt-staging-cluster-issuer + # See https://letsencrypt.org/docs/rate-limits + # cert-manager.io/cluster-issuer: letsencrypt-production-cluster-issuer + spec: + tls: + - hosts: + - registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-certmanager-letsencrypt-edge-tls-secret + rules: + - host: registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-certmanager-letsencrypt-edge-service + port: + number: 8080 +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-passthrough.yaml b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-passthrough.yaml new file mode 100644 index 0000000000..17ef249f49 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/registry-certmanager-passthrough.yaml @@ -0,0 +1,236 @@ +# This example template deploys Registry with a passthrough HTTPS route, using cert-manager operator. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-certmanager-passthrough +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# - cert-manager Operator for Red Hat OpenShift +# +# 3. Apply the template: +# +# oc process -f registry-certmanager-passthrough.yaml \ +# -p NAMESPACE=registry-certmanager-passthrough \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-certmanager-passthrough --timeout=120s +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-certmanager-passthrough-template +labels: + template: registry-certmanager-passthrough-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-certmanager-passthrough-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-passthrough-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-certmanager-passthrough-postgres + template: + metadata: + labels: + app: registry-certmanager-passthrough-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-certmanager-passthrough-postgres + namespace: ${NAMESPACE} + labels: + app: registry-certmanager-passthrough-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-certmanager-passthrough-postgres + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-certmanager-passthrough + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-certmanager-passthrough-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: REGISTRY_URL_OVERRIDE_HOST + value: registry.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + - name: REGISTRY_URL_OVERRIDE_PORT + value: "443" + - name: CORS_ALLOWED_ORIGINS + value: https://registry.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + security: + https: + secretName: registry-certmanager-passthrough-tls-secret + disableHttp: true + # Certificates + # Self-signed cluster issuer for the "root CA certificate" + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: selfsigned-cluster-issuer + spec: + selfSigned: { } + # Create the "root CA certificate" + - apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: selfsigned-ca + namespace: ${NAMESPACE} + spec: + secretName: ca-root-secret + duration: 17520h # 2*365*24h ~= 2 years + isCA: true + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + commonName: selfsigned-ca + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: selfsigned-cluster-issuer + # Issuer for Ingress + - apiVersion: cert-manager.io/v1 + kind: Issuer + metadata: + name: selfsigned-ca-issuer + namespace: ${NAMESPACE} + spec: + ca: + secretName: ca-root-secret + # Certificate for Registry + - apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: registry-certmanager-passthrough-tls + namespace: ${NAMESPACE} + spec: + secretName: registry-certmanager-passthrough-tls-secret + duration: 17520h # 2*365*24h ~= 2 years + isCA: false + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + dnsNames: + - registry.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + issuerRef: + group: cert-manager.io + kind: Issuer + name: selfsigned-ca-issuer + # A separate HTTP Ingress is not available because of the REGISTRY_URL_OVERRIDE_HOST configuration. + # HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-certmanager-passthrough-https-ingress + namespace: ${NAMESPACE} + annotations: + route.openshift.io/termination: passthrough + spec: + rules: + - host: registry.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: "" + pathType: ImplementationSpecific + backend: + service: + name: registry-certmanager-passthrough-service + port: + number: 8443 +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/https/registry-default-edge.yaml b/operator/docs/modules/ROOT/examples/templates/https/registry-default-edge.yaml new file mode 100644 index 0000000000..5f9f698544 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/https/registry-default-edge.yaml @@ -0,0 +1,211 @@ +# This example template deploys Registry with an edge-terminated HTTPS route, with a default ingress router certificate. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-default-edge +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# +# 3. Find and copy the default ingress router certificate to the ${NAMESPACE}: +# +# oc get secret -n openshift-ingress --field-selector=type=kubernetes.io/tls | grep -v metrics +# +# will list something like: +# +# NAME TYPE DATA AGE +# 0b9c209b-0566-4e3b-a2e2-c93e27e90eb2-ingress kubernetes.io/tls 2 20m +# +# oc get secret -n openshift-ingress -o json \ +# | jq 'del(.metadata["namespace", "creationTimestamp", "resourceVersion", "selfLink", "uid", "ownerReferences", "managedFields"]) | .metadata.name="registry-default-edge-tls-secret"' \ +# | oc create -f - +# +# 4. Apply the template: +# +# oc process -f registry-default-edge.yaml \ +# -p NAMESPACE=registry-default-edge \ +# -p INGRESS_ROUTER_CANONICAL_HOSTNAME=router-default.apps.apicur.eastus.aroapp.io \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-default-edge --timeout=120s +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-default-edge-template +labels: + template: registry-default-edge-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-default-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-default-edge-postgres + spec: + replicas: 1 + selector: + matchLabels: + app: registry-default-edge-postgres + template: + metadata: + labels: + app: registry-default-edge-postgres + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-default-edge-postgres + namespace: ${NAMESPACE} + labels: + app: registry-default-edge-postgres + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-default-edge-postgres + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-default-edge + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-default-edge-postgres.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} + env: + - name: CORS_ALLOWED_ORIGINS + value: >- + http://registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME}, + https://registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + deployment: + managedResources: + disableIngress: true + # HTTP Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-default-edge-http-ingress + namespace: ${NAMESPACE} + spec: + rules: + - host: >- + registry-http.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-default-edge-service + port: + number: 8080 + # HTTPS Ingress + - kind: Ingress + apiVersion: networking.k8s.io/v1 + metadata: + name: registry-default-edge-https-ingress + namespace: ${NAMESPACE} + annotations: + cert-manager.io/issuer: selfsigned-ca-issuer + spec: + tls: + - hosts: + - registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + secretName: registry-default-edge-tls-secret + rules: + - host: registry-https.${NAMESPACE}.${INGRESS_ROUTER_CANONICAL_HOSTNAME} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: registry-default-edge-service + port: + number: 8080 +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password + - name: INGRESS_ROUTER_CANONICAL_HOSTNAME + # Find out from a status block of any Ingress or Route resource, e.g.: + # status: + # loadBalancer: + # ingress: + # - hostname: router-default.apps.apicur.eastus.aroapp.io + required: true diff --git a/operator/docs/modules/ROOT/examples/templates/registry-simple-postgresql.yaml b/operator/docs/modules/ROOT/examples/templates/registry-simple-postgresql.yaml new file mode 100644 index 0000000000..fffdbd02f4 --- /dev/null +++ b/operator/docs/modules/ROOT/examples/templates/registry-simple-postgresql.yaml @@ -0,0 +1,139 @@ +# This example template deploys Registry with PostgreSQL database. +# +# Steps: +# +# 1. Create or select a namespace: +# +# oc new-project registry-simple-postgresql +# +# 2. Install the operator(s): +# +# - Red Hat Integration - Service Registry Operator +# +# 3. Apply the template: +# +# oc process -f registry-simple-postgresql.yaml \ +# -p NAMESPACE=registry-simple-postgresql \ +# | oc apply -f - && oc wait --for=condition=ready apicurioregistry registry-simple-postgresql --timeout=60s +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: registry-simple-postgresql-template +labels: + template: registry-simple-postgresql-template +objects: + # PostgreSQL storage + - kind: Deployment + apiVersion: apps/v1 + metadata: + name: registry-simple-postgresql-postgresql + namespace: ${NAMESPACE} + labels: + app: registry-simple-postgresql-postgresql + spec: + replicas: 1 + selector: + matchLabels: + app: registry-simple-postgresql-postgresql + template: + metadata: + labels: + app: registry-simple-postgresql-postgresql + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1024Mi + requests: + cpu: 500m + memory: 512Mi + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + name: postgresql + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 20 + successThreshold: 1 + failureThreshold: 3 + env: + - name: POSTGRESQL_PASSWORD + value: ${POSTGRESQL_PASSWORD} + - name: POSTGRESQL_USER + value: ${POSTGRESQL_USER} + - name: POSTGRESQL_DATABASE + value: ${POSTGRESQL_DATABASE} + ports: + - containerPort: 5432 + protocol: TCP + imagePullPolicy: IfNotPresent + terminationMessagePolicy: File + image: quay.io/centos7/postgresql-12-centos7:1 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: { } + schedulerName: default-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% + revisionHistoryLimit: 10 + progressDeadlineSeconds: 600 + - kind: Service + apiVersion: v1 + metadata: + name: registry-simple-postgresql-postgresql + namespace: ${NAMESPACE} + labels: + app: registry-simple-postgresql-postgresql + spec: + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + type: ClusterIP + selector: + app: registry-simple-postgresql-postgresql + # Registry + - apiVersion: registry.apicur.io/v1 + kind: ApicurioRegistry + metadata: + name: registry-simple-postgresql + namespace: ${NAMESPACE} + spec: + configuration: + persistence: sql + sql: + dataSource: + url: jdbc:postgresql://registry-simple-postgresql-postgresql.${NAMESPACE}.svc.cluster.local:5432/${POSTGRESQL_DATABASE} + userName: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} +parameters: + - name: NAMESPACE + required: true + - name: POSTGRESQL_DATABASE + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: password diff --git a/operator/docs/modules/ROOT/images/operator-hub-search-ar.png b/operator/docs/modules/ROOT/images/operator-hub-search-ar.png new file mode 100644 index 0000000000000000000000000000000000000000..0e0a0674cee8176913ab408fa237b764d4e3456b GIT binary patch literal 136386 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 literal 0 HcmV?d00001 diff --git a/operator/docs/modules/ROOT/images/operator-hub-search-sr.png b/operator/docs/modules/ROOT/images/operator-hub-search-sr.png new file mode 100644 index 0000000000000000000000000000000000000000..b7397b0f792350929c8496f9128e56eb822aa781 GIT binary patch literal 110536 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

{Ea2B?i> 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%0AwdBwXpqo%Pd-mb1Y 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 *OperatorHub*. +ifdef::apicurio-registry[] +. In the *Filter by keyword* text box, enter `Strimzi` to find the *{kafka-streams}* Operator. +endif::[] +ifdef::service-registry[] +. In the *Filter by keyword* text box, enter `AMQ` to find the *Red Hat Integration - {kafka-streams}* Operator. +endif::[] +. Read the information about the Operator, and click *Install*. This displays the *Create Operator Subscription* page. + +. Select your subscription settings, for example: +** *Installation Mode* > *A specific namespace on the cluster* > *my-project* +ifdef::apicurio-registry[] +** *Update Channel* > *stable* +endif::[] +ifdef::service-registry[] +** *Update Channel* > *amq-streams-1.5.x* +endif::[] +** *Approval Strategy* > *Manual* + +. Click *Subscribe*. This displays the *Operators* > *Installed Operators* page. + +. Wait a few moments until the *Status* for the {kafka-streams} Operator displays *Succeeded* and the subscription is *Up to Date*. + +.Additional resources +* link:https://docs.openshift.com/container-platform/4.6/operators/olm-adding-operators-to-cluster.html[Adding Operators to an OpenShift cluster] +* link:https://access.redhat.com/documentation/en-us/red_hat_amq/7.7/html/using_amq_streams_on_openshift/index?[Using AMQ Streams on OpenShift] diff --git a/operator/docs/modules/ROOT/partials/proc-install-olm-kubernetes.adoc b/operator/docs/modules/ROOT/partials/proc-install-olm-kubernetes.adoc new file mode 100644 index 0000000000..9759e8d138 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-install-olm-kubernetes.adoc @@ -0,0 +1,16 @@ +[id="install-registry-operator-olm-on-kubernetes"] += Installing {operator} using the OperatorHub on Kubernetes + +This chapter focuses on installation procedures for OpenShift using OperatorHub UI. +If you are deploying to Kubernetes, you can use command line tools to install Operator Lifecycle Manager (OLM), and instruct it to deploy the {registry} or other Operators. + +image::operator-hub-search-ar.png[] + +.Prerequisites +* You must have cluster administrator access to a Kubernetes cluster. + +.Procedure +. Go to https://operatorhub.io/operator/apicurio-registry[OperatorHub.io - Apicurio Registry] page. +. Select the *Version* you want to install +. Read the information about the Operator, and click *Install*. +. Follow the instructions on the installation page. diff --git a/operator/docs/modules/ROOT/partials/proc-install-olm-sr.adoc b/operator/docs/modules/ROOT/partials/proc-install-olm-sr.adoc new file mode 100644 index 0000000000..ba64852ca0 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-install-olm-sr.adoc @@ -0,0 +1,55 @@ +[id=install-registry-operator-olm] += Installing {operator} using Operator Lifecycle Manager + +The recommended way to install {operator} is to use the link:{LinkOLMDocs}[{NameOLMDocs}] (OLM), which can automatically manage the Operator deployment and upgrades. + +{operator} is released to the link:{LinkOperatorHub}[{NameOperatorHub}], so if your cluster has the OLM and OperatorHub installed, the cluster administrator can use the OpenShift web console to deploy the {operator}: + +image::operator-hub-search-sr.png[] + +.Prerequisites +* You must have cluster administrator access to an OpenShift cluster. + +.Procedure +. In the OpenShift Container Platform web console, log in using an account with cluster administrator privileges. + +. Create a new OpenShift project: + +.. In the left navigation menu, click *Home* > *Project* > *Create Project*. +.. Enter a project name, for example, `my-project`, and click *Create*. + +. In the left navigation menu, click *Operators* > *OperatorHub*. + +ifdef::apicurio-registry[] +. In the *Filter by keyword* text box, enter `registry` to find the *{operator}*. +endif::[] +ifdef::service-registry[] +. In the *Filter by keyword* text box, enter `registry` to find the *Red Hat Integration - {operator}*. +endif::[] +. Read the information about the Operator, and click *Install*. +This displays the *Create Operator Subscription* page. + +. Select your subscription settings, for example: +** *Installation Mode* > *A specific namespace on the cluster* > *my-project* +ifdef::service-registry[] +* *Update Channel*: Select one of the following: +*** *3.0.x*: Includes patch updates only, such as 3.0.1 and 3.0.2. For example, an installation on 3.0.x automatically ignores 3.1.x. +*** *3.x*: Includes all minor and patch updates, such as 3.1.0 and 3.0.1. For example, an installation on 3.0.x automatically upgrades to 3.1.x. +endif::[] +ifdef::apicurio-registry[] +** *Update Channel* > *3.x* +endif::[] +ifdef::service-registry[] +** *Approval Strategy* > *Manual* +endif::[] +ifdef::apicurio-registry[] +** *Approval Strategy* > *Automatic* +endif::[] + +. Click *Subscribe*. +This displays the *Operators* > *Installed Operators* page. + +. Wait a few moments until the *Status* for the {operator} displays *Succeeded* and the subscription is *Up to Date*. + +.Additional resources +* link:https://docs.openshift.com/container-platform/4.6/operators/olm-adding-operators-to-cluster.html[Adding Operators to an OpenShift cluster] diff --git a/operator/docs/modules/ROOT/partials/proc-install-postgresql.adoc b/operator/docs/modules/ROOT/partials/proc-install-postgresql.adoc new file mode 100644 index 0000000000..9ea9983b5c --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-install-postgresql.adoc @@ -0,0 +1,72 @@ +[id="install-postgresql-operatorhub"] += Installing PostgreSQL database storage using OpenShift OperatorHub + +One of the available storage options requires that you provide connection information to a PostgreSQL database. +You can use any PostgreSQL database available on your OpenShift cluster, but it is recommended to use link:{LinkOperatorHub}[{NameOperatorHub}] to choose and install an Operator that can manage a PostgreSQL database for you. + +You can install your preferred PostgresQL Operator, but this section shows how to install the *PostgreSQL Operator by Dev4Ddevs.com* and create a new database for {registry}. + +.Prerequisites + +* You must have cluster administrator access to an OpenShift cluster. + +.Procedure + +. In the OpenShift Container Platform web console, log in using an account with cluster administrator privileges. + +. Change to the OpenShift project in which {registry} is installed. For example, from the *Project* drop-down, select `my-project`. + +. In the left navigation menu, click *Operators* > *OperatorHub*. + +. In the *Filter by keyword* text box, enter `PostgreSQL` to find an Operator suitable for your environment, for example, *PostgreSQL Operator by Dev4Ddevs.com* or *Crunchy PostgreSQL for OpenShift*. + +. Read the information about the Operator, and click *Install*. This displays the *Create Operator Subscription* page. + +. Select your subscription settings, for example: +** *Installation Mode*: Select one of the following: +*** *All namespaces on the cluster (default)* +*** *A specific namespace on the cluster* and then *my-project* +** *Update Channel* > *stable* +** *Approval Strategy*: Select *Automatic* or *Manual* + +. Click *Subscribe*. This displays the *Operators* > *Installed Operators* page. + +. Wait a few moments until the *Status* for the PostgreSQL Operator displays *Succeeded* and the subscription is *Up to Date*. ++ +IMPORTANT: You must read the documentation from your chosen *PostgreSQL* Operator for details on how to create and manage your database. + +. Create a PostgreSQL database for your {registry} storage. For example, click *Installed Operators* > *PostgreSQL Operator by Dev4Ddevs.com* > *Create database* > *YAML*. + +. Edit the database settings as follows: +** `name`: Change the value to `registry` +** `image`: Change the value to `centos/postgresql-10-centos7` + +. Edit any other database settings as needed depending on your environment, for example: ++ +[source,yaml] +---- +apiVersion: postgresql.dev4devs.com/v1alpha1 +kind: Database +metadata: + name: registry + namespace: my-project +spec: + databaseCpu: 30m + databaseCpuLimit: 60m + databaseMemoryLimit: 512Mi + databaseMemoryRequest: 128Mi + databaseName: example + databaseNameKeyEnvVar: POSTGRESQL_DATABASE + databasePassword: postgres + databasePasswordKeyEnvVar: POSTGRESQL_PASSWORD + databaseStorageRequest: 1Gi + databaseUser: postgres + databaseUserKeyEnvVar: POSTGRESQL_USER + image: centos/postgresql-10-centos7 + size: 1 +---- + +. Click *Create Database*, and wait until the database is created. + +.Additional resources +* link:https://access.crunchydata.com/documentation/postgres-operator/4.5.0/quickstart/[Crunchy PostgreSQL Operator QuickStart] diff --git a/operator/docs/modules/ROOT/partials/proc-manage-environment-variables.adoc b/operator/docs/modules/ROOT/partials/proc-manage-environment-variables.adoc new file mode 100644 index 0000000000..11c9ff1ebf --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-manage-environment-variables.adoc @@ -0,0 +1,65 @@ +[id="manage-registry-environment-variables"] +// Do not forget to update link text in related xref(s). Antora does not support automatic name if the link has a fragment. += Managing {registry} environment variables + +{operator} manages most common {registry} configuration, but there are some options that it does not support yet. If a high-level configuration option is not available in the `ApicurioRegistry` CR, you can use an environment variable to adjust it. You can update these by setting an environment variable directly in the `ApicurioRegistry` CR, in the `spec.configuration.env` field. These are then forwarded to the `Deployment` resource of {registry}. + +.Procedure + +You can manage {registry} environment variables by using the OpenShift web console or CLI. + +OpenShift web console:: + +ifdef::apicurio-registry[] +. Select the *Installed Operators* tab, and then *{registry} Operator*. +endif::[] +ifdef::service-registry[] +. Select the *Installed Operators* tab, and then *Red Hat Integration - Service Registry Operator*. +endif::[] +. On the *Apicurio Registry* tab, click the `ApicurioRegistry` CR for your {registry} deployment. +. Click the *YAML* tab and then edit the `spec.configuration.env` section as needed. The following example shows how to set default global content rules: ++ +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry +spec: + configuration: + # ... + env: + - name: REGISTRY_RULES_GLOBAL_VALIDITY + value: FULL # One of: NONE, SYNTAX_ONLY, FULL + - name: REGISTRY_RULES_GLOBAL_COMPATIBILITY + value: FULL # One of: NONE, BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE +---- + +OpenShift CLI:: + +. Select the project where {registry} is installed. +. Run `oc get apicurioregistry` to get the list of `ApicurioRegistry` CRs +. Run `oc edit apicurioregistry` on the CR representing the {registry} instance that you want to configure. +. Add or modify the environment variable in the `spec.configuration.env` section. ++ +The {operator} might attempt to set an environment variable that is already explicitly specified in the `spec.configuration.env` field. If an environment variable configuration has a conflicting value, the value set by {operator} takes precedence. ++ +You can avoid this conflict by either using the high-level configuration for the feature, or only using the explicitly specified environment variables. The following is an example of a conflicting configuration: ++ +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry +spec: + configuration: + # ... + ui: + readOnly: true + env: + - name: REGISTRY_UI_FEATURES_READONLY + value: false +---- ++ +This configuration results in the {registry} web console being in read-only mode. diff --git a/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-plain.adoc b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-plain.adoc new file mode 100644 index 0000000000..835e8c75a1 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-plain.adoc @@ -0,0 +1,106 @@ +[id="registry-persistence-kafkasql-plain"] += Configuring plain Kafka storage with no security + +You can configure the {kafka-streams} Operator and {operator} to use a default connection with no security. + +.Prerequisites + +* You have installed the {operator} using the OperatorHub or command line. +* You have installed the {kafka-streams} Operator or have Kafka accessible from your OpenShift cluster. + +.Procedure + +. In the OpenShift web console, click *Installed Operators*, select the *{kafka-streams}* Operator details, and then the *Kafka* tab. + +. Click *Create Kafka* to provision a new Kafka cluster for {registry} storage. You can use the default value, for example: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta2 +kind: Kafka +metadata: + name: my-cluster + namespace: registry-example-kafkasql-plain + # Change or remove the explicit namespace +spec: + kafka: + config: + offsets.topic.replication.factor: 3 + transaction.state.log.replication.factor: 3 + transaction.state.log.min.isr: 2 + log.message.format.version: '2.7' + inter.broker.protocol.version: '2.7' + version: 2.7.0 + storage: + type: ephemeral + replicas: 3 + listeners: + - name: plain + port: 9092 + type: internal + tls: false + - name: tls + port: 9093 + type: internal + tls: true + entityOperator: + topicOperator: {} + userOperator: {} + zookeeper: + storage: + type: ephemeral + replicas: 3 +---- ++ +NOTE: Your OpenShift project namespace might be different. + +. When the cluster is ready, open the *Kafka* resource, examine the `status` block, and copy the `bootstrapServers` value for later use when deploying {registry}. For example: ++ +[source,yaml] +---- +status: + conditions: + ... + listeners: + - addresses: + - host: my-cluster-kafka-bootstrap.registry-example-kafkasql-plain.svc + port: 9092 + bootstrapServers: 'my-cluster-kafka-bootstrap.registry-example-kafkasql-plain.svc:9092' + type: plain + ... +---- ++ +The default Kafka topic name automatically created by {registry} to store data is `kafkasql-journal`. You can override this behavior or the default topic name by setting environment variables. The default values are as follows: + + ** `REGISTRY_KAFKASQL_TOPIC_AUTO_CREATE=true` + ** `REGISTRY_KAFKASQL_TOPIC=kafkasql-journal` + ++ +If you decide not to create the Kafka topic manually, skip the next step. + +. Click the *Kafka Topic* tab, and then *Create Kafka Topic* to create the `kafkasql-journal` topic: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta1 +kind: KafkaTopic +metadata: + name: kafkasql-journal + labels: + strimzi.io/cluster: my-cluster + namespace: registry-example-kafkasql-plain +spec: + partitions: 2 + replicas: 1 + config: + cleanup.policy: compact +---- + +. Select the *{operator}*, and in the *ApicurioRegistry* tab, click *Create ApicurioRegistry*, using the following example, but replace your value in the `bootstrapServers` field. ++ +[source,yaml] +---- +include::example$apicurioregistry_kafkasql_plain_cr.yaml[] +---- + +. Wait a few minutes to see the *Route* being created, where you can access the application. diff --git a/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-scram.adoc b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-scram.adoc new file mode 100644 index 0000000000..c2a4489382 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-scram.adoc @@ -0,0 +1,174 @@ +[id="registry-persistence-kafkasql-scram"] += Configuring Kafka storage with SCRAM security + +You can configure the {kafka-streams} Operator and {operator} to use Salted Challenge Response Authentication Mechanism (SCRAM-SHA-512) for the Kafka cluster. + + +.Prerequisites + +* You have installed the {operator} using the OperatorHub or command line. +* You have installed the {kafka-streams} Operator or have Kafka accessible from your OpenShift cluster. + +NOTE: This section assumes that {kafka-streams} Operator is available, however you can use any Kafka deployment. +In that case, you must manually create the Openshift secrets that the {operator} expects. + +.Procedure + +. In the OpenShift web console, click *Installed Operators*, select the *{kafka-streams}* Operator details, and then the *Kafka* tab. + +. Click *Create Kafka* to provision a new Kafka cluster for {registry} storage. + +. Configure the `authorization` and `tls` fields to use SCRAM-SHA-512 authentication for the Kafka cluster, for example: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta2 +kind: Kafka +metadata: + name: my-cluster + namespace: registry-example-kafkasql-scram + # Change or remove the explicit namespace +spec: + kafka: + config: + offsets.topic.replication.factor: 3 + transaction.state.log.replication.factor: 3 + transaction.state.log.min.isr: 2 + log.message.format.version: '2.7' + inter.broker.protocol.version: '2.7' + version: 2.7.0 + storage: + type: ephemeral + replicas: 3 + listeners: + - name: tls + port: 9093 + type: internal + tls: true + authentication: + type: scram-sha-512 + authorization: + type: simple + entityOperator: + topicOperator: {} + userOperator: {} + zookeeper: + storage: + type: ephemeral + replicas: 3 +---- ++ +The default Kafka topic name automatically created by {registry} to store data is `kafkasql-journal`. You can override this behavior or the default topic name by setting environment variables. The default values are as follows: + +** `REGISTRY_KAFKASQL_TOPIC_AUTO_CREATE=true` +** `REGISTRY_KAFKASQL_TOPIC=kafkasql-journal` + ++ +If you decide not to create the Kafka topic manually, skip the next step. + +. Click the *Kafka Topic* tab, and then *Create Kafka Topic* to create the `kafkasql-journal` topic: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta1 +kind: KafkaTopic +metadata: + name: kafkasql-journal + labels: + strimzi.io/cluster: my-cluster + namespace: registry-example-kafkasql-scram +spec: + partitions: 2 + replicas: 1 + config: + cleanup.policy: compact +---- + +. Create a *Kafka User* resource to configure SCRAM authentication and authorization for the {registry} user. You can specify a user name in the `metadata` section or use the default `my-user`. ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta1 +kind: KafkaUser +metadata: + name: my-user + labels: + strimzi.io/cluster: my-cluster + namespace: registry-example-kafkasql-scram +spec: + authentication: + type: scram-sha-512 + authorization: + acls: + - operation: All + resource: + name: '*' + patternType: literal + type: topic + - operation: All + resource: + name: '*' + patternType: literal + type: cluster + - operation: All + resource: + name: '*' + patternType: literal + type: transactionalId + - operation: All + resource: + name: '*' + patternType: literal + type: group + type: simple +---- ++ +NOTE: This simple example assumes admin permissions and creates the Kafka topic automatically. You must configure the `authorization` section specifically for the topics and resources that the {registry} requires. ++ +The following example shows the minimum configuration required when the Kafka topic is created manually: ++ +[source,yaml] +---- + ... + authorization: + acls: + - operations: + - Read + - Write + resource: + name: kafkasql-journal + patternType: literal + type: topic + - operations: + - Read + - Write + resource: + name: apicurio-registry- + patternType: prefix + type: group + type: simple +---- + +. Click *Workloads* and then *Secrets* to find two secrets that {kafka-streams} creates for {registry} to connect to the Kafka cluster: ++ +* `my-cluster-cluster-ca-cert` - contains the PKCS12 truststore for the Kafka cluster +* `my-user` - contains the user's keystore ++ +NOTE: The name of the secret can vary based on your cluster or user name. + +. If you create the secrets manually, they must contain the following key-value pairs: ++ +* *my-cluster-ca-cert* +** `ca.p12` - the truststore in PKCS12 format +** `ca.password` - truststore password +* *my-user* +** `password` - user password + +. Configure the following example settings to deploy the {registry}: ++ +[source,yaml] +---- +include::example$apicurioregistry_kafkasql_scram_cr.yaml[] +---- + +IMPORTANT: You must use a different `bootstrapServers` address than in the plain insecure use case. The address must support TLS connections, and is found in the specified *Kafka* resource under the `type: tls` field. diff --git a/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-tls.adoc b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-tls.adoc new file mode 100644 index 0000000000..a093bd2a35 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-persistence-kafkasql-tls.adoc @@ -0,0 +1,174 @@ +[id="registry-persistence-kafkasql-tls"] += Configuring Kafka storage with TLS security + +You can configure the {kafka-streams} Operator and {operator} to use an encrypted Transport Layer Security (TLS) connection. + +.Prerequisites + +* You have installed the {operator} using the OperatorHub or command line. +* You have installed the {kafka-streams} Operator or have Kafka accessible from your OpenShift cluster. + +NOTE: This section assumes that the {kafka-streams} Operator is available, however you can use any Kafka deployment. +In that case, you must manually create the Openshift secrets that the {operator} expects. + +.Procedure + +. In the OpenShift web console, click *Installed Operators*, select the *{kafka-streams}* Operator details, and then the *Kafka* tab. + +. Click *Create Kafka* to provision a new Kafka cluster for {registry} storage. + +. Configure the `authorization` and `tls` fields to use TLS authentication for the Kafka cluster, for example: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta2 +kind: Kafka +metadata: + name: my-cluster + namespace: registry-example-kafkasql-tls + # Change or remove the explicit namespace +spec: + kafka: + config: + offsets.topic.replication.factor: 3 + transaction.state.log.replication.factor: 3 + transaction.state.log.min.isr: 2 + log.message.format.version: '2.7' + inter.broker.protocol.version: '2.7' + version: 2.7.0 + storage: + type: ephemeral + replicas: 3 + listeners: + - name: tls + port: 9093 + type: internal + tls: true + authentication: + type: tls + authorization: + type: simple + entityOperator: + topicOperator: {} + userOperator: {} + zookeeper: + storage: + type: ephemeral + replicas: 3 +---- ++ +The default Kafka topic name automatically created by {registry} to store data is `kafkasql-journal`. You can override this behavior or the default topic name by setting environment variables. The default values are as follows: + +** `REGISTRY_KAFKASQL_TOPIC_AUTO_CREATE=true` +** `REGISTRY_KAFKASQL_TOPIC=kafkasql-journal` + ++ +If you decide not to create the Kafka topic manually, skip the next step. + +. Click the *Kafka Topic* tab, and then *Create Kafka Topic* to create the `kafkasql-journal` topic: ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta1 +kind: KafkaTopic +metadata: + name: kafkasql-journal + labels: + strimzi.io/cluster: my-cluster + namespace: registry-example-kafkasql-tls +spec: + partitions: 2 + replicas: 1 + config: + cleanup.policy: compact +---- + +. Create a *Kafka User* resource to configure authentication and authorization for the {registry} user. You can specify a user name in the `metadata` section or use the default `my-user`. ++ +[source,yaml] +---- +apiVersion: kafka.strimzi.io/v1beta1 +kind: KafkaUser +metadata: + name: my-user + labels: + strimzi.io/cluster: my-cluster + namespace: registry-example-kafkasql-tls +spec: + authentication: + type: tls + authorization: + acls: + - operation: All + resource: + name: '*' + patternType: literal + type: topic + - operation: All + resource: + name: '*' + patternType: literal + type: cluster + - operation: All + resource: + name: '*' + patternType: literal + type: transactionalId + - operation: All + resource: + name: '*' + patternType: literal + type: group + type: simple +---- ++ +NOTE: This simple example assumes admin permissions and creates the Kafka topic automatically. You must configure the `authorization` section specifically for the topics and resources that the {registry} requires. ++ +The following example shows the minimum configuration required when the Kafka topic is created manually: ++ +[source,yaml] +---- + ... + authorization: + acls: + - operations: + - Read + - Write + resource: + name: kafkasql-journal + patternType: literal + type: topic + - operations: + - Read + - Write + resource: + name: apicurio-registry- + patternType: prefix + type: group + type: simple +---- + +. Click *Workloads* and then *Secrets* to find two secrets that {kafka-streams} creates for {registry} to connect to the Kafka cluster: ++ +* `my-cluster-cluster-ca-cert` - contains the PKCS12 truststore for the Kafka cluster +* `my-user` - contains the user's keystore ++ +NOTE: The name of the secret can vary based on your cluster or user name. + +. If you create the secrets manually, they must contain the following key-value pairs: ++ +* *my-cluster-ca-cert* +** `ca.p12` - truststore in PKCS12 format +** `ca.password` - truststore password +* *my-user* +** `user.p12` - keystore in PKCS12 format +** `user.password` - keystore password + +. Configure the following example configuration to deploy the {registry}. ++ +[source,yaml] +---- +include::example$apicurioregistry_kafkasql_tls_cr.yaml[] +---- + +IMPORTANT: You must use a different `bootstrapServers` address than in the plain insecure use case. The address must support TLS connections and is found in the specified *Kafka* resource under the `type: tls` field. diff --git a/operator/docs/modules/ROOT/partials/proc-persistence-mem.adoc b/operator/docs/modules/ROOT/partials/proc-persistence-mem.adoc new file mode 100644 index 0000000000..6bc8f19ad4 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-persistence-mem.adoc @@ -0,0 +1,27 @@ +[id="registry-persistence-mem"] += Configuring {registry} In-Memory storage using CLI + +The in-memory storage option uses RAM to store the data on nodes where {registry} is deployed, and it is the simplest persistence option to use. +The {operator} will deploy {registry} in this way if you do not provide any configuration in the `ApicurioRegistry` CR: + +[source,yaml] +---- +include::example$apicurioregistry_mem_cr.yaml[] +---- + +.Prerequisites +* You must have an Kubernetes cluster with cluster administrator access. +* You must have already installed the {operator}. + +.Procedure +. Deploy the example CR using following commands: ++ +[source,bash,subs="attributes"] +---- +export NAMESPACE="default" +curl -sSL "https://raw.githubusercontent.com/Apicurio/apicurio-registry-operator/{operator-version-latest-release-tag}/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml" | kubectl apply -f - -n $NAMESPACE +---- + +IMPORTANT: This persistence option does not support data distribution across {registry} nodes. +Therefore, it is only recommended for development environments using a single replica (`Pod`). +Use embedded Infinispan persistence option when deploying multiple replicas. diff --git a/operator/docs/modules/ROOT/partials/proc-persistence-sql.adoc b/operator/docs/modules/ROOT/partials/proc-persistence-sql.adoc new file mode 100644 index 0000000000..7d13e55ab0 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-persistence-sql.adoc @@ -0,0 +1,38 @@ +[id="registry-persistence-sql"] += Configuring SQL (PostgreSQL) storage + +.Prerequisites +* You must have an OpenShift cluster with cluster administrator access. +* You must have already installed {operator} +* You have a PostgreSQL database reachable from your OpenShift cluster. See xref:assembly-operator-installation.adoc[]. + +ifdef::service-registry[] +IMPORTANT: The PostgreSQL storage option is a https://access.redhat.com/support/offerings/techpreview[Technology Preview] feature and is currently not suitable for production environments. +endif::[] + +.Procedure +. In the OpenShift Container Platform web console, log in with cluster administrator privileges. + +. Change to the OpenShift project in which {registry} and your PostgreSQL Operator are installed. +For example, from the *Project* drop-down, select `my-project`. + +ifdef::apicurio-registry[] +. Click *Installed Operators* > *{registry}* > *ApicurioRegistry* > *Create ApicurioRegistry*. +endif::[] +ifdef::service-registry[] +. Click *Installed Operators* > *Red Hat Integration - {registry}* > *ApicurioRegistry* > *Create ApicurioRegistry*. +endif::[] + +. Paste in the following `ApicurioRegistry` CR, and edit the values for the database `url` and credentials to match your environment: ++ +[source,yaml] +---- +include::example$apicurioregistry_sql_cr.yaml[] +---- + +. Click *Create* and wait for the {registry} route to be created on OpenShift. + +. Click *Networking* > *Route* to access the new route for the {registry} web console. + +.Additional resources +* link:https://access.crunchydata.com/documentation/postgres-operator/4.5.0/quickstart/[Crunchy PostgreSQL Operator QuickStart] diff --git a/operator/docs/modules/ROOT/partials/proc-registry-https-in-cluster.adoc b/operator/docs/modules/ROOT/partials/proc-registry-https-in-cluster.adoc new file mode 100644 index 0000000000..5c58297cc0 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-https-in-cluster.adoc @@ -0,0 +1,85 @@ +[id="registry-https-in-cluster"] +// Do not forget to update link text in related xref(s). Antora does not support automatic name if the link has a fragment. += Configuring an HTTPS connection to {registry} from inside the OpenShift cluster + +The following procedure shows how to configure {registry} deployment to expose a port for HTTPS connections from inside the OpenShift cluster. + +WARNING: This kind of connection is not directly available outside of the cluster. +Routing is based on hostname, which is encoded in the case of an HTTPS connection. +Therefore, edge termination or other configuration is still needed. +See xref:registry-https-outside-cluster[]. + +.Prerequisites +* You must have already installed the {operator}. + +.Procedure +. Generate a `keystore` with a self-signed certificate. +You can skip this step if you are using your own certificates. ++ +[source,bash] +---- +openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout tls.key -out tls.crt +---- + +. Create a new secret to hold the certificate and the private key. +.. In the left navigation menu of the OpenShift web console, click *Workloads* > *Secrets* > *Create Key/Value Secret*. +.. Use the following values: + +Name: `https-cert-secret` + +Key 1: `tls.key` + +Value 1: _tls.key_ (uploaded file) + +Key 2: `tls.crt` + +Value 2: _tls.crt_ (uploaded file) + ++ +-- +or create the secret using the following command: + +[source,bash] +---- +oc create secret generic https-cert-secret --from-file=tls.key --from-file=tls.crt +---- +-- + +. Edit the `spec.configuration.security.https` section of the `ApicurioRegistry` CR for your {registry} deployment, for example: ++ +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry +spec: + configuration: + # ... + security: + https: + secretName: https-cert-secret +---- + +. Verify that the connection is working: +.. Connect into a pod on the cluster using SSH (you can use the {registry} pod): ++ +[source,bash] +---- +oc rsh example-apicurioregistry-deployment-6f788db977-2wzpw +---- + +.. Find the cluster IP of the {registry} pod from the *Service* resource (see the *Location* column in the web console). +Afterwards, execute a test request (we are using self-signed certificate, so an insecure flag is required): ++ +[source,bash] +---- +curl -k https://172.30.230.78:8443/health +---- + +NOTE: In the Kubernetes secret containing the HTTPS certificate and key, the names `tls.crt` and `tls.key` must be used for the provided values. +This is currently not configurable. + +.Disabling HTTP +If you enabled HTTPS using the procedure in this section, you can also disable the default HTTP connection by setting the `spec.security.https.disableHttp` to `true`. This removes the HTTP port 8080 from the {registry} pod container, `Service`, and the `NetworkPolicy` (if present). + +Importantly, `Ingress` is also removed because the {operator} currently does not support configuring HTTPS in `Ingress`. +Users must create an `Ingress` for HTTPS connections manually. + +.Additional resources +* link:https://developers.redhat.com/blog/2021/01/06/how-to-enable-https-and-ssl-termination-in-a-quarkus-app[How to enable HTTPS and SSL termination in a Quarkus app] diff --git a/operator/docs/modules/ROOT/partials/proc-registry-https-outside-cluster.adoc b/operator/docs/modules/ROOT/partials/proc-registry-https-outside-cluster.adoc new file mode 100644 index 0000000000..6a4cc4e06e --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-https-outside-cluster.adoc @@ -0,0 +1,56 @@ +[id="registry-https-outside-cluster"] += Configuring an HTTPS connection to {registry} from outside the OpenShift cluster + +The following procedure shows how to configure {registry} deployment to expose an HTTPS edge-terminated route for connections from outside the OpenShift cluster. + +.Prerequisites +* You must have already installed the {operator}. +* Read the https://docs.openshift.com/container-platform/latest/networking/routes/secured-routes.html[OpenShift documentation for creating secured routes]. + +.Procedure +. Add a second *Route* in addition to the HTTP route created by the {operator}. For example: ++ +[source,yaml] +---- +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + [...] + labels: + app: example-apicurioregistry + [...] +spec: + host: example-apicurioregistry-default.apps.example.com + to: + kind: Service + name: example-apicurioregistry-service-9whd7 + weight: 100 + port: + targetPort: 8080 + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + wildcardPolicy: None +---- ++ +NOTE: Make sure the `insecureEdgeTerminationPolicy: Redirect` configuration property is set. ++ +If you do not specify a certificate, OpenShift will use a default. Alternatively, you can generate a custom self-signed certificate using the following commands: ++ +[source,bash] +---- +openssl genrsa 2048 > tls.key && +openssl req -new -x509 -nodes -sha256 -days 365 -key tls.key -out tls.crt +---- ++ +Then create a route using the OpenShift CLI: ++ +[source,bash] +---- +oc create route edge \ + --service=example-apicurioregistry-service-9whd7 \ + --cert=tls.crt --key=tls.key \ + --hostname=example-apicurioregistry-default.apps.example.com \ + --insecure-policy=Redirect \ + -n default +---- diff --git a/operator/docs/modules/ROOT/partials/proc-registry-operator-distribution-bundle-ar.adoc b/operator/docs/modules/ROOT/partials/proc-registry-operator-distribution-bundle-ar.adoc new file mode 100644 index 0000000000..f38b1bc06a --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-operator-distribution-bundle-ar.adoc @@ -0,0 +1,8 @@ +[id="registry-operator-distribution-bundle"] += {operator} distribution bundle + +Since version `1.0.0`, the {operator} project is distributed with an additional archive file containing installation files for the Operator, with example `ApicurioRegistry` custom resource files. In addition, full {operator} documentation and license information are included. + +Docker images for the Operator and the Operand are distributed using a public registry. + +For released versions, you can find the distribution on the https://github.com/Apicurio/apicurio-registry-operator/tags[{operator} releases page]. For information about how to build the bundle for development versions, see the https://github.com/Apicurio/apicurio-registry-operator/[{operator} GitHub repository]. diff --git a/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-ar.adoc b/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-ar.adoc new file mode 100644 index 0000000000..f125f77eea --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-ar.adoc @@ -0,0 +1,26 @@ +[id="registry-operator-quickstart"] += {operator} quickstart + +You can quickly deploy the {operator} on the command line, without the Operator Lifecycle Manager, by executing a single command. + +ifdef::apicurio-registry-operator-dev[] +NOTE: This procedure deploys the latest {operator} development version. To deploy a version that has already been released, see install files in https://github.com/Apicurio/apicurio-registry-operator/tree/main/install[{operator} GitHub repository]. +endif::[] + +.Procedure +. Choose the `$NAMESPACE` to use: ++ +[source,bash] +---- +export NAMESPACE="default" +---- + +. Get the installation file and apply it to your cluster: ++ +[source,bash,subs="attributes"] +---- +curl -sSL "https://raw.githubusercontent.com/Apicurio/apicurio-registry-operator/{operator-version-latest-release-tag}/install/install.yaml" | +sed "s/apicurio-registry-operator-namespace/$NAMESPACE/g" | kubectl apply -f - -n $NAMESPACE +---- ++ +NOTE: To deploy an older release of {operator}, follow the documentation for that version. If you are deploying on OpenShift, use the `oc` command with the same arguments. diff --git a/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-sr.adoc b/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-sr.adoc new file mode 100644 index 0000000000..cb0a000177 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-operator-quickstart-sr.adoc @@ -0,0 +1,38 @@ +[id="registry-operator-quickstart"] += Quickstart {operator} installation + +You can quickly install and deploy the {operator} on the command line, without the Operator Lifecycle Manager, by using a downloaded set of installation files and example CRDs. + +.Prerequisites + +* You are logged in to an OpenShift cluster with administrator access. +* You have the OpenShift `oc` command-line client installed. For more details, see the {LinkOCPCLIDocs}[{NameOCPCLIDocs}]. + +.Procedure + +. Browse to link:{LinkRedHatIntegrationDownloads}[{NameRedHatIntegrationDownloads}], select the product version, and download the examples in the {registry} CRDs `.zip` file. + +. Extract the downloaded CRDs `.zip` file and change to the `apicurio-registry-install-examples` directory. + +. Create an OpenShift project for the {operator} installation, for example: ++ +[source,bash] +---- +export NAMESPACE="apicurio-registry" +oc new-project "$NAMESPACE" +---- + +. Enter the following command to apply the example CRD in the `install/install.yaml` file: ++ +[source,bash] +---- +cat install/install.yaml | sed "s/apicurio-registry-operator-namespace/$NAMESPACE/g" | oc apply -f - +---- + +. Enter `oc get deployment` to check the readiness of the {operator}. For example, the output should be as follows: ++ +[source,bash] +---- +NAME READY UP-TO-DATE AVAILABLE AGE +apicurio-registry-operator 1/1 1 1 XmYs +---- \ No newline at end of file diff --git a/operator/docs/modules/ROOT/partials/proc-registry-quickstart-ar.adoc b/operator/docs/modules/ROOT/partials/proc-registry-quickstart-ar.adoc new file mode 100644 index 0000000000..9bd44185be --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-quickstart-ar.adoc @@ -0,0 +1,35 @@ +[id="registry-quickstart"] += Quickstart {registry} instance deployment + +To quickly create a new {registry} instance deployment, use the in-memory storage option, +which does not require an external storage to be configured as a prerequisite. + +ifdef::apicurio-registry-operator-dev[] +NOTE: This procedure deploys the latest {operator} development version. To deploy a version that has already been released, see install files in https://github.com/Apicurio/apicurio-registry-operator/tree/main/install[{operator} GitHub repository]. +endif::[] + +.Prerequisites +* Ensure that the {operator} is already installed. + +.Procedure +. Use a `$NAMESPACE` where the {operator} is deployed: ++ +[source,bash] +---- +export NAMESPACE="default" +---- + +. Create an `ApicurioRegistry` custom resource (CR): ++ +[source,bash,subs="attributes"] +---- +kubectl apply -f https://raw.githubusercontent.com/Apicurio/apicurio-registry-operator/{operator-version-latest-release-tag}/docs/modules/ROOT/examples/apicurioregistry_mem_cr.yaml -n $NAMESPACE +---- ++ +.Example CR for in-memory storage +[source,yaml] +---- +include::example$apicurioregistry_mem_cr.yaml[] +---- ++ +NOTE: To deploy an older release of {operator}, follow the documentation for that version. If you are deploying to OpenShift, use the `oc` command with the same arguments. diff --git a/operator/docs/modules/ROOT/partials/proc-registry-quickstart-sr.adoc b/operator/docs/modules/ROOT/partials/proc-registry-quickstart-sr.adoc new file mode 100644 index 0000000000..ec779c4e3f --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-quickstart-sr.adoc @@ -0,0 +1,55 @@ +[id="registry-quickstart"] += Quickstart {registry} instance deployment + +To create your {registry} instance deployment, use the SQL database storage option to connect to an existing PostgreSQL database. + +.Prerequisites +* Ensure that the {operator} is installed. +* You have a PostgreSQL database that is reachable from your OpenShift cluster. + +.Procedure +. Open the `examples/apicurioregistry_sql_cr.yaml` file in an editor and view the `ApicurioRegistry` custom resource (CR): ++ +.Example CR for SQL storage +[source,yaml] +---- +include::example$/apicurioregistry_sql_cr.yaml[] +---- + +. In the `dataSource` section, replace the example settings with your database connection details. For example: ++ +[source,yaml] +---- +dataSource: + url: "jdbc:postgresql://postgresql.apicurio-registry.svc:5432/registry" + userName: "pgadmin" + password: "pgpass" +---- + +. Enter the following commands to apply the updated `ApicurioRegistry` CR in the namespace with the {registry} Operator, and wait for the {registry} instance to deploy: ++ +[source,bash] +---- +oc project "$NAMESPACE" +oc apply -f ./examples/apicurioregistry_sql_cr.yaml +---- + +. Enter `oc get deployment` to check the readiness of the {registry} instance. For example, the output should be as follows: ++ +[source,bash] +---- +NAME READY UP-TO-DATE AVAILABLE AGE +example-apicurioregistry-sql-deployment 1/1 1 1 XmYs +---- + +. Enter `oc get routes` to get the `HOST/PORT` URL to launch the {registry} web console in your browser. For example: ++ +[source,bash] +---- +example-apicurioregistry-sql.apicurio-registry.router-default.apps.mycluster.myorg.mycompany.com +---- + +ifdef::apicurio-registry[] +.Additional resources +* xref:assembly-registry-storage.adoc[] +endif::[] \ No newline at end of file diff --git a/operator/docs/modules/ROOT/partials/proc-registry-security-keycloak.adoc b/operator/docs/modules/ROOT/partials/proc-registry-security-keycloak.adoc new file mode 100644 index 0000000000..2124d65bd5 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-security-keycloak.adoc @@ -0,0 +1,104 @@ +[id="registry-security-keycloak"] += Securing {registry} using the {keycloak} Operator + +The following procedure shows how to configure a {registry} REST API and web console to be protected by {keycloak}. + +{registry} supports the following user roles: + +.{registry} user roles +[%header,cols=2*] +|=== +| Name | Capabilities + +| `sr-admin` +| Full access, no restrictions. + +| `sr-developer` +| Create artifacts and configure artifact rules. Cannot modify global rules, perform import/export, or use `/admin` REST API endpoint. + +| `sr-readonly` +| View and search only. Cannot modify artifacts or rules, perform import/export, or use `/admin` REST API endpoint. +|=== + +NOTE: There is a related configuration option in the `ApicurioRegistry` CRD that you can use to set the web console to read-only mode. However, this configuration does not affect the REST API. + +.Prerequisites +* You must have already installed the {operator}. +* You must install the {keycloak} Operator or have {keycloak} accessible from your OpenShift cluster. + +IMPORTANT: The example configuration in this procedure is intended for development and testing only. To keep the procedure simple, it does not use HTTPS and other defenses recommended for a production environment. For more details, see the {keycloak} documentation. + +ifdef::apicurio-registry[] + +.Procedure +. In the OpenShift web console, click *Installed Operators* and *{keycloak} Operator*, and then the *Keycloak* tab. + +. To create the {keycloak} instance, see the https://www.keycloak.org/operator/basic-deployment[Keycloak documentation on how to create a basic deployment]. + +. When your {keycloak} instance is available, you can import the following example realm by using the steps in the https://www.keycloak.org/operator/realm-import[Keycloak Operator documentation]: + ++ +[source,yaml] +---- +include::example$/keycloak/keycloak_realm_import.yaml[] +---- ++ +IMPORTANT: You must customize this `KeycloakRealmImport` resource with values suitable for your environment if you are deploying to production. You can also create and manage realms using the {keycloak} web console. +endif::[] +ifdef::service-registry[] + +.Procedure +. In the OpenShift web console, click *Installed Operators* and *{keycloak} Operator*, and then the *Keycloak* tab. + +. Click *Create Keycloak* to provision a new {keycloak} instance for securing a {registry} deployment. You can use the default value, for example: ++ +[source,yaml] +---- +include::example$/keycloak/keycloak.yaml[] +---- + +. Wait until the instance has been created, and click *Networking* and then *Routes* to access the new route for the *keycloak* instance. + +. Click the *Location* URL and copy the displayed URL value for later use when deploying {registry}. + +. Click *Installed Operators* and *{keycloak} Operator*, and click the *Keycloak Realm* tab, and then *Create Keycloak Realm* to create a `registry` example realm: ++ +[source,yaml] +---- +include::example$/keycloak/keycloak_realm.yaml[] +---- ++ +IMPORTANT: You must customize this `KeycloakRealm` resource with values suitable for your environment if you are deploying to production. You can also create and manage realms using the {keycloak} web console. +endif::[] + +. If your cluster does not have a valid HTTPS certificate configured, you can create the following HTTP `Service` and `Ingress` resources as a temporary workaround: + +.. Click *Networking* and then *Services*, and click *Create Service* using the following example: ++ +[source,yaml] +---- +include::example$/keycloak/keycloak_http_service.yaml[] +---- +.. Click *Networking* and then *Ingresses*, and click *Create Ingress* using the following example:: ++ +---- +include::example$/keycloak/keycloak_http_ingress.yaml[] +---- ++ +Modify the `host` value to create a route accessible for the {registry} user, and use it instead of the HTTPS route created by {keycloak} Operator. + +. Click the *{operator}*, and on the *ApicurioRegistry* tab, click *Create ApicurioRegistry*, using the following example, but replace your values in the `keycloak` section. +ifdef::apicurio-registry[] ++ +[source,yaml] +---- +include::example$/keycloak/apicurioregistry_mem_keycloak_cr.yaml[] +---- +endif::[] +ifdef::service-registry[] ++ +[source,yaml] +---- +include::example$/keycloak/apicurioregistry_kafkasql_keycloak_cr.yaml[] +---- +endif::[] diff --git a/operator/docs/modules/ROOT/partials/proc-registry-sql-backup.adoc b/operator/docs/modules/ROOT/partials/proc-registry-sql-backup.adoc new file mode 100644 index 0000000000..1c29e3b0fb --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-sql-backup.adoc @@ -0,0 +1,37 @@ +[id=registry-sql-backup] += Backing up {registry} PostgreSQL storage + +When using storage in a PostgreSQL database, you must ensure that the data stored by {registry} is backed up regularly. + +https://www.postgresql.org/docs/12/backup-dump.html[SQL Dump] is a simple procedure that works with any PostgreSQL installation. +This uses the https://www.postgresql.org/docs/12/app-pgdump.html[pg_dump] utility to generate a file with SQL commands that you can use to recreate the database in the same state that it was in at the time of the dump. + +`pg_dump` is a regular PostgreSQL client application, which you can execute from any remote host that has access to the database. +Like any other client, the operations that can perform are limited to the user permissions. + +.Procedure +* Use the `pg_dump` command to redirect the output to a file: ++ +[source,bash] +---- + $ pg_dump dbname > dumpfile +---- ++ +You can specify the database server that `pg_dump` connects to using the `-h host` and `-p port` options. + +* You can reduce large dump files using a compression tool, such as gzip, for example: ++ +[source,bash] +---- + $ pg_dump dbname | gzip > filename.gz +---- + +.Additional resources +* For details on client authentication, see the https://www.postgresql.org/docs/12/client-authentication.html[PostgreSQL documentation]. + +ifdef::apicurio-registry[] +* For details on importing and exporting registry content, see https://www.apicur.io/registry/docs/apicurio-registry/2.0.0.Final/getting-started/assembly-managing-registry-artifacts-api.html[Managing Apicurio Registry content using the REST API]. +endif::[] +ifdef::service-registry[] +* For details on importing and exporting registry content, see link:{LinkManagingContentUsingRESTAPI}[{NameManagingContentUsingRESTAPI}]. +endif::[] diff --git a/operator/docs/modules/ROOT/partials/proc-registry-sql-restore.adoc b/operator/docs/modules/ROOT/partials/proc-registry-sql-restore.adoc new file mode 100644 index 0000000000..96f172b008 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-registry-sql-restore.adoc @@ -0,0 +1,25 @@ +[id="registry-sql-restore"] += Restoring {registry} PostgreSQL storage + +You can restore SQL Dump files created by `pg_dump` using the `psql` utility. + +.Prerequisites +* You must have already backed up your PostgreSQL datbase using `pg_dump`. See xref:registry-sql-backup[]. +* All users who own objects or have permissions on objects in the dumped database must already exist. + +.Procedure +. Enter the following command to create the database: ++ +[source,bash] +---- + $ createdb -T template0 dbname +---- + +. Enter the following command to restore the SQL dump ++ +[source,bash] +---- + $ psql dbname < dumpfile +---- + +. Run https://www.postgresql.org/docs/12/sql-analyze.html[ANALYZE] on each database so the query optimizer has useful statistics. diff --git a/operator/docs/modules/ROOT/partials/ref-get-help.adoc b/operator/docs/modules/ROOT/partials/ref-get-help.adoc new file mode 100644 index 0000000000..beeddde1de --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-get-help.adoc @@ -0,0 +1,12 @@ +[id="getting-registry-operator-help"] += Getting help with {operator} + +See the link:https://github.com/Apicurio/apicurio-registry[Apicurio Registry] and https://github.com/Apicurio/apicurio-registry-operator[Apicurio Registry Operator] projects on GitHub. +Any contributions, suggestions, and issue reports are welcome. + +ifdef::apicurio-registry[] +link:https://github.com/Apicurio/apicurio-registry-operator/issues/new[Create an issue] on GitHub if you find any problems. + +//Add back when these pages exist +//You can find more help and information about the project in the Troubleshooting and About pages. +endif::[] diff --git a/operator/docs/modules/ROOT/partials/ref-liveness-and-readiness.adoc b/operator/docs/modules/ROOT/partials/ref-liveness-and-readiness.adoc new file mode 100644 index 0000000000..a7ffa4f550 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-liveness-and-readiness.adoc @@ -0,0 +1,55 @@ +[id="registry-liveness-and-readiness"] += {registry} liveness and readiness environment variables + +{registry} provides readiness and liveness probes for OpenShift to ensure application health. These settings are configured to use reasonable defaults, but if you want to adjust them, this section provides details on the environment variables that you can configure. + +OpenShift liveness and readiness errors are explained as follows: + +* *Liveness error* - the application cannot make progress, OpenShift restarts the failing pod. +* *Readiness error* - the application is not ready, for example, it is overwhelmed by requests. OpenShift stops sending requests to the pod for the time the probe fails. If other pods are OK, they still receive requests. + + +.{registry} liveness environment variables +[%header,cols="2,1,3"] +|=== +| Name | Value type | Description + +| `LIVENESS_ERROR_THRESHOLD` +| Positive integer +| Number of liveness errors that can occur before the liveness probe fails. + +| `LIVENESS_COUNTER_RESET` +| Positive integer, seconds +| Period in which the _threshold_ number of errors must occur. For example, if this value is `60` and the threshold is `1`, the check fails after two errors occur in 1 minute. + +| `LIVENESS_STATUS_RESET` +| Positive integer, seconds +| Number of seconds that must elapse without any more errors for the liveness probe to reset to _OK_ status. Because OpenShift restarts the pod that fails the liveness check, this value, unlike readiness, does not actually affect what happens. + +| `LIVENESS_ERRORS_IGNORED` +| Comma-separated list of fully qualified exception class names. +| List of errors that are ignored for liveness checking purposes. +|=== + + +.{registry} readiness environment variables +[%header,cols="2,1,3"] +|=== +| Name | Value type | Description + +| `READINESS_ERROR_THRESHOLD` +| Positive integer +| Number of readiness errors that can occur before the readiness probe fails. + +| `READINESS_COUNTER_RESET` +| Positive integer, seconds +| Period in which the threshold number of errors must occur. For example, if this value is 60 and the threshold is 1, the check fails after two errors occur in 1 minute. + +| `READINESS_STATUS_RESET` +| Positive integer, seconds +| Number of seconds that must elapse without any more errors for the readiness probe to reset to OK status. In practice, this value means how long the pod remains in an unready state until it returns to normal operation. + +| `READINESS_TIMEOUT` +| positive integer, seconds +| The readiness system tracks the timeout of two operations: how long it takes for a storage request to complete, and how long it takes for an HTTP REST API request to return a response. If the operation takes more time, it is counted as a readiness error. This value controls those timeouts. +|=== diff --git a/operator/docs/modules/ROOT/partials/ref-registry-cr-spec.adoc b/operator/docs/modules/ROOT/partials/ref-registry-cr-spec.adoc new file mode 100644 index 0000000000..556804797c --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-cr-spec.adoc @@ -0,0 +1,363 @@ +[#spec] += {registry} CR spec + +The `spec` is the part of the `ApicurioRegistry` CR that is used to provide the desired state or configuration for the Operator to achieve. + +.ApicurioRegistry CR spec contents +The following example block contains the full tree of possible `spec` configuration options. +Some fields might not be required or should not be defined at the same time. + +ifdef::apicurio-registry[] +[source,yaml] +---- +spec: + configuration: + persistence: + sql: + dataSource: + url: + userName: + password: + kafkasql: + bootstrapServers: + security: + tls: + truststoreSecretName: + keystoreSecretName: + scram: + mechanism: + truststoreSecretName: + user: + passwordSecretName: + ui: + readOnly: + logLevel: + registryLogLevel: + security: + keycloak: + url: + realm: + apiClientId: + uiClientId: + https: + disableHttp: + secretName: + env: + deployment: + replicas: + host: + affinity: + tolerations: + imagePullSecrets: + metadata: + annotations: + labels: + image: + managedResources: + disableIngress: + disableNetworkPolicy: + disablePodDisruptionBudget: + podTemplateSpecPreview: +---- +endif::[] + +ifdef::service-registry[] +// Currently, the only difference is the absence of the `image` field. +// We want to control which image is being used in the product, and +// `ifdef` can't be used in source blocks. +[source,yaml] +---- +spec: + configuration: + persistence: + sql: + dataSource: + url: + userName: + password: + kafkasql: + bootstrapServers: + security: + tls: + truststoreSecretName: + keystoreSecretName: + scram: + mechanism: + truststoreSecretName: + user: + passwordSecretName: + ui: + readOnly: + logLevel: + registryLogLevel: + security: + keycloak: + url: + realm: + apiClientId: + uiClientId: + https: + disableHttp: + secretName: + env: + deployment: + replicas: + host: + affinity: + tolerations: + imagePullSecrets: + metadata: + annotations: + labels: + managedResources: + disableIngress: + disableNetworkPolicy: + disablePodDisruptionBudget: + podTemplateSpecPreview: +---- +endif::[] + +The following table describes each configuration option: + +.ApicurioRegistry CR spec configuration options +[%header,cols="4,2,2,3"] +|=== +| Configuration option | type | Default value | Description + +| `configuration` +| - +| - +| Section for configuration of {registry} application + +| `configuration/persistence` +| string +ifdef::service-registry[] +| _required_ +| Storage backend. One of `sql`, `kafkasql` +endif::[] +ifdef::apicurio-registry[] +| `mem` +| Storage backend. One of `mem`, `sql`, `kafkasql` +endif::[] + +| `configuration/sql` +| - +| - +| SQL storage backend configuration + +| `configuration/sql/dataSource` +| - +| - +| Database connection configuration for SQL storage backend + +| `configuration/sql/dataSource/url` +| string +| _required_ +| Database connection URL string + +| `configuration/sql/dataSource/userName` +| string +| _required_ +| Database connection user + +| `configuration/sql/dataSource/password` +| string +| _empty_ +| Database connection password + +| `configuration/kafkasql` +| - +| - +| Kafka storage backend configuration + +| `configuration/kafkasql/bootstrapServers` +| string +| _required_ +| Kafka bootstrap server URL, for Streams storage backend + +| `configuration/kafkasql/security/tls` +| - +| - +| Section to configure TLS authentication for Kafka storage backend + +| `configuration/kafkasql/security/tls/truststoreSecretName` +| string +| _required_ +| Name of a secret containing TLS truststore for Kafka + +| `configuration/kafkasql/security/tls/keystoreSecretName` +| string +| _required_ +| Name of a secret containing user TLS keystore + +| `configuration/kafkasql/security/scram/truststoreSecretName` +| string +| _required_ +| Name of a secret containing TLS truststore for Kafka + +| `configuration/kafkasql/security/scram/user` +| string +| _required_ +| SCRAM user name + +| `configuration/kafkasql/security/scram/passwordSecretName` +| string +| _required_ +| Name of a secret containing SCRAM user password + +| `configuration/kafkasql/security/scram/mechanism` +| string +| `SCRAM-SHA-512` +| SASL mechanism + +| `configuration/ui` +| - +| - +| {registry} web console settings + +| `configuration/ui/readOnly` +| string +| `false` +| Set {registry} web console to read-only mode + +| `configuration/logLevel` +| string +| `INFO` +| {registry} log level, for non-Apicurio components and libraries. One of `INFO`, `DEBUG` + +| `configuration/registryLogLevel` +| string +| `INFO` +| {registry} log level, for Apicurio application components (excludes non-Apicurio components and libraries). One of `INFO`, `DEBUG` + +| `configuration/security` +| - +| - +| {registry} web console and REST API security settings + +| `configuration/security/keycloak` +| - +| - +| Web console and REST API security configuration using {Keycloak} + +| `configuration/security/keycloak/url` +| string +| _required_ +| {keycloak} URL + +| `configuration/security/keycloak/realm` +| string +| _required_ +| {keycloak} realm + +| `configuration/security/keycloak/apiClientId` +| string +| `registry-client-api` +| {keycloak} client for REST API + +| `configuration/security/keycloak/uiClientId` +| string +| `registry-client-ui` +| {keycloak} client for web console + +| `configuration/security/https` +| - +| - +| Configuration for HTTPS. For more details, see xref:ROOT:assembly-registry-maintenance.adoc#registry-https-in-cluster[Configuring an HTTPS connection to {registry} from inside the OpenShift cluster]. + +| `configuration/security/https/sercretName` +| string +| _empty_ +| Name of a Kubernetes Secret that contains the HTTPS certificate and key, which must be named `tls.crt` and `tls.key`, respectively. Setting this field enables HTTPS, and vice versa. + +| `configuration/security/https/disableHttp` +| bool +| `false` +| Disable HTTP port and Ingress. HTTPS must be enabled as a prerequisite. + +| `configuration/env` +| k8s.io/api/core/v1 []EnvVar +| _empty_ +| Configure a list of environment variables to be provided to the {registry} pod. For more details, see xref:ROOT:assembly-registry-maintenance.adoc#manage-registry-environment-variables[Managing {registry} environment variables]. + +| `deployment` +| - +| - +| Section for {registry} deployment settings + +| `deployment/replicas` +| positive integer +| `1` +| Number of {registry} pods to deploy + +| `deployment/host` +| string +| _auto-generated_ +| Host/URL where the {registry} console and API are available. If possible, {operator} attempts to determine the correct value based on the settings of your cluster router. The value is auto-generated only once, so user can override it afterwards. + +| `deployment/affinity` +| k8s.io/api/core/v1 Affinity +| _empty_ +| {registry} deployment affinity configuration + +| `deployment/tolerations` +| k8s.io/api/core/v1 []Toleration +| _empty_ +| {registry} deployment tolerations configuration + +| `deployment/imagePullSecrets` +| k8s.io/api/core/v1 []LocalObjectReference +| _empty_ +| Configure image pull secrets for {registry} deployment + +| `deployment/metadata` +| - +| - +| Configure a set of labels or annotations for the {registry} pod. + +| `deployment/metadata/labels` +| map[string]string +| _empty_ +| Configure a set of labels for {registry} pod + +| `deployment/metadata/annotations` +| map[string]string +| _empty_ +| Configure a set of annotations for {registry} pod + +ifdef::apicurio-registry[] +| `deployment/image` +| string +| _empty_ +| Override the default image being used to deploy {registry} +endif::[] + +// TODO vvv +| `deployment/managedResources` +| - +| - +| Section to configure how the {operator} manages Kubernetes resources. For more details, see xref:ROOT:assembly-operator-configuration.adoc#managed-resources[{registry} managed resources]. + +| `deployment/managedResources/disableIngress` +| bool +| `false` +| If set, the operator will not create and manage an `Ingress` resource for {registry} deployment. + +| `deployment/managedResources/disableNetworkPolicy` +| bool +| `false` +| If set, the operator will not create and manage a `NetworkPolicy` resource for {registry} deployment. + +| `deployment/managedResources/disablePodDisruptionBudget` +| bool +| `false` +| If set, the operator will not create and manage an `PodDisruptionBudget` resource for {registry} deployment. + +| `deployment/podTemplateSpecPreview` +| k8s.io/api/core/v1 PodTemplateSpec +| _empty_ +| Configure parts of the {registry} deployment resource. For more details, see xref:ROOT:assembly-registry-maintenance.adoc#pod-spec[Configuring {registry} deployment using PodTemplate]. +|=== + +NOTE: If an option is marked as _required_, it might be conditional on other configuration options being enabled. +Empty values might be accepted, but the Operator does not perform the specified action. diff --git a/operator/docs/modules/ROOT/partials/ref-registry-cr-status.adoc b/operator/docs/modules/ROOT/partials/ref-registry-cr-status.adoc new file mode 100644 index 0000000000..959c1521fa --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-cr-status.adoc @@ -0,0 +1,77 @@ +[#status] += {registry} CR status + +The `status` is the section of the CR managed by the {operator} that contains a description of the current deployment and application state. + +.ApicurioRegistry CR status contents +The `status` section contains the following fields: +[source,yaml] +---- +status: + info: + host: + conditions: + - type: + status: + reason: + message: + lastTransitionTime: + managedResources: + - kind: + namespace: + name: +---- + +.ApicurioRegistry CR status fields +[%header,cols="2,1,3"] +|=== +| Status field | Type | Description + +| `info` +| - +| Section with information about the deployed {registry}. + +| `info/host` +| string +| URL where the {registry} UI and REST API are accessible. + +| `conditions` +| - +| List of conditions that report the status of the {registry}, or the Operator with respect to that deployment. + +| `conditions/type` +| string +| Type of the condition. + +| `conditions/status` +| string +| Status of the condition, one of `True`, `False`, `Unknown`. + +| `conditions/reason` +| string +| A programmatic identifier indicating the reason for the condition's last transition. + +| `conditions/message` +| string +| A human-readable message indicating details about the transition. + +| `conditions/lastTransitionTime` +| string +| The last time the condition transitioned from one status to another. + +| `managedResources` +| - +| List of {platform} resources managed by {operator} + +| `managedResources/kind` +| string +| Resource kind. + +| `managedResources/namespace` +| string +| Resource namespace. + +| `managedResources/name` +| string +| Resource name. +|=== diff --git a/operator/docs/modules/ROOT/partials/ref-registry-cr.adoc b/operator/docs/modules/ROOT/partials/ref-registry-cr.adoc new file mode 100644 index 0000000000..94273944a8 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-cr.adoc @@ -0,0 +1,59 @@ +[id="apicurio-registry-custom-resource"] += {registry} Custom Resource + +The {operator} defines an `ApicurioRegistry` link:https://docs.openshift.com/container-platform/latest/operators/understanding/crds/crd-extending-api-with-crds.html[custom resource (CR)] that represents a single deployment of {registry} on OpenShift. + +These resource objects are created and maintained by users to instruct the {operator} how to deploy and configure {registry}. + +.Example ApicurioRegistry CR +The following command displays the `ApicurioRegistry` resource: + +[source,bash,subs="attributes"] +---- +{cli-client} get apicurioregistry +{cli-client} edit apicurioregistry example-apicurioregistry +---- + +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry + namespace: demo-kafka + # ... +spec: + configuration: + persistence: kafkasql + kafkasql: + bootstrapServers: 'my-cluster-kafka-bootstrap.demo-kafka.svc:9092' + deployment: + host: >- + example-apicurioregistry.demo-kafka.example.com +status: + conditions: + - lastTransitionTime: "2021-05-03T10:47:11Z" + message: "" + reason: Reconciled + status: "True" + type: Ready + info: + host: example-apicurioregistry.demo-kafka.example.com + managedResources: + - kind: Deployment + name: example-apicurioregistry-deployment + namespace: demo-kafka + - kind: Service + name: example-apicurioregistry-service + namespace: demo-kafka + - kind: Ingress + name: example-apicurioregistry-ingress + namespace: demo-kafka +---- + +IMPORTANT: By default, the {operator} watches its own project namespace only. +Therefore, you must create the `ApicurioRegistry` CR in the same namespace, if you are deploying the Operator manually. +You can modify this behavior by updating `WATCH_NAMESPACE` environment variable in the Operator `Deployment` resource. + +.Additional resources +* link:https://docs.openshift.com/container-platform/4.6/operators/understanding/crds/crd-extending-api-with-crds.html[Extending the Kubernetes API with Custom Resource Definitions] diff --git a/operator/docs/modules/ROOT/partials/ref-registry-labels.adoc b/operator/docs/modules/ROOT/partials/ref-registry-labels.adoc new file mode 100644 index 0000000000..5b3a100ef9 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-labels.adoc @@ -0,0 +1,55 @@ +[id="registry-labels"] +// Do not forget to update link text in related xref(s). Antora does not support automatic name if the link has a fragment. + += {operator} labels + +Resources managed by the {operator} are usually labeled as follows: + +.{operator} labels for managed resources +[%header,cols="1,2"] +|=== +| Label | Description + +| `app` +| Name of the {registry} deployment that the resource belongs to, based on the name of the specified `ApicurioRegistry` CR. + +| `apicur.io/type` +| Type of the deployment: `apicurio-registry` or `operator` + +| `apicur.io/name` +| Name of the deployment: same value as `app` or `apicurio-registry-operator` + +| `apicur.io/version` +| Version of the {registry} or the {operator} + +| `app.kubernetes.io/{star}` +| A set of recommended Kubernetes labels for application deployments. + +ifdef::service-registry[] +| `com.company` and `rht.{star}`` +| Metering labels for Red Hat products. +endif::[] +|=== + +.Custom labels and annotations +You can provide custom labels and annotation for the {registry} pod, using the `spec.deployment.metadata.labels` and `spec.deployment.metadata.annotations` fields, for example: + +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry +spec: + configuration: + # ... + deployment: + metadata: + labels: + example.com/environment: staging + annotations: + example.com/owner: my-team +---- + +.Additional resources +* https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/[Recommended Kubernetes labels for application deployments] diff --git a/operator/docs/modules/ROOT/partials/ref-registry-managed-resources.adoc b/operator/docs/modules/ROOT/partials/ref-registry-managed-resources.adoc new file mode 100644 index 0000000000..6f360b2b7c --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-managed-resources.adoc @@ -0,0 +1,49 @@ +[id="managed-resources"] +// Do not forget to update link text in related xref(s). Antora does not support automatic name if the link has a fragment. += {registry} managed resources + +The resources managed by the {operator} when deploying {registry} are as follows: + +* `Deployment` +ifdef::apicurio-registry[] +* `Ingress` +endif::[] +ifdef::service-registry[] +* `Ingress` (and `Route`) +endif::[] +* `NetworkPolicy` +* `PodDisruptionBudget` +* `Service` + +You can disable the {operator} from creating and managing some resources, so they can be configured manually. +This provides greater flexibility when using features that the {operator} does not currently support. + +If you disable a resource type, its existing instance is deleted. +If you enable a resource, the {operator} attempts to find a resource using the `app` label, for example, `app=example-apicurioregistry`, and starts managing it. Otherwise, the Operator creates a new instance. + +You can disable the following resource types in this way: + +ifdef::apicurio-registry[] +* `Ingress` +endif::[] +ifdef::service-registry[] +* `Ingress` (and `Route`) +endif::[] +* `NetworkPolicy` +* `PodDisruptionBudget` + +For example: + +[source,yaml] +---- +apiVersion: registry.apicur.io/v1 +kind: ApicurioRegistry +metadata: + name: example-apicurioregistry +spec: + deployment: + managedResources: + disableIngress: true + disableNetworkPolicy: true + disablePodDisruptionBudget: false # Can be omitted +---- diff --git a/operator/docs/modules/ROOT/partials/ref-registry-operator-prerequisites.adoc b/operator/docs/modules/ROOT/partials/ref-registry-operator-prerequisites.adoc new file mode 100644 index 0000000000..b6c57002f1 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-operator-prerequisites.adoc @@ -0,0 +1,18 @@ +[id="registry-operator-prerequisites"] += {operator} platforms + +The {operator} supports the following platform versions: + +.{operator} platforms +[%header,cols=2*] +|=== +| Platform | Required version +ifdef::apicurio-registry[] +| Kubernetes +| 1.19+ +endif::[] +| OpenShift +| 4.6+ +|=== + +NOTE: {operator} does not yet deploy and manage {registry} storage. You must ensure that storage options such as Kafka or PostgreSQL are installed and configured. diff --git a/operator/docs/modules/ROOT/partials/ref-registry-pod-template-spec.adoc b/operator/docs/modules/ROOT/partials/ref-registry-pod-template-spec.adoc new file mode 100644 index 0000000000..4e450222e0 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/ref-registry-pod-template-spec.adoc @@ -0,0 +1,76 @@ +[id="pod-spec"] +// Do not forget to update link text in related xref(s). Antora does not support automatic name if the link has a fragment. += Configuring {registry} deployment using PodTemplate + +ifdef::apicurio-registry[] +IMPORTANT: This is a Technology Preview feature only, which might evolve in future releases. Before using this feature in production, make sure to test that your deployment works as expected. Review the Release Notes in future releases for updates. +endif::[] + +ifdef::service-registry[] +[IMPORTANT] +==== +This is a Technology Preview feature only. +Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. +Red Hat does not recommend using them in production. + +These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process. For more information about the support scope of Red Hat Technology Preview features, see https://access.redhat.com/support/offerings/techpreview. +==== +endif::[] + +The `ApicurioRegistry` CRD contains the `spec.deployment.podTemplateSpecPreview` field, which has the same structure as the field `spec.template` in a Kubernetes `Deployment` resource (the `PodTemplateSpec` struct). + +With some restrictions, the {operator} forwards the data from this field to the corresponding field in the {registry} deployment. +This provides greater configuration flexibility, without the need for the {operator} to natively support each use case. + +The following table contains a list of subfields that are not accepted by the {operator}, and result in a configuration error: + +.Restrictions on the `podTemplateSpecPreview` subfields +[%header,cols="4,3,4"] +|=== +| `podTemplateSpecPreview` subfield | Status | Details + +| `metadata.annotations` +| alternative exists +| `spec.deployment.metadata.annotations` + +| `metadata.labels` +| alternative exists +| `spec.deployment.metadata.labels` + +| `spec.affinity` +| alternative exists +| `spec.deployment.affinity` + +| `spec.containers[*]` +| warning +| To configure the {registry} container, `name: registry` must be used + +| `spec.containers[name = "registry"].env` +| alternative exists +| `spec.configuration.env` + +ifdef::apicurio-registry[] +| `spec.containers[name = "registry"].image` +| alternative exists +| `spec.deployment.image` +endif::[] +ifdef::service-registry[] +| `spec.containers[name = "registry"].image` +| reserved +| - +endif::[] + +| `spec.imagePullSecrets` +| alternative exists +| `spec.deployment.imagePullSecrets` + +| `spec.tolerations` +| alternative exists +| `spec.deployment.tolerations` + +|=== + +WARNING: If you set a field in `podTemplateSpecPreview`, its value must be valid, as if you configured it in the {registry} `Deployment` directly. The {operator} might still modify the values you provided, but it will not fix an invalid value or make sure a default value is present. + +.Additional resources +* link:https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates[Kubernetes documentation on Pod templates] diff --git a/operator/docs/modules/ROOT/partials/shared/all-attributes.adoc b/operator/docs/modules/ROOT/partials/shared/all-attributes.adoc new file mode 100644 index 0000000000..2b4e7ec18b --- /dev/null +++ b/operator/docs/modules/ROOT/partials/shared/all-attributes.adoc @@ -0,0 +1,2 @@ +include::attributes.adoc[] +include::attributes-links.adoc[] diff --git a/operator/docs/modules/ROOT/partials/shared/attributes-links.adoc b/operator/docs/modules/ROOT/partials/shared/attributes-links.adoc new file mode 100644 index 0000000000..63feacb9a4 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/shared/attributes-links.adoc @@ -0,0 +1,18 @@ +// Upstream + +// Downstream +//:LinkRedHatIntegrationDownloads: https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?product=rhboar&downloadType=distributions +:LinkRedHatIntegrationDownloads: https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?downloadType=distributions&product=red.hat.integration +:NameRedHatIntegrationDownloads: Red Hat Software Downloads + +:LinkOLMDocs: https://docs.openshift.com/container-platform/latest/operators/understanding/olm/olm-understanding-olm.html +:NameOLMDocs: Operator Lifecycle Manager + +:LinkOperatorHub: https://docs.openshift.com/container-platform/latest/operators/understanding/olm-understanding-operatorhub.html +:NameOperatorHub: OperatorHub + +:LinkOCPCLIDocs: https://docs.openshift.com/container-platform/latest/cli_reference/openshift_cli/getting-started-cli.html +:NameOCPCLIDocs: OpenShift CLI documentation + +:LinkManagingContentUsingRESTAPI: https://access.redhat.com/documentation/en-us/red_hat_integration/2023.q2/html/service_registry_user_guide/managing-registry-artifacts-api_registry +:NameManagingContentUsingRESTAPI: Managing {registry} content using the REST API diff --git a/operator/docs/modules/ROOT/partials/shared/attributes.adoc b/operator/docs/modules/ROOT/partials/shared/attributes.adoc new file mode 100644 index 0000000000..970272a24c --- /dev/null +++ b/operator/docs/modules/ROOT/partials/shared/attributes.adoc @@ -0,0 +1,81 @@ +// Standard document attributes to be used in the documentation. + +// The following are shared by all documents: + +// ===== High-level Parameters: + +//:apicurio-registry-operator-downstream: +// - If set, downstream documentation is generated. (Inclusion parameter) + +:apicurio-registry-operator-dev: +// - If set, documentation for the upstream development version is generated. + +// ===== Upstream +ifndef::apicurio-registry-operator-downstream[] + +:apicurio-registry: + +:registry: Apicurio Registry +:operator: {registry} Operator +:operator-full: {operator} + +:registry-version: 3.x +:operator-version: 3.0.0-dev + +// IMPORTANT: This value may be used as a tag when linking to content on GitHub. +:operator-version-latest-release-tag: main + +:platform: Kubernetes +:cli-client: kubectl + +:kafka-streams: Strimzi + +:keycloak: Keycloak + +endif::[] + +// ===== Downstream +ifdef::apicurio-registry-operator-downstream[] + +:service-registry: + +:org-name: Red Hat +:prodnamefull: {org-name} Integration +:registry-name-full: {prodnamefull} - Service Registry +:registry: Service Registry +:operator: {registry} Operator +:operator-full: {org-name} Integration - {operator} + +:registry-version: 3.x +:operator-version: 1.2.0-dev + +:platform: OpenShift +:cli-client: oc +:kafka-streams: AMQ Streams +:keycloak: {org-name} Single Sign-On + + +ifdef::RHAF[] +:prodnamefull: {org-name} Application Foundations +:registry-name-full: {org-name} build of Apicurio Registry +:registry: Apicurio Registry +:operator: {registry} Operator +endif::[] + +endif::[] + +// ===== Common +:registry-ocp-version: 4.13 + + +// Characters +:copy: © +:infin: ∞ +:mdash: — +:nbsp: +:ndash: – +:reg: ® +:trade: ™ +:star: * +:curlyleft: { +:curlyright: } diff --git a/operator/docs/resources/licenses/licenses.csv b/operator/docs/resources/licenses/licenses.csv new file mode 100644 index 0000000000..b172d2c55a --- /dev/null +++ b/operator/docs/resources/licenses/licenses.csv @@ -0,0 +1,72 @@ +github.com/Apicurio/apicurio-registry-operator,https://github.com/Apicurio/apicurio-registry-operator/blob/HEAD/LICENSE,Apache-2.0 +github.com/beorn7/perks/quantile,https://github.com/beorn7/perks/blob/v1.0.1/LICENSE,MIT +github.com/cespare/xxhash/v2,https://github.com/cespare/xxhash/blob/v2.2.0/LICENSE.txt,MIT +github.com/davecgh/go-spew/spew,https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE,ISC +github.com/emicklei/go-restful/v3,https://github.com/emicklei/go-restful/blob/v3.11.0/LICENSE,MIT +github.com/evanphx/json-patch,https://github.com/evanphx/json-patch/blob/v5.9.0/LICENSE,BSD-3-Clause +github.com/evanphx/json-patch/v5,https://github.com/evanphx/json-patch/blob/v5.8.0/v5/LICENSE,BSD-3-Clause +github.com/fsnotify/fsnotify,https://github.com/fsnotify/fsnotify/blob/v1.7.0/LICENSE,BSD-3-Clause +github.com/go-logr/logr,https://github.com/go-logr/logr/blob/v1.4.1/LICENSE,Apache-2.0 +github.com/go-logr/zapr,https://github.com/go-logr/zapr/blob/v1.3.0/LICENSE,Apache-2.0 +github.com/go-openapi/jsonpointer,https://github.com/go-openapi/jsonpointer/blob/v0.20.0/LICENSE,Apache-2.0 +github.com/go-openapi/jsonreference,https://github.com/go-openapi/jsonreference/blob/v0.20.2/LICENSE,Apache-2.0 +github.com/go-openapi/swag,https://github.com/go-openapi/swag/blob/v0.22.4/LICENSE,Apache-2.0 +github.com/gogo/protobuf,https://github.com/gogo/protobuf/blob/v1.3.2/LICENSE,BSD-3-Clause +github.com/golang/groupcache/lru,https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE,Apache-2.0 +github.com/golang/protobuf,https://github.com/golang/protobuf/blob/v1.5.3/LICENSE,BSD-3-Clause +github.com/google/gnostic-models,https://github.com/google/gnostic-models/blob/v0.6.8/LICENSE,Apache-2.0 +github.com/google/go-cmp/cmp,https://github.com/google/go-cmp/blob/v0.6.0/LICENSE,BSD-3-Clause +github.com/google/gofuzz,https://github.com/google/gofuzz/blob/v1.2.0/LICENSE,Apache-2.0 +github.com/google/uuid,https://github.com/google/uuid/blob/v1.4.0/LICENSE,BSD-3-Clause +github.com/imdario/mergo,https://github.com/imdario/mergo/blob/v0.3.12/LICENSE,BSD-3-Clause +github.com/josharian/intern,https://github.com/josharian/intern/blob/v1.0.0/license.md,MIT +github.com/json-iterator/go,https://github.com/json-iterator/go/blob/v1.1.12/LICENSE,MIT +github.com/kballard/go-shellquote,https://github.com/kballard/go-shellquote/blob/95032a82bc51/LICENSE,MIT +github.com/mailru/easyjson,https://github.com/mailru/easyjson/blob/v0.7.7/LICENSE,MIT +github.com/matttproud/golang_protobuf_extensions/v2/pbutil,https://github.com/matttproud/golang_protobuf_extensions/blob/v2.0.0/LICENSE,Apache-2.0 +github.com/modern-go/concurrent,https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE,Apache-2.0 +github.com/modern-go/reflect2,https://github.com/modern-go/reflect2/blob/v1.0.2/LICENSE,Apache-2.0 +github.com/munnerz/goautoneg,https://github.com/munnerz/goautoneg/blob/a7dc8b61c822/LICENSE,BSD-3-Clause +github.com/openshift/api,https://github.com/openshift/api/blob/44756aa36879/LICENSE,Apache-2.0 +github.com/openshift/client-go,https://github.com/openshift/client-go/blob/2425b4b6d3b3/LICENSE,Apache-2.0 +github.com/pkg/errors,https://github.com/pkg/errors/blob/v0.9.1/LICENSE,BSD-2-Clause +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring,https://github.com/prometheus-operator/prometheus-operator/blob/pkg/apis/monitoring/v0.70.0/pkg/apis/monitoring/LICENSE,Apache-2.0 +github.com/prometheus-operator/prometheus-operator/pkg/client,https://github.com/prometheus-operator/prometheus-operator/blob/pkg/client/v0.70.0/pkg/client/LICENSE,Apache-2.0 +github.com/prometheus/client_golang/prometheus,https://github.com/prometheus/client_golang/blob/v1.18.0/LICENSE,Apache-2.0 +github.com/prometheus/client_model/go,https://github.com/prometheus/client_model/blob/v0.5.0/LICENSE,Apache-2.0 +github.com/prometheus/common,https://github.com/prometheus/common/blob/v0.45.0/LICENSE,Apache-2.0 +github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg,https://github.com/prometheus/common/blob/v0.45.0/internal/bitbucket.org/ww/goautoneg/README.txt,BSD-3-Clause +github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/v0.12.0/LICENSE,Apache-2.0 +github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3-Clause +github.com/sykesm/zap-logfmt,https://github.com/sykesm/zap-logfmt/blob/v0.0.4/LICENSE,MIT +go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.11.0/LICENSE.txt,MIT +go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.27.0/LICENSE,MIT +golang.org/x/exp/maps,https://cs.opensource.google/go/x/exp/+/a9213eeb:LICENSE,BSD-3-Clause +golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.20.0:LICENSE,BSD-3-Clause +golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/v0.15.0:LICENSE,BSD-3-Clause +golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.16.0:LICENSE,BSD-3-Clause +golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.16.0:LICENSE,BSD-3-Clause +golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.14.0:LICENSE,BSD-3-Clause +golang.org/x/time/rate,https://cs.opensource.google/go/x/time/+/v0.5.0:LICENSE,BSD-3-Clause +gomodules.xyz/jsonpatch/v2,https://github.com/gomodules/jsonpatch/blob/v2.4.0/v2/LICENSE,Apache-2.0 +google.golang.org/protobuf,https://github.com/protocolbuffers/protobuf-go/blob/v1.31.0/LICENSE,BSD-3-Clause +gopkg.in/inf.v0,https://github.com/go-inf/inf/blob/v0.9.1/LICENSE,BSD-3-Clause +gopkg.in/yaml.v2,https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE,Apache-2.0 +gopkg.in/yaml.v3,https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE,MIT +k8s.io/api,https://github.com/kubernetes/api/blob/v0.29.0/LICENSE,Apache-2.0 +k8s.io/apiextensions-apiserver/pkg/apis/apiextensions,https://github.com/kubernetes/apiextensions-apiserver/blob/v0.29.0/LICENSE,Apache-2.0 +k8s.io/apimachinery/pkg,https://github.com/kubernetes/apimachinery/blob/v0.29.0/LICENSE,Apache-2.0 +k8s.io/apimachinery/third_party/forked/golang,https://github.com/kubernetes/apimachinery/blob/v0.29.0/third_party/forked/golang/LICENSE,BSD-3-Clause +k8s.io/client-go,https://github.com/kubernetes/client-go/blob/v0.29.0/LICENSE,Apache-2.0 +k8s.io/component-base/config,https://github.com/kubernetes/component-base/blob/v0.29.0/LICENSE,Apache-2.0 +k8s.io/klog/v2,https://github.com/kubernetes/klog/blob/v2.110.1/LICENSE,Apache-2.0 +k8s.io/kube-openapi/pkg,https://github.com/kubernetes/kube-openapi/blob/f0671cc7e66a/LICENSE,Apache-2.0 +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json,https://github.com/kubernetes/kube-openapi/blob/f0671cc7e66a/pkg/internal/third_party/go-json-experiment/json/LICENSE,BSD-3-Clause +k8s.io/kube-openapi/pkg/validation/spec,https://github.com/kubernetes/kube-openapi/blob/f0671cc7e66a/pkg/validation/spec/LICENSE,Apache-2.0 +k8s.io/utils,https://github.com/kubernetes/utils/blob/b307cd553661/LICENSE,Apache-2.0 +k8s.io/utils/internal/third_party/forked/golang/net,https://github.com/kubernetes/utils/blob/b307cd553661/internal/third_party/forked/golang/LICENSE,BSD-3-Clause +sigs.k8s.io/controller-runtime,https://github.com/kubernetes-sigs/controller-runtime/blob/v0.16.5/LICENSE,Apache-2.0 +sigs.k8s.io/json,https://github.com/kubernetes-sigs/json/blob/bc3834ca7abd/LICENSE,Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4,https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.4.1/LICENSE,Apache-2.0 +sigs.k8s.io/yaml,https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/LICENSE,Apache-2.0 +sigs.k8s.io/yaml/goyaml.v2,https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/goyaml.v2/LICENSE,Apache-2.0 diff --git a/operator/docs/tips-for-creating-asciidoc-content.adoc b/operator/docs/tips-for-creating-asciidoc-content.adoc new file mode 100644 index 0000000000..cda97425eb --- /dev/null +++ b/operator/docs/tips-for-creating-asciidoc-content.adoc @@ -0,0 +1,403 @@ +// Enable icons instead of text in admonitions (TIP, NOTE, and so on) +:icons: +:source-highlighter: pygments + +[[style]] += Tips for Creating AsciiDoc Content + +Contributors to Apicurio Registry user documentation follow these style conventions + +* <> +* <> +* <> +* <> +* <> +* <> +* <> +* <> + +[[style-comments]] +== Inserting comments +// This is a single line comment +Single line comments start with a double forward slash, like this: +.... +// This is a single line comment +.... + +Multi-line comments are enclosed in a group of four forward slashes, like this: +.... +//// +This is a slightly longish +multi-line +comment. +//// +.... + +[[style-blocks]] +== Inserting paragraphs and lists + +* <> +* <> +* <> +* <> + +[[style-blocks-paras]] +=== Inserting paragraphs +To enter a paragraph, just enter the text. + +Insert a blank line before a subsequent paragraph. + + +[[style-blocks-itemized-list]] +=== Formatting unordered lists +A simple unordered list (bulleted list) is signalled by putting an asterisk at the start of each line, like this: + +.... +* First bullet. +* Second bullet. +* Third bullet. +.... + +This renders as: + +==== +* First bullet. +* Second bullet. +* Third bullet. +==== + +One of the most useful things to know about unordered lists is how to add extra content to a bullet point without breaking out of the list? +The answer is to join the content with a `+` character (on its own line). + +For example, consider the following unordered list: + +.... +* Launch the virtual machine with the following command: ++ +---- +$ vagrant up +---- ++ +NOTE: Make sure that you run this command in the same directory as the `Vagrantfile` file + +* Shut down the virtual machine with the following command: ++ +---- +$ vagrant halt +---- +.... + +Which renders as: + +==== +* Launch the virtual machine with the following command: ++ +---- +$ vagrant up +---- ++ +NOTE: Make sure that run this command in the same directory as the `Vagrantfile` file + +* Shut down the virtual machine with the following command: ++ +---- +$ vagrant halt +---- +==== + +[[style-blocks-ordered-list]] +=== Formatting ordered lists +An ordered list (numbered list) is signaled by putting a dot, `.`, at the start of each line. Once again, to join content and keep it in the same numbered point, use a the `+` character. + +For example, consider the following ordered list: + +.... +. Log in to OpenShift by entering the following command: ++ +---- +$ oc login -u admin -p admin +---- ++ +NOTE: The `admin` user account is created by default in the CDK. + +. Switch to the `test` project by entering the following command: ++ +---- +$ oc project test +---- +.... + +Which renders as: + +==== +. Log in to OpenShift by entering the following command: ++ +---- +$ oc login -u admin -p admin +---- ++ +NOTE: The `admin` user account is created by default in the CDK. + +. Switch to the `test` project by entering the following command: ++ +---- +$ oc project test +---- +==== + +[[style-blocks-variable-list]] +=== Formatting variable lists +The variable list is a great layout to use when you need to present a list of terms and associated descriptions (and is often a superior alternative to using a bulleted list). + +For example, consider the following variable list: + +.... +OpenShift client:: If you are using the CDK, the `oc` client tool can conveniently be installed as follows: ++ +---- +$ vagrant service-manager install-cli openshift +---- + +Docker client:: If you are using the CDK, the `docker` client tool can conveniently be installed as follows: ++ +---- +$ vagrant service-manager install-cli docker +---- +.... + +Which renders as: + +==== +OpenShift client:: If you are using the CDK, the `oc` client tool can conveniently be installed as follows: ++ +---- +$ vagrant service-manager install-cli openshift +---- + +Docker client:: If you are using the CDK, the `docker` client tool can conveniently be installed as follows: ++ +---- +$ vagrant service-manager install-cli docker +---- +==== + +[[style-code]] +== Formatting code +* <> +* <> +* <> +* <> +* <> + +[[style-code-inline]] +=== Formatting inline code +Use backticks to enclose inline code. + +For example, to start the fuse container, enter the `./bin/fuse` command. + +---- +For example, to start the fuse container, enter the `./bin/fuse` command. +---- + +You can use `_underscores inside backticks_` or `*asterisks inside backticks*`. But if you prefer the underscore or asterisk to be shown literally, `\_escape the first one with a backslash_`. + +---- +You can use `_underscores inside backticks_` or `*asterisks inside backticks*`. But if you prefer the underscore or asterisk to be shown literally, `\_escape the first one with a backslash_`. +---- + + +[[style-code-listing-notitle]] +=== Providing code blocks without titles +You _could_ create a code listing by putting spaces at the start of +each line of code, but _this approach is deprecated._ + +It is much better to delimit a code block by putting a line with four hyphens `----` at the beginning and end of the listing, like this: + +.... +---- +oc login -u admin -p admin +---- +.... + +Which renders as: +==== +---- +oc login -u admin -p admin +---- +==== + +If you are presenting a snippet of XML code, it is strongly recommended to switch on syntax highlighting, like this: + +.... +[source,xml] +---- + + + foo + + +---- +.... + +Which renders as: + +==== +[source,xml] +---- + + + foo + + +---- +==== + +Likewise, for Java code snippets it is highly recommended to switch on syntax highlighting like this: + +.... +[source,java] +---- +class FooBar { + int getNumberOfFoos(); + void setNumberOfFoos(); +} +---- +.... + +Which renders as: + +==== +[source,java] +---- +class FooBar { + int getNumberOfFoos(); + void setNumberOfFoos(); +} +---- +==== + +[[style-code-listing-title]] +=== Adding titles to code blocks +To define a code listing with a title, precede it with a title line like `.This is a Code Example`. +And if you are giving a code listing a title, it is generally a good idea to assign an anchor ID (between `[[` and `]]`) as well and to put it in a generic block (enclosed in `====` lines). For example: + +.... +[[style-code-xml-example]] +.Code Caption +==== +[source,xml] +---- + + + foo + + +---- +==== +.... + +Which renders as: + +[[style-code-xml-example]] +.Code Caption +==== +[source,xml] +---- + + + foo + + +---- +==== + +And because you have given the listing an anchor ID, you can easily cross-reference the <>. + + +[[style-code-callouts]] +=== Formatting code blocks that have callouts and replaceables +Sometimes a code listing uses callouts and also italics for replaceables. +To be able to insert callouts and also preserve italics, +insert `[subs="+quotes"]` before the code listing. + +[[style-code-listing-attribute-sub]] +=== Substituting attributes in code blocks +There are circumstances where it can be useful to substitutes attribute +values inside code listings. +By default, this is not possible because the curly braces, `{}`, are + interpreted literally inside a code listing. +But if you specify `[subs="attributes"]` at the start of the listing, +attribute substitution _is_ performed. For example: + +.... +[subs="attributes"] +---- +mvn archetype:generate \ + -DarchetypeCatalog={archetype-catalog} \ + -DarchetypeGroupId=org.jboss.fuse.fis.archetypes \ + -DarchetypeArtifactId=spring-boot-camel-archetype \ + -DarchetypeVersion={archetype-version} +---- +.... + +Which renders as: + +:archetype-version: 2.2.180.fuse-000003 +:archetype-catalog: https://repository.jboss.org/nexus/content/groups/ea/archetype-catalog.xml + +[subs="attributes"] +---- +mvn archetype:generate \ + -DarchetypeCatalog={archetype-catalog} \ + -DarchetypeGroupId=org.jboss.fuse.fis.archetypes \ + -DarchetypeArtifactId=spring-boot-camel-archetype \ + -DarchetypeVersion={archetype-version} +---- + +[[style-gui]] +== Formatting GUI items + +Enclose GUI items in asterisks. This includes menu selections, +dialog titles, button labels, popup selections and any other text that +appears in a GUI. The asterisks make the item appear in bold font. + +To format a sequence of selections, separate the items with a hyphen +followed by a greater than symbol. For example: + +---- +Select *File* -> *Open* -> *New* +---- + +This renders as: + +Select *File* -> *Open* -> *New* + +[[style-user-input]] +== Formatting user input + +Indicate user input with bold and monospace. For example, enter this: + +---- +In the *Name* field, enter `*Twitter*`. +---- + +To render this: + +In the *Name* field, enter `*Twitter*`. + +[[formatting-replaceables]] +== Formatting replaceables + +A replaceable is a variable or placeholder in text, a +file path, a command or a code listing. The user must replace the +replaceable with a valid value. For example: +---- +INSTALL-DIR/run.sh. +---- + +[[additional-resources]] +== Additional resources + +* link:https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[AsciiDoc Syntax Quick Reference] +* link:https://asciidoc.org/userguide.html[AsciiDoc User Guide] +* link:https://github.com/redhat-documentation/modular-docs#modular-documentation-reference-guide[Modular Documentation Reference Guide].