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 0000000000..0e0a0674ce Binary files /dev/null and b/operator/docs/modules/ROOT/images/operator-hub-search-ar.png differ 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 0000000000..b7397b0f79 Binary files /dev/null and b/operator/docs/modules/ROOT/images/operator-hub-search-sr.png differ diff --git a/operator/docs/modules/ROOT/nav.adoc b/operator/docs/modules/ROOT/nav.adoc new file mode 100644 index 0000000000..595b3326df --- /dev/null +++ b/operator/docs/modules/ROOT/nav.adoc @@ -0,0 +1,7 @@ +include::partial$shared/all-attributes.adoc[] + +* xref:ROOT:assembly-operator-quickstart.adoc[] +* xref:ROOT:assembly-operator-installation.adoc[] +* xref:ROOT:assembly-registry-storage.adoc[] +* xref:ROOT:assembly-registry-maintenance.adoc[] +* xref:ROOT:assembly-operator-configuration.adoc[] diff --git a/operator/docs/modules/ROOT/pages/assembly-operator-configuration.adoc b/operator/docs/modules/ROOT/pages/assembly-operator-configuration.adoc new file mode 100644 index 0000000000..b8a05bd04f --- /dev/null +++ b/operator/docs/modules/ROOT/pages/assembly-operator-configuration.adoc @@ -0,0 +1,19 @@ +include::partial$shared/all-attributes.adoc[] + +[id="registry-configuration-reference"] += {operator} configuration reference + +This chapter provides detailed information on the custom resource used to configure the {operator} to deploy {registry}: + +* xref:apicurio-registry-custom-resource[] +* xref:spec[] +* xref:status[] +* xref:managed-resources[] +* xref:registry-labels[] + +// INCLUDES +include::partial$ref-registry-cr.adoc[leveloffset=+1] +include::partial$ref-registry-cr-spec.adoc[leveloffset=+1] +include::partial$ref-registry-cr-status.adoc[leveloffset=+1] +include::partial$ref-registry-managed-resources.adoc[leveloffset=+1] +include::partial$ref-registry-labels.adoc[leveloffset=+1] diff --git a/operator/docs/modules/ROOT/pages/assembly-operator-installation.adoc b/operator/docs/modules/ROOT/pages/assembly-operator-installation.adoc new file mode 100644 index 0000000000..4a690884c2 --- /dev/null +++ b/operator/docs/modules/ROOT/pages/assembly-operator-installation.adoc @@ -0,0 +1,23 @@ +include::partial$shared/all-attributes.adoc[] + +[id="installing-the-registry"] += Installing {operator} using the OperatorHub + +This chapter explains how to install {operator} on Kubernetes or OpenShift. +It also shows how to install the {kafka-streams} or Java Persistence API (PostgreSQL) storage option: + +ifdef::apicurio-registry[] +* xref:install-registry-operator-olm-on-kubernetes[] +endif::[] + +* xref:install-registry-operator-olm[] +* xref:install-kafka-operatorhub[] +* xref:install-postgresql-operatorhub[] + +// INCLUDES +ifdef::apicurio-registry[] +include::partial$proc-install-olm-kubernetes.adoc[leveloffset=+1] +endif::[] +include::partial$proc-install-olm-sr.adoc[leveloffset=+1] +include::partial$proc-install-kafka.adoc[leveloffset=+1] +include::partial$proc-install-postgresql.adoc[leveloffset=+1] diff --git a/operator/docs/modules/ROOT/pages/assembly-operator-quickstart.adoc b/operator/docs/modules/ROOT/pages/assembly-operator-quickstart.adoc new file mode 100644 index 0000000000..6984e9057d --- /dev/null +++ b/operator/docs/modules/ROOT/pages/assembly-operator-quickstart.adoc @@ -0,0 +1,30 @@ +include::partial$shared/all-attributes.adoc[] + +[id="operator-quickstart"] += {operator} quickstart + +You can quickly install the {operator} on the command line by using Custom Resource Definitions (CRDs). + +The quickstart example deploys your {registry} instance with +ifdef::service-registry[] +storage in an SQL database: +endif::[] +ifdef::apicurio-registry[] +in-memory storage: +endif::[] + +* xref:registry-operator-quickstart[] +* xref:registry-quickstart[] + +NOTE: The recommended installation option for production environments is the OpenShift OperatorHub. The recommended storage option is an SQL database for performance, stability, and data management. + +// INCLUDES +ifdef::service-registry[] +include::partial$proc-registry-operator-quickstart-sr.adoc[leveloffset=+1] +include::partial$proc-registry-quickstart-sr.adoc[leveloffset=+1] +endif::[] +ifdef::apicurio-registry[] +include::partial$proc-registry-operator-quickstart-ar.adoc[leveloffset=+1] +include::partial$proc-registry-quickstart-ar.adoc[leveloffset=+1] +//include::partial$proc-registry-operator-distribution-bundle-ar.adoc[leveloffset=+1] +endif::[] diff --git a/operator/docs/modules/ROOT/pages/assembly-registry-maintenance.adoc b/operator/docs/modules/ROOT/pages/assembly-registry-maintenance.adoc new file mode 100644 index 0000000000..3b0bc99684 --- /dev/null +++ b/operator/docs/modules/ROOT/pages/assembly-registry-maintenance.adoc @@ -0,0 +1,27 @@ +include::partial$shared/all-attributes.adoc[] + +[id="managing-the-registry"] += Configuring and managing {registry} deployment + +//// +This chapter explains how to configure and manage your {registry} deployment: + +* xref:registry-security-keycloak[] +* xref:manage-registry-environment-variables[] +* xref:registry-liveness-and-readiness[] +* xref:pod-spec[] +* xref:registry-https-in-cluster[] +* xref:registry-https-outside-cluster[] +* xref:registry-sql-backup[] +* xref:registry-sql-restore[] + +//// +// INCLUDES +//include::partial$proc-registry-security-keycloak.adoc[leveloffset=+1] +//include::partial$proc-manage-environment-variables.adoc[leveloffset=+1] +//include::partial$ref-liveness-and-readiness.adoc[leveloffset=+1] +include::partial$ref-registry-pod-template-spec.adoc[leveloffset=+1] +//include::partial$proc-registry-https-in-cluster.adoc[leveloffset=+1] +//include::partial$proc-registry-https-outside-cluster.adoc[leveloffset=+1] +//include::partial$proc-registry-sql-backup.adoc[leveloffset=+1] +//include::partial$proc-registry-sql-restore.adoc[leveloffset=+1] diff --git a/operator/docs/modules/ROOT/pages/assembly-registry-storage.adoc b/operator/docs/modules/ROOT/pages/assembly-registry-storage.adoc new file mode 100644 index 0000000000..f3676bbb6d --- /dev/null +++ b/operator/docs/modules/ROOT/pages/assembly-registry-storage.adoc @@ -0,0 +1,36 @@ +include::partial$shared/all-attributes.adoc[] + +[id="registry-configuration-reference"] += Configuring {registry} storage + +This chapter explains how to configure the available {registry} storage options: + +* xref:registry-persistence-options[] + +ifdef::apicurio-registry[] +* xref:registry-persistence-mem[] +endif::[] + +* xref:registry-persistence-sql[] +* xref:registry-persistence-kafkasql-plain[] +* xref:registry-persistence-kafkasql-tls[] +* xref:registry-persistence-kafkasql-scram[] + + +ifdef::apicurio-registry[] +NOTE: This chapter mostly focuses on storage configuration procedures for OpenShift using OperatorHub UI. +If you are deploying to Kubernetes, you can use command line tools to perform the equivalent steps. +The {operator} supports the same configuration options on OpenShift and Kubernetes. +endif::[] + +// INCLUDES +include::partial$con-persistence-options.adoc[leveloffset=+1] + +ifdef::apicurio-registry[] +include::partial$proc-persistence-mem.adoc[leveloffset=+1] +endif::[] +include::partial$proc-persistence-sql.adoc[leveloffset=+1] +include::partial$proc-persistence-kafkasql-plain.adoc[leveloffset=+1] +include::partial$proc-persistence-kafkasql-tls.adoc[leveloffset=+1] +include::partial$proc-persistence-kafkasql-scram.adoc[leveloffset=+1] + diff --git a/operator/docs/modules/ROOT/pages/index.adoc b/operator/docs/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000000..67ec1b33f6 --- /dev/null +++ b/operator/docs/modules/ROOT/pages/index.adoc @@ -0,0 +1,21 @@ +include::partial$shared/all-attributes.adoc[] + +[id="apicurio-registry-operator"] += {operator} Documentation + +Welcome to the user +ifdef::apicurio-registry[] +and developer +endif::[] +documentation for the {operator}: + +* xref:assembly-operator-quickstart.adoc[Get started with {operator}] + +ifdef::apicurio-registry[] +* https://github.com/Apicurio/apicurio-registry-operator[See the {operator} project on GitHub] +endif::[] + +include::partial$con-registry-intro.adoc[leveloffset=+1] +include::partial$con-registry-operator-intro.adoc[leveloffset=+1] +include::partial$ref-registry-operator-prerequisites.adoc[leveloffset=+1] +include::partial$ref-get-help.adoc[leveloffset=+1] diff --git a/operator/docs/modules/ROOT/partials/con-persistence-options.adoc b/operator/docs/modules/ROOT/partials/con-persistence-options.adoc new file mode 100644 index 0000000000..2ac9e8fc37 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/con-persistence-options.adoc @@ -0,0 +1,45 @@ +[id="registry-persistence-options"] += {registry} storage options + +The main decision to make when deploying {registry} is which storage backend to use. + +The following storage options are available: + +.{registry} data storage options +[%header,cols="1,3"] +|=== +|Storage option +|Description + +ifdef::apicurio-registry[] +|In-memory +|Data is stored in RAM on each {registry} node. This is the easiest deployment to use, but is not recommended for production environment. All data is lost when restarting {registry} with this storage option, which is suitable for a development environment only. +endif::[] + +|SQL database +|Data is stored in a relational database, in this case PostgreSQL 12+. This is the recommended storage option in a production environment for performance, stability, and data management (backup/restore, and so on). + +ifdef::apicurio-registry[] +|Apache Kafka +endif::[] +ifdef::service-registry[] +|{kafka-streams} +endif::[] +|Data is stored using Apache Kafka, with the help of a local SQL database on each node. This storage option is provided for production environments where database management expertise is not available, or where storage in Kafka is a specific requirement. +|=== + + +ifdef::apicurio-registry[] +.Storage requiring installation +The following options require that the storage is already installed as a prerequisite: + +* SQL (PostgreSQL) +* Apache Kafka +endif::[] + +ifdef::service-registry[] +These options require that the storage is already installed as a prerequisite. +endif::[] + +.Additional resources +* xref:assembly-operator-installation.adoc[] diff --git a/operator/docs/modules/ROOT/partials/con-registry-intro.adoc b/operator/docs/modules/ROOT/partials/con-registry-intro.adoc new file mode 100644 index 0000000000..cb0d8b67a8 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/con-registry-intro.adoc @@ -0,0 +1,12 @@ +[id="registry-intro"] += {registry} + +{registry} stores and retrieves API designs and event schemas, and gives you control of their evolution. + +For more information about the {registry}, see the documentation at https://www.apicur.io/registry/. + +ifdef::service-registry[] + +{registry} is based on the https://github.com/apicurio/apicurio-registry[Apicurio Registry] open source community project. + +endif::[] diff --git a/operator/docs/modules/ROOT/partials/con-registry-operator-intro.adoc b/operator/docs/modules/ROOT/partials/con-registry-operator-intro.adoc new file mode 100644 index 0000000000..86f53c0f37 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/con-registry-operator-intro.adoc @@ -0,0 +1,14 @@ +[id="registry-operator-intro"] += {operator} + +{operator} provides a quick and easy way to deploy and manage {registry} on +ifdef::apicurio-registry[] +Kubernetes or +endif::[] +OpenShift. + +The Operator supports basic installation and configuration of {registry}, so you can access the {registry} API and web console in a few minutes. + +ifdef::service-registry[] +{operator} is based on the https://github.com/apicurio/apicurio-registry-operator[Apicurio Registry Operator] open source community project. +endif::[] diff --git a/operator/docs/modules/ROOT/partials/proc-install-kafka.adoc b/operator/docs/modules/ROOT/partials/proc-install-kafka.adoc new file mode 100644 index 0000000000..668fd79cd1 --- /dev/null +++ b/operator/docs/modules/ROOT/partials/proc-install-kafka.adoc @@ -0,0 +1,46 @@ +[id=install-kafka-operatorhub] += Installing {kafka-streams} storage using OpenShift OperatorHub + +The recommended Kafka storage option requires that you provide connection information to a Kafka cluster. You can use any Kafka cluster with Kafka support. However, it is recommended to use the {kafka-streams} Operator to provide and maintain a Kafka cluster for you. + +If you do not already have Kafka installed, you can install the {kafka-streams} Operator on your OpenShift cluster from the link:{LinkOperatorHub}[{NameOperatorHub}]. + +.Prerequisites + +* You must have cluster administrator access to an OpenShift cluster +ifdef::service-registry[] +* See link:https://access.redhat.com/documentation/en-us/red_hat_amq/7.7/html/using_amq_streams_on_openshift/getting-started-str[Using AMQ Streams on OpenShift] for detailed information on installing {kafka-streams}. This section shows a simple example of installing using the OpenShift OperatorHub. +endif::[] + +.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*. +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].