From 3d7f86632e181e526a41d6539f66bccc12a2e5b5 Mon Sep 17 00:00:00 2001 From: Sahil Shah Date: Wed, 29 May 2024 16:26:01 -0400 Subject: [PATCH 001/339] Control Plane latency recommendations for reliable clusters --- modules/control-plane-latency.adoc | 9 +++++++++ ...latency-recommendations-for-reliable-clusters.adoc | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 modules/control-plane-latency.adoc create mode 100644 scalability_and_performance/control-plane-latency-recommendations-for-reliable-clusters.adoc diff --git a/modules/control-plane-latency.adoc b/modules/control-plane-latency.adoc new file mode 100644 index 000000000000..e2d9da231f37 --- /dev/null +++ b/modules/control-plane-latency.adoc @@ -0,0 +1,9 @@ +// Module included in the following assemblies: +// +// * scalability_and_performance/control-plane-latency-recommendations-for-reliable-clusters.adoc + +:_mod-docs-content-type: CONCEPT +[id="control-plane-latency_{context}"] += Recommended Control Plane latency for reliable clusters + +We recommend inducing 15ms latency, for the cluster to function normally and to avoid critical alerts such as KubeAPIErrorBudgetBurn and etcdGRPCRequestsSlow. diff --git a/scalability_and_performance/control-plane-latency-recommendations-for-reliable-clusters.adoc b/scalability_and_performance/control-plane-latency-recommendations-for-reliable-clusters.adoc new file mode 100644 index 000000000000..d08c8084a515 --- /dev/null +++ b/scalability_and_performance/control-plane-latency-recommendations-for-reliable-clusters.adoc @@ -0,0 +1,11 @@ +:_mod-docs-content-type: ASSEMBLY +[id="control-plane-latency-recommendations-for-reliable-clusters"] += Control Plane latency recommendations for reliable clusters +include::_attributes/common-attributes.adoc[] +:context: control-plane-latency-recommendations-for-reliable-clusters + +toc::[] + +This topic provides recommended Control Plane latency for reliable clusters. + +include::modules/control-plane-latency.adoc[leveloffset=+1] \ No newline at end of file From 8598c429c3c30db648cffb36d78c225dcd024fe1 Mon Sep 17 00:00:00 2001 From: Daniel Chadwick Date: Tue, 28 May 2024 17:32:06 -0400 Subject: [PATCH 002/339] ocpbugs33135: fixing api version in procedure --- modules/nodes-clusters-cgroups-2-install.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nodes-clusters-cgroups-2-install.adoc b/modules/nodes-clusters-cgroups-2-install.adoc index f9a7a6b3bcf5..cf05f83d82b0 100644 --- a/modules/nodes-clusters-cgroups-2-install.adoc +++ b/modules/nodes-clusters-cgroups-2-install.adoc @@ -17,7 +17,7 @@ include::snippets/deprecated-feature.adoc[] + [source,yaml] ---- -apiVersion: config.openshift.io/v2 +apiVersion: config.openshift.io/v1 kind: Node metadata: name: cluster From 42ef3bfa3914c0d6c62c214581e3c05e76ceb2fc Mon Sep 17 00:00:00 2001 From: srir Date: Sat, 11 May 2024 17:51:07 +0530 Subject: [PATCH 003/339] TELCODOCS#1253: Support for device encryption --- modules/lvms-about-adding-devices-to-a-vg.adoc | 2 ++ .../persistent-storage-using-lvms.adoc | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/modules/lvms-about-adding-devices-to-a-vg.adoc b/modules/lvms-about-adding-devices-to-a-vg.adoc index 7780b3b16f05..14870e7b74a1 100644 --- a/modules/lvms-about-adding-devices-to-a-vg.adoc +++ b/modules/lvms-about-adding-devices-to-a-vg.adoc @@ -12,6 +12,8 @@ You can specify the device paths in the `deviceSelector.paths` field, the `devic You can also add the path to the RAID arrays to integrate the RAID arrays with {lvms}. For more information, see "Integrating RAID arrays with {lvms}". +You can also add encrypted devices to the volume group. You can enable disk encryption on the cluster nodes during an {product-title} installation. After encrypting a device, you can specify the path to the LUKS encrypted device in the `deviceSelector` field. For information on disk encryption, see "About disk encryption" and "Configuring disk encryption and mirroring". + The devices that you want to add to the VG must be supported by {lvms}. For information about unsupported devices, see "Devices not supported by {lvms}". {lvms} adds the devices to the VG only if the following conditions are met: diff --git a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc index fd4a0b14892f..0ec5d132bfa3 100644 --- a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc +++ b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc @@ -71,6 +71,10 @@ include::modules/lvms-about-adding-devices-to-a-vg.adoc[leveloffset=+2] * xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#lvms-unsupported-devices_logical-volume-manager-storage[Devices not supported by {lvms}] +* xref:../../../installing/install_config/installing-customizing.adoc#installation-special-config-encrypt-disk_installing-customizing[About disk encryption] + +* xref:../../../installing/install_config/installing-customizing.adoc#installation-special-config-storage-procedure_installing-customizing[Configuring disk encryption and mirroring] + * xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#lvms-integrating-software-raid-arrays_logical-volume-manager-storage[Integrating software RAID arrays with {lvms}] // Devices not supported by LVMS From d501be9836b73e8cd15d1ea55c6f81059ba2796c Mon Sep 17 00:00:00 2001 From: Satyajeet Munje Date: Mon, 27 May 2024 12:16:58 +0530 Subject: [PATCH 004/339] OBSDOCS-1077 --- modules/logging-set-input-rate-limit.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/logging-set-input-rate-limit.adoc b/modules/logging-set-input-rate-limit.adoc index 34862bb65eca..f4fd4268db37 100644 --- a/modules/logging-set-input-rate-limit.adoc +++ b/modules/logging-set-input-rate-limit.adoc @@ -33,7 +33,7 @@ spec: application: selector: matchLabels: { example: label } <2> - containerLimit: + containerLimit: maxRecordsPerSecond: 0 <3> # ... ---- @@ -54,12 +54,12 @@ spec: - name: <1> application: namespaces: [ example-ns-1, example-ns-2 ] <2> - containerLimit: - maxRecordsPerSecond: 10 <3> + containerLimit: + maxRecordsPerSecond: 10 <3> - name: application: namespaces: [ test ] - containerLimit: + containerLimit: maxRecordsPerSecond: 1000 # ... ---- From 3456a17c19bc3490bdd19386968459c5859f0c74 Mon Sep 17 00:00:00 2001 From: Brian Burt Date: Tue, 28 May 2024 12:57:24 -0400 Subject: [PATCH 005/339] OBSDOCS-844-update-cmo-config-map-ref-4.16 --- ...e-for-the-cluster-monitoring-operator.adoc | 91 +++++-------------- 1 file changed, 21 insertions(+), 70 deletions(-) diff --git a/observability/monitoring/config-map-reference-for-the-cluster-monitoring-operator.adoc b/observability/monitoring/config-map-reference-for-the-cluster-monitoring-operator.adoc index 27c35feb3188..36092e7247ee 100644 --- a/observability/monitoring/config-map-reference-for-the-cluster-monitoring-operator.adoc +++ b/observability/monitoring/config-map-reference-for-the-cluster-monitoring-operator.adoc @@ -142,8 +142,6 @@ The `ClusterMonitoringConfiguration` resource defines settings that customize th |enableUserWorkload|*bool|`UserWorkloadEnabled` is a Boolean flag that enables monitoring for user-defined projects. -|k8sPrometheusAdapter|*link:#k8sprometheusadapter[K8sPrometheusAdapter]|`K8sPrometheusAdapter` defines settings for the Prometheus Adapter component. - |kubeStateMetrics|*link:#kubestatemetricsconfig[KubeStateMetricsConfig]|`KubeStateMetricsConfig` defines settings for the `kube-state-metrics` agent. |metricsServer|*link:#metricsserverconfig[MetricsServerConfig]|`MetricsServer` defines settings for the Metrics Server component. @@ -166,52 +164,6 @@ The `ClusterMonitoringConfiguration` resource defines settings that customize th |=== -== DedicatedServiceMonitors - -=== Description - -[IMPORTANT] -==== -This setting is deprecated and is planned to be removed in a future {product-title} version. -In the current version, this setting still exists but has no effect. -==== - -You can use the `DedicatedServiceMonitors` resource to configure dedicated Service Monitors for the Prometheus Adapter - -Appears in: link:#k8sprometheusadapter[K8sPrometheusAdapter] - -[options="header"] -|=== -| Property | Type | Description -|enabled|bool|When `enabled` is set to `true`, the Cluster Monitoring Operator (CMO) deploys a dedicated Service Monitor that exposes the kubelet `/metrics/resource` endpoint. This Service Monitor sets `honorTimestamps: true` and only keeps metrics that are relevant for the pod resource queries of Prometheus Adapter. Additionally, Prometheus Adapter is configured to use these dedicated metrics. Overall, this feature improves the consistency of Prometheus Adapter-based CPU usage measurements used by, for example, the `oc adm top pod` command or the Horizontal Pod Autoscaler. - -|=== - -== K8sPrometheusAdapter - -=== Description - -The `K8sPrometheusAdapter` resource defines settings for the Prometheus Adapter component. - -Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] - -[options="header"] -|=== -| Property | Type | Description -|audit|*Audit|Defines the audit configuration used by the Prometheus Adapter instance. Possible profile values are: `metadata`, `request`, `requestresponse`, and `none`. The default value is `metadata`. - -|nodeSelector|map[string]string|Defines the nodes on which the pods are scheduled. - -|resources|*v1.ResourceRequirements|Defines resource requests and limits for the `PrometheusAdapter` container. - -|tolerations|[]v1.Toleration|Defines tolerations for the pods. - -|topologySpreadConstraints|[]v1.TopologySpreadConstraint|Defines a pod's topology spread constraints. - -|dedicatedServiceMonitors|*link:#dedicatedservicemonitors[DedicatedServiceMonitors]|Defines dedicated service monitors. - -|=== - == KubeStateMetricsConfig === Description @@ -237,16 +189,15 @@ Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] === Description -:FeatureName: Metrics Server -include::snippets/technology-preview.adoc[leveloffset=+1] - -The `MetricsServerConfig` resource defines settings for the Metrics Server component. Note that this setting only applies when the `TechPreviewNoUpgrade` feature gate is enabled. +The `MetricsServerConfig` resource defines settings for the Metrics Server component. Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] [options="header"] |=== | Property | Type | Description +|audit|*Audit|Defines the audit configuration used by the Metrics Server instance. Possible profile values are `Metadata`, `Request`, `RequestResponse`, and `None`. The default value is `Metadata`. + |nodeSelector|map[string]string|Defines the nodes on which the pods are scheduled. |tolerations|[]v1.Toleration|Defines tolerations for the pods. @@ -257,24 +208,6 @@ Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] |=== -== PrometheusOperatorAdmissionWebhookConfig - -=== Description - -The `PrometheusOperatorAdmissionWebhookConfig` resource defines settings for the admission webhook workload for Prometheus Operator. - -Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] - -[options="header"] -|=== -| Property | Type | Description - -|resources|*v1.ResourceRequirements|Defines resource requests and limits for the `prometheus-operator-admission-webhook` container. - -|topologySpreadConstraints|[]v1.TopologySpreadConstraint|Defines a pod's topology spread constraints. - -|=== - == MonitoringPluginConfig === Description @@ -573,6 +506,24 @@ link:#userworkloadconfiguration[UserWorkloadConfiguration] |=== +== PrometheusOperatorAdmissionWebhookConfig + +=== Description + +The `PrometheusOperatorAdmissionWebhookConfig` resource defines settings for the admission webhook workload for Prometheus Operator. + +Appears in: link:#clustermonitoringconfiguration[ClusterMonitoringConfiguration] + +[options="header"] +|=== +| Property | Type | Description + +|resources|*v1.ResourceRequirements|Defines resource requests and limits for the `prometheus-operator-admission-webhook` container. + +|topologySpreadConstraints|[]v1.TopologySpreadConstraint|Defines a pod's topology spread constraints. + +|=== + == PrometheusRestrictedConfig === Description From 261cd5f36642b5f009fe604957017e9bde719e40 Mon Sep 17 00:00:00 2001 From: Mahesh Nyayadhish Date: Thu, 30 May 2024 18:03:00 +0530 Subject: [PATCH 006/339] Add step on how to get DN for allowedSubjectPatterns Signed-off-by: Mahesh Nyayadhish --- modules/nw-mutual-tls-auth.adoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/nw-mutual-tls-auth.adoc b/modules/nw-mutual-tls-auth.adoc index 2a7db9c7f441..25319a42e343 100644 --- a/modules/nw-mutual-tls-auth.adoc +++ b/modules/nw-mutual-tls-auth.adoc @@ -61,3 +61,9 @@ $ oc edit IngressController default -n openshift-ingress-operator allowedSubjectPatterns: - "^/CN=example.com/ST=NC/C=US/O=Security/OU=OpenShift$" ---- +. Optional, get the Distinguished Name (DN) for `allowedSubjectPatterns` by entering the following command. +[source,terminal] +---- +$ openssl x509 -in custom-cert.pem -noout -subject +subject= /CN=example.com/ST=NC/C=US/O=Security/OU=OpenShift +---- From 0791b90c5f237c87a6cf0d5f6a4e8230b04ce684 Mon Sep 17 00:00:00 2001 From: Srivaralakshmi Date: Mon, 27 May 2024 21:20:14 +0530 Subject: [PATCH 007/339] RHDEVDOCS-6067-Update Samples Operator config section with deprecation notice for 4.16 fixing nitpick fixing peer review comments --- openshift_images/configuring-samples-operator.adoc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/openshift_images/configuring-samples-operator.adoc b/openshift_images/configuring-samples-operator.adoc index 9416855d47df..6df75cc56011 100644 --- a/openshift_images/configuring-samples-operator.adoc +++ b/openshift_images/configuring-samples-operator.adoc @@ -23,15 +23,9 @@ The Cluster Samples Operator, which operates in the `openshift` namespace, insta endif::openshift-rosa,openshift-dedicated[] [IMPORTANT] -.Cluster Samples Operator is being downsized +.The Cluster Samples Operator is being deprecated ==== -* Starting from {product-title} 4.13, Cluster Samples Operator is downsized. Cluster Samples Operator will stop providing the following updates for non-Source-to-Image (Non-S2I) image streams and templates: -- new image streams and templates -- updates to the existing image streams and templates unless it is a CVE update - -* Cluster Samples Operator will provide support for Non-S2I image streams and templates as per the link:https://access.redhat.com/support/policy/updates/openshift#dates[{product-title} lifecycle policy dates and support guidelines]. - -* Cluster Samples Operator will continue to support the S2I builder image streams and templates and accept the updates. S2I image streams and templates include: +* Starting from {product-title} 4.16, the Cluster Samples Operator is deprecated. No new templates, samples, or non-Source-to-Image (Non-S2I) image streams will be added to the Cluster Samples Operator. However, the existing S2I builder image streams and templates will continue to receive updates until the Cluster Samples Operator is removed in a future release. S2I image streams and templates include: - Ruby - Python - Node.js @@ -45,7 +39,7 @@ endif::openshift-rosa,openshift-dedicated[] - .NET - Go -* Starting from {product-title} 4.16, Cluster Samples Operator will stop managing non-S2I image streams and templates. You can contact the image stream or template owner for any requirements and future plans. In addition, refer to the link:https://github.com/openshift/library/blob/master/official.yaml[list of the repositories hosting the image stream or templates]. +* The Cluster Samples Operator will stop managing and providing support to the non-S2I samples (image streams and templates). You can contact the image stream or template owner for any requirements and future plans. In addition, refer to the link:https://github.com/openshift/library/blob/master/official.yaml[list of the repositories hosting the image stream or templates]. ==== include::modules/samples-operator-overview.adoc[leveloffset=+1] From 2b344e349f41cf118465c57de1a295e39a450fac Mon Sep 17 00:00:00 2001 From: Orel Misan Date: Thu, 9 May 2024 10:55:52 +0300 Subject: [PATCH 008/339] virt: Configure guest for real-time Add the instructions to configure a RHEL 9 VM for real-time usage. Signed-off-by: Orel Misan --- modules/virt-configuring-vm-real-time.adoc | 123 +++++++++++++++++---- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/modules/virt-configuring-vm-real-time.adoc b/modules/virt-configuring-vm-real-time.adoc index b2b15744fa64..3dd0f52f30d7 100644 --- a/modules/virt-configuring-vm-real-time.adoc +++ b/modules/virt-configuring-vm-real-time.adoc @@ -6,7 +6,7 @@ [id="virt-configuring-vm-real-time_{context}"] = Configuring a virtual machine for real-time workloads -You can configure a virtual machines (VM) to run real-time workloads. +You can configure a virtual machine (VM) to run real-time workloads. .Prerequisites * Your cluster is configured to run real-time workloads. @@ -23,12 +23,13 @@ kind: VirtualMachine metadata: name: realtime-vm spec: + running: true template: metadata: annotations: - cpu-load-balancing.crio.io: disable <1> - cpu-quota.crio.io: disable <2> - irq-load-balancing.crio.io: disable <3> + cpu-load-balancing.crio.io: disable # <1> + cpu-quota.crio.io: disable # <2> + irq-load-balancing.crio.io: disable # <3> spec: domain: cpu: @@ -38,8 +39,8 @@ spec: numa: guestMappingPassthrough: {} realtime: {} - sockets: 1 <4> - cores: 4 <5> + sockets: 1 # <4> + cores: 4 # <5> threads: 1 devices: autoattachGraphicsDevice: false @@ -49,56 +50,138 @@ spec: memory: guest: 4Gi hugepages: - pageSize: 1Gi <6> + pageSize: 1Gi # <6> terminationGracePeriodSeconds: 0 # ... ---- <1> This annotation specifies that load balancing is disabled for CPUs that are used by the container. <2> This annotation specifies that the CPU quota is disabled for CPUs that are used by the container. <3> This annotation specifies that interrupt request (IRQ) load balancing is disabled for CPUs that are used by the container. -<4> The number of sockets inside the VM. +<4> The number of sockets inside the VM. <5> The number of cores inside the VM. This must be a value greater than or equal to `1`. <6> The size of the huge pages. The possible values for x86-64 architectures are `1Gi` and `2Mi`. In this example, the request is for 4 huge pages of size 1 Gi. - . Apply the `VirtualMachine` manifest: + [source,terminal] ---- $ oc apply -f .yaml ---- - -. Configure the guest operating system. The following example shows the configuration steps for a {op-system-base} 8 operating system: +. Configure the guest operating system. The following example shows the configuration steps for a {op-system-base} 9 operating system: .. Run the following command to connect to the VM console: + [source,terminal] ---- $ virtctl console ---- - -.. Configure huge pages by using the GRUB boot loader command-line interface. In the following example, 8 1G huge pages are specified. +.. If you are not already logged in as a root user, switch to the root user account to execute the remaining configuration steps. +.. Disable the `irqbalance` service by using the following command: + [source,terminal] ---- -$ grubby --update-kernel=ALL --args="default_hugepagesz=1GB hugepagesz=1G hugepages=8" +# systemctl disable irqbalance && systemctl stop irqbalance ---- - -.. To achieve low-latency tuning by using the `cpu-partitioning` profile in the TuneD application, run the following commands: +.. Enable the real-time and network function virtualization (NFV) repositories: + [source,terminal] ---- -$ dnf install -y tuned-profiles-cpu-partitioning +# subscription-manager repos --enable rhel-9-for-x86_64-rt-rpms --enable rhel-9-for-x86_64-nfv-rpms ---- +.. Install the necessary packages by running the following command: + [source,terminal] ---- -$ echo isolated_cores=2-9 > /etc/tuned/cpu-partitioning-variables.conf +# dnf install tuned cloud-init ---- -The first two CPUs (0 and 1) are set aside for house keeping tasks and the rest are isolated for the real-time application. +.. To achieve low-latency tuning by using the `realtime-virtual-guest` profile in the TuneD application, run the following commands: + [source,terminal] ---- -$ tuned-adm profile cpu-partitioning +# dnf install kernel-rt realtime-tests tuned-profiles-realtime ---- ++ +[source,terminal] +---- +# dnf install tuned-profiles-nfv-guest +---- +.. Edit the `/etc/tuned/realtime-virtual-guest-variables.conf` file: ++ +[source,conf] +---- +# +# Variable settings below override the definitions from the +# /etc/tuned/realtime-variables.conf file. + +# +# Core isolation +# +# The 'isolated_cores=' variable below controls which cores should be +# isolated. By default we reserve 1 core per socket for housekeeping +# and isolate the rest. But you can isolate any range as shown in the +# examples below. Just remember to keep only one isolated_cores= line. +# +# Examples: +# isolated_cores=2,4-7 +# isolated_cores=2-23 +# +# Reserve 1 core per socket for housekeeping, isolate the rest. +# Change this for a core list or range as shown above. +isolated_cores=2-3 <1> +# +# Uncomment the 'isolate_managed_irq=Y' bellow if you want to move kernel +# managed IRQs out of isolated cores. Note that this requires kernel +# support. Please only specify this parameter if you are sure that the +# kernel supports it. +# +isolate_managed_irq=Y <2> + +# +# Set the desired combined queue count value using the parameter provided +# below. Ideally this should be set to the number of housekeeping CPUs i.e., +# in the example given below it is assumed that the system has 4 housekeeping +# (non-isolated) CPUs. +# +# netdev_queue_count=4 +---- +<1> The first two CPUs (0 and 1) are set aside for house keeping tasks and the rest are isolated for the real-time application. +<2> Set the `isolate_managed_irq` parameter to `Y` to move kernel-managed interrupt requests out of isolated cores. +.. Activate the TuneD profile: ++ +[source,terminal] +---- +# tuned-adm profile realtime-virtual-guest +---- +.. Set the real-time kernel as the default by using the GRUB boot loader command-line interface: ++ +[source,terminal] +---- +# grubby --set-default=/boot/vmlinuz- +---- +.. Set the kernel arguments by using the GRUB boot loader command-line interface: ++ +[source,terminal] +---- +# grubby --args="iommu=pt intel_iommu=on default_hugepagesz=1G idle=poll" --update-kernel=$(grubby --default-kernel) +---- . Restart the VM to apply the changes. +.Verification +* Use the `cyclictest` tool to verify that the real-time guest is configured properly: ++ +[source,terminal] +---- +# cyclictest --priority 1 --policy fifo -h 50 -a 2-3 --mainaffinity 0,1 -t 2 -m -q -i 200 -D 12h +---- +where: +`-a`:: Specifies the CPU set on which the test runs. This is the same as the isolated CPUs that you configured in the `realtime-variables.conf` file. +`-D`:: Specifies the test duration. Append `m`, `h`, or `d` to specify minutes, hours or days. + ++ +.Example output +[source,terminal] +---- +# Min Latencies: 00004 00004 +# Avg Latencies: 00004 00004 +# Max Latencies: 00014 00013 <1> +---- +<1> The `Max Latencies` value in the output must be less than 40 micro seconds. \ No newline at end of file From f396b293d580ff962f2a99c4f7efe918e06df54f Mon Sep 17 00:00:00 2001 From: Daniel Chadwick Date: Wed, 1 May 2024 15:15:01 -0400 Subject: [PATCH 009/339] ocpbugs25624: correcting RHACM product name --- modules/infrastructure-components.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure-components.adoc b/modules/infrastructure-components.adoc index 36da526a83cc..a02791fa932a 100644 --- a/modules/infrastructure-components.adoc +++ b/modules/infrastructure-components.adoc @@ -18,7 +18,7 @@ To qualify as an infrastructure node and use the included entitlement, only comp * Cluster aggregated logging * Red Hat Quay * {rh-storage-first} -* Red Hat Advanced Cluster Manager +* Red Hat Advanced Cluster Management for Kubernetes * Red Hat Advanced Cluster Security for Kubernetes * Red Hat OpenShift GitOps * Red Hat OpenShift Pipelines From 4e2a685eddff8185c615fd062e81b66f318b99b0 Mon Sep 17 00:00:00 2001 From: aravipra Date: Mon, 27 May 2024 16:58:49 +0530 Subject: [PATCH 010/339] OCPBUGS-30729: Graphic image file is changed in default clusters roles --- images/rbac.png | Bin 83938 -> 84735 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/rbac.png b/images/rbac.png index 04dea884056923b4b832b2693df921a6b17b7895..393a6ac9f79cc34894072a20658094b19bf04f19 100644 GIT binary patch delta 39362 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�?ibm5|xaNev`D8 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 From eb22b5dfcfe2695108a058066fbd629f167750b7 Mon Sep 17 00:00:00 2001 From: Daniel Chadwick Date: Wed, 17 Apr 2024 09:47:10 -0400 Subject: [PATCH 011/339] ocpbugs21585: changing label for selector node --- modules/creating-an-infra-node.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/creating-an-infra-node.adoc b/modules/creating-an-infra-node.adoc index a2f5d887d3df..26f598b6a4f6 100644 --- a/modules/creating-an-infra-node.adoc +++ b/modules/creating-an-infra-node.adoc @@ -65,10 +65,10 @@ kind: Scheduler metadata: name: cluster spec: - defaultNodeSelector: topology.kubernetes.io/region=us-east-1 <1> + defaultNodeSelector: node-role.kubernetes.io/infra="" <1> # ... ---- -<1> This example node selector deploys pods on nodes in the `us-east-1` region by default. +<1> This example node selector deploys pods on infrastructure nodes by default. .. Save the file to apply the changes. From 6bd8c16596c2d98aa40313d86e0271c5cf387341 Mon Sep 17 00:00:00 2001 From: Sabrina Jess Date: Tue, 28 May 2024 13:18:19 -0400 Subject: [PATCH 012/339] web console checkups --- modules/virt-latency-checkup-web-console.adoc | 28 +++++++++++++++++++ ...easuring-latency-vm-secondary-network.adoc | 2 +- modules/virt-storage-checkup-web-console.adoc | 21 ++++++++++++++ .../virt-running-cluster-checkups.adoc | 15 ++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 modules/virt-latency-checkup-web-console.adoc create mode 100644 modules/virt-storage-checkup-web-console.adoc diff --git a/modules/virt-latency-checkup-web-console.adoc b/modules/virt-latency-checkup-web-console.adoc new file mode 100644 index 000000000000..cd41e31f25f9 --- /dev/null +++ b/modules/virt-latency-checkup-web-console.adoc @@ -0,0 +1,28 @@ +// Module included in the following assemblies: +// +// * virt/monitoring/virt-running-cluster-checkups.adoc + +:_mod-docs-content-type: PROCEDURE +[id="virt-latency-checkup-web-console_{context}"] += Running a latency checkup in the web console + +Run a latency checkup to verify network connectivity and measure the latency between two virtual machines attached to a secondary network interface. + +.Prerequisites + +* You must add a `NetworkAttachmentDefinition` to the namespace. + +.Procedure + +. Navigate to *Virtualization* -> *Checkups* in the web console. +. Click the *Network latency* tab. +. Click *Install permissions*. +. Click *Run checkup*. +. Enter a name for the checkup in the *Name* field. +. Select a *NetworkAttachmentDefinition* from the drop-down menu. +. Optional: Set a duration for the latency sample in the *Sample duration (seconds)* field. +. Optional: Define a maximum latency time interval by enabling *Set maximum desired latency (milliseconds)* and defining the time interval. +. Optional: Target specific nodes by enabling *Select nodes* and specifying the *Source node* and *Target node*. +. Click *Run*. + +You can view the status of the latency checkup in the *Checkups* list on the *Latency checkup* tab. Click on the name of the checkup for more details. \ No newline at end of file diff --git a/modules/virt-measuring-latency-vm-secondary-network.adoc b/modules/virt-measuring-latency-vm-secondary-network.adoc index 2b2a55a61400..52b196547458 100644 --- a/modules/virt-measuring-latency-vm-secondary-network.adoc +++ b/modules/virt-measuring-latency-vm-secondary-network.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="virt-measuring-latency-vm-secondary-network_{context}"] -= Running a latency checkup += Running a latency checkup on the CLI You use a predefined checkup to verify network connectivity and measure latency between two virtual machines (VMs) that are attached to a secondary network interface. The latency checkup uses the ping utility. diff --git a/modules/virt-storage-checkup-web-console.adoc b/modules/virt-storage-checkup-web-console.adoc new file mode 100644 index 000000000000..b7a0bd652fac --- /dev/null +++ b/modules/virt-storage-checkup-web-console.adoc @@ -0,0 +1,21 @@ +// Module included in the following assemblies: +// +// * virt/monitoring/virt-running-cluster-checkups.adoc + +:_mod-docs-content-type: PROCEDURE +[id="virt-storage-checkup-web-console_{context}"] += Running a storage checkup in the web console + +Run a storage checkup to validate that storage is working correctly for virtual machines. + +.Procedure + +. Navigate to *Virtualization* -> *Checkups* in the web console. +. Click the *Storage* tab. +. Click *Install permissions*. +. Click *Run checkup*. +. Enter a name for the checkup in the *Name* field. +. Enter a timeout value for the checkup in the *Timeout (minutes)* fields. +. Click *Run*. + +You can view the status of the storage checkup in the *Checkups* list on the *Storage* tab. Click on the name of the checkup for more details. \ No newline at end of file diff --git a/virt/monitoring/virt-running-cluster-checkups.adoc b/virt/monitoring/virt-running-cluster-checkups.adoc index 49a33f6a7fab..05e2fbf35f1a 100644 --- a/virt/monitoring/virt-running-cluster-checkups.adoc +++ b/virt/monitoring/virt-running-cluster-checkups.adoc @@ -22,6 +22,21 @@ include::snippets/technology-preview.adoc[] include::modules/virt-about-cluster-checkup-framework.adoc[leveloffset=+1] +== Running cluster checkups in the web console + +Use the web console to run a latency or storage checkup on a cluster. + +Use the following procedures the first time you run a latency checkup and storage checkup in the web console. For additional checkups, click *Run checkup* on either checkup tab, and select the appropriate checkup from the drop down menu. + +[IMPORTANT] +==== +Before you run a latency checkup, you must first xref:../../virt/vm_networking/virt-connecting-vm-to-linux-bridge.adoc#virt-connecting-vm-to-linux-bridge[create a bridge interface] on the cluster nodes to connect the VM's secondary interface to any interface on the node. If you do not create a bridge interface, the VMs will not start and the job will fail. +==== + +include::modules/virt-latency-checkup-web-console.adoc[leveloffset=+2] + +include::modules/virt-storage-checkup-web-console.adoc[leveloffset=+2] + include::modules/virt-measuring-latency-vm-secondary-network.adoc[leveloffset=+1] include::modules/virt-checking-cluster-dpdk-readiness.adoc[leveloffset=+1] From d4d501887ce865fe3369e19278d39412e44c694a Mon Sep 17 00:00:00 2001 From: Frances_McDonald Date: Wed, 15 May 2024 21:48:18 +0100 Subject: [PATCH 013/339] moved info at end before procedure moved note under no 2 callout changed the link for AWS ARN updated some callouts info applied peer review comments restore deleted file changed intro and level offsets for new module in the assemblies changed format of json files applied new aws commands from new gdoc removed a space grammar changes replaced A with The updated the title applied second peer review suggestions applied pm suggestions applied SRE suggestions PM requested to move the new module further up the TOC moved AWS link to additional resources added whats new to release notes changed whats new to release notes changed whats new to release notes changed whats new to release notes made ref to classic only removed bold with core only --- ...equirements-attaching-boundary-policy.adoc | 375 ++++++++++++++++++ .../rosa-sts-about-iam-resources.adoc | 11 +- rosa_planning/rosa-sts-ocm-role.adoc | 5 +- rosa_release_notes/rosa-release-notes.adoc | 2 + 4 files changed, 390 insertions(+), 3 deletions(-) create mode 100644 modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc diff --git a/modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc b/modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc new file mode 100644 index 000000000000..133873f582c7 --- /dev/null +++ b/modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc @@ -0,0 +1,375 @@ +// Module included in the following assemblies: +// +// * rosa_planning/rosa-sts-ocm-role.adoc +// * rosa_architecture/rosa-sts-about-iam-resources.adoc +:_mod-docs-content-type: PROCEDURE +[id="rosa-sts-aws-requirements-attaching-boundary-policy_{context}"] += Permission boundaries for the installer role + +You can apply a policy as a _permissions boundary_ on an installer role. +You can use an AWS-managed policy or a customer-managed policy to set the boundary for an Amazon Web Services(AWS) Identity and Access Management (IAM) entity (user or role). The combination of policy and boundary policy limits the maximum permissions for the user or role. ROSA includes a set of three prepared permission boundary policy files, with which you can restrict permissions for the installer role since changing the installer policy itself is not supported. + +[NOTE] +==== +This feature is only supported on Red Hat OpenShift Service on AWS (classic architecture) clusters. +==== + +The permission boundary policy files are as follows: + +* The _Core_ boundary policy file contains the minimum permissions needed for ROSA (classic architecture) installer to install an {product-title} cluster. +The installer does not have permissions to create a virtual private cloud (VPC) or PrivateLink (PL). A VPC needs to be provided. +* The _VPC_ boundary policy file contains the minimum permissions needed for ROSA (classic architecture) installer to create/manage the VPC. It does not include permissions for PL or core installation. If you need to install a cluster with enough permissions for the installer to install the cluster and create/manage the VPC, but you do not need to set up PL, then use the core and VPC boundary files together with the installer role. +* The _PrivateLink (PL)_ boundary policy file contains the minimum permissions needed for ROSA (classic architecture) installer to create the AWS PL with a cluster. It does not include permissions for VPC or core installation. Provide a pre-created VPC for all PL clusters during installation. + +When using the permission boundary policy files, the following combinations apply: + +* No permission boundary policies means that the full installer policy permissions apply to your cluster. +* *Core* only sets the most restricted permissions for the installer role. The VPC and PL permissions are not included in the *Core only* boundary policy. +** Installer cannot create or manage the VPC or PL. +** You must have a customer-provided VPC, and PrivateLink (PL) is not available. +* *Core + VPC* sets the core and VPC permissions for the installer role. +** Installer cannot create or manage the PL. +** Assumes you are not using custom/BYO-VPC. +** Assumes the installer will create and manage the VPC. +* *Core + PrivateLink (PL)* means the installer can provision the PL infrastructure. +** You must have a customer-provided VPC. +** This is for a private cluster with PL. + +This example procedure is applicable for an installer role and policy with the most restriction of permissions, using only the _core_ installer permission boundary policy for ROSA. You can complete this with the AWS console or the AWS CLI. This example uses the AWS CLI and the following policy: + +.`sts_installer_core_permission_boundary_policy.json` +[%collapsible] +==== +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "ec2:AllocateAddress", + "ec2:AssociateAddress", + "ec2:AttachNetworkInterface", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CopyImage", + "ec2:CreateNetworkInterface", + "ec2:CreateSecurityGroup", + "ec2:CreateTags", + "ec2:CreateVolume", + "ec2:DeleteNetworkInterface", + "ec2:DeleteSecurityGroup", + "ec2:DeleteSnapshot", + "ec2:DeleteTags", + "ec2:DeleteVolume", + "ec2:DeregisterImage", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeDhcpOptions", + "ec2:DescribeImages", + "ec2:DescribeInstanceAttribute", + "ec2:DescribeInstanceCreditSpecifications", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:DescribeInstanceTypeOfferings", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInternetGateways", + "ec2:DescribeKeyPairs", + "ec2:DescribeNatGateways", + "ec2:DescribeNetworkAcls", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribePrefixLists", + "ec2:DescribeRegions", + "ec2:DescribeReservedInstancesOfferings", + "ec2:DescribeRouteTables", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSecurityGroupRules", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DescribeVpcAttribute", + "ec2:DescribeVpcClassicLink", + "ec2:DescribeVpcClassicLinkDnsSupport", + "ec2:DescribeVpcEndpoints", + "ec2:DescribeVpcs", + "ec2:GetConsoleOutput", + "ec2:GetEbsDefaultKmsKeyId", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:ReleaseAddress", + "ec2:RevokeSecurityGroupEgress", + "ec2:RevokeSecurityGroupIngress", + "ec2:RunInstances", + "ec2:StartInstances", + "ec2:StopInstances", + "ec2:TerminateInstances", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer", + "elasticloadbalancing:AttachLoadBalancerToSubnets", + "elasticloadbalancing:ConfigureHealthCheck", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateLoadBalancerListeners", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:DescribeInstanceHealth", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:RegisterInstancesWithLoadBalancer", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:SetLoadBalancerPoliciesOfListener", + "iam:AddRoleToInstanceProfile", + "iam:CreateInstanceProfile", + "iam:DeleteInstanceProfile", + "iam:GetInstanceProfile", + "iam:TagInstanceProfile", + "iam:GetRole", + "iam:GetRolePolicy", + "iam:GetUser", + "iam:ListAttachedRolePolicies", + "iam:ListInstanceProfiles", + "iam:ListInstanceProfilesForRole", + "iam:ListRolePolicies", + "iam:ListRoles", + "iam:ListUserPolicies", + "iam:ListUsers", + "iam:PassRole", + "iam:RemoveRoleFromInstanceProfile", + "iam:SimulatePrincipalPolicy", + "iam:TagRole", + "iam:UntagRole", + "route53:ChangeResourceRecordSets", + "route53:ChangeTagsForResource", + "route53:CreateHostedZone", + "route53:DeleteHostedZone", + "route53:GetAccountLimit", + "route53:GetChange", + "route53:GetHostedZone", + "route53:ListHostedZones", + "route53:ListHostedZonesByName", + "route53:ListResourceRecordSets", + "route53:ListTagsForResource", + "route53:UpdateHostedZoneComment", + "s3:CreateBucket", + "s3:DeleteBucket", + "s3:DeleteObject", + "s3:GetAccelerateConfiguration", + "s3:GetBucketAcl", + "s3:GetBucketCORS", + "s3:GetBucketLocation", + "s3:GetBucketLogging", + "s3:GetBucketObjectLockConfiguration", + "s3:GetBucketPolicy", + "s3:GetBucketRequestPayment", + "s3:GetBucketTagging", + "s3:GetBucketVersioning", + "s3:GetBucketWebsite", + "s3:GetEncryptionConfiguration", + "s3:GetLifecycleConfiguration", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:GetObjectTagging", + "s3:GetObjectVersion", + "s3:GetReplicationConfiguration", + "s3:ListBucket", + "s3:ListBucketVersions", + "s3:PutBucketAcl", + "s3:PutBucketTagging", + "s3:PutEncryptionConfiguration", + "s3:PutObject", + "s3:PutObjectAcl", + "s3:PutObjectTagging", + "servicequotas:GetServiceQuota", + "servicequotas:ListAWSDefaultServiceQuotas", + "sts:AssumeRole", + "sts:AssumeRoleWithWebIdentity", + "sts:GetCallerIdentity", + "tag:GetResources", + "tag:UntagResources", + "kms:DescribeKey", + "cloudwatch:GetMetricData", + "ec2:CreateRoute", + "ec2:DeleteRoute", + "ec2:CreateVpcEndpoint", + "ec2:DeleteVpcEndpoints", + "ec2:CreateVpcEndpointServiceConfiguration", + "ec2:DeleteVpcEndpointServiceConfigurations", + "ec2:DescribeVpcEndpointServiceConfigurations", + "ec2:DescribeVpcEndpointServicePermissions", + "ec2:DescribeVpcEndpointServices", + "ec2:ModifyVpcEndpointServicePermissions" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": "*", + "Condition": { + "StringEquals": { + "aws:ResourceTag/red-hat-managed": "true" + } + } + } + ] +} +---- +==== + +[IMPORTANT] +==== +To use the permission boundaries, you will need to prepare the permission boundary policy and add it to your relevant installer role in AWS IAM. +While the ROSA (`rosa`) CLI offers a permission boundary function, it applies to all roles and not just the installer role, which means it does not work with the provided permission boundary policies (which are only for the installer role). +==== + +.Prerequisites + +* You have an AWS account. +* You have the permissions required to administer AWS roles and policies. +* You have installed and configured the latest AWS (`aws`) and ROSA (`rosa`) CLIs on your workstation. +* You have already prepared your ROSA account-wide roles, includes the installer role, and the corresponding policies. If these do not exist in your AWS account, see "Creating the account-wide STS roles and policies" in _Additional resources_. + +.Procedure + +. Prepare the policy file by entering the following command in the `rosa` CLI: ++ +[source,terminal] +---- +$ curl -o ./rosa-installer-core.json https://raw.githubusercontent.com/openshift/managed-cluster-config/master/resources/sts/4.16/sts_installer_core_permission_boundary_policy.json +---- + +. Create the policy in AWS and gather its Amazon Resource Name (ARN) by entering the following command: ++ +[source,terminal] +---- +$ aws iam create-policy \ +--policy-name rosa-core-permissions-boundary-policy \ +--policy-document file://./rosa-installer-core.json \ +--description "ROSA installer core permission boundary policy, the minimum permission set, allows BYO-VPC, disallows PrivateLink" +---- ++ +.Example output +[source,terminal] +---- +{ + "Policy": { + "PolicyName": "rosa-core-permissions-boundary-policy", + "PolicyId": "", + "Arn": "arn:aws:iam:::policy/rosa-core-permissions-boundary-policy", + "Path": "/", + "DefaultVersionId": "v1", + "AttachmentCount": 0, + "PermissionsBoundaryUsageCount": 0, + "IsAttachable": true, + "CreateDate": "", + "UpdateDate": "" + } +} +---- +. Add the permission boundary policy to the installer role you want to restrict by entering the following command: ++ +[source,terminal] +---- +$ aws iam put-role-permissions-boundary \ +--role-name ManagedOpenShift-Installer-Role \ +--permissions-boundary arn:aws:iam:::policy/rosa-core-permissions-boundary-policy +---- + +. Display the installer role to validate attached policies (including permissions boundary) by entering the following command in the `rosa` CLI: ++ +[source,terminal] +---- +$ aws iam get-role --role-name ManagedOpenShift-Installer-Role \ +--output text | grep PERMISSIONSBOUNDARY +---- ++ +.Example output +[source,terminal] +---- +PERMISSIONSBOUNDARY arn:aws:iam:::policy/rosa-core-permissions-boundary-policy Policy +---- ++ + ++ +For more examples of PL and VPC permission boundary policies see: ++ +.`sts_installer_privatelink_permission_boundary_policy.json` +[%collapsible] +==== +[source,json] +---- +{ +"Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:ModifyVpcEndpointServiceConfiguration", + "route53:ListHostedZonesByVPC", + "route53:CreateVPCAssociationAuthorization", + "route53:AssociateVPCWithHostedZone", + "route53:DeleteVPCAssociationAuthorization", + "route53:DisassociateVPCFromHostedZone", + "route53:ChangeResourceRecordSets" + ], + "Resource": "*" + } + ] +} +---- +==== ++ +.`sts_installer_vpc_permission_boundary_policy.json` +[%collapsible] +==== +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:AssociateDhcpOptions", + "ec2:AssociateRouteTable", + "ec2:AttachInternetGateway", + "ec2:CreateDhcpOptions", + "ec2:CreateInternetGateway", + "ec2:CreateNatGateway", + "ec2:CreateRouteTable", + "ec2:CreateSubnet", + "ec2:CreateVpc", + "ec2:DeleteDhcpOptions", + "ec2:DeleteInternetGateway", + "ec2:DeleteNatGateway", + "ec2:DeleteRouteTable", + "ec2:DeleteSubnet", + "ec2:DeleteVpc", + "ec2:DetachInternetGateway", + "ec2:DisassociateRouteTable", + "ec2:ModifySubnetAttribute", + "ec2:ModifyVpcAttribute", + "ec2:ReplaceRouteTableAssociation" + ], + "Resource": "*" + } + ] +} +---- +==== diff --git a/rosa_architecture/rosa-sts-about-iam-resources.adoc b/rosa_architecture/rosa-sts-about-iam-resources.adoc index 26a0afbc2e5a..333ed4f05a15 100644 --- a/rosa_architecture/rosa-sts-about-iam-resources.adoc +++ b/rosa_architecture/rosa-sts-about-iam-resources.adoc @@ -76,14 +76,21 @@ include::modules/rosa-sts-account-wide-roles-and-policies.adoc[leveloffset=+1] * For a definition of OpenShift major, minor, and patch versions, see xref:../rosa_architecture/rosa_policy_service_definition/rosa-life-cycle.adoc#rosa-life-cycle-definitions_rosa-life-cycle[the {product-title} update life cycle]. include::modules/rosa-sts-account-wide-role-and-policy-commands.adoc[leveloffset=+2] +include::modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For more information, see link:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html[Permissions boundaries for IAM entities] (AWS documentation). +* For more information about creating the required account-wide STS roles and policies see xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly.adoc#rosa-sts-creating-account-wide-sts-roles-and-policies_rosa-sts-creating-a-cluster-quickly[Creating the account-wide STS roles and policies]. + include::modules/rosa-sts-operator-roles.adoc[leveloffset=+1] include::modules/rosa-sts-operator-role-commands.adoc[leveloffset=+2] include::modules/rosa-sts-about-operator-role-prefixes.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources - -* For steps to create the cluster-specific Operator IAM roles using a custom prefix, see xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-customizations-cli_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster with customizations using the CLI] or xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-customizations-ocm_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster with customizations by using {cluster-manager}]. + For steps to create the cluster-specific Operator IAM roles using a custom prefix, see xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-customizations-cli_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster with customizations using the CLI] or xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-customizations-ocm_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster with customizations by using {cluster-manager}]. [id="rosa-sts-oidc-provider-requirements-for-operators_{context}"] == Open ID Connect (OIDC) requirements for Operator authentication diff --git a/rosa_planning/rosa-sts-ocm-role.adoc b/rosa_planning/rosa-sts-ocm-role.adoc index b15473ae00b8..0516815591c5 100644 --- a/rosa_planning/rosa-sts-ocm-role.adoc +++ b/rosa_planning/rosa-sts-ocm-role.adoc @@ -60,8 +60,11 @@ If you unlink or delete your `user-role` IAM role prior to deleting your cluster include::modules/rosa-sts-aws-requirements-association-concept.adoc[leveloffset=+1] include::modules/rosa-sts-aws-requirements-creating-association.adoc[leveloffset=+2] include::modules/rosa-sts-aws-requirements-creating-multi-association.adoc[leveloffset=+2] +include::modules/rosa-sts-aws-requirements-attaching-boundary-policy.adoc[leveloffset=+1] [role="_additional-resources"] == Additional resources -* See xref:../support/troubleshooting/rosa-troubleshooting-iam-resources.adoc#rosa-sts-ocm-roles-and-permissions-troubleshooting[Troubleshooting IAM roles] +* See link:https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html[Permissions boundaries for IAM entities] (AWS documentation). +* See xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly.adoc#rosa-sts-creating-account-wide-sts-roles-and-policies_rosa-sts-creating-a-cluster-quickly[Creating the account-wide STS roles and policies]. +* See xref:../support/troubleshooting/rosa-troubleshooting-iam-resources.adoc#rosa-sts-ocm-roles-and-permissions-troubleshooting[Troubleshooting IAM roles]. * See xref:../rosa_architecture/rosa-sts-about-iam-resources.adoc#rosa-sts-account-wide-roles-and-policies[Account-wide IAM role and policy reference] for a list of IAM roles needed for cluster creation. \ No newline at end of file diff --git a/rosa_release_notes/rosa-release-notes.adoc b/rosa_release_notes/rosa-release-notes.adoc index c23701b6e7f4..96d863189318 100644 --- a/rosa_release_notes/rosa-release-notes.adoc +++ b/rosa_release_notes/rosa-release-notes.adoc @@ -16,6 +16,8 @@ toc::[] [id="rosa-q2-2024_{context}"] === Q2 2024 +* **Permission boundaries for the installer role policy.** You can apply a policy as a _permissions boundary_ on the ROSA installer role. The combination of policy and boundary policy limits the maximum permissions for the Amazon Web Services(AWS) Identity and Access Management (IAM) entity role. ROSA includes a set of three prepared permission boundary policy files, with which you can restrict permissions for the installer role since changing the installer policy itself is not supported. For more information, see xref:../rosa_architecture/rosa-sts-about-iam-resources.adoc#rosa-sts-aws-requirements-attaching-boundary-policy_rosa-sts-about-iam-resources[Permission boundaries for the installer role]. This is applicable only to Red Hat OpenShift Service on AWS (classic architecture). + * **Cluster delete protection.** You can now enable the cluster delete protection option, which helps to prevent you from accidentally deleting a cluster. For more information on using the cluster delete protection option with the ROSA CLI, see xref:../cli_reference/rosa_cli/rosa-manage-objects-cli.adoc#rosa-edit-cluster_rosa-managing-objects-cli[edit cluster]. For more information on using the cluster delete protection option in the UI, see xref:../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly.adoc#rosa-sts-creating-a-cluster-using-defaults-ocm_rosa-sts-creating-a-cluster-quickly[Creating a cluster with the default options using OpenShift Cluster Manager]. * **ROSA CLI update.** The ROSA CLI (`rosa`) was updated to a new version. For information about what has changed in this release, see the link:https://github.com/openshift/rosa/releases/tag/v1.2.39[ROSA CLI release notes]. For more information about the ROSA CLI (`rosa`), see xref:../cli_reference/rosa_cli/rosa-get-started-cli.adoc#rosa-about_rosa-getting-started-cli[About the ROSA CLI]. From c566bfc2486f4dd8bcf7460b171c1e90512edeef Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Fri, 31 May 2024 10:12:54 -0400 Subject: [PATCH 014/339] replace attributes in assembly titles --- _topic_maps/_topic_map.yml | 2 +- .../cpmso_provider_configurations/cpmso-config-options-aws.adoc | 2 +- .../cpmso-config-options-azure.adoc | 2 +- .../cpmso_provider_configurations/cpmso-config-options-gcp.adoc | 2 +- .../cpmso-config-options-openstack.adoc | 2 +- .../cpmso-config-options-vsphere.adoc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index d1f03886f0f4..38e304b25f63 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2324,7 +2324,7 @@ Topics: File: cpmso-config-options-gcp - Name: Control plane configuration options for Nutanix File: cpmso-config-options-nutanix - - Name: Control plane configuration options for Red Hat OpenStack + - Name: Control plane configuration options for Red Hat OpenStack Platform File: cpmso-config-options-openstack - Name: Control plane configuration options for VMware vSphere File: cpmso-config-options-vsphere diff --git a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-aws.adoc b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-aws.adoc index 7de57e1b9b22..6dea46ccf6d7 100644 --- a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-aws.adoc +++ b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-aws.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="cpmso-config-options-aws"] -= Control plane configuration options for {aws-full} += Control plane configuration options for Amazon Web Services include::_attributes/common-attributes.adoc[] :context: cpmso-config-options-aws diff --git a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-azure.adoc b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-azure.adoc index 61c77c8dd3d0..adf6afe1cfef 100644 --- a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-azure.adoc +++ b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-azure.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="cpmso-config-options-azure"] -= Control plane configuration options for {azure-full} += Control plane configuration options for Microsoft Azure include::_attributes/common-attributes.adoc[] :context: cpmso-config-options-azure diff --git a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-gcp.adoc b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-gcp.adoc index 33f44b73f43d..7b268b443415 100644 --- a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-gcp.adoc +++ b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-gcp.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="cpmso-config-options-gcp"] -= Control plane configuration options for {gcp-full} += Control plane configuration options for Google Cloud Platform include::_attributes/common-attributes.adoc[] :context: cpmso-config-options-gcp diff --git a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-openstack.adoc b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-openstack.adoc index a5c4ad21845a..6976bdec89ce 100644 --- a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-openstack.adoc +++ b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-openstack.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="cpmso-config-options-openstack"] -= Control plane configuration options for {rh-openstack} += Control plane configuration options for Red Hat OpenStack Platform include::_attributes/common-attributes.adoc[] :context: cpmso-config-options-openstack diff --git a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-vsphere.adoc b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-vsphere.adoc index f50d49b2350c..4890115d643e 100644 --- a/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-vsphere.adoc +++ b/machine_management/control_plane_machine_management/cpmso_provider_configurations/cpmso-config-options-vsphere.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="cpmso-config-options-vsphere"] -= Control plane configuration options for {vmw-full} += Control plane configuration options for VMware vSphere include::_attributes/common-attributes.adoc[] :context: cpmso-config-options-vsphere From afcce6306177ce4bccd8a93b76c3ee1179a53f9f Mon Sep 17 00:00:00 2001 From: Eliska Romanova Date: Wed, 22 May 2024 12:56:37 +0200 Subject: [PATCH 015/339] OBSDOCS-1068: Update supported monitoring component versions matrix for the OCP 4.16 release --- ...ort-version-matrix-for-monitoring-components.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/monitoring-support-version-matrix-for-monitoring-components.adoc b/modules/monitoring-support-version-matrix-for-monitoring-components.adoc index 329b054de5f3..edf91f1cd7fa 100644 --- a/modules/monitoring-support-version-matrix-for-monitoring-components.adoc +++ b/modules/monitoring-support-version-matrix-for-monitoring-components.adoc @@ -10,17 +10,17 @@ The following matrix contains information about versions of monitoring component .{product-title} and component versions |=== -|{product-title} |Prometheus Operator |Prometheus |Prometheus Adapter |Metrics Server (Technology Preview) |Alertmanager |kube-state-metrics agent |monitoring-plugin |node-exporter agent |Thanos +|{product-title} |Prometheus Operator |Prometheus |Metrics Server |Alertmanager |kube-state-metrics agent |monitoring-plugin |node-exporter agent |Thanos -|4.16 |0.73.2 |2.51.2 |0.11.2 |0.7.1 |0.26.0 |2.12.0 |1.0.0 |1.8.0 |0.35.0 +|4.16 |0.73.2 |2.52.0 |0.7.1 |0.26.0 |2.12.0 |1.0.0 |1.8.0 |0.35.0 -|4.15 |0.70.0 |2.48.0 |0.11.2 |0.6.4 |0.26.0 |2.10.1 |1.0.0 |1.7.0 |0.32.5 +|4.15 |0.70.0 |2.48.0 |0.6.4 |0.26.0 |2.10.1 |1.0.0 |1.7.0 |0.32.5 -|4.14 |0.67.1 |2.46.0 |0.10.0 |N/A |0.25.0 |2.9.2 |1.0.0 |1.6.1 |0.30.2 +|4.14 |0.67.1 |2.46.0 |N/A |0.25.0 |2.9.2 |1.0.0 |1.6.1 |0.30.2 -|4.13 |0.63.0 |2.42.0 |0.10.0 |N/A |0.25.0 |2.8.1 |N/A |1.5.0 |0.30.2 +|4.13 |0.63.0 |2.42.0 |N/A |0.25.0 |2.8.1 |N/A |1.5.0 |0.30.2 -|4.12 |0.60.1 |2.39.1 |0.10.0 |N/A |0.24.0 |2.6.0 |N/A |1.4.0 |0.28.1 +|4.12 |0.60.1 |2.39.1 |N/A |0.24.0 |2.6.0 |N/A |1.4.0 |0.28.1 |=== [NOTE] From 2aa2714af9a3aaf287bbe55d5da77fe5f6d04858 Mon Sep 17 00:00:00 2001 From: StephenJamesSmith Date: Thu, 30 May 2024 15:26:23 -0400 Subject: [PATCH 016/339] TELCODOCS-1890: Remove H200 from MIG note in GPU enablement --- modules/nvidia-gpu-enablement.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nvidia-gpu-enablement.adoc b/modules/nvidia-gpu-enablement.adoc index c554e5b68aa6..23e9037f2cf8 100644 --- a/modules/nvidia-gpu-enablement.adoc +++ b/modules/nvidia-gpu-enablement.adoc @@ -14,5 +14,5 @@ image::512_OpenShift_NVIDIA_GPU_enablement_1223.png[NVIDIA GPU enablement] [NOTE] ==== -MIG is only supported with A30, A100, A100X, A800, AX800, H100, H200, and H800. +MIG is only supported with A30, A100, A100X, A800, AX800, H100, and H800. ==== From 936086c3fd5a1cd55b3b91fba230bb84749303c6 Mon Sep 17 00:00:00 2001 From: Brian Burt Date: Wed, 29 May 2024 10:00:11 -0400 Subject: [PATCH 017/339] OBSDOCS-1098-remove-prometheus-adapter-refs-for-4.16 --- images/monitoring-architecture.png | Bin 74512 -> 86609 bytes modules/infrastructure-moving-monitoring.adoc | 2 +- ...nd-requests-for-monitoring-components.adoc | 2 +- modules/monitoring-common-terms.adoc | 6 +++--- ...ng-configurable-monitoring-components.adoc | 6 +++--- ...itoring-default-monitoring-components.adoc | 12 +++--------- ...nd-requests-for-monitoring-components.adoc | 12 ++++++------ .../configuring-the-monitoring-stack.adoc | 5 +---- 8 files changed, 18 insertions(+), 27 deletions(-) diff --git a/images/monitoring-architecture.png b/images/monitoring-architecture.png index b3d15f0cbbebe2227c72901f325e548fbabc08e2..5f2be05da69e7656d55ee4d3eef897d352f19cbd 100644 GIT binary patch literal 86609 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

~$9S<>VML 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ⅈd6QA-sE2)#B;^Jr)G|1Xm|HBRe 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 diff --git a/modules/infrastructure-moving-monitoring.adoc b/modules/infrastructure-moving-monitoring.adoc index c1852ae07167..a75076cc8795 100644 --- a/modules/infrastructure-moving-monitoring.adoc +++ b/modules/infrastructure-moving-monitoring.adoc @@ -57,7 +57,7 @@ data: - key: node-role.kubernetes.io/infra value: reserved effect: NoExecute - k8sPrometheusAdapter: + metricsServer: nodeSelector: node-role.kubernetes.io/infra: "" tolerations: diff --git a/modules/monitoring-about-specifying-limits-and-requests-for-monitoring-components.adoc b/modules/monitoring-about-specifying-limits-and-requests-for-monitoring-components.adoc index 6d6ec7ca0a12..1131a8e800fa 100644 --- a/modules/monitoring-about-specifying-limits-and-requests-for-monitoring-components.adoc +++ b/modules/monitoring-about-specifying-limits-and-requests-for-monitoring-components.adoc @@ -14,7 +14,7 @@ You can configure resource limits and request settings for core platform monitor * node-exporter * openshift-state-metrics * Prometheus (for core platform monitoring and for user-defined projects) -* Prometheus Adapter +* Metrics Server * Prometheus Operator and its admission webhook service * Telemeter Client * Thanos Querier diff --git a/modules/monitoring-common-terms.adoc b/modules/monitoring-common-terms.adoc index 025f506b4f0b..56318f6a327a 100644 --- a/modules/monitoring-common-terms.adoc +++ b/modules/monitoring-common-terms.adoc @@ -54,6 +54,9 @@ Kubernetes scheduler allocates pods to nodes. labels:: Labels are key-value pairs that you can use to organize and select subsets of objects such as a pod. +Metrics Server:: +The Metrics Server monitoring component collects resource metrics and exposes them in the `metrics.k8s.io` Metrics API service for use by other tools and APIs, which frees the core platform Prometheus stack from handling this functionality. + node:: A worker machine in the {product-title} cluster. A node is either a virtual machine (VM) or a physical machine. @@ -75,9 +78,6 @@ The pod is the smallest logical unit in Kubernetes. A pod is comprised of one or Prometheus:: Prometheus is the monitoring system on which the {product-title} monitoring stack is based. Prometheus is a time-series database and a rule evaluation engine for metrics. Prometheus sends alerts to Alertmanager for processing. -Prometheus adapter:: -The Prometheus Adapter translates Kubernetes node and pod queries for use in Prometheus. The resource metrics that are translated include CPU and memory utilization. The Prometheus Adapter exposes the cluster resource metrics API for horizontal pod autoscaling. - Prometheus Operator:: The Prometheus Operator (PO) in the `openshift-monitoring` project creates, configures, and manages platform Prometheus and Alertmanager instances. It also automatically generates monitoring target configurations based on Kubernetes label queries. diff --git a/modules/monitoring-configurable-monitoring-components.adoc b/modules/monitoring-configurable-monitoring-components.adoc index ac31029b3ff6..173a0ad2e257 100644 --- a/modules/monitoring-configurable-monitoring-components.adoc +++ b/modules/monitoring-configurable-monitoring-components.adoc @@ -5,9 +5,9 @@ [id="configurable-monitoring-components_{context}"] = Configurable monitoring components -This table shows the monitoring components you can configure and the keys used to specify the components in the +This table shows the monitoring components you can configure and the keys used to specify the components in the ifndef::openshift-dedicated,openshift-rosa[] -`cluster-monitoring-config` and +`cluster-monitoring-config` and endif::openshift-dedicated,openshift-rosa[] `user-workload-monitoring-config` `ConfigMap` objects. @@ -30,7 +30,7 @@ ifndef::openshift-dedicated,openshift-rosa[] |monitoring-plugin | `monitoringPlugin` | |openshift-state-metrics |`openshiftStateMetrics` | |Telemeter Client |`telemeterClient` | -|Prometheus Adapter |`k8sPrometheusAdapter` | +|Metrics Server |`metricsServer` | |Thanos Querier |`thanosQuerier` | |Thanos Ruler | |`thanosRuler` |==== diff --git a/modules/monitoring-default-monitoring-components.adoc b/modules/monitoring-default-monitoring-components.adoc index 38b3780e9530..1b0d93be811b 100644 --- a/modules/monitoring-default-monitoring-components.adoc +++ b/modules/monitoring-default-monitoring-components.adoc @@ -23,14 +23,8 @@ By default, the {product-title} {product-version} monitoring stack includes thes |Prometheus |Prometheus is the monitoring system on which the {product-title} monitoring stack is based. Prometheus is a time-series database and a rule evaluation engine for metrics. Prometheus sends alerts to Alertmanager for processing. -|Prometheus Adapter -|The Prometheus Adapter (PA in the preceding diagram) translates Kubernetes node and pod queries for use in Prometheus. The resource metrics that are translated include CPU and memory utilization metrics. The Prometheus Adapter exposes the cluster resource metrics API for horizontal pod autoscaling. The Prometheus Adapter is also used by the `oc adm top nodes` and `oc adm top pods` commands. - -|Metrics Server (Technology Preview) -|If enabled, the Metrics Server component collects resource metrics and exposes them in the `metrics.k8s.io` Metrics API service for use by other tools and APIs, which frees the core platform Prometheus stack from handling this functionality. - -The Technology Preview of the Metrics Server component is automatically installed instead of Prometheus Adapter if you configure the `FeatureGate` custom resource with the `TechPreviewNoUpgrade` option. -For more information about the support scope of Red{nbsp}Hat Technology Preview features, see link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview Features Support Scope]. +|Metrics Server +|The Metrics Server component (MS in the preceding diagram) collects resource metrics and exposes them in the `metrics.k8s.io` Metrics API service for use by other tools and APIs, which frees the core platform Prometheus stack from handling this functionality. Note that with the {product-title} 4.16 release, Metrics Server replaces Prometheus Adapter. |Alertmanager |The Alertmanager service handles alerts received from Prometheus. Alertmanager is also responsible for sending the alerts to external notification systems. @@ -39,7 +33,7 @@ For more information about the support scope of Red{nbsp}Hat Technology Preview |The kube-state-metrics exporter agent (KSM in the preceding diagram) converts Kubernetes objects to metrics that Prometheus can use. |monitoring-plugin -|The monitoring-plugin dynamic plugin component deploys the monitoring pages in the *Observe* section of the {product-title} web console. +|The monitoring-plugin dynamic plugin component deploys the monitoring pages in the *Observe* section of the {product-title} web console. You can use Cluster Monitoring Operator (CMO) config map settings to manage monitoring-plugin resources for the web console pages. |openshift-state-metrics agent diff --git a/modules/monitoring-specifying-limits-and-requests-for-monitoring-components.adoc b/modules/monitoring-specifying-limits-and-requests-for-monitoring-components.adoc index 87c1f7ca2503..d448881a985f 100644 --- a/modules/monitoring-specifying-limits-and-requests-for-monitoring-components.adoc +++ b/modules/monitoring-specifying-limits-and-requests-for-monitoring-components.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="specifying-limits-and-resource-requests-for-monitoring-components_{context}"] -= Specifying limits and requests for monitoring components += Specifying limits and requests for monitoring components To configure CPU and memory resources, specify values for resource limits and requests in the appropriate `ConfigMap` object for the namespace in which the monitoring component is located: @@ -72,13 +72,13 @@ data: requests: cpu: 200m memory: 500Mi - k8sPrometheusAdapter: + metricsServer: resources: - limits: - cpu: 500m - memory: 1Gi requests: - cpu: 200m + cpu: 10m + memory: 50Mi + limits: + cpu: 50m memory: 500Mi kubeStateMetrics: resources: diff --git a/observability/monitoring/configuring-the-monitoring-stack.adoc b/observability/monitoring/configuring-the-monitoring-stack.adoc index ff0dc9bd330c..3a1b8290005b 100644 --- a/observability/monitoring/configuring-the-monitoring-stack.adoc +++ b/observability/monitoring/configuring-the-monitoring-stack.adoc @@ -301,13 +301,10 @@ include::modules/monitoring-enabling-query-logging-for-thanos-querier.adoc[level * See xref:../../observability/monitoring/configuring-the-monitoring-stack.adoc#preparing-to-configure-the-monitoring-stack[Preparing to configure the monitoring stack] for steps to create monitoring config maps. endif::openshift-dedicated,openshift-rosa[] -// Setting audit log levels for the Prometheus Adapter -ifndef::openshift-dedicated,openshift-rosa[] -include::modules/monitoring-setting-audit-log-levels-for-the-prometheus-adapter.adoc[leveloffset=+1] - [role="_additional-resources"] .Additional resources +ifndef::openshift-dedicated,openshift-rosa[] * See xref:../../observability/monitoring/configuring-the-monitoring-stack.adoc#preparing-to-configure-the-monitoring-stack[Preparing to configure the monitoring stack] for steps to create monitoring config maps. endif::openshift-dedicated,openshift-rosa[] From 4e994d7db3f250054f5d54069565516bf673ef85 Mon Sep 17 00:00:00 2001 From: Sebastian Kopacz Date: Fri, 31 May 2024 11:18:10 -0400 Subject: [PATCH 018/339] Fixing TechPreviewNoUpgrade typos --- modules/arch-platform-operators.adoc | 2 +- modules/olm-installing-po-after.adoc | 4 ++-- operators/admin/olm-managing-po.adoc | 2 +- .../olm_v1/olmv1-installing-an-operator-from-a-catalog.adoc | 2 +- operators/olm_v1/olmv1-managing-plain-bundles.adoc | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/arch-platform-operators.adoc b/modules/arch-platform-operators.adoc index 3e70106e974a..abe61345e889 100644 --- a/modules/arch-platform-operators.adoc +++ b/modules/arch-platform-operators.adoc @@ -22,4 +22,4 @@ Operator Lifecycle Manager (OLM) introduces a new type of Operator called _platf Using the existing cluster capabilities feature in {product-title}, cluster administrators can already disable a subset of Cluster Version Operator-based (CVO) components considered non-essential to the initial payload prior to cluster installation. Platform Operators iterate on this model by providing additional customization options. Through the platform Operator mechanism, which relies on resources from the RukPak component, OLM-based Operators can now be installed at cluster installation time and can block cluster rollout if the Operator fails to install successfully. -In {product-title} 4.12, this Technology Preview release focuses on the basic platform Operator mechanism and builds a foundation for expanding the concept in upcoming releases. You can use the cluster-wide `PlatformOperator` API to configure Operators before or after cluster creation on clusters that have enabled the `TechPreviewNoUpgrades` feature set. \ No newline at end of file +In {product-title} 4.12, this Technology Preview release focuses on the basic platform Operator mechanism and builds a foundation for expanding the concept in upcoming releases. You can use the cluster-wide `PlatformOperator` API to configure Operators before or after cluster creation on clusters that have enabled the `TechPreviewNoUpgrade` feature set. \ No newline at end of file diff --git a/modules/olm-installing-po-after.adoc b/modules/olm-installing-po-after.adoc index 18637156c917..1c8aeba9e35e 100644 --- a/modules/olm-installing-po-after.adoc +++ b/modules/olm-installing-po-after.adoc @@ -6,7 +6,7 @@ [id="olm-installing-po-after_{context}"] = Installing platform Operators after cluster creation -As a cluster administrator, you can install platform Operators after cluster creation on clusters that have enabled the `TechPreviewNoUpgrades` feature set by using the cluster-wide `PlatformOperator` API. +As a cluster administrator, you can install platform Operators after cluster creation on clusters that have enabled the `TechPreviewNoUpgrade` feature set by using the cluster-wide `PlatformOperator` API. .Procedure @@ -35,7 +35,7 @@ $ oc apply -f service-mesh-po.yaml + [NOTE] ==== -If your cluster does not have the `TechPreviewNoUpgrades` feature set enabled, the object creation fails with the following message: +If your cluster does not have the `TechPreviewNoUpgrade` feature set enabled, the object creation fails with the following message: [source,terminal] ---- diff --git a/operators/admin/olm-managing-po.adoc b/operators/admin/olm-managing-po.adoc index a9f17134d25c..4074cf1e2442 100644 --- a/operators/admin/olm-managing-po.adoc +++ b/operators/admin/olm-managing-po.adoc @@ -24,7 +24,7 @@ include::modules/olm-po-techpreview.adoc[leveloffset=+2] == Prerequisites - Access to an {product-title} cluster using an account with `cluster-admin` permissions. -- The `TechPreviewNoUpgrades` feature set enabled on the cluster. +- The `TechPreviewNoUpgrade` feature set enabled on the cluster. + [WARNING] ==== diff --git a/operators/olm_v1/olmv1-installing-an-operator-from-a-catalog.adoc b/operators/olm_v1/olmv1-installing-an-operator-from-a-catalog.adoc index 07b429930ece..00a05fe62c74 100644 --- a/operators/olm_v1/olmv1-installing-an-operator-from-a-catalog.adoc +++ b/operators/olm_v1/olmv1-installing-an-operator-from-a-catalog.adoc @@ -21,7 +21,7 @@ include::snippets/technology-preview.adoc[] -- include::snippets/olmv1-cli-only.adoc[] -- -* The `TechPreviewNoUpgrades` feature set enabled on the cluster +* The `TechPreviewNoUpgrade` feature set enabled on the cluster + [WARNING] ==== diff --git a/operators/olm_v1/olmv1-managing-plain-bundles.adoc b/operators/olm_v1/olmv1-managing-plain-bundles.adoc index 08a5a77736e4..55db28763df1 100644 --- a/operators/olm_v1/olmv1-managing-plain-bundles.adoc +++ b/operators/olm_v1/olmv1-managing-plain-bundles.adoc @@ -35,7 +35,7 @@ As a cluster administrator, you can build and publish a file-based catalog that -- include::snippets/olmv1-cli-only.adoc[] -- -* The `TechPreviewNoUpgrades` feature set enabled on the cluster +* The `TechPreviewNoUpgrade` feature set enabled on the cluster + [WARNING] ==== From c0cf962f63b63373714df7d6c1cdc52d26801cd9 Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Mon, 13 May 2024 14:52:15 -0400 Subject: [PATCH 019/339] OSDOCS-10291: CCM as optional capability --- installing/cluster-capabilities.adoc | 3 ++ ...ter-cloud-controller-manager-operator.adoc | 44 ++++++++++++++++++- modules/installation-initializing-manual.adoc | 2 +- modules/installation-vsphere-config-yaml.adoc | 2 +- snippets/capabilities-table.adoc | 3 ++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/installing/cluster-capabilities.adoc b/installing/cluster-capabilities.adoc index 3fdd4f32dbfc..1d3f1568ebcf 100644 --- a/installing/cluster-capabilities.adoc +++ b/installing/cluster-capabilities.adoc @@ -40,6 +40,9 @@ include::modules/cluster-bare-metal-operator.adoc[leveloffset=+2] // Build capability include::modules/build-config-capability.adoc[leveloffset=+2] +// Cloud controller manager capability +include::modules/cluster-cloud-controller-manager-operator.adoc[leveloffset=+2] + // Cloud credential capability include::modules/cloud-credential-operator.adoc[leveloffset=+2] diff --git a/modules/cluster-cloud-controller-manager-operator.adoc b/modules/cluster-cloud-controller-manager-operator.adoc index 82fb199097b8..45dcce0edf7c 100644 --- a/modules/cluster-cloud-controller-manager-operator.adoc +++ b/modules/cluster-cloud-controller-manager-operator.adoc @@ -2,12 +2,43 @@ // // * operators/operator-reference.adoc +ifeval::["{context}" == "cluster-operators-ref"] +:operators: +endif::[] +ifeval::["{context}" == "cluster-capabilities"] +:cluster-caps: +endif::[] + [id="cluster-cloud-controller-manager-operator_{context}"] -= Cluster Cloud Controller Manager Operator +ifdef::operators[= Cloud Controller Manager Operator] +ifdef::cluster-caps[= Cloud controller manager capability] [discrete] == Purpose +ifdef::cluster-caps[] +The Cloud Controller Manager Operator provides features for the `CloudControllerManager` capability. + +[NOTE] +==== +Currently, disabling the `CloudControllerManager` capability is not supported on all platforms. +==== + +You can determine if your cluster supports disabling the `CloudControllerManager` capability by checking values in the installation configuration (`install-config.yaml`) file for your cluster. + +In the `install-config.yaml` file, locate the `platform` parameter. + +* If the value of the `platform` parameter is `Baremetal` or `None`, you can disable the `CloudControllerManager` capability on your cluster. + +* If the value of the `platform` parameter is `External`, locate the `platform.external.cloudControllerManager` parameter. +If the value of the `platform.external.cloudControllerManager` parameter is `None`, you can disable the `CloudControllerManager` capability on your cluster. + +[IMPORTANT] +==== +If these parameters contain any other values than those listed, you cannot disable the `CloudControllerManager` capability on your cluster. +==== +endif::cluster-caps[] + [NOTE] ==== The status of this Operator is General Availability for {aws-first}, {gcp-first}, {ibm-cloud-name}, global {azure-full}, Microsoft Azure Stack Hub, Nutanix, {rh-openstack-first}, and {vmw-full}. @@ -15,7 +46,7 @@ The status of this Operator is General Availability for {aws-first}, {gcp-first} The Operator is available as a link:https://access.redhat.com/support/offerings/techpreview[Technology Preview] for {alibaba} and {ibm-power-server-name}. ==== -The Cluster Cloud Controller Manager Operator manages and updates the cloud controller managers deployed on top of {product-title}. The Operator is based on the Kubebuilder framework and `controller-runtime` libraries. It is installed via the Cluster Version Operator (CVO). +The Cloud Controller Manager Operator manages and updates the cloud controller managers deployed on top of {product-title}. The Operator is based on the Kubebuilder framework and `controller-runtime` libraries. It is installed via the Cluster Version Operator (CVO). It contains the following components: @@ -24,7 +55,16 @@ It contains the following components: By default, the Operator exposes Prometheus metrics through the `metrics` service. +ifdef::operators[] [discrete] == Project link:https://github.com/openshift/cluster-cloud-controller-manager-operator[cluster-cloud-controller-manager-operator] +endif::operators[] + +ifeval::["{context}" == "cluster-operators-ref"] +:!operators: +endif::[] +ifeval::["{context}" == "cluster-capabilities"] +:!cluster-caps: +endif::[] \ No newline at end of file diff --git a/modules/installation-initializing-manual.adoc b/modules/installation-initializing-manual.adoc index 4441b3a35985..69e7d8419791 100644 --- a/modules/installation-initializing-manual.adoc +++ b/modules/installation-initializing-manual.adoc @@ -89,7 +89,7 @@ Installing the cluster requires that you manually create the installation config ifdef::vsphere-upi,restricted-upi[] [IMPORTANT] ==== -The Cluster Cloud Controller Manager Operator performs a connectivity check on a provided hostname or IP address. Ensure that you specify a hostname or an IP address to a reachable vCenter server. If you provide metadata to a non-existent vCenter server, installation of the cluster fails at the bootstrap stage. +The Cloud Controller Manager Operator performs a connectivity check on a provided hostname or IP address. Ensure that you specify a hostname or an IP address to a reachable vCenter server. If you provide metadata to a non-existent vCenter server, installation of the cluster fails at the bootstrap stage. ==== endif::vsphere-upi,restricted-upi[] diff --git a/modules/installation-vsphere-config-yaml.adoc b/modules/installation-vsphere-config-yaml.adoc index 40aaa9b7bb20..869e09d87489 100644 --- a/modules/installation-vsphere-config-yaml.adoc +++ b/modules/installation-vsphere-config-yaml.adoc @@ -150,7 +150,7 @@ If you must specify VMs across multiple datastores, use a `datastore` object to + [IMPORTANT] ==== -The Cluster Cloud Controller Manager Operator performs a connectivity check on a provided hostname or IP address. Ensure that you specify a hostname or an IP address to a reachable vCenter server. If you provide metadata to a non-existent vCenter server, installation of the cluster fails at the bootstrap stage. +The Cloud Controller Manager Operator performs a connectivity check on a provided hostname or IP address. Ensure that you specify a hostname or an IP address to a reachable vCenter server. If you provide metadata to a non-existent vCenter server, installation of the cluster fails at the bootstrap stage. ==== <13> The vSphere disk provisioning method. ifndef::openshift-origin[] diff --git a/snippets/capabilities-table.adoc b/snippets/capabilities-table.adoc index 502228066832..b9bfa78fc74f 100644 --- a/snippets/capabilities-table.adoc +++ b/snippets/capabilities-table.adoc @@ -25,6 +25,9 @@ The following table describes the `baselineCapabilitySet` values. |`v4.15` |Specify this option when you want to enable the default capabilities for {product-title} 4.15. By specifying `v4.15`, capabilities that are introduced in newer versions of {product-title} are not enabled. The default capabilities in {product-title} 4.15 are `baremetal`, `MachineAPI`, `marketplace`, `OperatorLifecycleManager`, `openshift-samples`, `Console`, `Insights`, `Storage`, `CSISnapshot`, `NodeTuning`, `ImageRegistry`, `Build`, `CloudCredential`, and `DeploymentConfig`. +|`v4.16` +|Specify this option when you want to enable the default capabilities for {product-title} 4.16. By specifying `v4.16`, capabilities that are introduced in newer versions of {product-title} are not enabled. The default capabilities in {product-title} 4.16 are `baremetal`, `MachineAPI`, `marketplace`, `OperatorLifecycleManager`, `openshift-samples`, `Console`, `Insights`, `Storage`, `CSISnapshot`, `NodeTuning`, `ImageRegistry`, `Build`, `CloudCredential`, `DeploymentConfig`, and `CloudControllerManager`. + |`None` |Specify when the other sets are too large, and you do not need any capabilities or want to fine-tune via `additionalEnabledCapabilities`. From e1d6cb5c5e1625cae1baa272f1a9b6d17d18fb35 Mon Sep 17 00:00:00 2001 From: Gwynne Monahan Date: Thu, 30 May 2024 13:04:48 -0500 Subject: [PATCH 020/339] OSSM-6378 xrefs in ossm-routing-ingress --- modules/ossm-routing-ingress.adoc | 4 ---- service_mesh/v2x/ossm-traffic-manage.adoc | 7 +++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/ossm-routing-ingress.adoc b/modules/ossm-routing-ingress.adoc index 15d5e070579a..a3ff04e13e1a 100644 --- a/modules/ossm-routing-ingress.adoc +++ b/modules/ossm-routing-ingress.adoc @@ -24,10 +24,6 @@ That command returns the `NAME`, `TYPE`, `CLUSTER-IP`, `EXTERNAL-IP`, `PORT(S)`, If the `EXTERNAL-IP` value is set, your environment has an external load balancer that you can use for the ingress gateway. If the `EXTERNAL-IP` value is ``, or perpetually ``, your environment does not provide an external load balancer for the ingress gateway. -ifdef::openshift-enterprise[] -You can access the gateway using the service's xref:../../networking/configuring-node-port-service-range.adoc#configuring-node-port-service-range[node port]. - -endif::[] //// TO DO - remove XREF in this module. diff --git a/service_mesh/v2x/ossm-traffic-manage.adoc b/service_mesh/v2x/ossm-traffic-manage.adoc index c3847515570b..e360bccafea9 100644 --- a/service_mesh/v2x/ossm-traffic-manage.adoc +++ b/service_mesh/v2x/ossm-traffic-manage.adoc @@ -19,6 +19,13 @@ endif::openshift-rosa,openshift-dedicated[] include::modules/ossm-routing-ingress.adoc[leveloffset=+2] +ifdef::openshift-enterprise[] +[role="_additional-resources"] +.Additional resources + +* xref:../../networking/configuring-node-port-service-range.adoc#configuring-node-port-service-range[Configuring the node port service range] +endif::[] + include::modules/ossm-routing-gateways.adoc[leveloffset=+2] [id="ossm-auto-route_{context}"] From 660182291c1b3b49faeca05a93308b04607c4e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CShauna=20Diaz=E2=80=9D?= Date: Thu, 30 May 2024 13:17:33 -0400 Subject: [PATCH 021/339] OSDOCS-10716: updates audit log default values --- modules/microshift-audit-logs-config-intro.adoc | 17 ++++++++++++----- modules/microshift-audit-logs-config-proc.adoc | 14 +++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/microshift-audit-logs-config-intro.adoc b/modules/microshift-audit-logs-config-intro.adoc index 1a62eda02ee5..a83b7609dcfc 100644 --- a/modules/microshift-audit-logs-config-intro.adoc +++ b/modules/microshift-audit-logs-config-intro.adoc @@ -20,11 +20,18 @@ You can set fields in combination to define a maximum storage limit for retained {microshift-short} includes the following default audit log rotation values: -* `maxFileSize`: 200Mb -* `maxFiles`: 10 files -* `maxFileAge`: 0, This value means that no default age limit is set. -* `profile`: Default, This profile logs only metadata for read and write requests. +.{microshift-short} default audit log values +[cols="20%,20%,50%",options="header"] +|=== -The maximum default storage usage for audit log retention is 2000Mb, provided that there are 10 or fewer files. +|Audit log parameter|Default setting|Definition +|`maxFileAge`:|`0`|How long log files are retained before automatic deletion. The default value means that a log file is never deleted based on age. This value can be configured. +|`maxFiles`:|`10`|The total number of log files retained. By default, {microshift-short} retains 10 log files. The oldest is deleted when an excess file is created. This value can be configured. +|`maxFileSize`:|`200`|By default, when the `audit.log` file reaches the `maxFileSize` limit, the `audit.log` file is rotated and {microshift-short} begins writing to a new `audit.log` file. This value in in megabytes and can be configured. +|`profile`:|`Default`|The `Default` profile setting only logs metadata for read and write requests; request bodies are not logged except for OAuth access token requests. If you do not specify this field, the `Default` profile is used. + +|=== + +The maximum default storage usage for audit log retention is 2000Mb if there are 10 or fewer files. If you do not specify a value for a field, the default value is used. If you remove a previously set field value, the default value is restored after the next {microshift-short} service restart. diff --git a/modules/microshift-audit-logs-config-proc.adoc b/modules/microshift-audit-logs-config-proc.adoc index 709a3216a6ce..eac1a949686b 100644 --- a/modules/microshift-audit-logs-config-proc.adoc +++ b/modules/microshift-audit-logs-config-proc.adoc @@ -20,16 +20,16 @@ You can configure audit log settings by using the {microshift-short} service con apiServer: # .... auditLog: - maxFileSize: 200 # <1> - maxFiles: 1 # <2> - maxFileAge: 7 # <3> + maxFileAge: 7 # <1> + maxFileSize: 200 # <2> + maxFiles: 1 # <3> profile: Default # <4> # .... ---- -<1> The maximum audit log file size in megabytes. If the value is 0, the limit is disabled. In this example, the file is rotated as soon as the live log reaches the 200 MB limit. -<2> The maximum number of rotated audit log files retained. After the limit is reached, the log files in order from oldest to newest are deleted. When the value is 0, the limit is disabled. In this example, the value `1` results in only 1 file of size `maxFileSize` being retained in addition to the current active log. -<3> Specifies the maximum time in days that log files are kept. Files older than this limit are deleted. If the value is 0, the limit is disabled. In this example, after a log file is more than 7 days old, it is deleted. The files are deleted regardless of whether or not the live log has reached the maximum file size specified in the `maxFileSize` field. File age is determined by the timestamp written in the name of the rotated log file, for example, `audit-2024-05-16T17-03-59.994.log`. -<4> Logs only metadata for read and write requests; does not log request bodies except for OAuth access token requests. If you do not specify this field, the Default profile is used. +<1> Specifies the maximum time in days that log files are kept. Files older than this limit are deleted. In this example, after a log file is more than 7 days old, it is deleted. The files are deleted regardless of whether or not the live log has reached the maximum file size specified in the `maxFileSize` field. File age is determined by the timestamp written in the name of the rotated log file, for example, `audit-2024-05-16T17-03-59.994.log`. When the value is `0`, the limit is disabled. +<2> The maximum audit log file size in megabytes. In this example, the file is rotated as soon as the live log reaches the 200 MB limit. When the value is set to `0`, the limit is disabled. +<3> The maximum number of rotated audit log files retained. After the limit is reached, the log files are deleted in order from oldest to newest. In this example, the value `1` results in only 1 file of size `maxFileSize` being retained in addition to the current active log. When the value is set to `0`, the limit is disabled. +<4> Logs only metadata for read and write requests; does not log request bodies except for OAuth access token requests. If you do not specify this field, the `Default` profile is used. . Optional: To specify a new directory for logs, you can stop {microshift-short}, and then move the `/var/log/kube-apiserver` directory to your desired location: From 132f6e438f40656cd9a2a28edb0d2afeb2585165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CShauna=20Diaz=E2=80=9D?= Date: Thu, 16 May 2024 14:01:06 -0400 Subject: [PATCH 022/339] OSDOCS-9421: router configuration MicroShift --- .../microshift-nw-router.adoc | 19 +++++ modules/microshift-default-settings.adoc | 66 ++++++++-------- modules/microshift-nw-router-con.adoc | 55 +++++++++++++ ...icroshift-nw-router-config-ip-address.adoc | 77 +++++++++++++++++++ .../microshift-nw-router-config-ports.adoc | 47 +++++++++++ modules/microshift-nw-router-disable.adoc | 65 ++++++++++++++++ 6 files changed, 299 insertions(+), 30 deletions(-) create mode 100644 modules/microshift-nw-router-con.adoc create mode 100644 modules/microshift-nw-router-config-ip-address.adoc create mode 100644 modules/microshift-nw-router-config-ports.adoc create mode 100644 modules/microshift-nw-router-disable.adoc diff --git a/microshift_networking/microshift-nw-router.adoc b/microshift_networking/microshift-nw-router.adoc index 6095dc8e7117..d8aac678e524 100644 --- a/microshift_networking/microshift-nw-router.adoc +++ b/microshift_networking/microshift-nw-router.adoc @@ -8,3 +8,22 @@ toc::[] Learn about default and custom settings for configuring the router with {microshift-short}. +include::modules/microshift-nw-router-con.adoc[leveloffset=+1] + +include::modules/microshift-nw-router-disable.adoc[leveloffset=+1] + +[id="microshift-configuring-router-ingress_{context}"] +== Configuring router ingress + +If your {microshift-short} applications need to listen only for data traffic, you can configure the `listenAddress` setting to isolate your devices. You can also configure specific ports and IP addresses for network connections. Use the combination required to customize the endpoint configuration for your use case. + +include::modules/microshift-nw-router-config-ports.adoc[leveloffset=+2] + +include::modules/microshift-nw-router-config-ip-address.adoc[leveloffset=+2] + +[role="_additional-resources"] +[id="additional-resources_microshift-understanding-and-configuring-router_{context}"] +== Additional resources +* xref:../microshift_configuring/microshift-using-config-tools.adoc#microshift-yaml-default_microshift-using-config-tools[Default settings] ({microshift-short}) + +* xref:../microshift_networking/microshift_network_policy/microshift-network-policy-index.adoc#microshift-network-policies[About network policies] diff --git a/modules/microshift-default-settings.adoc b/modules/microshift-default-settings.adoc index 608e66c7e83d..c05a404d01d8 100644 --- a/modules/microshift-default-settings.adoc +++ b/modules/microshift-default-settings.adoc @@ -21,32 +21,32 @@ $ microshift show-config apiServer: advertiseAddress: 10.44.0.0/32 # <1> auditLog: - maxFileAge: 10 - maxFileSize: 200 - maxFiles: 10 - profile: Default + maxFileAge: 0 # <2> + maxFileSize: 200 # <3> + maxFiles: 10 # <4> + profile: Default # <5> namedCertificates: - certPath: "" keyPath: "" names: - "" - subjectAltNames: [] # <2> + subjectAltNames: [] # <6> debugging: - logLevel: "Normal" # <3> + logLevel: "Normal" # <7> dns: - baseDomain: microshift.example.com <4> + baseDomain: microshift.example.com # <8> etcd: - memoryLimitMB: 0 # <5> + memoryLimitMB: 0 # <9> ingress: listenAddress: - - "" - ports: + - "" # <10> + ports: # <11> http: 80 https: 443 routeAdmissionPolicy: - namespaceOwnership: InterNamespaceAllowed # <6> - status: Managed # <7> -manifests: # <8> + namespaceOwnership: InterNamespaceAllowed # <12> + status: Managed # <13> +manifests: # <14> kustomizePaths: - /usr/lib/microshift/manifests - /usr/lib/microshift/manifests.d/* @@ -54,24 +54,30 @@ manifests: # <8> - /etc/microshift/manifests.d/* network: clusterNetwork: - - 10.42.0.0/16 # <9> + - 10.42.0.0/16 # <15> serviceNetwork: - - 10.43.0.0/16 # <10> - serviceNodePortRange: 30000-32767 # <11> + - 10.43.0.0/16 # <16> + serviceNodePortRange: 30000-32767 # <17> node: - hostnameOverride: "" # <12> - nodeIP: "" # <13> + hostnameOverride: "" # <18> + nodeIP: "" # <19> ---- <1> A string that specifies the IP address from which the API server is advertised to members of the cluster. The default value is calculated based on the address of the service network. -<2> Subject Alternative Names for API server certificates. -<3> Log verbosity. Valid values for this field are `Normal`, `Debug`, `Trace`, or `TraceAll`. -<4> By default, `etcd` uses as much memory as needed to handle the load on the system. However, in memory constrained systems, it might be preferred or necessary to limit the amount of memory `etcd` can to use at a given time. -<5> Base domain of the cluster. All managed DNS records are subdomains of this base. -<6> Describes how host name claims across namespaces are handled. By default, allows routes to claim different paths of the same host name across namespaces. Can also be set as `Strict` to not allow routes in different namespaces to claim the same host. If the value is deleted and a new one is not added, `InterNamespaceAllowed` is automatically set. -<7> Default router status, can be `Managed` or `Removed`. -<8> The locations on the filesystem to scan for `kustomization` files to use to load manifests. Set to a list of paths to scan only those paths. Set to an empty list to disable loading manifests. The entries in the list can be glob patterns to match multiple subdirectories. -<9> A block of IP addresses from which Pod IP addresses are allocated. This field is immutable after installation. -<10> A block of virtual IP addresses for Kubernetes services. IP address pool for services. A single entry is supported. This field is immutable after installation. -<11> The port range allowed for Kubernetes services of type NodePort. If not specified, the default range of 30000-32767 is used. Services without a `NodePort` specified are automatically allocated one from this range. This parameter can be updated after the cluster is installed. -<12> The name of the node. The default value is the hostname. If non-empty, this string is used to identify the node instead of the hostname. -<13> The IP address of the node. The default value is the IP address of the default route. +<2> How long log files are kept before automatic deletion. The default value of `0` in the `maxFileAge` parameter means a log file is never deleted based on age. This value can be configured. +<3> By default, when the `audit.log` file reaches the `maxFileSize` limit, the `audit.log` file is rotated and {microshift-short} begins writing to a new `audit.log` file. This value can be configured. +<4> The total number of log files kept. By default, {microshift-short} retains 10 log files. The oldest is deleted when an excess file is created. This value can be configured. +<5> Logs only metadata for read and write requests; does not log request bodies except for OAuth access token requests. If you do not specify this field, the `Default` profile is used. +<6> Subject Alternative Names for API server certificates. +<7> Log verbosity. Valid values for this field are `Normal`, `Debug`, `Trace`, or `TraceAll`. +<8> By default, `etcd` uses as much memory as needed to handle the load on the system. However, in memory constrained systems, it might be preferred or necessary to limit the amount of memory `etcd` can to use at a given time. +<9> Base domain of the cluster. All managed DNS records are subdomains of this base. +<10> The `ingress.listenAddress` value defaults to the entire network of the host. The valid configurable value is a list that can be either a single IP address or NIC name or multiple IP addresses and NIC names. +<11> Default ports shown. Configurable. Valid values for both port entries are a single, unique port in the 1-65535 range. The values of the `ports.http` and `ports.https` fields cannot be the same. +<12> Describes how hostname claims across namespaces are handled. By default, allows routes to claim different paths of the same hostname across namespaces. Valid values are `Strict` and `InterNamespaceAllowed`. Specifying `Strict` prevents routes in different namespaces from claiming the same hostname. If the value is deleted in a customized {microshift-short} `config.yaml`, the `InterNamespaceAllowed` value is automatically set. +<13> Default router status, can be `Managed` or `Removed`. +<14> The locations on the file system to scan for `kustomization` files to use to load manifests. Set to a list of paths to scan only those paths. Set to an empty list to disable loading manifests. The entries in the list can be glob patterns to match multiple subdirectories. +<15> A block of IP addresses from which pod IP addresses are allocated. This field is immutable after installation. +<16> A block of virtual IP addresses for Kubernetes services. IP address pool for services. A single entry is supported. This field is immutable after installation. +<17> The port range allowed for Kubernetes services of type `NodePort`. If not specified, the default range of 30000-32767 is used. Services without a `NodePort` specified are automatically allocated one from this range. This parameter can be updated after the cluster is installed. +<18> The name of the node. The default value is the hostname. If non-empty, this string is used to identify the node instead of the hostname. +<19> The IP address of the node. The default value is the IP address of the default route. diff --git a/modules/microshift-nw-router-con.adoc b/modules/microshift-nw-router-con.adoc new file mode 100644 index 000000000000..7c323576ed0c --- /dev/null +++ b/modules/microshift-nw-router-con.adoc @@ -0,0 +1,55 @@ +// Module included in the following assemblies: +// +// * microshift_networking/microshift-nw-router.adoc + +:_mod-docs-content-type: CONCEPT +[id="microshift-about-router-config_{context}"] += About configuring the router + +To make ingress optional, you can configure {microshift-short} ingress router settings to manage which ports, if any, are exposed to network traffic. Specified routing is an example of ingress load balancing. + +* The default ingress router is always on, running on all IP addresses on the `http: 80` and `https: 443` ports. +* Default router settings allow access to any namespace. + +Some applications running on top of {microshift-short} might not require the default router and instead create their own. You can configure the router to control both ingress and namespace access. + +[TIP] +==== +You can check for the presence of the default router in your {microshift-short} installation before you begin configurations by using the `oc get deployment -n openshift-ingress` command, which returns the following output: + +[source,terminal] +---- +NAME READY UP-TO-DATE AVAILABLE AGE +router-default 1/1 1 1 2d23h +---- +==== + +[id="microshift-router-csettings_{context}"] +== Router settings and valid values + +The ingress router settings consist of the following parameters and valid values: + +.Example `config.yaml` router settings +[source,yaml] +---- +# ... +ingress: + listenAddress: + - "" # <1> + ports: # <2> + http: 80 + https: 443 + routeAdmissionPolicy: + namespaceOwnership: InterNamespaceAllowed # <3> + status: Managed # <4> +# ... +---- +<1> The `ingress.listenAddress` value defaults to the entire network of the host. Valid customizable values can be a single IP address or host name or a list of IP addresses or host names. +<2> Valid values for both port entries are a single, unique port in the 1-65535 range. The values of the `ports.http` and `ports.https` fields cannot be the same. +<3> Default value. Allows routes to claim different paths of the same host name across namespaces. +<4> Default value. `Managed` is required for the ingress ports to remain open. + +[IMPORTANT] +==== +The firewalld service is bypassed by the default {microshift-short} router and by configurations that enable the router. Ingress and egress must be controlled by setting network policies when the router is active. +==== diff --git a/modules/microshift-nw-router-config-ip-address.adoc b/modules/microshift-nw-router-config-ip-address.adoc new file mode 100644 index 000000000000..83a0a3a8bd20 --- /dev/null +++ b/modules/microshift-nw-router-config-ip-address.adoc @@ -0,0 +1,77 @@ +// Module included in the following assemblies: +// +// * microshift_networking/microshift-nw-router.adoc + +:_mod-docs-content-type: PROCEDURE +[id="microshift-config-ip-addresses_{context}"] += Configuring router IP addresses + +You can restrict the network traffic to the router by configuring specific IP addresses. For example: + +* Use cases where the router is reachable only on internal networks, but not on northbound public networks +* Use cases where the router is reachable only by northbound public networks, but not on internal networks +* Use cases where the router is reachable by both internal networks and northbound public networks, but on separate IP addresses + +.Prerequisites + +* You installed {microshift-short}. +* You created a {microshift-short} `config.yaml` file. +* The {oc-first} is installed. + +[TIP] +==== +If you complete all the configurations that you need to make in the {microshift-short} `config.yaml` file at the same time, you can minimize system restarts. +==== + +.Procedure + +. Update the list in the `ingress.listenAddress` field in the {microshift-short} `config.yaml` according to your requirements and as shown in the following examples: ++ +.Default router IP address list +[source,yaml] +---- +# ... +ingress: + listenAddress: + - "" # <1> +# ... +---- +<1> The `ingress.listenAddress` value defaults to the entire network of the host. To continue to use the default list, remove the `listen.Address` field from the {microshift-short} `config.yaml` file. To customize this parameter, use a list. The list can contain either a single IP address or NIC name or multiple IP addresses and NIC names. ++ +[IMPORTANT] +==== +You must either remove the `listenAddress` parameter or add values to it in the form of a list when using the `config.yaml` file. Do not leave the field empty or {microshift-short} crashes on restart. +==== ++ +.Example router setting with a single host IP address +[source,yaml] +---- +# ... +ingress: + listenAddress: + - 10.2.1.100 +# ... +---- ++ +.Example router setting with a combination of IP addresses and NIC names +[source,yaml] +---- +# ... +ingress: + listenAddress: + - 10.2.1.100 + - 10.2.2.10 + - ens3 +# ... +---- + +. Restart the {microshift-short} service by running the following command: ++ +[source,terminal] +---- +$ sudo systemctl restart microshift +---- + +.Verification + +* To verify that your settings are applied, make sure that the `ingress.listenAddress` IP addresses are reachable, then you can `curl` the route with the destination to one of these load balancer IP address. \ No newline at end of file diff --git a/modules/microshift-nw-router-config-ports.adoc b/modules/microshift-nw-router-config-ports.adoc new file mode 100644 index 000000000000..bab4a02067e9 --- /dev/null +++ b/modules/microshift-nw-router-config-ports.adoc @@ -0,0 +1,47 @@ +// Module included in the following assemblies: +// +// * microshift_networking/microshift-nw-router.adoc + +:_mod-docs-content-type: PROCEDURE +[id="microshift-config-router-ports_{context}"] += Configuring router ports + +You can control which ports your devices use by configuring the router ingress fields. + +.Prerequisites + +* You installed {microshift-short}. +* You created a {microshift-short} `config.yaml` file. +* The {oc-first} is installed. + +[TIP] +==== +If you complete all the configurations that you need to make in the {microshift-short} `config.yaml` file at the same time, you can minimize system restarts. +==== + +.Procedure + +. Update the {microshift-short} `config.yaml` port values in the `ingress.ports.http` and `ingress.ports.https` fields to the ports you want to use: ++ +.Example `config.yaml` router settings +[source,yaml] +---- +# ... +ingress: + ports: # <1> + http: 80 + https: 443 + routeAdmissionPolicy: + namespaceOwnership: InterNamespaceAllowed + status: Managed # <2> +# ... +---- +<1> Default ports shown. Customizable. Valid values for both port entries are a single, unique port in the 1-65535 range. The values of the `ports.http` and `ports.https` fields cannot be the same. +<2> The default value. `Managed` is required for the ingress ports to remain open. + +. Restart the {microshift-short} service by running the following command: ++ +[source,terminal] +---- +$ sudo systemctl restart microshift +---- \ No newline at end of file diff --git a/modules/microshift-nw-router-disable.adoc b/modules/microshift-nw-router-disable.adoc new file mode 100644 index 000000000000..54d66c4c7359 --- /dev/null +++ b/modules/microshift-nw-router-disable.adoc @@ -0,0 +1,65 @@ +// Module included in the following assemblies: +// +// * microshift_networking/microshift-nw-router.adoc + +:_mod-docs-content-type: PROCEDURE +[id="microshift-disabling-the-router_{context}"] += Disabling the router + +In use cases such as industrial IoT spaces where {microshift-short} pods only need to connect to southbound operational systems and northbound cloud-data systems, inbound services are not needed. Use this procedure to disable the router in such egress-only use cases. + +.Prerequisites + +* You installed {microshift-short}. +* You created a {microshift-short} `config.yaml` file. +* The {oc-first} is installed. + +[TIP] +==== +If you complete all the configurations that you need to make in the {microshift-short} `config.yaml` file at the same time, you can minimize system restarts. +==== + +.Procedure + +. Update the value of `ingress.status` field to `Removed` in the {microshift-short} `config.yaml` file as shown in the following example: ++ +.Example `config.yaml` ingress stanza +[source,yaml] +---- +# ... +ingress: + ports: + http: 80 + https: 443 + routeAdmissionPolicy: + namespaceOwnership: InterNamespaceAllowed + status: Removed # <1> +# ... +---- +<1> When the value is set to `Removed`, the ports listed in `ingress.ports` are automatically closed. Any other settings in the `ingress` stanza are ignored, for example, any values in the `routeAdmissionPolicy.namespaceOwnership` field. + +. Restart the {microshift-short} service by running the following command: ++ +[source,terminal] +---- +$ sudo systemctl restart microshift +---- ++ +[NOTE] +==== +The {microshift-short} service outputs current configurations during restarts. +==== + +.Verification +* After the system restarts, verify that the router has been removed and that ingress is stopped by running the following command: ++ +[source,terminal] +---- +$ oc -n openshift-ingress get svc +---- ++ +.Expected output +[source,text] +---- +No resources found in openshift-ingress namespace. +---- From 743e0cad09a5c9b5839fd0dc990cee5ac7efb8be Mon Sep 17 00:00:00 2001 From: JoeAldinger Date: Wed, 29 May 2024 10:04:02 -0400 Subject: [PATCH 023/339] OSDOCS-10425:fixes contradictory statement in OVN-K docs --- modules/nw-ovn-kubernetes-rollback.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nw-ovn-kubernetes-rollback.adoc b/modules/nw-ovn-kubernetes-rollback.adoc index f6d8a71f33ed..e797e9424c32 100644 --- a/modules/nw-ovn-kubernetes-rollback.adoc +++ b/modules/nw-ovn-kubernetes-rollback.adoc @@ -14,7 +14,7 @@ During the migration you must reboot every node in your cluster. ifeval::["{context}" == "rollback-to-openshift-sdn"] [IMPORTANT] ==== -Rollback to OpenShift SDN if the migration to OVN-Kubernetes fails. +You must wait until the migration process from OpenShift SDN to OVN-Kubernetes network plugin is successful before initiating a rollback. ==== endif::[] From 5c862594e4ae1bd121ebbc01dd5b340ddcb32eb3 Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Fri, 31 May 2024 10:45:53 -0400 Subject: [PATCH 024/339] remove extra slash from xref --- machine_management/index.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machine_management/index.adoc b/machine_management/index.adoc index 9d63052526a4..0bcbb6c38d1f 100644 --- a/machine_management/index.adoc +++ b/machine_management/index.adoc @@ -99,7 +99,7 @@ You can automatically scale your {product-title} cluster to ensure flexibility f [id="machine-mgmt-intro-add-for-upi_{context}"] == Adding compute machines on user-provisioned infrastructure -User-provisioned infrastructure is an environment where you can deploy infrastructure such as compute, network, and storage resources that host the {product-title}. You can xref:../machine_management//user_infra/adding-compute-user-infra-general.adoc#adding-compute-user-infra-general[add compute machines] to a cluster on user-provisioned infrastructure during or after the installation process. +User-provisioned infrastructure is an environment where you can deploy infrastructure such as compute, network, and storage resources that host the {product-title}. You can xref:../machine_management/user_infra/adding-compute-user-infra-general.adoc#adding-compute-user-infra-general[add compute machines] to a cluster on user-provisioned infrastructure during or after the installation process. [id="machine-mgmt-intro-add-rhel_{context}"] == Adding RHEL compute machines to your cluster From 4a4d72a9fab1234bf9193fcb3a1a1f91978f6cdf Mon Sep 17 00:00:00 2001 From: Ben Hardesty Date: Tue, 21 May 2024 16:53:46 -0400 Subject: [PATCH 025/339] OSDOCS-10608: Remove MCD metrics from ROSA docs --- _topic_maps/_topic_map_rosa.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index b3fc6b9433fe..9c5d9d3c5aab 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -1367,8 +1367,8 @@ Topics: # File: nodes-nodes-managing-max-pods - Name: Using the Node Tuning Operator File: nodes-node-tuning-operator - - Name: Remediating, fencing, and maintaining nodes - File: nodes-remediating-fencing-maintaining-rhwa +# - Name: Remediating, fencing, and maintaining nodes +# File: nodes-remediating-fencing-maintaining-rhwa # Cannot create namespace needed to oc debug and reboot; revisit after Operator book converted # - Name: Understanding node rebooting # File: nodes-nodes-rebooting @@ -1387,8 +1387,8 @@ Topics: # Distros: openshift-rosa # - Name: Monitoring for problems in your nodes # File: nodes-nodes-problem-detector - - Name: Machine Config Daemon metrics - File: nodes-nodes-machine-config-daemon-metrics +# - Name: Machine Config Daemon metrics +# File: nodes-nodes-machine-config-daemon-metrics # cannot patch resource "nodes" # - Name: Creating infrastructure nodes # File: nodes-nodes-creating-infrastructure-nodes From 6c4102e86fd7ebc17526647c829cd8b827311dab Mon Sep 17 00:00:00 2001 From: shreyasiddhartha Date: Mon, 20 May 2024 16:50:34 +0530 Subject: [PATCH 026/339] OBSDOCS-944 --- ...monitoring-configuring-kepler-redfish.adoc | 94 +++++++++++++++++++ ...power-monitoring-kepler-configuration.adoc | 2 +- .../configuring-power-monitoring.adoc | 2 + 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 modules/power-monitoring-configuring-kepler-redfish.adoc diff --git a/modules/power-monitoring-configuring-kepler-redfish.adoc b/modules/power-monitoring-configuring-kepler-redfish.adoc new file mode 100644 index 000000000000..fea1ac2d7e41 --- /dev/null +++ b/modules/power-monitoring-configuring-kepler-redfish.adoc @@ -0,0 +1,94 @@ +// Module included in the following assemblies: + +// * power_monitoring/configuring-power-monitoring.adoc + +:_mod-docs-content-type: PROCEDURE +[id="power-monitoring-configuring-kepler-redfish_{context}"] += Configuring {PM-kepler} to use Redfish + +You can configure {PM-kepler} to use Redfish as the source for running or hosting containers. {PM-kepler} can then monitor the power usage of these containers. + +.Prerequisites +* You have access to the {product-title} web console. +* You are logged in as a user with the `cluster-admin` role. +* You have installed the {PM-operator}. + +.Procedure + +. In the *Administrator* perspective of the web console, click *Operators* -> *Installed Operators*. + +. Click *{PM-title-c}* from the *Installed Operators* list and click the *{PM-kepler}* tab. + +. Click *Create {PM-kepler}*. If you already have a {PM-kepler} instance created, click *Edit Kepler*. + +. Configure `.spec.exporter.redfish` of the {PM-kepler} instance by specifying the mandatory `secretRef` field. You can also configure the optional `probeInterval` and `skipSSLVerify` fields to meet your needs. ++ +.Example {PM-kepler} instance +[source,yaml] +---- +apiVersion: kepler.system.sustainable.computing.io/v1alpha1 +kind: Kepler +metadata: + name: kepler +spec: + exporter: + deployment: +# ... + redfish: + secretRef: required <1> + probeInterval: 60s <2> + skipSSLVerify: false <3> +# ... +---- +<1> Required: Specifies the name of the secret that contains the credentials for accessing the Redfish server. +<2> Optional: Controls the frequency at which the power information is queried from Redfish. The default value is `60s`. +<3> Optional: Controls if {PM-kepler} skips verifying the Redfish server certificate. The default value is `false`. ++ +[NOTE] +==== +After {PM-kepler} is deployed, the `openshift-power-monitoring` namespace is created. +==== +. Create the `redfish.csv` file with the following data format: ++ +[source,csv] +---- +,,,https:/// +---- ++ +.Example `redfish.csv` file +[source,csv] +---- +control-plane,exampleuser,examplepass,https://redfish.nodes.example.com +worker-1,exampleuser,examplepass,https://redfish.nodes.example.com +worker-2,exampleuser,examplepass,https://another.redfish.nodes.example.com +---- +. Create the secret under the `openshift-power-monitoring` namespace. You must create the secret with the following conditions: ++ +-- +* The secret type is `Opaque`. +* The credentials are stored under the `redfish.csv` key in the `data` field of the secret. +-- ++ +[source,terminal] +---- +$ oc -n openshift-power-monitoring \ + create secret generic redfish-secret \ + --from-file=redfish.csv +---- ++ +.Example output +[source,yaml] +---- +apiVersion: v1 +kind: Secret +metadata: + name: redfish-secret +data: + redfish.csv: YmFyCg== + # ... +---- ++ +[IMPORTANT] +==== +The {PM-kepler} deployment will not continue until the Redfish secret is created. You can find this information in the `status` of a {PM-kepler} instance. +==== \ No newline at end of file diff --git a/modules/power-monitoring-kepler-configuration.adoc b/modules/power-monitoring-kepler-configuration.adoc index 9788c36e1319..1a5af2e67c7b 100644 --- a/modules/power-monitoring-kepler-configuration.adoc +++ b/modules/power-monitoring-kepler-configuration.adoc @@ -10,7 +10,7 @@ You can configure {PM-kepler} with the `spec` field of the `{PM-kepler}` resourc [IMPORTANT] ==== -Ensure that the name of your {PM-kepler} instance is `kepler`. All other instances are ignored by the {PM-operator}. +Ensure that the name of your {PM-kepler} instance is `kepler`. All other instances are rejected by the {PM-operator} Webhook. ==== The following is the list of configuration options: diff --git a/observability/power_monitoring/configuring-power-monitoring.adoc b/observability/power_monitoring/configuring-power-monitoring.adoc index 545604f1f31c..732e032cb292 100644 --- a/observability/power_monitoring/configuring-power-monitoring.adoc +++ b/observability/power_monitoring/configuring-power-monitoring.adoc @@ -14,3 +14,5 @@ The `{PM-kepler}` resource is a Kubernetes custom resource definition (CRD) that include::modules/power-monitoring-kepler-configuration.adoc[leveloffset=+1] include::modules/power-monitoring-monitoring-kepler-status.adoc[leveloffset=+1] + +include::modules/power-monitoring-configuring-kepler-redfish.adoc[leveloffset=+1] From 056cfca00476c459ef3c4bddf2e05c871b2a131d Mon Sep 17 00:00:00 2001 From: Eliska Romanova Date: Thu, 23 May 2024 12:31:06 +0200 Subject: [PATCH 027/339] OBSDOCS-977: Document improved scrape sample alerts --- ...itoring-creating-scrape-sample-alerts.adoc | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/modules/monitoring-creating-scrape-sample-alerts.adoc b/modules/monitoring-creating-scrape-sample-alerts.adoc index f8343d22ba90..2b96ad1dc137 100644 --- a/modules/monitoring-creating-scrape-sample-alerts.adoc +++ b/modules/monitoring-creating-scrape-sample-alerts.adoc @@ -30,38 +30,38 @@ metadata: labels: prometheus: k8s role: alert-rules - name: monitoring-stack-alerts <1> - namespace: ns1 <2> + name: monitoring-stack-alerts #<1> + namespace: ns1 #<2> spec: groups: - name: general.rules rules: - - alert: TargetDown <3> + - alert: TargetDown #<3> annotations: message: '{{ printf "%.4g" $value }}% of the {{ $labels.job }}/{{ $labels.service - }} targets in {{ $labels.namespace }} namespace are down.' <4> + }} targets in {{ $labels.namespace }} namespace are down.' #<4> expr: 100 * (count(up == 0) BY (job, namespace, service) / count(up) BY (job, namespace, service)) > 10 - for: 10m <5> + for: 10m #<5> labels: - severity: warning <6> - - alert: ApproachingEnforcedSamplesLimit <7> + severity: warning #<6> + - alert: ApproachingEnforcedSamplesLimit #<7> annotations: - message: '{{ $labels.container }} container of the {{ $labels.pod }} pod in the {{ $labels.namespace }} namespace consumes {{ $value | humanizePercentage }} of the samples limit budget.' <8> - expr: scrape_samples_scraped/50000 > 0.8 <9> - for: 10m <10> + message: '{{ $labels.container }} container of the {{ $labels.pod }} pod in the {{ $labels.namespace }} namespace consumes {{ $value | humanizePercentage }} of the samples limit budget.' #<8> + expr: (scrape_samples_post_metric_relabeling / (scrape_sample_limit > 0)) > 0.9 #<9> + for: 10m #<10> labels: - severity: warning <11> + severity: warning #<11> ---- <1> Defines the name of the alerting rule. -<2> Specifies the user-defined project where the alerting rule will be deployed. -<3> The `TargetDown` alert will fire if the target cannot be scraped or is not available for the `for` duration. -<4> The message that will be output when the `TargetDown` alert fires. +<2> Specifies the user-defined project where the alerting rule is deployed. +<3> The `TargetDown` alert fires if the target cannot be scraped and is not available for the `for` duration. +<4> The message that is displayed when the `TargetDown` alert fires. <5> The conditions for the `TargetDown` alert must be true for this duration before the alert is fired. <6> Defines the severity for the `TargetDown` alert. -<7> The `ApproachingEnforcedSamplesLimit` alert will fire when the defined scrape sample threshold is reached or exceeded for the specified `for` duration. -<8> The message that will be output when the `ApproachingEnforcedSamplesLimit` alert fires. -<9> The threshold for the `ApproachingEnforcedSamplesLimit` alert. In this example the alert will fire when the number of samples per target scrape has exceeded 80% of the enforced sample limit of `50000`. The `for` duration must also have passed before the alert will fire. The `` in the expression `scrape_samples_scraped/ > ` must match the `enforcedSampleLimit` value defined in the `user-workload-monitoring-config` `ConfigMap` object. +<7> The `ApproachingEnforcedSamplesLimit` alert fires when the defined scrape sample threshold is exceeded and lasts for the specified `for` duration. +<8> The message that is displayed when the `ApproachingEnforcedSamplesLimit` alert fires. +<9> The threshold for the `ApproachingEnforcedSamplesLimit` alert. In this example, the alert fires when the number of ingested samples exceeds 90% of the configured limit. <10> The conditions for the `ApproachingEnforcedSamplesLimit` alert must be true for this duration before the alert is fired. <11> Defines the severity for the `ApproachingEnforcedSamplesLimit` alert. @@ -71,3 +71,9 @@ spec: ---- $ oc apply -f monitoring-stack-alerts.yaml ---- + +. Additionally, you can check if a target has hit the configured limit: + +.. In the *Administrator* perspective of the web console, go to *Observe* -> *Targets* and select an endpoint with a `Down` status that you want to check. ++ +The *Scrape failed: sample limit exceeded* message is displayed if the endpoint failed because of an exceeded sample limit. From 73797b7ecc00171806f1a9569ddf3eefee6a5987 Mon Sep 17 00:00:00 2001 From: Eliska Romanova Date: Tue, 7 May 2024 10:56:18 +0200 Subject: [PATCH 028/339] OBSDOCS-702: Clarify available endpoint auth methods in user workload monitoring --- ...-remote-write-authentication-settings.adoc | 2 - ...vice-endpoint-authentication-settings.adoc | 158 ++++++++++++++++++ ...specifying-how-a-service-is-monitored.adoc | 22 ++- .../monitoring/managing-metrics.adoc | 1 + 4 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 modules/monitoring-example-service-endpoint-authentication-settings.adoc diff --git a/modules/monitoring-example-remote-write-authentication-settings.adoc b/modules/monitoring-example-remote-write-authentication-settings.adoc index 2139d1ebdb6f..4ce0fa1b02c4 100644 --- a/modules/monitoring-example-remote-write-authentication-settings.adoc +++ b/modules/monitoring-example-remote-write-authentication-settings.adoc @@ -183,12 +183,10 @@ metadata: stringData: id: <1> secret: <2> - token: <3> type: Opaque ---- <1> The Oauth 2.0 ID. <2> The OAuth 2.0 secret. -<3> The OAuth 2.0 token. The following shows an `oauth2` remote write authentication sample configuration that uses a `Secret` object named `oauth2-credentials` in the `{namespace-name}` namespace: diff --git a/modules/monitoring-example-service-endpoint-authentication-settings.adoc b/modules/monitoring-example-service-endpoint-authentication-settings.adoc new file mode 100644 index 000000000000..969e611fa433 --- /dev/null +++ b/modules/monitoring-example-service-endpoint-authentication-settings.adoc @@ -0,0 +1,158 @@ +// Module included in the following assemblies: +// +// * observability/monitoring/configuring-the-monitoring-stack.adoc + +:_mod-docs-content-type: REFERENCE +[id="example-service-endpoint-authentication-settings_{context}"] += Example service endpoint authentication settings + +You can configure authentication for service endpoints for user-defined project monitoring by using `ServiceMonitor` and `PodMonitor` custom resource definitions (CRDs). + +The following samples show different authentication settings for a `ServiceMonitor` resource. +Each sample shows how to configure a corresponding `Secret` object that contains authentication credentials and other relevant settings. + +== Sample YAML authentication with a bearer token + +The following sample shows bearer token settings for a `Secret` object named `example-bearer-auth` in the `ns1` namespace: + +.Example bearer token secret +[source,yaml] +---- +apiVersion: v1 +kind: Secret +metadata: + name: example-bearer-auth + namespace: ns1 +stringData: + token: #<1> +---- +<1> Specify an authentication token. + +The following sample shows bearer token authentication settings for a `ServiceMonitor` CRD. The example uses a `Secret` object named `example-bearer-auth`: + +[id="sample-yaml-bearer-token_{context}"] +.Example bearer token authentication settings +[source,yaml] +---- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: prometheus-example-monitor + namespace: ns1 +spec: + endpoints: + - authorization: + credentials: + key: token #<1> + name: example-bearer-auth #<2> + port: web + selector: + matchLabels: + app: prometheus-example-app +---- +<1> The key that contains the authentication token in the specified `Secret` object. +<2> The name of the `Secret` object that contains the authentication credentials. + +[IMPORTANT] +===== +Do not use `bearerTokenFile` to configure bearer token. If you use the `bearerTokenFile` configuration, the `ServiceMonitor` resource is rejected. +===== + +[id="sample-yaml-basic-auth_{context}"] +== Sample YAML for Basic authentication + +The following sample shows Basic authentication settings for a `Secret` object named `example-basic-auth` in the `ns1` namespace: + +.Example Basic authentication secret +[source,yaml] +---- +apiVersion: v1 +kind: Secret +metadata: + name: example-basic-auth + namespace: ns1 +stringData: + user: #<1> + password: #<2> +---- +<1> Specify a username for authentication. +<2> Specify a password for authentication. + +The following sample shows Basic authentication settings for a `ServiceMonitor` CRD. The example uses a `Secret` object named `example-basic-auth`: + +.Example Basic authentication settings +[source,yaml] +---- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: prometheus-example-monitor + namespace: ns1 +spec: + endpoints: + - basicAuth: + username: + key: user #<1> + name: example-basic-auth #<2> + password: + key: password #<3> + name: example-basic-auth #<2> + port: web + selector: + matchLabels: + app: prometheus-example-app +---- +<1> The key that contains the username in the specified `Secret` object. +<2> The name of the `Secret` object that contains the Basic authentication. +<3> The key that contains the password in the specified `Secret` object. + +[id="sample-yaml-oauth-20_{context}"] +== Sample YAML authentication with OAuth 2.0 + +The following sample shows OAuth 2.0 settings for a `Secret` object named `example-oauth2` in the `ns1` namespace: + +.Example OAuth 2.0 secret +[source,yaml] +---- +apiVersion: v1 +kind: Secret +metadata: + name: example-oauth2 + namespace: ns1 +stringData: + id: #<1> + secret: #<2> +---- +<1> Specify an Oauth 2.0 ID. +<2> Specify an Oauth 2.0 secret. + +The following sample shows OAuth 2.0 authentication settings for a `ServiceMonitor` CRD. The example uses a `Secret` object named `example-oauth2`: + +.Example OAuth 2.0 authentication settings +[source,yaml] +---- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: prometheus-example-monitor + namespace: ns1 +spec: + endpoints: + - oauth2: + clientId: + secret: + key: id #<1> + name: example-oauth2 #<2> + clientSecret: + key: secret #<3> + name: example-oauth2 #<2> + tokenUrl: https://example.com/oauth2/token #<4> + port: web + selector: + matchLabels: + app: prometheus-example-app +---- +<1> The key that contains the OAuth 2.0 ID in the specified `Secret` object. +<2> The name of the `Secret` object that contains the OAuth 2.0 credentials. +<3> The key that contains the OAuth 2.0 secret in the specified `Secret` object. +<4> The URL used to fetch a token with the specified `clientId` and `clientSecret`. diff --git a/modules/monitoring-specifying-how-a-service-is-monitored.adoc b/modules/monitoring-specifying-how-a-service-is-monitored.adoc index bd5c6795b68b..28f974444618 100644 --- a/modules/monitoring-specifying-how-a-service-is-monitored.adoc +++ b/modules/monitoring-specifying-how-a-service-is-monitored.adoc @@ -6,7 +6,6 @@ [id="specifying-how-a-service-is-monitored_{context}"] = Specifying how a service is monitored -[role="_abstract"] To use the metrics exposed by your service, you must configure {product-title} monitoring to scrape metrics from the `/metrics` endpoint. You can do this using a `ServiceMonitor` custom resource definition (CRD) that specifies how a service should be monitored, or a `PodMonitor` CRD that specifies how a pod should be monitored. The former requires a `Service` object, while the latter does not, allowing Prometheus to directly scrape metrics from the metrics endpoint exposed by a pod. This procedure shows you how to create a `ServiceMonitor` resource for a service in a user-defined project. @@ -29,30 +28,29 @@ The `prometheus-example-app` sample service does not support TLS authentication. .Procedure -. Create a YAML file for the `ServiceMonitor` resource configuration. In this example, the file is called `example-app-service-monitor.yaml`. +. Create a new YAML configuration file named `example-app-service-monitor.yaml`. -. Add the following `ServiceMonitor` resource configuration details: +. Add a `ServiceMonitor` resource to the YAML file. The following example creates a service monitor named `prometheus-example-monitor` to scrape metrics exposed by the `prometheus-example-app` service in the `ns1` namespace: + [source,yaml] ---- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: - labels: - k8s-app: prometheus-example-monitor name: prometheus-example-monitor - namespace: ns1 + namespace: ns1 #<1> spec: endpoints: - interval: 30s - port: web + port: web #<2> scheme: http - selector: + selector: #<3> matchLabels: app: prometheus-example-app ---- -+ -This defines a `ServiceMonitor` resource that scrapes the metrics exposed by the `prometheus-example-app` sample service, which includes the `version` metric. +<1> Specify a user-defined namespace where your service runs. +<2> Specify endpoint ports to be scraped by Prometheus. +<3> Configure a selector to match your service based on its metadata labels. + [NOTE] ==== @@ -68,11 +66,11 @@ $ oc apply -f example-app-service-monitor.yaml + It takes some time to deploy the `ServiceMonitor` resource. -. You can check that the `ServiceMonitor` resource is running: +. Verify that the `ServiceMonitor` resource is running: + [source,terminal] ---- -$ oc -n ns1 get servicemonitor +$ oc -n get servicemonitor ---- + .Example output diff --git a/observability/monitoring/managing-metrics.adoc b/observability/monitoring/managing-metrics.adoc index b7d4556e8886..d258deedc0da 100644 --- a/observability/monitoring/managing-metrics.adoc +++ b/observability/monitoring/managing-metrics.adoc @@ -21,6 +21,7 @@ include::modules/monitoring-understanding-metrics.adoc[leveloffset=+1] include::modules/monitoring-setting-up-metrics-collection-for-user-defined-projects.adoc[leveloffset=+1] include::modules/monitoring-deploying-a-sample-service.adoc[leveloffset=+2] include::modules/monitoring-specifying-how-a-service-is-monitored.adoc[leveloffset=+2] +include::modules/monitoring-example-service-endpoint-authentication-settings.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources From 786cb0f1c43100ef28bdc5d662f698b1b82d462a Mon Sep 17 00:00:00 2001 From: Daniel Chadwick Date: Tue, 28 May 2024 16:57:31 -0400 Subject: [PATCH 029/339] osdocs9673: creating sigstore modules --- _topic_maps/_topic_map.yml | 2 ++ modules/nodes-sigstore-using-about.adoc | 9 +++++++++ nodes/nodes-sigstore-using.adoc | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 modules/nodes-sigstore-using-about.adoc create mode 100644 nodes/nodes-sigstore-using.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 38e304b25f63..76aac2ac354b 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2625,6 +2625,8 @@ Topics: File: nodes-sno-worker-nodes - Name: Node metrics dashboard File: nodes-dashboard-using +- Name: Manage secure signatures with sigstore + File: nodes-sigstore-using --- Name: Windows Container Support for OpenShift Dir: windows_containers diff --git a/modules/nodes-sigstore-using-about.adoc b/modules/nodes-sigstore-using-about.adoc new file mode 100644 index 000000000000..39ffe2ec583e --- /dev/null +++ b/modules/nodes-sigstore-using-about.adoc @@ -0,0 +1,9 @@ +// Module included in the following assemblies: +// +// * nodes/nodes-sigstore-using.adoc + +:_mod-docs-content-type: CONCEPT +[id="nodes-sigstore-using-about_{context}"] += About the sigstore project + +The sigstore project enables developers to sign-off on what they build and administrators to verify signatures and monitor workflows at scale. With the sigstore project, signatures can be stored in the same registry as the build images. A second server is not needed. The identity piece of a signature is tied to the OpenID Connect (OIDC) identity through the Fulcio certificate authority, which simplifies the signature process by allowing key-less signing. Additionally, sigstore includes Rekor, which records signature metadata to an immutable, tamper-resistant ledger. \ No newline at end of file diff --git a/nodes/nodes-sigstore-using.adoc b/nodes/nodes-sigstore-using.adoc new file mode 100644 index 000000000000..fac9b8354169 --- /dev/null +++ b/nodes/nodes-sigstore-using.adoc @@ -0,0 +1,17 @@ +:_mod-docs-content-type: ASSEMBLY +[id="nodes-sigstore-using"] += Manage secure signatures with sigstore +include::_attributes/common-attributes.adoc[] +:context: nodes-sigstore-using + +toc::[] + +You can use the sigstore project with {product-title} to improve supply chain security. + +// The following include statements pull in the module files that comprise +// the assembly. Include any combination of concept, procedure, or reference +// modules required to cover the user story. You can also include other +// assemblies. + +// AManage secure signatures with SigStore +include::modules/nodes-sigstore-using-about.adoc[leveloffset=+1] \ No newline at end of file From 0d8d71d1e38f76cefe61f0a2061259362a2d719e Mon Sep 17 00:00:00 2001 From: Janelle Neczypor Date: Fri, 31 May 2024 15:39:40 -0700 Subject: [PATCH 030/339] OSDOCS-10780 --- .../cloud-experts-rosa-cloudwatch-sts.adoc | 2 +- .../rosa-mobb-prerequisites-tutorial.adoc | 4 ++-- modules/rosa-creating-node-tuning.adoc | 6 +++--- modules/rosa-deleting-node-tuning.adoc | 2 +- modules/rosa-hcp-vpc-terraform.adoc | 2 +- modules/rosa-modifying-node-tuning.adoc | 6 +++--- modules/rosa-operator-config.adoc | 4 ++-- modules/rosa-sts-account-roles-terraform.adoc | 4 ++-- modules/rosa-sts-byo-oidc-options.adoc | 2 +- modules/rosa-sts-ocm-and-user-role-troubleshooting.adoc | 6 +++--- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cloud_experts_tutorials/cloud-experts-rosa-cloudwatch-sts.adoc b/cloud_experts_tutorials/cloud-experts-rosa-cloudwatch-sts.adoc index c4d731d360d8..c86618e9de2b 100644 --- a/cloud_experts_tutorials/cloud-experts-rosa-cloudwatch-sts.adoc +++ b/cloud_experts_tutorials/cloud-experts-rosa-cloudwatch-sts.adoc @@ -226,7 +226,7 @@ EOF $ aws logs describe-log-groups --log-group-name-prefix rosa-${ROSA_CLUSTER_NAME} ---- + -.Sample output +.Example output + [source,c] ---- diff --git a/cloud_experts_tutorials/rosa-mobb-prerequisites-tutorial.adoc b/cloud_experts_tutorials/rosa-mobb-prerequisites-tutorial.adoc index a1474b9faf81..8b20a1de78da 100644 --- a/cloud_experts_tutorials/rosa-mobb-prerequisites-tutorial.adoc +++ b/cloud_experts_tutorials/rosa-mobb-prerequisites-tutorial.adoc @@ -107,7 +107,7 @@ $ aws configure $ aws configure ---- + -.Sample output +.Example output [source,terminal] ---- AWS Access Key ID []: @@ -127,7 +127,7 @@ $ aws sts get-caller-identity + You should receive output similar to the following: + -.Sample output +.Example output [source,terminal] ---- { diff --git a/modules/rosa-creating-node-tuning.adoc b/modules/rosa-creating-node-tuning.adoc index 5cb34aac624b..48c90aba6bcc 100644 --- a/modules/rosa-creating-node-tuning.adoc +++ b/modules/rosa-creating-node-tuning.adoc @@ -25,7 +25,7 @@ $ rosa create tuning-config -c --name --spec-path + You must supply the path to the `spec.json` file or the command returns an error. + -.Sample output +.Example output [source,terminal] ---- $ I: Tuning config 'sample-tuning' has been created on cluster 'cluster-example'. @@ -45,7 +45,7 @@ You can specify the type of output you want for the configuration list. ** Without specifying the output type, you see the ID and name of the tuning configuration: + -.Sample output without specifying output type +.Example output without specifying output type [source,terminal] ---- ID NAME @@ -59,7 +59,7 @@ ID NAME The following JSON output has hard line-returns for the sake of reading clarity. This JSON output is invalid unless you remove the newlines in the JSON strings. ==== + -.Sample output specifying JSON output +.Example output specifying JSON output [source,terminal] ---- [ diff --git a/modules/rosa-deleting-node-tuning.adoc b/modules/rosa-deleting-node-tuning.adoc index 0d35a303b6f3..f2908ea751a5 100644 --- a/modules/rosa-deleting-node-tuning.adoc +++ b/modules/rosa-deleting-node-tuning.adoc @@ -30,7 +30,7 @@ $ rosa delete tuning-config -c + The tuning configuration on the cluster is deleted + -.Sample output +.Example output [source,terminal] ---- ? Are you sure you want to delete tuning config sample-tuning on cluster sample-cluster? Yes diff --git a/modules/rosa-hcp-vpc-terraform.adoc b/modules/rosa-hcp-vpc-terraform.adoc index fee289ce1074..ea0c5ad0f754 100644 --- a/modules/rosa-hcp-vpc-terraform.adoc +++ b/modules/rosa-hcp-vpc-terraform.adoc @@ -66,7 +66,7 @@ $ export SUBNET_IDS=$(terraform output -raw cluster-subnets-string) $ echo $SUBNET_IDS ---- + -.Sample output +.Example output + [source,terminal] ---- diff --git a/modules/rosa-modifying-node-tuning.adoc b/modules/rosa-modifying-node-tuning.adoc index cf58e11c62bd..4a8e17bfdf08 100644 --- a/modules/rosa-modifying-node-tuning.adoc +++ b/modules/rosa-modifying-node-tuning.adoc @@ -31,7 +31,7 @@ The following items in this spec file are: <2> Provide the name of your tuning configuration. <3> Optionally, you can provide the output type. If you do not specify any outputs, you only see the ID and name of the tuning configuration. + -.Sample output without specifying output type +.Example output without specifying output type [source,terminal] ---- Name: sample-tuning @@ -53,7 +53,7 @@ Spec: { ---- + -.Sample output specifying JSON output +.Example output specifying JSON output [source,terminal] ---- { @@ -95,7 +95,7 @@ In this command, you use the `spec.json` file to edit your configurations. $ rosa describe tuning-config -c --name ---- + -.Sample output +.Example output [source,terminal] ---- Name: sample-tuning diff --git a/modules/rosa-operator-config.adoc b/modules/rosa-operator-config.adoc index afcca25ffd42..3bb6e1ab7aa8 100644 --- a/modules/rosa-operator-config.adoc +++ b/modules/rosa-operator-config.adoc @@ -49,7 +49,7 @@ $ rosa create operator-roles --hosted-cp + You must include the `--hosted-cp` parameter to create the correct roles for {hcp-title} clusters. This command returns the following information. + -.Sample output +.Example output + [source,terminal] ---- @@ -90,7 +90,7 @@ The Operator roles are now created and ready to use for creating your {hcp-title $ rosa list operator-roles ---- + -.Sample output +.Example output + [source,terminal] ---- diff --git a/modules/rosa-sts-account-roles-terraform.adoc b/modules/rosa-sts-account-roles-terraform.adoc index 5b2186291c09..29f7b4d1bc9d 100644 --- a/modules/rosa-sts-account-roles-terraform.adoc +++ b/modules/rosa-sts-account-roles-terraform.adoc @@ -187,7 +187,7 @@ $ terraform init $ terraform validate ---- + -.Sample output +.Example output + [source,terminal] ---- @@ -219,7 +219,7 @@ If you used the `terraform plan` command first, you can provide your created `ac $ rosa list account-roles ---- + -.Sample output +.Example output [source,terminal] ---- diff --git a/modules/rosa-sts-byo-oidc-options.adoc b/modules/rosa-sts-byo-oidc-options.adoc index bfc53b6b409f..c22d460fe82c 100644 --- a/modules/rosa-sts-byo-oidc-options.adoc +++ b/modules/rosa-sts-byo-oidc-options.adoc @@ -54,7 +54,7 @@ Creates an OIDC configuration that is hosted under Red Hat's AWS account. This c $ rosa create oidc-config --managed ---- -.Sample output +.Example output [source,terminal] ---- W: For a managed OIDC Config only auto mode is supported. However, you may choose the provider creation mode diff --git a/modules/rosa-sts-ocm-and-user-role-troubleshooting.adoc b/modules/rosa-sts-ocm-and-user-role-troubleshooting.adoc index 1a0651de73f2..adffc6deb251 100644 --- a/modules/rosa-sts-ocm-and-user-role-troubleshooting.adoc +++ b/modules/rosa-sts-ocm-and-user-role-troubleshooting.adoc @@ -8,7 +8,7 @@ You may receive an error when trying to create a cluster using the {product-title} (ROSA) CLI, `rosa`. -.Sample output +.Example output [source,terminal] ---- E: Failed to create cluster: The sts_user_role is not linked to account '1oNl'. Please create a user role and link it to the account. @@ -29,7 +29,7 @@ After any user sets up an `ocm-role` IAM resource linked to a Red Hat account, a $ rosa list ocm-role ---- + -.Sample output +.Example output + [source,terminal] ---- @@ -43,7 +43,7 @@ ManagedOpenShift-OCM-Role-1158 arn:aws:iam::2066:role/ManagedOpenShift-OCM-Role $ rosa list user-role ---- + -.Sample output +.Example output + [source,terminal] ---- From 5863e3935c69350f3d0356b9d96ea964890e3435 Mon Sep 17 00:00:00 2001 From: Michael Ryan Peter Date: Wed, 22 May 2024 10:59:24 -0400 Subject: [PATCH 031/339] OSDOCS-10522: Remove platform Operators - Remove PO from topic maps - Update existing content to remove PO references - Delete platform Operators content --- _topic_maps/_topic_map.yml | 3 - _topic_maps/_topic_map_osd.yml | 2 - _topic_maps/_topic_map_rosa.yml | 2 - _topic_maps/_topic_map_rosa_hcp.yml | 2 - architecture/control-plane.adoc | 11 -- modules/olm-deleting-po.adoc | 65 ---------- modules/olm-installing-po-during.adoc | 117 ------------------ modules/olm-po-techpreview.adoc | 68 ---------- modules/olm-rukpak-about.adoc | 6 +- .../understanding/olm-packaging-format.adoc | 2 - 10 files changed, 2 insertions(+), 276 deletions(-) delete mode 100644 modules/olm-deleting-po.adoc delete mode 100644 modules/olm-installing-po-during.adoc delete mode 100644 modules/olm-po-techpreview.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 76aac2ac354b..9d1d36b37c07 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1862,9 +1862,6 @@ Topics: - Name: Catalog source pod scheduling File: olm-cs-podsched Distros: openshift-origin,openshift-enterprise - - Name: Managing platform Operators - File: olm-managing-po - Distros: openshift-enterprise,openshift-origin - Name: Troubleshooting Operator issues File: olm-troubleshooting-operator-issues Distros: openshift-enterprise,openshift-origin diff --git a/_topic_maps/_topic_map_osd.yml b/_topic_maps/_topic_map_osd.yml index e8fedaffdbc8..dd6880706d97 100644 --- a/_topic_maps/_topic_map_osd.yml +++ b/_topic_maps/_topic_map_osd.yml @@ -716,8 +716,6 @@ Topics: File: olm-managing-custom-catalogs - Name: Catalog source pod scheduling File: olm-cs-podsched -# - Name: Managing platform Operators <= Tech Preview -# File: olm-managing-po - Name: Troubleshooting Operator issues File: olm-troubleshooting-operator-issues - Name: Developing Operators diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index 9c5d9d3c5aab..743de310b11d 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -937,8 +937,6 @@ Topics: File: olm-managing-custom-catalogs - Name: Catalog source pod scheduling File: olm-cs-podsched -# - Name: Managing platform Operators <= Tech Preview -# File: olm-managing-po - Name: Troubleshooting Operator issues File: olm-troubleshooting-operator-issues - Name: Developing Operators diff --git a/_topic_maps/_topic_map_rosa_hcp.yml b/_topic_maps/_topic_map_rosa_hcp.yml index 37873d275cec..75f776e3df62 100644 --- a/_topic_maps/_topic_map_rosa_hcp.yml +++ b/_topic_maps/_topic_map_rosa_hcp.yml @@ -940,8 +940,6 @@ Topics: # File: olm-managing-custom-catalogs # - Name: Catalog source pod scheduling # File: olm-cs-podsched -# - Name: Managing platform Operators <= Tech Preview -# File: olm-managing-po # - Name: Troubleshooting Operator issues # File: olm-troubleshooting-operator-issues # - Name: Developing Operators diff --git a/architecture/control-plane.adoc b/architecture/control-plane.adoc index abfde49056f3..3ca8747723fb 100644 --- a/architecture/control-plane.adoc +++ b/architecture/control-plane.adoc @@ -50,17 +50,6 @@ include::modules/arch-olm-operators.adoc[leveloffset=+2] * For more details on running add-on Operators in {product-title}, see the _Operators_ guide sections on xref:../operators/understanding/olm/olm-understanding-olm.adoc#olm-understanding-olm[Operator Lifecycle Manager (OLM)] and xref:../operators/understanding/olm-understanding-operatorhub.adoc#olm-understanding-operatorhub[OperatorHub]. * For more details on the Operator SDK, see xref:../operators/operator_sdk/osdk-about.adoc#osdk-about[Developing Operators]. -ifdef::openshift-enterprise,openshift-webscale,openshift-origin[] -include::modules/arch-platform-operators.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../operators/admin/olm-managing-po.adoc#olm-managing-po[Managing platform Operators] -* xref:../operators/admin/olm-managing-po.adoc#olm-po-techpreview_olm-managing-po[Technology Preview restrictions for platform Operators] -* xref:../operators/understanding/olm-packaging-format.adoc#olm-rukpak-about_olm-packaging-format[RukPak component and packaging format] -* xref:../installing/cluster-capabilities.adoc#cluster-capabilities[Cluster capabilities] -endif::[] - // This module does not apply to OSD/ROSA ifndef::openshift-dedicated,openshift-rosa[] include::modules/understanding-machine-config-operator.adoc[leveloffset=+1] diff --git a/modules/olm-deleting-po.adoc b/modules/olm-deleting-po.adoc deleted file mode 100644 index 94077dee3d21..000000000000 --- a/modules/olm-deleting-po.adoc +++ /dev/null @@ -1,65 +0,0 @@ -// Module included in the following assemblies: -// -// * operators/admin/olm-managing-po.adoc - -:_mod-docs-content-type: PROCEDURE -[id="olm-deleting-po_{context}"] -= Deleting platform Operators - -As a cluster administrator, you can delete existing platform Operators. Operator Lifecycle Manager (OLM) performs a cascading deletion. First, OLM removes the bundle deployment for the platform Operator, which then deletes any objects referenced in the `registry+v1` type bundle. - -[NOTE] -==== -The platform Operator manager and bundle deployment provisioner only manage objects that are referenced in the bundle, but not objects subsequently deployed by any bundle workloads themselves. For example, if a bundle workload creates a namespace and the Operator is not configured to clean it up before the Operator is removed, it is outside of the scope of OLM to remove the namespace during platform Operator deletion. -==== - -.Procedure - -. Get a list of installed platform Operators and find the name for the Operator you want to delete: -+ -[source,terminal] ----- -$ oc get platformoperator ----- - -. Delete the `PlatformOperator` resource for the chosen Operator, for example, for the Quay Operator: -+ -[source,terminal] ----- -$ oc delete platformoperator quay-operator ----- -+ -.Example output -[source,terminal] ----- -platformoperator.platform.openshift.io "quay-operator" deleted ----- - -.Verification - -. Verify the namespace for the platform Operator is eventually deleted, for example, for the Quay Operator: -+ -[source,terminal] ----- -$ oc get ns quay-operator-system ----- -+ -.Example output -[source,terminal] ----- -Error from server (NotFound): namespaces "quay-operator-system" not found ----- - -. Verify the `platform-operators-aggregated` cluster Operator continues to report an `Available=True` status: -+ -[source,terminal] ----- -$ oc get co platform-operators-aggregated ----- -+ -.Example output -[source,terminal,subs="attributes+"] ----- -NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE -platform-operators-aggregated {product-version}.0-0 True False False 70s ----- \ No newline at end of file diff --git a/modules/olm-installing-po-during.adoc b/modules/olm-installing-po-during.adoc deleted file mode 100644 index a79f85651422..000000000000 --- a/modules/olm-installing-po-during.adoc +++ /dev/null @@ -1,117 +0,0 @@ -// Module included in the following assemblies: -// -// * operators/admin/olm-managing-po.adoc - -:_mod-docs-content-type: PROCEDURE -[id="olm-installing-po-during_{context}"] -= Installing platform Operators during cluster creation - -As a cluster administrator, you can install platform Operators by providing `FeatureGate` and `PlatformOperator` manifests during cluster creation. - -.Procedure - -. Choose a platform Operator from the supported set of OLM-based Operators. For the list of this set and details on current limitations, see "Technology Preview restrictions for platform Operators". - -. Select a cluster installation method and follow the instructions through creating an `install-config.yaml` file. For more details on preparing for a cluster installation, see "Selecting a cluster installation method and preparing it for users". - -. After you have created the `install-config.yaml` file and completed any modifications to it, change to the directory that contains the installation program and create the manifests: -+ -[source,terminal] ----- -$ ./openshift-install create manifests --dir <1> ----- -<1> For ``, specify the name of the directory that contains the `install-config.yaml` file for your cluster. - -. Create a `FeatureGate` object YAML file in the `/manifests/` directory that enables the `TechPreviewNoUpgrade` feature set, for example a `feature-gate.yaml` file: -+ -.Example `feature-gate.yaml` file -[source,yaml] ----- -apiVersion: config.openshift.io/v1 -kind: FeatureGate -metadata: - annotations: - include.release.openshift.io/self-managed-high-availability: "true" - include.release.openshift.io/single-node-developer: "true" - release.openshift.io/create-only: "true" - name: cluster -spec: - featureSet: TechPreviewNoUpgrade <1> ----- -<1> Enable the `TechPreviewNoUpgrade` feature set. - -. Create a `PlatformOperator` object YAML file for your chosen platform Operator in the `/manifests/` directory, for example a `service-mesh-po.yaml` file for the {SMProductName} Operator: -+ -.Example `service-mesh-po.yaml` file -[source,yaml] ----- -apiVersion: platform.openshift.io/v1alpha1 -kind: PlatformOperator -metadata: - name: service-mesh-po -spec: - package: - name: servicemeshoperator ----- - -. When you are ready to complete the cluster install, refer to your chosen installation method and continue through running the `openshift-install create cluster` command. -+ -During cluster creation, your provided manifests are used to enable the `TechPreviewNoUpgrade` feature set and install your chosen platform Operator. -+ -[IMPORTANT] -==== -Failure of the platform Operator to successfully install will block the cluster installation process. -==== - -.Verification - -. Check the status of the `service-mesh-po` platform Operator by running the following command: -+ -[source,terminal] ----- -$ oc get platformoperator service-mesh-po -o yaml ----- -+ -.Example output -[source,yaml] ----- -... -status: - activeBundleDeployment: - name: service-mesh-po - conditions: - - lastTransitionTime: "2022-10-24T17:24:40Z" - message: Successfully applied the service-mesh-po BundleDeployment resource - reason: InstallSuccessful - status: "True" <1> - type: Installed ----- -<1> Wait until the `Installed` status condition reports `True`. - -. Verify that the `platform-operators-aggregated` cluster Operator is reporting an `Available=True` status: -+ -[source,terminal] ----- -$ oc get clusteroperator platform-operators-aggregated -o yaml ----- -+ -.Example output -[source,yaml] ----- -... -status: - conditions: - - lastTransitionTime: "2022-10-24T17:43:26Z" - message: All platform operators are in a successful state - reason: AsExpected - status: "False" - type: Progressing - - lastTransitionTime: "2022-10-24T17:43:26Z" - status: "False" - type: Degraded - - lastTransitionTime: "2022-10-24T17:43:26Z" - message: All platform operators are in a successful state - reason: AsExpected - status: "True" - type: Available ----- diff --git a/modules/olm-po-techpreview.adoc b/modules/olm-po-techpreview.adoc deleted file mode 100644 index f6f5accd1604..000000000000 --- a/modules/olm-po-techpreview.adoc +++ /dev/null @@ -1,68 +0,0 @@ -// Module included in the following assemblies: -// -// * operators/admin/olm-managing-po.adoc - -:_mod-docs-content-type: CONCEPT -[id="olm-po-techpreview_{context}"] -= Technology Preview restrictions for platform Operators - -During the Technology Preview release of the platform Operators feature in {product-title} 4.12, the following restrictions determine whether an Operator can be installed through the platform Operators mechanism: - -* Kubernetes manifests must be packaged using the Operator Lifecycle Manager (OLM) `registry+v1` bundle format. -* The Operator cannot declare package or group/version/kind (GVK) dependencies. -* The Operator cannot specify cluster service version (CSV) install modes other than `AllNamespaces` -* The Operator cannot specify any `Webhook` or `APIService` definitions. -* All package bundles must be in the `redhat-operators` catalog source. - -After considering these restrictions, the following Operators can be successfully installed: - -.OLM-based Operators installable as platform Operators -[cols="1,1"] -|=== -|3scale-operator -|amq-broker-rhel8 - -|amq-online -|amq-streams - -|ansible-cloud-addons-operator -|apicast-operator - -|container-security-operator -|eap - -|file-integrity-operator -|gatekeeper-operator-product - -|integration-operator -|jws-operator - -|kiali-ossm -|node-healthcheck-operator - -|odf-csi-addons-operator -|odr-hub-operator - -|openshift-custom-metrics-autoscaler-operator -|openshift-gitops-operator - -|openshift-pipelines-operator-rh -|quay-operator - -|red-hat-camel-k -|rhpam-kogito-operator - -|service-registry-operator -|servicemeshoperator - -|skupper-operator -| -|=== - -[NOTE] -==== -The following features are not available during this Technology Preview release: - -* Automatically upgrading platform Operator packages after cluster rollout -* Extending the platform Operator mechanism to support any optional, CVO-based components -==== diff --git a/modules/olm-rukpak-about.adoc b/modules/olm-rukpak-about.adoc index 091b682f889f..91944d2edfa2 100644 --- a/modules/olm-rukpak-about.adoc +++ b/modules/olm-rukpak-about.adoc @@ -11,9 +11,7 @@ ifeval::["{context}" == "olm-packaging-format"] :FeatureName: RukPak include::snippets/technology-preview.adoc[] -{product-title} 4.12 introduces the _platform Operator_ type as a Technology Preview feature. The platform Operator mechanism relies on the RukPak component, also introduced in {product-title} 4.12, and its resources to manage content. - -{product-title} 4.14 introduces {olmv1-first} as a Technology Preview feature, which also relies on the RukPak component. +{product-title} 4.14 introduces {olmv1-first} as a Technology Preview feature, which relies on the RukPak component. endif::[] ifeval::["{context}" == "olmv1-rukpak"] = About RukPak @@ -36,4 +34,4 @@ A Git repository that contains a bundle within a directory Provisioner:: Controllers that install and manage content on a Kubernetes cluster Bundle deployment:: -Generates deployed instances of a bundle \ No newline at end of file +Generates deployed instances of a bundle diff --git a/operators/understanding/olm-packaging-format.adoc b/operators/understanding/olm-packaging-format.adoc index e4e47667a077..105e9ca60577 100644 --- a/operators/understanding/olm-packaging-format.adoc +++ b/operators/understanding/olm-packaging-format.adoc @@ -79,8 +79,6 @@ include::modules/olm-rukpak-about.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* xref:../../operators/admin/olm-managing-po.adoc#olm-managing-po[Managing platform Operators] -* xref:../../operators/admin/olm-managing-po.adoc#olm-po-techpreview_olm-managing-po[Technology Preview restrictions for platform Operators] * xref:../../operators/olm_v1/index.adoc#olmv1-about[About Operator Lifecycle Manager 1.0 (Technology Preview)] include::modules/olm-rukpak-bundle.adoc[leveloffset=+2] From bf3150cacb5f618f80239a534b0bff675a27737a Mon Sep 17 00:00:00 2001 From: srir Date: Mon, 13 May 2024 16:29:02 +0530 Subject: [PATCH 032/339] TELCODOCS#1876: Moved troubleshooting assembly modules to the main LVMS assembly --- _topic_maps/_topic_map.yml | 2 - ...ting-a-pvc-stuck-in-the-pending-state.adoc | 21 ++++--- ...eshooting-performing-a-forced-cleanup.adoc | 62 +++++++++---------- ...ms-troubleshooting-persistent-storage.adoc | 9 +++ ...shooting-recovering-from-disk-failure.adoc | 52 ++++++++++++---- ...m-missing-lvms-or-operator-components.adoc | 52 ++++++---------- ...shooting-recovering-from-node-failure.adoc | 19 ++++-- .../persistent-storage-using-lvms.adoc | 33 ++++++++++ ...g-local-persistent-storage-using-lvms.adoc | 31 ---------- 9 files changed, 157 insertions(+), 124 deletions(-) create mode 100644 modules/lvms-troubleshooting-persistent-storage.adoc delete mode 100644 storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 9d1d36b37c07..5a5208e1fe05 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1662,8 +1662,6 @@ Topics: File: persistent-storage-hostpath - Name: Persistent storage using LVM Storage File: persistent-storage-using-lvms - - Name: Troubleshooting local persistent storage using LVMS - File: troubleshooting-local-persistent-storage-using-lvms - Name: Using Container Storage Interface (CSI) Dir: container_storage_interface Distros: openshift-enterprise,openshift-origin diff --git a/modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc b/modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc index b9c981fcf33e..f89f7c304f72 100644 --- a/modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc +++ b/modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc @@ -1,20 +1,23 @@ -// This module is included in the following assemblies: +// Module included in the following assemblies: // -// storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc :_mod-docs-content-type: PROCEDURE [id="investigating-a-pvc-stuck-in-the-pending-state_{context}"] = Investigating a PVC stuck in the Pending state -A persistent volume claim (PVC) can get stuck in a `Pending` state for a number of reasons. For example: +A persistent volume claim (PVC) can get stuck in the `Pending` state for the following reasons: -- Insufficient computing resources -- Network problems -- Mismatched storage class or node selector -- No available volumes -- The node with the persistent volume (PV) is in a `Not Ready` state +- Insufficient computing resources. +- Network problems. +- Mismatched storage class or node selector. +- No available persistent volumes (PVs). +- The node with the PV is in the `Not Ready` state. -Identify the cause by using the `oc describe` command to review details about the stuck PVC. +.Prerequisites + +* You have installed the {oc-first}. +* You have logged in to the {oc-first} as a user with `cluster-admin` permissions. .Procedure diff --git a/modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc b/modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc index 8e53ef18ccf4..9eccaa5bd204 100644 --- a/modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc +++ b/modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc @@ -1,18 +1,22 @@ -// This module is included in the following assemblies: +// Module included in the following assemblies: // -// storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc :_mod-docs-content-type: PROCEDURE [id="performing-a-forced-cleanup_{context}"] -= Performing a forced cleanup += Performing a forced clean-up -If disk- or node-related problems persist after you complete the troubleshooting procedures, it might be necessary to perform a forced cleanup procedure. A forced cleanup is used to comprehensively address persistent issues and ensure the proper functioning of the LVMS. +If the disk or node-related problems persist even after you have completed the troubleshooting procedures, you must perform a forced clean-up. A forced clean-up is used to address persistent issues and ensure the proper functioning of {lvms-first}. .Prerequisites -. All of the persistent volume claims (PVCs) created using the logical volume manager storage (LVMS) driver have been removed. +* You have installed the {oc-first}. -. The pods using those PVCs have been stopped. +* You have logged in to the {oc-first} as a user with `cluster-admin` permissions. + +* You have deleted all the persistent volume claims (PVCs) that were created by using {lvms}. + +* You have stopped the pods that are using the PVCs that were created by using {lvms}. .Procedure @@ -24,74 +28,70 @@ If disk- or node-related problems persist after you complete the troubleshooting $ oc project openshift-storage ---- -. Ensure there is no `Logical Volume` custom resource (CR) remaining by running the following command: +. Check if the `LogicalVolume` custom resources (CRs) are present by running the following command: + [source,terminal] ---- $ oc get logicalvolume ---- -+ -.Example output -[source,terminal] ----- -No resources found ----- -.. If there are any `LogicalVolume` CRs remaining, remove their finalizers by running the following command: +.. If the `LogicalVolume` CRs are present, delete them by running the following command: + [source,terminal] ---- -$ oc patch logicalvolume -p '{"metadata":{"finalizers":[]}}' --type=merge <1> +$ oc delete logicalvolume <1> ---- -<1> Replace `` with the name of the CR. +<1> Replace `` with the name of the `LogicalVolume` CR. -.. After removing their finalizers, delete the CRs by running the following command: +.. After deleting the `LogicalVolume` CRs, remove their finalizers by running the following command: + [source,terminal] ---- -$ oc delete logicalvolume <1> +$ oc patch logicalvolume -p '{"metadata":{"finalizers":[]}}' --type=merge <1> ---- -<1> Replace `` with the name of the CR. +<1> Replace `` with the name of the `LogicalVolume` CR. -. Make sure there are no `LVMVolumeGroup` CRs left by running the following command: +. Check if the `LVMVolumeGroup` CRs are present by running the following command: + [source,terminal] ---- $ oc get lvmvolumegroup ---- + +.. If the `LVMVolumeGroup` CRs are present, delete them by running the following command: + -.Example output [source,terminal] ---- -No resources found +$ oc delete lvmvolumegroup <1> ---- +<1> Replace `` with the name of the `LVMVolumeGroup` CR. -.. If there are any `LVMVolumeGroup` CRs left, remove their finalizers by running the following command: +.. After deleting the `LVMVolumeGroup` CRs, remove their finalizers by running the following command: + [source,terminal] ---- $ oc patch lvmvolumegroup -p '{"metadata":{"finalizers":[]}}' --type=merge <1> ---- -<1> Replace `` with the name of the CR. +<1> Replace `` with the name of the `LVMVolumeGroup` CR. -.. After removing their finalizers, delete the CRs by running the following command: +. Delete any `LVMVolumeGroupNodeStatus` CRs by running the following command: + [source,terminal] ---- -$ oc delete lvmvolumegroup <1> +$ oc delete lvmvolumegroupnodestatus --all ---- -<1> Replace `` with the name of the CR. -. Remove any `LVMVolumeGroupNodeStatus` CRs by running the following command: +. Delete the `LVMCluster` CR by running the following command: + [source,terminal] ---- -$ oc delete lvmvolumegroupnodestatus --all +$ oc delete lvmcluster --all ---- -. Remove the `LVMCluster` CR by running the following command: +.. After deleting the `LVMCluster` CR, remove its finalizer by running the following command: + [source,terminal] ---- -$ oc delete lvmcluster --all +$ oc patch lvmcluster -p '{"metadata":{"finalizers":[]}}' --type=merge <1> ---- +<1> Replace `` with the name of the `LVMCluster` CR. diff --git a/modules/lvms-troubleshooting-persistent-storage.adoc b/modules/lvms-troubleshooting-persistent-storage.adoc new file mode 100644 index 000000000000..3dffe9fa4f12 --- /dev/null +++ b/modules/lvms-troubleshooting-persistent-storage.adoc @@ -0,0 +1,9 @@ +// Module included in the following assemblies: +// +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc + +:_mod-docs-content-type: CONCEPT +[id="lvms-troubleshooting-persistent-storage_{context}"] += Troubleshooting persistent storage + +While configuring persistent storage using {lvms-first}, you can encounter several issues that require troubleshooting. \ No newline at end of file diff --git a/modules/lvms-troubleshooting-recovering-from-disk-failure.adoc b/modules/lvms-troubleshooting-recovering-from-disk-failure.adoc index 182f12c42b69..633fe15cd9ad 100644 --- a/modules/lvms-troubleshooting-recovering-from-disk-failure.adoc +++ b/modules/lvms-troubleshooting-recovering-from-disk-failure.adoc @@ -1,12 +1,44 @@ -// This module is included in the following assemblies: +// Module included in the following assemblies: // -// storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc :_mod-docs-content-type: PROCEDURE [id="recovering-from-disk-failure_{context}"] = Recovering from disk failure -If you see a failure message while inspecting the events associated with the persistent volume claim (PVC), there might be a problem with the underlying volume or disk. Disk and volume provisioning issues often result with a generic error first, such as `Failed to provision volume with StorageClass `. A second, more specific error message usually follows. +If you see a failure message while inspecting the events associated with the persistent volume claim (PVC), there can be a problem with the underlying volume or disk. + +Disk and volume provisioning issues result with a generic error message such as `Failed to provision volume with storage class `. The generic error message is followed by a specific volume failure error message. + +The following table describes the volume failure error messages: + +.Volume failure error messages +[%autowidth, options="header"] +|=== + +|Error message |Description + +|`Failed to check volume existence` +|Indicates a problem in verifying whether the volume already exists. Volume verification failure can be caused by network connectivity problems or other failures. + +|`Failed to bind volume` +|Failure to bind a volume can happen if the persistent volume (PV) that is available does not match the requirements of the PVC. + +|`FailedMount` or `FailedAttachVolume` +|This error indicates problems when trying to mount the volume to a node. If the disk has failed, this error can appear when a pod tries to use the PVC. + +|`FailedUnMount` +|This error indicates problems when trying to unmount a volume from a node. If the disk has failed, this error can appear when a pod tries to use the PVC. + +|`Volume is already exclusively attached to one node and cannot be attached to another` +|This error can appear with storage solutions that do not support `ReadWriteMany` access modes. + +|=== + +.Prerequisites + +* You have installed the {oc-first}. +* You have logged in to the {oc-first} as a user with `cluster-admin` permissions. .Procedure @@ -16,18 +48,12 @@ If you see a failure message while inspecting the events associated with the per ---- $ oc describe pvc <1> ---- -<1> Replace `` with the name of the PVC. Here are some examples of disk or volume failure error messages and their causes: -+ -- *Failed to check volume existence:* Indicates a problem in verifying whether the volume already exists. Volume verification failure can be caused by network connectivity problems or other failures. -+ -- *Failed to bind volume:* Failure to bind a volume can happen if the persistent volume (PV) that is available does not match the requirements of the PVC. -+ -- *FailedMount or FailedUnMount:* This error indicates problems when trying to mount the volume to a node or unmount a volume from a node. If the disk has failed, this error might appear when a pod tries to use the PVC. -+ -- *Volume is already exclusively attached to one node and cannot be attached to another:* This error can appear with storage solutions that do not support `ReadWriteMany` access modes. +<1> Replace `` with the name of the PVC. . Establish a direct connection to the host where the problem is occurring. . Resolve the disk issue. -After you have resolved the issue with the disk, you might need to perform the forced cleanup procedure if failure messages persist or reoccur. \ No newline at end of file +.Next steps + +* If the volume failure messages persist or recur even after you have resolved the issue with the disk, you must perform a forced clean-up. For more information, see "Performing a forced clean-up". \ No newline at end of file diff --git a/modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc b/modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc index 4d695306c4fe..3863da8db661 100644 --- a/modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc +++ b/modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc @@ -1,16 +1,21 @@ -// This module is included in the following assemblies: +// Module included in the following assemblies: // -// storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc :_mod-docs-content-type: PROCEDURE [id="recovering-from-missing-lvms-or-operator-components_{context}"] -= Recovering from missing LVMS or Operator components += Recovering from a missing storage class -If you encounter a storage class "not found" error, check the `LVMCluster` resource and ensure that all the logical volume manager storage (LVMS) pods are running. You can create an `LVMCluster` resource if it does not exist. +If you encounter the `storage class not found` error, check the `LVMCluster` custom resource (CR) and ensure that all the {lvms-first} pods are in the `Running` state. + +.Prerequisites + +* You have installed the {oc-first}. +* You have logged in to the {oc-first} as a user with `cluster-admin` permissions. .Procedure -. Verify the presence of the LVMCluster resource by running the following command: +. Verify that the `LVMCluster` CR is present by running the following command: + [source,terminal] ---- @@ -24,33 +29,9 @@ NAME AGE my-lvmcluster 65m ---- -. If the cluster does not have an `LVMCluster` resource, create one by running the following command: -+ -[source,terminal] ----- -$ oc create -n openshift-storage -f <1> ----- -<1> Replace `` with a custom resource URL or file tailored to your requirements. -+ -.Example custom resource -[source,yaml,options="nowrap",role="white-space-pre"] ----- -apiVersion: lvm.topolvm.io/v1alpha1 -kind: LVMCluster -metadata: - name: my-lvmcluster -spec: - storage: - deviceClasses: - - name: vg1 - default: true - thinPoolConfig: - name: thin-pool-1 - sizePercent: 90 - overprovisionRatio: 10 ----- +. If the `LVMCluster` CR is not present, create an `LVMCluster` CR. For more information, see "Ways to create an LVMCluster custom resource". -. Check that all the pods from LVMS are in the `Running` state in the `openshift-storage` namespace by running the following command: +. In the `openshift-storage` namespace, check that all the {lvms} pods are in the `Running` state by running the following command: + [source,terminal] ---- @@ -67,9 +48,14 @@ topolvm-node-dr26h 4/4 Running 0 66m vg-manager-r6zdv 1/1 Running 0 66m ---- + -The expected output is one running instance of `lvms-operator` and `vg-manager`. One instance of `topolvm-controller` and `topolvm-node` is expected for each node. +The output of this command must contain a running instance of the following pods: + +* `lvms-operator` +* `vg-manager` +* `topolvm-controller` +* `topolvm-node` + -If `topolvm-node` is stuck in the `Init` state, there is a failure to locate an available disk for LVMS to use. To retrieve the information necessary to troubleshoot, review the logs of the `vg-manager` pod by running the following command: +If the `topolvm-node` pod is stuck in the `Init` state, it is due to a failure to locate an available disk for {lvms} to use. To retrieve the necessary information to troubleshoot this issue, review the logs of the `vg-manager` pod by running the following command: + [source,terminal] ---- diff --git a/modules/lvms-troubleshooting-recovering-from-node-failure.adoc b/modules/lvms-troubleshooting-recovering-from-node-failure.adoc index 17ab0696ae58..4463637c537c 100644 --- a/modules/lvms-troubleshooting-recovering-from-node-failure.adoc +++ b/modules/lvms-troubleshooting-recovering-from-node-failure.adoc @@ -1,12 +1,19 @@ -// This module is included in the following assemblies: +// Module included in the following assemblies: // -// storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc :_mod-docs-content-type: PROCEDURE [id="recovering-from-node-failure_{context}"] = Recovering from node failure -Sometimes a persistent volume claim (PVC) is stuck in a `Pending` state because a particular node in the cluster has failed. To identify the failed node, you can examine the restart count of the `topolvm-node` pod. An increased restart count indicates potential problems with the underlying node, which may require further investigation and troubleshooting. +A persistent volume claim (PVC) can be stuck in the `Pending` state due to a node failure in the cluster. + +To identify the failed node, you can examine the restart count of the `topolvm-node` pod. An increased restart count indicates potential problems with the underlying node, which might require further investigation and troubleshooting. + +.Prerequisites + +* You have installed the {oc-first}. +* You have logged in to the {oc-first} as a user with `cluster-admin` permissions. .Procedure @@ -30,5 +37,7 @@ vg-manager-r6zdv 1/1 Running 0 66m vg-manager-990ut 1/1 Running 0 66m vg-manager-an118 1/1 Running 0 66m ---- -+ -After you resolve any issues with the node, you might need to perform the forced cleanup procedure if the PVC is still stuck in a `Pending` state. \ No newline at end of file + +.Next steps + +* If the PVC is stuck in the `Pending` state even after you have resolved any issues with the node, you must perform a forced clean-up. For more information, see "Performing a forced clean-up". \ No newline at end of file diff --git a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc index 0ec5d132bfa3..88a6db102534 100644 --- a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc +++ b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc @@ -226,3 +226,36 @@ include::modules/lvms-download-log-files-and-diagnostics.adoc[leveloffset=+1] .Additional resources * xref:../../../support/gathering-cluster-data.adoc#about-must-gather_gathering-cluster-data[About the must-gather tool] + +//Troubleshooting local persistent storage using LVM Storage + +include::modules/lvms-troubleshooting-persistent-storage.adoc[leveloffset=+1] + +include::modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc[leveloffset=+2] + +include::modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#about-lvmcluster_logical-volume-manager-storage[About the LVMCluster custom resource] + +* xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#about-creating-lvmcluster-cr_logical-volume-manager-storage[Ways to create an LVMCluster custom resource] + +include::modules/lvms-troubleshooting-recovering-from-node-failure.adoc[leveloffset=+2] + +[role="_additional-resources"] +[id="additional-resources-forced-cleanup-1"] +.Additional resources + +* xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#performing-a-forced-cleanup_logical-volume-manager-storage[Performing a forced clean-up] + +include::modules/lvms-troubleshooting-recovering-from-disk-failure.adoc[leveloffset=+2] + +[role="_additional-resources"] +[id="additional-resources-forced-cleanup-2"] +.Additional resources + +* xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#performing-a-forced-cleanup_logical-volume-manager-storage[Performing a forced clean-up] + +include::modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc[leveloffset=+2] \ No newline at end of file diff --git a/storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc b/storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc deleted file mode 100644 index 3ae4d7e76db5..000000000000 --- a/storage/persistent_storage/persistent_storage_local/troubleshooting-local-persistent-storage-using-lvms.adoc +++ /dev/null @@ -1,31 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="troubleshooting-local-persistent-storage"] -= Troubleshooting local persistent storage using LVMS -include::_attributes/common-attributes.adoc[] -:context: troubleshooting-local-persistent-storage-using-lvms - -toc::[] - -Because {product-title} does not scope a persistent volume (PV) to a single project, it can be shared across the cluster and claimed by any project using a persistent volume claim (PVC). This can lead to a number of issues that require troubleshooting. - -include::modules/lvms-troubleshooting-investigating-a-pvc-stuck-in-the-pending-state.adoc[leveloffset=+1] - -include::modules/lvms-troubleshooting-recovering-from-missing-lvms-or-operator-components.adoc[leveloffset=+1] - -include::modules/lvms-troubleshooting-recovering-from-node-failure.adoc[leveloffset=+1] - -[role="_additional-resources"] -[id="additional-resources-forced-cleanup-1"] -.Additional resources - -* xref:../../../troubleshooting-local-persistent-storage-using-lvms.adoc#performing-a-forced-cleanup_troubleshooting-local-persistent-storage-using-lvms[Performing a forced cleanup] - -include::modules/lvms-troubleshooting-recovering-from-disk-failure.adoc[leveloffset=+1] - -[role="_additional-resources"] -[id="additional-resources-forced-cleanup-2"] -.Additional resources - -* xref:../../../troubleshooting-local-persistent-storage-using-lvms.adoc#performing-a-forced-cleanup_troubleshooting-local-persistent-storage-using-lvms[Performing a forced cleanup] - -include::modules/lvms-troubleshooting-performing-a-forced-cleanup.adoc[leveloffset=+1] From ff47c4ec49e404a9fce48a79e7a07c28160f9c17 Mon Sep 17 00:00:00 2001 From: Andrea Hoffer Date: Thu, 25 Apr 2024 15:34:08 -0400 Subject: [PATCH 033/339] OSDOCS#10143: Updating that SA API token secrets are no longer automatically generated --- ...sing-service-accounts-in-applications.adoc | 6 ---- modules/cluster-image-registry-operator.adoc | 4 +-- modules/nodes-pods-secrets-creating-sa.adoc | 20 ++++++++---- .../service-account-auto-secret-removed.adoc | 32 ++++--------------- nodes/pods/nodes-pods-secrets.adoc | 21 ++++-------- 5 files changed, 29 insertions(+), 54 deletions(-) diff --git a/authentication/using-service-accounts-in-applications.adoc b/authentication/using-service-accounts-in-applications.adoc index 153777c25491..8a31f8792af4 100644 --- a/authentication/using-service-accounts-in-applications.adoc +++ b/authentication/using-service-accounts-in-applications.adoc @@ -12,12 +12,6 @@ include::modules/service-accounts-default.adoc[leveloffset=+1] include::modules/service-account-auto-secret-removed.adoc[leveloffset=+2] -.Additional resources - -* For information about requesting bound service account tokens, see xref:../authentication/bound-service-account-tokens.adoc#bound-sa-tokens-configuring_bound-service-account-tokens[Configuring bound service account tokens using volume projection]. - -* For information about creating a service account token secret, see xref:../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating-sa_nodes-pods-secrets[Creating a service account token secret]. - include::modules/service-accounts-creating.adoc[leveloffset=+1] // include::modules/service-accounts-using-credentials-inside-a-container.adoc[leveloffset=+1] diff --git a/modules/cluster-image-registry-operator.adoc b/modules/cluster-image-registry-operator.adoc index c84ff8fa2d45..d02ce4dadf7f 100644 --- a/modules/cluster-image-registry-operator.adoc +++ b/modules/cluster-image-registry-operator.adoc @@ -34,11 +34,11 @@ If insufficient information is available to define a complete `image-registry` r The Cluster Image Registry Operator runs in the `openshift-image-registry` namespace and it also manages the registry instance in that location. All configuration and workload resources for the registry reside in that namespace. ifdef::cluster-caps[] -In order to integrate the image registry into the cluster's user authentication and authorization system, a service account token secret and an image pull secret are generated for each service account in the cluster. +In order to integrate the image registry into the cluster's user authentication and authorization system, an image pull secret is generated for each service account in the cluster. [IMPORTANT] ==== -If you disable the `ImageRegistry` capability or if you disable the integrated {product-registry} in the Cluster Image Registry Operator's configuration, the service account token secret and image pull secret are not generated for each service account. +If you disable the `ImageRegistry` capability or if you disable the integrated {product-registry} in the Cluster Image Registry Operator's configuration, the image pull secret is not generated for each service account. ==== If you disable the `ImageRegistry` capability, you can reduce the overall resource footprint of {product-title} in resource-constrained environments. Depending on your deployment, you can disable this component if you do not need it. diff --git a/modules/nodes-pods-secrets-creating-sa.adoc b/modules/nodes-pods-secrets-creating-sa.adoc index 5443175bbd03..2da2c55a88a9 100644 --- a/modules/nodes-pods-secrets-creating-sa.adoc +++ b/modules/nodes-pods-secrets-creating-sa.adoc @@ -4,24 +4,30 @@ :_mod-docs-content-type: PROCEDURE [id="nodes-pods-secrets-creating-sa_{context}"] -= Creating a service account token secret += Creating a legacy service account token secret -As an administrator, you can create a service account token secret, which allows you to distribute a service account token to applications that must authenticate to the API. +As an administrator, you can create a legacy service account token secret, which allows you to distribute a service account token to applications that must authenticate to the API. -[NOTE] +[WARNING] ==== -It is recommended to obtain bound service account tokens using the TokenRequest API instead of using service account token secrets. The tokens obtained from the TokenRequest API are more secure than the tokens stored in secrets, because they have a bounded lifetime and are not readable by other API clients. +It is recommended to obtain bound service account tokens using the TokenRequest API instead of using legacy service account token secrets. You should create a service account token secret only if you cannot use the TokenRequest API and if the security exposure of a nonexpiring token in a readable API object is acceptable to you. -You should create a service account token secret only if you cannot use the TokenRequest API and if the security exposure of a non-expiring token in a readable API object is acceptable to you. +Bound service account tokens are more secure than service account token secrets for the following reasons: -See the Additional resources section that follows for information on creating bound service account tokens. +* Bound service account tokens have a bounded lifetime. +* Bound service account tokens contain audiences. +* Bound service account tokens can be bound to pods or secrets and the bound tokens are invalidated when the bound object is removed. + +Workloads are automatically injected with a projected volume to obtain a bound service account token. If your workload needs an additional service account token, add an additional projected volume in your workload manifest. + +For more information, see "Configuring bound service account tokens using volume projection". ==== .Procedure . Create a `Secret` object in a YAML file on a control plane node: + -.Example `secret` object: +.Example `Secret` object [source,yaml] ---- apiVersion: v1 diff --git a/modules/service-account-auto-secret-removed.adoc b/modules/service-account-auto-secret-removed.adoc index 11024559fee2..9612e558e53d 100644 --- a/modules/service-account-auto-secret-removed.adoc +++ b/modules/service-account-auto-secret-removed.adoc @@ -5,37 +5,19 @@ :_mod-docs-content-type: CONCEPT [id="auto-generated-sa-token-secrets_{context}"] -= Automatically generated secrets += Automatically generated image pull secrets -By default, {product-title} creates the following secrets for each service account: +By default, {product-title} creates an image pull secret for each service account. -* A dockercfg image pull secret -* A service account token secret -+ [NOTE] ==== -Prior to {product-title} 4.11, a second service account token secret was generated when a service account was created. This service account token secret was used to access the Kubernetes API. +Prior to {product-title} 4.16, a long-lived service account API token secret was also generated for each service account that was created. Starting with {product-title} 4.16, this service account API token secret is no longer created. -Starting with {product-title} 4.11, this second service account token secret is no longer created. This is because the `LegacyServiceAccountTokenNoAutoGeneration` upstream Kubernetes feature gate was enabled, which stops the automatic generation of secret-based service account tokens to access the Kubernetes API. - -After upgrading to {product-version}, any existing service account token secrets are not deleted and continue to function. +After upgrading to {product-version}, any existing long-lived service account API token secrets are not deleted and will continue to function. For information about detecting long-lived API tokens that are in use in your cluster or deleting them if they are not needed, see the Red Hat Knowledgebase article link:https://access.redhat.com/articles/7058801[Long-lived service account API tokens in OpenShift Container Platform]. ==== -This service account token secret and docker configuration image pull secret are necessary to integrate the {product-registry} into the cluster's user authentication and authorization system. - -However, if you do not enable the `ImageRegistry` capability or if you disable the integrated {product-registry} in the Cluster Image Registry Operator's configuration, these secrets are not generated for each service account. - -[WARNING] -==== -Do not rely on these automatically generated secrets for your own use; they might be removed in a future {product-title} release. -==== - -Workloads are automatically injected with a projected volume to obtain a bound service account token. If your workload needs an additional service account token, add an additional projected volume in your workload manifest. Bound service account tokens are more secure than service account token secrets for the following reasons: - -* Bound service account tokens have a bounded lifetime. -* Bound service account tokens contain audiences. -* Bound service account tokens can be bound to pods or secrets and the bound tokens are invalidated when the bound object is removed. +This image pull secret is necessary to integrate the {product-registry} into the cluster's user authentication and authorization system. -For more information, see _Configuring bound service account tokens using volume projection_. +However, if you do not enable the `ImageRegistry` capability or if you disable the integrated {product-registry} in the Cluster Image Registry Operator's configuration, an image pull secret is not generated for each service account. -You can also manually create a service account token secret to obtain a token, if the security exposure of a non-expiring token in a readable API object is acceptable to you. For more information, see _Creating a service account token secret_. +When the integrated {product-registry} is disabled on a cluster that previously had it enabled, the previously generated image pull secrets are deleted automatically. diff --git a/nodes/pods/nodes-pods-secrets.adoc b/nodes/pods/nodes-pods-secrets.adoc index 648853a23402..466e3f7297af 100644 --- a/nodes/pods/nodes-pods-secrets.adoc +++ b/nodes/pods/nodes-pods-secrets.adoc @@ -14,13 +14,6 @@ include::modules/nodes-pods-secrets-about.adoc[leveloffset=+1] include::modules/service-account-auto-secret-removed.adoc[leveloffset=+2] -.Additional resources - -ifndef::openshift-rosa,openshift-dedicated[] -* For information about requesting bound service account tokens, see xref:../../authentication/bound-service-account-tokens.adoc#bound-sa-tokens-configuring_bound-service-account-tokens[Using bound service account tokens] -endif::openshift-rosa,openshift-dedicated[] -* For information about creating a service account token secret, see xref:../../nodes/pods/nodes-pods-secrets.doc#nodes-pods-secrets-creating-sa_nodes-pods-secrets[Creating a service account token secret]. - include::modules/nodes-pods-secrets-creating.adoc[leveloffset=+1] include::modules/nodes-pods-secrets-creating-opaque.adoc[leveloffset=+2] @@ -28,20 +21,20 @@ include::modules/nodes-pods-secrets-creating-opaque.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* For more information on using secrets in pods, see xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets]. +* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets] include::modules/nodes-pods-secrets-creating-sa.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* For more information on using secrets in pods, see xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets]. +* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets] ifndef::openshift-rosa,openshift-dedicated[] -* For information on requesting bound service account tokens, see xref:../../authentication/bound-service-account-tokens.adoc#bound-sa-tokens-configuring_bound-service-account-tokens[Using bound service account tokens] +* xref:../../authentication/bound-service-account-tokens.adoc#bound-sa-tokens-configuring_bound-service-account-tokens[Configuring bound service account tokens using volume projection] -* For information on creating service accounts, see xref:../../authentication/understanding-and-creating-service-accounts.adoc#understanding-and-creating-service-accounts[Understanding and creating service accounts]. +* xref:../../authentication/understanding-and-creating-service-accounts.adoc#understanding-and-creating-service-accounts[Understanding and creating service accounts] endif::openshift-rosa,openshift-dedicated[] include::modules/nodes-pods-secrets-creating-basic.adoc[leveloffset=+2] @@ -49,21 +42,21 @@ include::modules/nodes-pods-secrets-creating-basic.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* For more information on using secrets in pods, see xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets]. +* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets] include::modules/nodes-pods-secrets-creating-ssh.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets]. +* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets] include::modules/nodes-pods-secrets-creating-docker.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* For more information on using secrets in pods, see xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets]. +* xref:../../nodes/pods/nodes-pods-secrets.adoc#nodes-pods-secrets-creating_nodes-pods-secrets[Understanding how to create secrets] include::modules/nodes-pods-secrets-creating-web-console-secrets.adoc[leveloffset=+2] From dd610ace5df2c72233f5a22f8d9c61cc0ebd1716 Mon Sep 17 00:00:00 2001 From: Shubha Narayanan Date: Fri, 10 May 2024 13:20:22 +0530 Subject: [PATCH 034/339] Added optional tags parameter un install config --- ...aller-provisioned-vsphere-config-yaml.adoc | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/installation-installer-provisioned-vsphere-config-yaml.adoc b/modules/installation-installer-provisioned-vsphere-config-yaml.adoc index 7af89af033fb..14fbb3c2c900 100644 --- a/modules/installation-installer-provisioned-vsphere-config-yaml.adoc +++ b/modules/installation-installer-provisioned-vsphere-config-yaml.adoc @@ -42,7 +42,7 @@ networking: hostPrefix: 23 machineNetwork: - cidr: 10.0.0.0/16 - networkType: OVNKubernetes <9> + networkType: OVNKubernetes <11> serviceNetwork: - 172.30.0.0/16 endif::network[] @@ -62,6 +62,8 @@ platform: - resourcePool: "//host//Resources/" <7> folder: "//vm//" + tagIDs: <8> + - <9> zone: ingressVIPs: - 10.0.0.2 @@ -72,9 +74,9 @@ platform: port: 443 server: user: administrator@vsphere.local - diskType: thin <8> + diskType: thin <10> ifdef::restricted[] - clusterOSImage: http://mirror.example.com/images/rhcos-47.83.202103221318-0-vmware.x86_64.ova <9> + clusterOSImage: http://mirror.example.com/images/rhcos-47.83.202103221318-0-vmware.x86_64.ova <11> endif::restricted[] ifndef::openshift-origin[] fips: false @@ -83,15 +85,15 @@ ifndef::restricted[] pullSecret: '{"auths": ...}' endif::restricted[] ifdef::restricted[] -pullSecret: '{"auths":{"": {"auth": "","email": "you@example.com"}}}' <10> +pullSecret: '{"auths":{"": {"auth": "","email": "you@example.com"}}}' <12> endif::restricted[] sshKey: 'ssh-ed25519 AAAA...' ifdef::restricted[] -additionalTrustBundle: | <11> +additionalTrustBundle: | <13> -----BEGIN CERTIFICATE----- ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ -----END CERTIFICATE----- -imageContentSources: <12> +imageContentSources: <14> - mirrors: - ://release source: @@ -114,18 +116,20 @@ You can specify the path of any datastore that exists in a datastore cluster. By If you must specify VMs across multiple datastores, use a `datastore` object to specify a failure domain in your cluster's `install-config.yaml` configuration file. For more information, see "VMware vSphere region and zone enablement". ==== <7> Optional: Provides an existing resource pool for machine creation. If you do not specify a value, the installation program uses the root resource pool of the vSphere cluster. -<8> The vSphere disk provisioning method. +<8> Optional: Each VM created by {product-title} is assigned a unique tag that is specific to the cluster. The assigned tag enables the installation program to identify and remove the associated VMs when a cluster is decommissioned. You can list up to ten additional tag IDs to be attached to the VMs provisioned by the installation program. +<9> The ID of the tag to be associated by the installation program. For example, `urn:vmomi:InventoryServiceTag:208e713c-cae3-4b7f-918e-4051ca7d1f97:GLOBAL`. For more information about determining the tag ID, see the link:https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vcenterhost.doc/GUID-E8E854DD-AA97-4E0C-8419-CE84F93C4058.html[vSphere Tags and Attributes documentation]. +<10> The vSphere disk provisioning method. ifdef::network[] -<9> The cluster network plugin to install. The default value `OVNKubernetes` is the only supported value. +<11> The cluster network plugin to install. The default value `OVNKubernetes` is the only supported value. endif::network[] ifdef::restricted[] -<9> The location of the {op-system-first} image that is accessible from the bastion server. -<10> For ``, specify the registry domain name, and optionally the +<11> The location of the {op-system-first} image that is accessible from the bastion server. +<12> For ``, specify the registry domain name, and optionally the port, that your mirror registry uses to serve content. For example `registry.example.com` or `registry.example.com:5000`. For ``, specify the base64-encoded user name and password for your mirror registry. -<11> Provide the contents of the certificate file that you used for your mirror registry. -<12> Provide the `imageContentSources` section from the output of the command to mirror the repository. +<13> Provide the contents of the certificate file that you used for your mirror registry. +<14> Provide the `imageContentSources` section from the output of the command to mirror the repository. endif::restricted[] [NOTE] From 50cf3bd5d0893595891681de879ecdbfc5e9b4b6 Mon Sep 17 00:00:00 2001 From: Avital Pinnick Date: Mon, 3 Jun 2024 14:32:16 +0300 Subject: [PATCH 035/339] Remove assisted installer files --- .../assisted-installer-installing.adoc | 57 ------------------ ...sisted-installer-preparing-to-install.adoc | 26 -------- ...installer-adding-hosts-to-the-cluster.adoc | 25 -------- ...ller-assisted-installer-prerequisites.adoc | 60 ------------------- ...ed-installer-booting-with-a-usb-drive.adoc | 17 ------ ...installer-completing-the-installation.adoc | 57 ------------------ ...r-configuring-host-network-interfaces.adoc | 31 ---------- .../assisted-installer-configuring-hosts.adoc | 25 -------- ...sted-installer-configuring-networking.adoc | 51 ---------------- ...sted-installer-installing-the-cluster.adoc | 15 ----- ...aller-pre-installation-considerations.adoc | 18 ------ modules/assisted-installer-release-notes.adoc | 36 ----------- ...installer-setting-the-cluster-details.adoc | 47 --------------- 13 files changed, 465 deletions(-) delete mode 100644 installing/installing_on_prem_assisted/assisted-installer-installing.adoc delete mode 100644 installing/installing_on_prem_assisted/assisted-installer-preparing-to-install.adoc delete mode 100644 modules/assisted-installer-adding-hosts-to-the-cluster.adoc delete mode 100644 modules/assisted-installer-assisted-installer-prerequisites.adoc delete mode 100644 modules/assisted-installer-booting-with-a-usb-drive.adoc delete mode 100644 modules/assisted-installer-completing-the-installation.adoc delete mode 100644 modules/assisted-installer-configuring-host-network-interfaces.adoc delete mode 100644 modules/assisted-installer-configuring-hosts.adoc delete mode 100644 modules/assisted-installer-configuring-networking.adoc delete mode 100644 modules/assisted-installer-installing-the-cluster.adoc delete mode 100644 modules/assisted-installer-pre-installation-considerations.adoc delete mode 100644 modules/assisted-installer-release-notes.adoc delete mode 100644 modules/assisted-installer-setting-the-cluster-details.adoc diff --git a/installing/installing_on_prem_assisted/assisted-installer-installing.adoc b/installing/installing_on_prem_assisted/assisted-installer-installing.adoc deleted file mode 100644 index d04370a13312..000000000000 --- a/installing/installing_on_prem_assisted/assisted-installer-installing.adoc +++ /dev/null @@ -1,57 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installing-with-ai"] -= Installing with the Assisted Installer -include::_attributes/common-attributes.adoc[] -:context: assisted-installer-installing - -toc::[] - -After you ensure the cluster nodes and network requirements are met, you can begin installing the cluster. - -include::modules/assisted-installer-pre-installation-considerations.adoc[leveloffset=+1] - -include::modules/assisted-installer-setting-the-cluster-details.adoc[leveloffset=+1] - -include::modules/assisted-installer-configuring-host-network-interfaces.adoc[leveloffset=+1] - -[role="_additional_resources"] -.Additional resources -* xref:../installing_bare_metal_ipi/ipi-install-installation-workflow.adoc#configuring-host-network-interfaces-in-the-install-config-yaml-file_ipi-install-installation-workflow[Configuring network interfaces] - -* link:http://nmstate.io[NMState version 2.1.4] - -include::modules/assisted-installer-adding-hosts-to-the-cluster.adoc[leveloffset=+1] - -include::modules/installing-with-usb-media.adoc[leveloffset=+1] - -include::modules/assisted-installer-booting-with-a-usb-drive.adoc[leveloffset=+1] - -include::modules/install-booting-from-an-iso-over-http-redfish.adoc[leveloffset=+1] - -[role="_additional_resources"] -.Additional resources - -* xref:../installing_bare_metal_ipi/ipi-install-installation-workflow.adoc#bmc-addressing_ipi-install-installation-workflow[BMC addressing]. - -* xref:../installing_bare_metal_ipi/ipi-install-prerequisites.adoc#ipi-install-firmware-requirements-for-installing-with-virtual-media_ipi-install-prerequisites[Firmware requirements for installing with virtual media] - -include::modules/assisted-installer-configuring-hosts.adoc[leveloffset=+1] - -include::modules/assisted-installer-configuring-networking.adoc[leveloffset=+1] - -include::modules/assisted-installer-installing-the-cluster.adoc[leveloffset=+1] - -include::modules/assisted-installer-completing-the-installation.adoc[leveloffset=+1] - - -[role="_additional_resources"] -[id="ai-saas-installing-additional-resources_{context}"] -== Additional resources - -* xref:../../cli_reference/openshift_cli/getting-started-cli.adoc#cli-installing-cli_cli-developer-commands[Installing the OpenShift CLI]. - -* xref:../../cli_reference/openshift_cli/getting-started-cli.adoc#cli-logging-in_cli-developer-commands[Logging in to the OpenShift CLI] - -* xref:../../post_installation_configuration/preparing-for-users.adoc#creating-cluster-admin_post-install-preparing-for-users[Creating a cluster admin] - -* xref:../../post_installation_configuration/preparing-for-users.adoc#removing-kubeadmin_post-install-preparing-for-users[Removing the kubeadmin user] diff --git a/installing/installing_on_prem_assisted/assisted-installer-preparing-to-install.adoc b/installing/installing_on_prem_assisted/assisted-installer-preparing-to-install.adoc deleted file mode 100644 index 19242e82a7ce..000000000000 --- a/installing/installing_on_prem_assisted/assisted-installer-preparing-to-install.adoc +++ /dev/null @@ -1,26 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="preparing-to-install-with-ai"] -= Preparing to install with the Assisted Installer -include::_attributes/common-attributes.adoc[] -:context: assisted-installer-preparing-to-install - -toc::[] - -Before installing a cluster, you must ensure the cluster nodes and network meet the requirements. - -[id="assisted-installer-prerequisites"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. -* If you use a firewall, you must xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configure it] so that {ai-full} can access the resources it requires to function. - -include::modules/assisted-installer-assisted-installer-prerequisites.adoc[leveloffset=+1] - -[role="_additional-resources"] -[id="ai-saas-preparing--to-install-additional-resources_{context}"] -== Additional resources - -* xref:../installing_bare_metal_ipi/ipi-install-prerequisites.adoc#ipi-install-firmware-requirements-for-installing-with-virtual-media_ipi-install-prerequisites[Firmware requirements for installing with virtual media] - -* xref:../installing_bare_metal_ipi/ipi-install-prerequisites.adoc#network-requirements-increase-mtu_ipi-install-prerequisites[Increase the network MTU] diff --git a/modules/assisted-installer-adding-hosts-to-the-cluster.adoc b/modules/assisted-installer-adding-hosts-to-the-cluster.adoc deleted file mode 100644 index c0de5db33bb6..000000000000 --- a/modules/assisted-installer-adding-hosts-to-the-cluster.adoc +++ /dev/null @@ -1,25 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="adding-hosts-to-the-cluster_{context}"] -= Adding hosts to the cluster - -You must add one or more hosts to the cluster. Adding a host to the cluster involves generating a discovery ISO. The discovery ISO runs {op-system-first} in-memory with an agent. Perform the following procedure for each host on the cluster. - -.Procedure - -. Click the *Add hosts* button and select the installation media. - -.. Select *Minimal image file: Provision with virtual media* to download a smaller image that will fetch the data needed to boot. The nodes must have virtual media capability. This is the recommended method. - -.. Select *Full image file: Provision with physical media* to download the larger full image. - -. Add an SSH public key so that you can connect to the cluster nodes as the `core` user. Having a login to the cluster nodes can provide you with debugging information during the installation. - -. Optional: If the cluster hosts are behind a firewall that requires the use of a proxy, select *Configure cluster-wide proxy settings*. Enter the username, password, IP address and port for the HTTP and HTTPS URLs of the proxy server. - -. Click *Generate Discovery ISO*. - -. Download the discovery ISO. diff --git a/modules/assisted-installer-assisted-installer-prerequisites.adoc b/modules/assisted-installer-assisted-installer-prerequisites.adoc deleted file mode 100644 index d689ae8c1418..000000000000 --- a/modules/assisted-installer-assisted-installer-prerequisites.adoc +++ /dev/null @@ -1,60 +0,0 @@ -// This is included in the following assemblies: -// -// installing-on-prem-assisted.adoc -:_mod-docs-content-type: CONCEPT - -[id='assisted-installer-prerequisites_{context}'] -= Assisted Installer prerequisites - -The {ai-full} validates the following prerequisites to ensure successful installation. - -== Hardware - -For control plane nodes or the {sno} node, nodes must have at least the following resources: - -* 8 CPU cores -* 16.00 GiB RAM -* 100 GB storage -* 10ms write speed or less for etcd `wal_fsync_duration_seconds` - -For worker nodes, each node must have at least the following resources: - -* 4 CPU cores -* 16.00 GiB RAM -* 100 GB storage - -== Networking - -The network must meet the following requirements: - -* A DHCP server unless using static IP addressing. -* A base domain name. You must ensure that the following requirements are met: - - There is no wildcard, such as `*..`, or the installation will not proceed. - - A DNS A/AAAA record for `api..`. - - A DNS A/AAAA record with a wildcard for `*.apps..`. -* Port `6443` is open for the API URL if you intend to allow users outside the firewall to access the cluster via the `oc` CLI tool. -* Port `443` is open for the console if you intend to allow users outside the firewall to access the console. - -[IMPORTANT] -==== -DNS A/AAAA record settings at top-level domain registrars can take significant time to update. Ensure the A/AAAA record DNS settings are working before installation to prevent installation delays. -==== - -The {product-title} cluster's network must also meet the following requirements: - -* Connectivity between all cluster nodes -* Connectivity for each node to the internet -* Access to an NTP server for time synchronization between the cluster nodes - -== Preflight validations - -The {ai-full} ensures the cluster meets the prerequisites before installation, because it eliminates complex postinstallation troubleshooting, thereby saving significant amounts of time and effort. Before installing software on the nodes, the {ai-full} conducts the following validations: - -* Ensures network connectivity -* Ensures sufficient network bandwidth -* Ensures connectivity to the registry -* Ensures time synchronization between cluster nodes -* Verifies that the cluster nodes meet the minimum hardware requirements -* Validates the installation configuration parameters - -If the {ai-full} does not successfully validate the foregoing requirements, installation will not proceed. diff --git a/modules/assisted-installer-booting-with-a-usb-drive.adoc b/modules/assisted-installer-booting-with-a-usb-drive.adoc deleted file mode 100644 index 18480c1ec777..000000000000 --- a/modules/assisted-installer-booting-with-a-usb-drive.adoc +++ /dev/null @@ -1,17 +0,0 @@ -// This is included in the following assemblies: -// -// installing_sno/install-sno-installing-sno.adoc - -:_mod-docs-content-type: PROCEDURE -[id="booting-with-a-usb-drive_{context}"] -= Booting with a USB drive - -To register nodes with the {ai-full} using a bootable USB drive, use the following procedure. - -.Procedure - -. Attach the {op-system} discovery ISO to the target host. - -. Configure the boot drive order in the server BIOS settings to boot from the attached discovery ISO, and then reboot the server. - -. On the administration host, return to the browser. Wait for the host to appear in the list of discovered hosts. diff --git a/modules/assisted-installer-completing-the-installation.adoc b/modules/assisted-installer-completing-the-installation.adoc deleted file mode 100644 index 13817ac68989..000000000000 --- a/modules/assisted-installer-completing-the-installation.adoc +++ /dev/null @@ -1,57 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="completing-the-installation_{context}"] -= Completing the installation - -After the cluster is installed and initialized, the {ai-full} indicates that the installation is finished. The {ai-full} provides the console URL, the `kubeadmin` username and password, and the `kubeconfig` file. Additionally, the {ai-full} provides cluster details including the {product-title} version, base domain, CPU architecture, API and Ingress IP addresses, and the cluster and service network IP addresses. - -.Prerequisites - -* You have installed the `oc` CLI tool. - - -.Procedure - -. Make a copy of the `kubeadmin` username and password. - -. Download the `kubeconfig` file and copy it to the `auth` directory under your working directory: -+ -[source,terminal] ----- -$ mkdir -p /auth ----- -+ -[source,terminal] ----- -$ cp kubeadmin /auth ----- -+ -[NOTE] -==== -The `kubeconfig` file is available for download for 24 hours after completing the installation. -==== - -. Add the `kubeconfig` file to your environment: -+ -[source,terminal] ----- -$ export KUBECONFIG=/auth/kubeconfig ----- - -. Login with the `oc` CLI tool: -+ -[source,terminal] ----- -$ oc login -u kubeadmin -p ----- -+ -Replace `` with the password of the `kubeadmin` user. - -. Click on the web console URL or click *Launch OpenShift Console* to open the console. - -. Enter the `kubeadmin` username and password. Follow the instructions in the {product-title} console to configure an identity provider and configure alert receivers. - -. Add a bookmark of the {product-title} console. diff --git a/modules/assisted-installer-configuring-host-network-interfaces.adoc b/modules/assisted-installer-configuring-host-network-interfaces.adoc deleted file mode 100644 index ce86869d7251..000000000000 --- a/modules/assisted-installer-configuring-host-network-interfaces.adoc +++ /dev/null @@ -1,31 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="configuring-host-network-interfaces_{context}"] -= Optional: Configuring host network interfaces - -The {ai-full} supports IPv4 networking and dual stack networking. The {ai-full} also supports configuring host network interfaces with the NMState library, a declarative network manager API for hosts. You can use NMState to deploy hosts with static IP addressing, bonds, VLANs and other advanced networking features. If you chose to configure host network interfaces, you must set network-wide configurations. Then, you must create a host-specific configuration for each host and generate the discovery ISO with the host-specific settings. - -.Procedure - -. Select the internet protocol version. Valid options are *IPv4* and *Dual stack*. - -. If the cluster hosts are on a shared VLAN, enter the VLAN ID. - -. Enter the network-wide IP addresses. If you selected *Dual stack* networking, you must enter both IPv4 and IPv6 addresses. - -.. Enter the cluster network's IP address range in CIDR notation. - -.. Enter the default gateway IP address. - -.. Enter the DNS server IP address. - -. Enter the host-specific configuration. - -.. If you are only setting a static IP address that uses a single network interface, use the form view to enter the IP address and the MAC address for the host. - -.. If you are using multiple interfaces, bonding, or other advanced networking features, use the YAML view and enter the desired network state for the host using NMState syntax. - -.. Add the MAC address and interface name for each interface used in your network configuration. diff --git a/modules/assisted-installer-configuring-hosts.adoc b/modules/assisted-installer-configuring-hosts.adoc deleted file mode 100644 index 3a89c5e0bb38..000000000000 --- a/modules/assisted-installer-configuring-hosts.adoc +++ /dev/null @@ -1,25 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="configuring-hosts_{context}"] -= Configuring hosts - -After booting the hosts with the discovery ISO, the hosts will appear in the table at the bottom of the page. You can configure the hostname, role, and installation disk for each host. - -.Procedure - -. Select a host. - -. From the *Actions* list, select *Change hostname*. You must ensure each host has a valid and unique hostname. If necessary, enter a new name for the host and click *Change*. - -. For multi-host clusters, in the *Role* column next to the host name, you can click on the menu to change the role of the host. -+ -If you do not select a role, the {ai-full} will assign the role automatically. The minimum hardware requirements for control plane nodes exceed that of worker nodes. If you assign a role to a host, ensure that you assign the control plane role to hosts that meet the minimum hardware requirements. - -. To the left of the checkbox next to a host name, click to expand the host details. If you have multiple disk drives, you can select a different disk drive to act as the installation disk. - -. Repeat this procedure for each host. - -Once all cluster hosts appear with a status of *Ready*, proceed to the next step. diff --git a/modules/assisted-installer-configuring-networking.adoc b/modules/assisted-installer-configuring-networking.adoc deleted file mode 100644 index 07f436301969..000000000000 --- a/modules/assisted-installer-configuring-networking.adoc +++ /dev/null @@ -1,51 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="configuring-networking_{context}"] -= Configuring networking - -Before installing {product-title}, you must configure the cluster network. - -.Procedure - -. In the *Networking* page, select one of the following if it is not already selected for you: -+ -** *Cluster-Managed Networking:* Selecting cluster-managed networking means that the {ai-full} will configure a standard network topology, including `keepalived` and Virtual Router Redundancy Protocol (VRRP) for managing the API and Ingress VIP addresses. -+ -** *User-Managed Networking*: Selecting user-managed networking allows you to deploy {product-title} with a non-standard network topology. For example, if you want to deploy with an external load balancer instead of `keepalived` and VRRP, or if you intend to deploy the cluster nodes across many distinct L2 network segments. - -. For cluster-managed networking, configure the following settings: - -.. Define the *Machine network*. You can use the default network or select a subnet. - -.. Define an *API virtual IP*. An API virtual IP provides an endpoint for all users to interact with, and configure the platform. - -.. Define an *Ingress virtual IP*. An Ingress virtual IP provides an endpoint for application traffic flowing from outside the cluster. - -. For user-managed networking, configure the following settings: - -.. Select your *Networking stack type*: -+ -** *IPv4*: Select this type when your hosts are only using IPv4. -+ -** *Dual-stack*: You can select dual-stack when your hosts are using IPv4 together with IPv6. - -.. Define the *Machine network*. You can use the default network or select a subnet. - -.. Define an *API virtual IP*. An API virtual IP provides an endpoint for all users to interact with, and configure the platform. - -.. Define an *Ingress virtual IP*. An Ingress virtual IP provides an endpoint for application traffic flowing from outside the cluster. - -.. Optional: You can select *Allocate IPs via DHCP server* to automatically allocate the *API IP* and *Ingress IP* using the DHCP server. - -. Optional: Select *Use advanced networking* to configure the following advanced networking properties: - -** *Cluster network CIDR*: Define an IP address block from which Pod IP addresses are allocated. - -** *Cluster network host prefix*: Define a subnet prefix length to assign to each node. - -** *Service network CIDR*: Define an IP address to use for service IP addresses. - -** *Network type*: Select either *Software-Defined Networking (SDN)* for standard networking or *Open Virtual Networking (OVN)* for telco features. diff --git a/modules/assisted-installer-installing-the-cluster.adoc b/modules/assisted-installer-installing-the-cluster.adoc deleted file mode 100644 index 2fac0c22e30f..000000000000 --- a/modules/assisted-installer-installing-the-cluster.adoc +++ /dev/null @@ -1,15 +0,0 @@ -// This is included in the following assemblies: -// -// assisted-installer-installing.adoc - -:_mod-docs-content-type: PROCEDURE -[id="installing-the-cluster_{context}"] -= Installing the cluster - -After you have completed the configuration and all the nodes are *Ready*, you can begin installation. The installation process takes a considerable amount of time, and you can monitor the installation from the {ai-full} web console. Nodes will reboot during the installation, and they will initialize after installation. - -.Procedure - -* Press *Begin installation*. - -. Click on the link in the *Status* column of the *Host Inventory* list to see the installation status of a particular host. diff --git a/modules/assisted-installer-pre-installation-considerations.adoc b/modules/assisted-installer-pre-installation-considerations.adoc deleted file mode 100644 index 366915764f72..000000000000 --- a/modules/assisted-installer-pre-installation-considerations.adoc +++ /dev/null @@ -1,18 +0,0 @@ -// This is included in the following assemblies: -// -// installing-on-prem-assisted.adoc - -:_mod-docs-content-type: CONCEPT -[id='pre-installation-considerations_{context}'] -= Preinstallation considerations - -Before installing {product-title} with the {ai-full}, you must consider the following configuration choices: - -* Which base domain to use -* Which {product-title} product version to install -* Whether to install a full cluster or {sno} -* Whether to use a DHCP server or a static network configuration -* Whether to use IPv4 or dual-stack networking -* Whether to install {VirtProductName} -* Whether to install {rh-storage-first} -* Whether to integrate with vSphere when installing on vSphere diff --git a/modules/assisted-installer-release-notes.adoc b/modules/assisted-installer-release-notes.adoc deleted file mode 100644 index 6cd7e4692f26..000000000000 --- a/modules/assisted-installer-release-notes.adoc +++ /dev/null @@ -1,36 +0,0 @@ -// This is included in the following assemblies: -// -//installing_bare_metal_assisted/installing-bare-metal-assisted.adoc - -:_mod-docs-content-type: REFERENCE -[id="assisted-installer-release-notes_{context}"] -= {ai-full} {ai-version} release notes - -[id="ai-release-notes-about-this-release_{context}"] -== About this release - -These release notes track the development of {ai-full} {ai-version}. - -This product was previously released as a Technology Preview product and is now generally available and enabled by default in the {cluster-manager-first}. - -[id="ai-release-notes-bug-fixes_{context}"] -== Bug fixes - -* Previously, users could define `localhost` as a valid host name for all of their hosts. As a result, host names were not unique, and {ai-full} could not install the cluster. With this release, users cannot complete the cluster installation if any of the hosts are named `localhost`. An error appears and users must rename the hosts. -//(link:https://issues.redhat.com/browse/MGMT-8088[MGMT-8088]) - -* Previously, in the *OpenShift Web Console troubleshooting* window, the *Optional* field remained blank when undefined instead of displaying an IP address. With this release, the *Optional* field was removed. -//(link:https://issues.redhat.com/browse/MGMT-9283[MGMT-9283]) - -* Previously, when installing a cluster on vSphere, the {ai-full} created machines and `MachineSet` objects for every virtual machine. With this release, {ai-full} no longer creates machines or `MachineSet` objects for user-provisioned VMs. -//(link:https://issues.redhat.com/browse/MGMT-9559[MGMT-9559]) - -* Previously, if Operators failed to install during an installation with {ai-full}, users received an error message and were directed to reset the cluster installation. With this release, if Operators fail to install, the cluster is automatically degraded. - -* Previously, after installing an Operator using {ai-full}, the Operator appeared as *available* in the cluster *Status* area in the *Installation progress* page. However, users had to check the Operator avilability in the {product-title} web console. With this release, the Operator appears as *installed* in the *Status* area. - -[id="ai-release-notes-known-issues_{context}"] -== Known issues - -* The minimum disk size required for installing on bare metal using {ai-full} is specified as 120GB. The actual required minimum disk size is 100GB. -//(link:https://issues.redhat.com/browse/MGMT-9682[MGMT-9682]) diff --git a/modules/assisted-installer-setting-the-cluster-details.adoc b/modules/assisted-installer-setting-the-cluster-details.adoc deleted file mode 100644 index c39635061ec6..000000000000 --- a/modules/assisted-installer-setting-the-cluster-details.adoc +++ /dev/null @@ -1,47 +0,0 @@ -// This is included in the following assemblies: -// -// installing-on-prem-assisted.adoc - -:_mod-docs-content-type: PROCEDURE -[id='setting-the-cluster-details_{context}'] -= Setting the cluster details - -To create a cluster with the {ai-full} web user interface, use the following procedure. - -.Procedure - -. Log in to the link:https://console.redhat.com[RedHat Hybrid Cloud Console]. - -. In the menu, click *OpenShift*. - -. Click *Create cluster*. - -. Click the *Datacenter* tab. - -. Under the *{ai-full}* section, select *Create cluster*. - -. Enter a name for the cluster in the *Cluster name* field. - -. Enter a base domain for the cluster in the *Base domain* field. All subdomains for the cluster will use this base domain. -+ -[NOTE] -==== -The base domain must be a valid DNS name. You must not have a wild card domain set up for the base domain. -==== - -. Select the version of {product-title} to install. - -. Optional: Select *Install single node Openshift (SNO)* if you want to install {product-title} on a single node. - -. Optional: The {ai-full} already has the pull secret associated to your account. If you want to use a different pull secret, select *Edit pull secret*. - -. Optional: {ai-full} defaults to using x86_64 CPU architecture. If you are installing {product-title} on 64-bit ARM CPUs, select *Use arm64 CPU architecture*. Keep in mind, some features are not available with 64-bit ARM CPU architecture. - -. Optional: If you are using a static IP configuration for the cluster nodes instead of DHCP reservations, select *Static network configuration*. - -. Optional: If you want to enable encryption of the installation disks, select *Enable encryption of installation disks*. For multi-node clusters, you can choose to encrypt the control plane and worker node installation disks separately. - -[IMPORTANT] -==== -You cannot change the base domain, the SNO checkbox, the CPU architecture, the host's network configuration, or the disk-encryption after installation begins. -==== From 4d48f38411c098194ca4f7bc7bf2862a74a949c1 Mon Sep 17 00:00:00 2001 From: mapandya Date: Fri, 31 May 2024 12:21:23 -0400 Subject: [PATCH 036/339] Egress firewall reorganizing content --- _topic_maps/_topic_map.yml | 16 ++++++++++------ .../egress_firewall/_attributes | 1 + .../editing-egress-firewall-ovn.adoc | 0 .../egress_firewall/images | 1 + .../egress_firewall/modules | 1 + .../removing-egress-firewall-ovn.adoc | 0 .../egress_firewall/snippets | 1 + .../viewing-egress-firewall-ovn.adoc | 0 8 files changed, 14 insertions(+), 6 deletions(-) create mode 120000 networking/openshift_network_security/egress_firewall/_attributes rename networking/{ovn_kubernetes_network_provider => openshift_network_security/egress_firewall}/editing-egress-firewall-ovn.adoc (100%) create mode 120000 networking/openshift_network_security/egress_firewall/images create mode 120000 networking/openshift_network_security/egress_firewall/modules rename networking/{ovn_kubernetes_network_provider => openshift_network_security/egress_firewall}/removing-egress-firewall-ovn.adoc (100%) create mode 120000 networking/openshift_network_security/egress_firewall/snippets rename networking/{ovn_kubernetes_network_provider => openshift_network_security/egress_firewall}/viewing-egress-firewall-ovn.adoc (100%) diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 5a5208e1fe05..200667c37f9f 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1303,6 +1303,16 @@ Topics: File: ovn-k-banp - Name: Understanding the Ingress Node Firewall Operator File: ingress-node-firewall-operator + - Name: Egress Firewall + Dir: egress_firewall + Distros: openshift-enterprise,openshift-origin + Topics: + - Name: Viewing an egress firewall for a project + File: viewing-egress-firewall-ovn + - Name: Editing an egress firewall for a project + File: editing-egress-firewall-ovn + - Name: Removing an egress firewall from a project + File: removing-egress-firewall-ovn - Name: Configuring an egress firewall for a project File: configuring-egress-firewall-ovn - Name: Configuring IPsec encryption @@ -1470,12 +1480,6 @@ Topics: File: logging-network-policy - Name: Configure an external gateway on the default network File: configuring-secondary-external-gateway - - Name: Viewing an egress firewall for a project - File: viewing-egress-firewall-ovn - - Name: Editing an egress firewall for a project - File: editing-egress-firewall-ovn - - Name: Removing an egress firewall from a project - File: removing-egress-firewall-ovn - Name: Configuring an egress IP address File: configuring-egress-ips-ovn - Name: Assigning an egress IP address diff --git a/networking/openshift_network_security/egress_firewall/_attributes b/networking/openshift_network_security/egress_firewall/_attributes new file mode 120000 index 000000000000..20cc1dcb77bf --- /dev/null +++ b/networking/openshift_network_security/egress_firewall/_attributes @@ -0,0 +1 @@ +../../_attributes/ \ No newline at end of file diff --git a/networking/ovn_kubernetes_network_provider/editing-egress-firewall-ovn.adoc b/networking/openshift_network_security/egress_firewall/editing-egress-firewall-ovn.adoc similarity index 100% rename from networking/ovn_kubernetes_network_provider/editing-egress-firewall-ovn.adoc rename to networking/openshift_network_security/egress_firewall/editing-egress-firewall-ovn.adoc diff --git a/networking/openshift_network_security/egress_firewall/images b/networking/openshift_network_security/egress_firewall/images new file mode 120000 index 000000000000..847b03ed0541 --- /dev/null +++ b/networking/openshift_network_security/egress_firewall/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/networking/openshift_network_security/egress_firewall/modules b/networking/openshift_network_security/egress_firewall/modules new file mode 120000 index 000000000000..36719b9de743 --- /dev/null +++ b/networking/openshift_network_security/egress_firewall/modules @@ -0,0 +1 @@ +../../modules/ \ No newline at end of file diff --git a/networking/ovn_kubernetes_network_provider/removing-egress-firewall-ovn.adoc b/networking/openshift_network_security/egress_firewall/removing-egress-firewall-ovn.adoc similarity index 100% rename from networking/ovn_kubernetes_network_provider/removing-egress-firewall-ovn.adoc rename to networking/openshift_network_security/egress_firewall/removing-egress-firewall-ovn.adoc diff --git a/networking/openshift_network_security/egress_firewall/snippets b/networking/openshift_network_security/egress_firewall/snippets new file mode 120000 index 000000000000..5a3f5add140e --- /dev/null +++ b/networking/openshift_network_security/egress_firewall/snippets @@ -0,0 +1 @@ +../../snippets/ \ No newline at end of file diff --git a/networking/ovn_kubernetes_network_provider/viewing-egress-firewall-ovn.adoc b/networking/openshift_network_security/egress_firewall/viewing-egress-firewall-ovn.adoc similarity index 100% rename from networking/ovn_kubernetes_network_provider/viewing-egress-firewall-ovn.adoc rename to networking/openshift_network_security/egress_firewall/viewing-egress-firewall-ovn.adoc From cd980085332b2ca70932b0244ae0eae038cd5614 Mon Sep 17 00:00:00 2001 From: Olivia Brown Date: Mon, 3 Jun 2024 09:56:30 -0400 Subject: [PATCH 037/339] OCPBUGS-31019: Compute Node to Nodes (Typo fix) --- modules/update-duration-mco.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/update-duration-mco.adoc b/modules/update-duration-mco.adoc index accba1406323..69d5e5edc496 100644 --- a/modules/update-duration-mco.adoc +++ b/modules/update-duration-mco.adoc @@ -50,4 +50,4 @@ ip-10-0-207-224.us-east-2.compute.internal Ready worker + If the status of the node is `NotReady` or `SchedulingDisabled`, then the node is not available and this impacts the update duration. + -You can check the status of nodes from the *Administrator* perspective in the web console by expanding **Compute** → **Node**. +You can check the status of nodes from the *Administrator* perspective in the web console by expanding **Compute** -> **Nodes**. From 528ee48bc8a79827ec42e3697f8812888e371a84 Mon Sep 17 00:00:00 2001 From: xenolinux Date: Fri, 31 May 2024 16:46:22 +0530 Subject: [PATCH 038/339] OSDOCS#10760: Add machine config for hcp --- _topic_maps/_topic_map.yml | 2 + hosted_control_planes/hcp-machine-config.adoc | 17 +++ hosted_control_planes/hcp-observability.adoc | 1 - modules/configuring-node-pools-for-hcp.adoc | 1 + modules/debug-nodes-hcp.adoc | 109 ------------------ modules/node-tuning-hosted-cluster.adoc | 3 +- modules/scale-down-data-plane.adoc | 2 +- .../sriov-operator-hosted-control-planes.adoc | 2 +- 8 files changed, 23 insertions(+), 114 deletions(-) create mode 100644 hosted_control_planes/hcp-machine-config.adoc delete mode 100644 modules/debug-nodes-hcp.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 200667c37f9f..495594f28be5 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2370,6 +2370,8 @@ Topics: File: hcp-getting-started - Name: Authentication and authorization for hosted control planes File: hcp-authentication-authorization +- Name: Handling a machine configuration for hosted control planes + File: hcp-machine-config - Name: Using feature gates in a hosted cluster File: hcp-using-feature-gates - Name: Updating hosted control planes diff --git a/hosted_control_planes/hcp-machine-config.adoc b/hosted_control_planes/hcp-machine-config.adoc new file mode 100644 index 000000000000..de00c2fc213e --- /dev/null +++ b/hosted_control_planes/hcp-machine-config.adoc @@ -0,0 +1,17 @@ +:_mod-docs-content-type: ASSEMBLY +[id="hcp-machine-config"] +include::_attributes/common-attributes.adoc[] += Handling a machine configuration for {hcp} +:context: hcp-machine-config + +toc::[] + +In a standalone {product-title} cluster, a machine config pool manages a set of nodes. You can handle a machine configuration by using the `MachineConfigPool` custom resource (CR). + +In {hcp}, the `MachineConfigPool` CR does not exist. A node pool contains a set of compute nodes. You can handle a machine configuration by using node pools. + +include::modules/configuring-node-pools-for-hcp.adoc[leveloffset=+1] + +include::modules/node-tuning-hosted-cluster.adoc[leveloffset=+1] + +include::modules/sriov-operator-hosted-control-planes.adoc[leveloffset=+1] diff --git a/hosted_control_planes/hcp-observability.adoc b/hosted_control_planes/hcp-observability.adoc index 2d51b05550f6..4feb1ea49725 100644 --- a/hosted_control_planes/hcp-observability.adoc +++ b/hosted_control_planes/hcp-observability.adoc @@ -8,6 +8,5 @@ toc::[] You can gather metrics for {hcp} by configuring metrics sets. The HyperShift Operator can create or delete monitoring dashboards in the management cluster for each hosted cluster that it manages. -//using service-level DNS for control plane services include::modules/hosted-control-planes-metrics-sets.adoc[leveloffset=+1] include::modules/hosted-control-planes-monitoring-dashboard.adoc[leveloffset=+1] diff --git a/modules/configuring-node-pools-for-hcp.adoc b/modules/configuring-node-pools-for-hcp.adoc index 9f89bfc38b8b..0b3270a5eeeb 100644 --- a/modules/configuring-node-pools-for-hcp.adoc +++ b/modules/configuring-node-pools-for-hcp.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // // * updates/updating_a_cluster/updating-hosted-control-planes.adoc +// * hosted_control_planes/hcp-machine-config.adoc :_mod-docs-content-type: PROCEDURE [id="configuring-node-pools-for-hcp_{context}"] diff --git a/modules/debug-nodes-hcp.adoc b/modules/debug-nodes-hcp.adoc deleted file mode 100644 index 9d70a5bc91ca..000000000000 --- a/modules/debug-nodes-hcp.adoc +++ /dev/null @@ -1,109 +0,0 @@ -{hcp-capital}// Module included in the following assemblies: -// -// * hosted_control_planes/hcp-troubleshooting.adoc - -:_mod-docs-content-type: PROCEDURE -[id="debug-nodes-hcp_{context}"] -= Checking why worker nodes did not join the hosted cluster - -If your control plane API endpoint is available, but worker nodes did not join the hosted cluster on AWS, you can debug worker node issues. To troubleshoot why worker nodes did not join the hosted cluster on AWS, you can check the following information. - -:FeatureName: {hcp-capital} on AWS -include::snippets/technology-preview.adoc[] - -.Prerequisites - -* You have link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.9/html/clusters/cluster_mce_overview#hosting-service-cluster-configure-aws[configured the hosting cluster on AWS]. -* Your control plane API endpoint is available. - -.Procedure - -. Address any error messages in the status of the `HostedCluster` and `NodePool` resources: - -.. Check the status of the `HostedCluster` resource by running the following command: -+ -[source,terminal] ----- -$ oc get hc -n -o jsonpath='{.status}' ----- - -.. Check the status of the `NodePool` resource by running the following command: -+ -[source,terminal] ----- -$ oc get hc -n -o jsonpath='{.status}' ----- -+ -If you did not find any error messages in the status of the `HostedCluster` and `NodePool` resources, proceed to the next step. - -. Check if your worker machines are created by running the following commands, replacing values as necessary: -+ -[source,terminal] ----- -$ HC_NAMESPACE="clusters" -$ HC_NAME="cluster_name" -$ CONTROL_PLANE_NAMESPACE="${HC_NAMESPACE}-${HC_NAME}" -$ oc get machines.cluster.x-k8s.io -n $CONTROL_PLANE_NAMESPACE -$ oc get awsmachines -n $CONTROL_PLANE_NAMESPACE ----- - -. If worker machines do not exist, check if the `machinedeployment` and `machineset` resources are created by running the following commands: -+ -[source,terminal] ----- -$ oc get machinedeployment -n $CONTROL_PLANE_NAMESPACE -$ oc get machineset -n $CONTROL_PLANE_NAMESPACE ----- - -. If the `machinedeployment` and `machineset` resources do not exist, check logs of the HyperShift Operator by running the following command: -+ -[source,terminal] ----- -$ oc logs deployment/operator -n hypershift ----- - -. If worker machines exist but are not provisioned in the hosted cluster, check the log of the cluster API provider by running the following command: -+ -[source,terminal] ----- -$ oc logs deployment/capi-provider -c manager -n $CONTROL_PLANE_NAMESPACE ----- - -. If worker machines exist and are provisioned in the cluster, ensure that machines are initialized through Ignition successfully by checking the system console logs. Check the system console logs of every machine by using the `console-logs` utility by running the following command: -+ -[source,terminal] ----- -$ ./bin/hypershift console-logs aws --name $HC_NAME --aws-creds ~/.aws/credentials --output-dir /tmp/console-logs ----- -+ -You can access the system console logs in the `/tmp/console-logs` directory. The control plane exposes the Ignition endpoint. If you see an error related to the Ignition endpoint, then the Ignition endpoint is not accessible from the worker nodes through `https`. - -. If worker machines are provisioned and initialized through Ignition successfully, you can extract and access the journal logs of every worker machine by creating a bastion machine. A bastion machine allows you to access worker machines by using SSH. - -.. Create a bastion machine by running the following command: -+ -[source,terminal] ----- -$ ./bin/hypershift create bastion aws --aws-creds ~/.aws/credentials --name $CLUSTER_NAME --ssh-key-file /tmp/ssh/id_rsa.pub ----- - -.. Optional: If you used the `--generate-ssh` flag when creating the cluster, you can extract the public and private key for the cluster by running the following commands: -+ -[souce,terminal] ----- -$ mkdir /tmp/ssh -$ oc get secret -n clusters ${HC_NAME}-ssh-key -o jsonpath='{ .data.id_rsa }' | base64 -d > /tmp/ssh/id_rsa -$ oc get secret -n clusters ${HC_NAME}-ssh-key -o jsonpath='{ .data.id_rsa\.pub }' | base64 -d > /tmp/ssh/id_rsa.pub ----- - -.. Extract journal logs from the every worker machine by running the following commands: -+ -[source,terminal] ----- -$ mkdir /tmp/journals -$ INFRAID="$(oc get hc -n clusters $CLUSTER_NAME -o jsonpath='{ .spec.infraID }')" -$ SSH_PRIVATE_KEY=/tmp/ssh/id_rsa -$ ./test/e2e/util/dump/copy-machine-journals.sh /tmp/journals ----- -+ -You must place journal logs in the `/tmp/journals` directory in a compressed format. Check for the error that indicates why kubelet did not join the cluster. diff --git a/modules/node-tuning-hosted-cluster.adoc b/modules/node-tuning-hosted-cluster.adoc index b509da75244e..6dae7b1ef625 100644 --- a/modules/node-tuning-hosted-cluster.adoc +++ b/modules/node-tuning-hosted-cluster.adoc @@ -1,13 +1,12 @@ // Module included in the following assemblies: // // * scalability_and_performance/using-node-tuning-operator.adoc +// * hosted_control_planes/hcp-machine-config.adoc :_mod-docs-content-type: PROCEDURE [id="node-tuning-hosted-cluster_{context}"] = Configuring node tuning in a hosted cluster -//# Manage node-level tuning with the Node Tuning Operator - To set node-level tuning on the nodes in your hosted cluster, you can use the Node Tuning Operator. In {hcp}, you can configure node tuning by creating config maps that contain `Tuned` objects and referencing those config maps in your node pools. .Procedure diff --git a/modules/scale-down-data-plane.adoc b/modules/scale-down-data-plane.adoc index 7d90841c19b2..d18d8de82952 100644 --- a/modules/scale-down-data-plane.adoc +++ b/modules/scale-down-data-plane.adoc @@ -1,6 +1,6 @@ // Module included in the following assemblies: // -// * hosted_control_planes/hcp-managing.adoc +// * hosted_control_planes/hcp-troubleshooting.adoc :_mod-docs-content-type: PROCEDURE [id="scale-down-data-plane_{context}"] diff --git a/modules/sriov-operator-hosted-control-planes.adoc b/modules/sriov-operator-hosted-control-planes.adoc index 9044ff117063..66065aeae9c5 100644 --- a/modules/sriov-operator-hosted-control-planes.adoc +++ b/modules/sriov-operator-hosted-control-planes.adoc @@ -1,7 +1,7 @@ // Module included in the following assemblies: // // * networking/hardware_networks/configuring-sriov-operator.adoc -// * hosted-control-planes/hcp-managing.adoc +// * hosted-control-planes/hcp-machine-config.adoc :_mod-docs-content-type: PROCEDURE [id="sriov-operator-hosted-control-planes_{context}"] From 021d30453b047eea504c1827c60645cf18ac8100 Mon Sep 17 00:00:00 2001 From: EricPonvelle Date: Tue, 4 Jun 2024 09:16:51 -0400 Subject: [PATCH 039/339] OSDOCS#10801: Added a known issue for OIDC configurations. --- rosa_release_notes/rosa-release-notes.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/rosa_release_notes/rosa-release-notes.adoc b/rosa_release_notes/rosa-release-notes.adoc index 96d863189318..28aaffce91c5 100644 --- a/rosa_release_notes/rosa-release-notes.adoc +++ b/rosa_release_notes/rosa-release-notes.adoc @@ -136,6 +136,7 @@ include::snippets/technology-preview.adoc[leveloffset=+1] [id="rosa-known-issues_{context}"] == Known issues +* If you configure your cluster using external OIDC configuration and set the `--user-auth` flag to `disabled`, the console pods might enter a crash loop. (link:https://issues.redhat.com/browse/OCPBUGS-29510[*OCPBUGS-29510*]) * The OpenShift Cluster Manager roles (`ocm-role`) and user roles (`user-role`) that are key to the ROSA provisioning wizard might get enabled accidentally in your Red Hat organization by another user. However, this behavior does not affect the usability. * The `htpasswd` identity provider does not function as expected in all scenarios against the `rosa create admin` function. From 8f305273cc05f08c4bded46dbadbd292d7581afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CShauna=20Diaz=E2=80=9D?= Date: Tue, 4 Jun 2024 08:30:08 -0400 Subject: [PATCH 040/339] OSDOCS-10799: update LVMS min storage sizes for file types --- .../microshift-storage-plugin-overview.adoc | 4 ++++ ...s-limitations-to-configure-size-of-devices.adoc | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/microshift_storage/microshift-storage-plugin-overview.adoc b/microshift_storage/microshift-storage-plugin-overview.adoc index c956da231d99..3fe7e89168a2 100644 --- a/microshift_storage/microshift-storage-plugin-overview.adoc +++ b/microshift_storage/microshift-storage-plugin-overview.adoc @@ -2,6 +2,7 @@ [id="microshift-storage-plugin-overview"] = Dynamic storage using the LVMS plugin include::_attributes/attributes-microshift.adoc[] +include::_attributes/common-attributes.adoc[] :context: microshift-storage-plugin-overview toc::[] @@ -14,6 +15,9 @@ include::modules/microshift-lvms-system-requirements.adoc[leveloffset=+1] include::modules/microshift-lvms-deployment.adoc[leveloffset=+1] +//OCP module with edits +include::modules/lvms-limitations-to-configure-size-of-devices.adoc[leveloffset=+1] + include::modules/microshift-lvmd-yaml-creating.adoc[leveloffset=+1] include::modules/microshift-lvms-config-example-basic.adoc[leveloffset=+1] diff --git a/modules/lvms-limitations-to-configure-size-of-devices.adoc b/modules/lvms-limitations-to-configure-size-of-devices.adoc index 54be6ec9de4f..963687a8f3a0 100644 --- a/modules/lvms-limitations-to-configure-size-of-devices.adoc +++ b/modules/lvms-limitations-to-configure-size-of-devices.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // // * storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc +// * microshift_storage/microshift-storage-plugin-overview.adoc :_mod-docs-content-type: CONCEPT [id="limitations-to-configure-size-of-devices_{context}"] @@ -13,7 +14,15 @@ The limitations to configure the size of the devices that you can use to provisi ** You can define the size of PE and LE during the physical and logical device creation. ** The default PE and LE size is 4 MB. ** If the size of the PE is increased, the maximum size of the LVM is determined by the kernel limits and your disk space. - +ifdef::microshift[] +** The size limit for {op-system-base-full} 9 using the default PE and LE size is 8 EB. +** The following are the minimum storage sizes that you can request for each file system type: +*** `block`: 8 MiB +*** `xfs`: 300 MiB +*** `ext4`: 32 MiB +endif::microshift[] + +ifndef::microshift[] .Size limits for different architectures using the default PE and LE size [cols="1,1,1,1,1", width="100%", options="header"] |==== @@ -45,4 +54,5 @@ The limitations to configure the size of the devices that you can use to provisi -- 1. Theoretical size. 2. Tested size. --- \ No newline at end of file +-- +endif::microshift[] \ No newline at end of file From c5742cd04e8d3170e6513c1b4e2f846dbbfe543c Mon Sep 17 00:00:00 2001 From: Jessi Manthei Date: Fri, 31 May 2024 11:22:14 -0500 Subject: [PATCH 041/339] OCPGUBS-31937 HAProxy load interval limit --- modules/configuring-haproxy-interval.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/configuring-haproxy-interval.adoc b/modules/configuring-haproxy-interval.adoc index 34f73a83c65d..f9a08f0b4821 100644 --- a/modules/configuring-haproxy-interval.adoc +++ b/modules/configuring-haproxy-interval.adoc @@ -14,7 +14,7 @@ The default minimum HAProxy reload interval is five seconds. You can configure a [WARNING] ==== -Setting a large value for the minimum HAProxy reload interval can cause latency in observing updates to routes and their endpoints. To lessen the risk, avoid setting a value larger than the tolerable latency for updates. +Setting a large value for the minimum HAProxy reload interval can cause latency in observing updates to routes and their endpoints. To lessen the risk, avoid setting a value larger than the tolerable latency for updates. The maximum value for HAProxy reload interval is 120 seconds. ==== .Procedure From fe82e97c6b675ddfe67349a4411736d277dbca9f Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Tue, 4 Jun 2024 14:05:45 -0400 Subject: [PATCH 042/339] Adds additional URLs to allowlist --- modules/configuring-firewall.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/configuring-firewall.adoc b/modules/configuring-firewall.adoc index 458db31cdba5..c17c88ee50a3 100644 --- a/modules/configuring-firewall.adoc +++ b/modules/configuring-firewall.adoc @@ -62,6 +62,18 @@ If your environment has a dedicated load balancer in front of your {product-titl |443 |Provides core container images +|`cdn04.quay.io` +|443 +|Provides core container images + +|`cdn05.quay.io` +|443 +|Provides core container images + +|`cdn06.quay.io` +|443 +|Provides core container images + |`sso.redhat.com` |443 |The `https://console.redhat.com` site uses authentication from `sso.redhat.com` From 22435503f3ad861bddcbe1085f272e417141e69d Mon Sep 17 00:00:00 2001 From: Eric Ponvelle Date: Wed, 3 Apr 2024 15:15:58 -0400 Subject: [PATCH 043/339] OSDOCS-9751: Added and described machine pool graphics --- images/hcp-rosa-machine-pools.png | Bin 0 -> 157828 bytes modules/machine-pools-hcp.adoc | 20 +++++ modules/rosa-adding-tags-cli.adoc | 73 ++++++++++++++++++ modules/rosa-adding-tags.adoc | 9 +++ modules/rosa-create-objects.adoc | 10 +++ .../rosa-managing-worker-nodes.adoc | 2 + .../rosa-nodes-machinepools-about.adoc | 3 + 7 files changed, 117 insertions(+) create mode 100644 images/hcp-rosa-machine-pools.png create mode 100644 modules/machine-pools-hcp.adoc create mode 100644 modules/rosa-adding-tags-cli.adoc create mode 100644 modules/rosa-adding-tags.adoc diff --git a/images/hcp-rosa-machine-pools.png b/images/hcp-rosa-machine-pools.png new file mode 100644 index 0000000000000000000000000000000000000000..4e239d1c009efdd7f1e8fa61e8b3f8de0851fc2f GIT binary patch literal 157828 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ⅅhM99WR-L+_ll=` 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 a6wf3?LNWwn;iF4IAup|bI!DU*+W!HfF!uZa literal 0 HcmV?d00001 diff --git a/modules/machine-pools-hcp.adoc b/modules/machine-pools-hcp.adoc new file mode 100644 index 000000000000..72439d92bf5a --- /dev/null +++ b/modules/machine-pools-hcp.adoc @@ -0,0 +1,20 @@ +// Module included in the following assemblies: +// +// * rosa_cluster_admin/rosa_nodes/rosa-nodes-machinepools-about.adoc + +:_mod-docs-content-type: CONCEPT +[id="machine-pools-hcp_{context}"] += Machine pools in {hcp-title} clusters + +In {hcp-title} clusters, the hosted control plane spans three availability zones (AZ) in the installed cloud region. Each machine pool in a {hcp-title} cluster deploys in a single subnet within a single AZ. Each of these AZs can have only one machine pool. + +Each machine pool in an {hcp-title} cluster upgrades independently. Because the machine pools upgrade independently, they must remain within 2 minor (Y-stream) versions of the hosted control plane. For example, if your hosted control plane is 4.16.z, your machine pools must be at least 4.14.z. + +The following image depicts how machine pools work within ROSA and {hcp-title} clusters: + +image::hcp-rosa-machine-pools.png[Machine pools on ROSA classic and ROSA with HCP clusters] + +[NOTE] +==== +Machine pools in {hcp-title} clusters each upgrade independently and the machine pool versions must remain within two minor (Y-stream) versions of the control plane. +==== \ No newline at end of file diff --git a/modules/rosa-adding-tags-cli.adoc b/modules/rosa-adding-tags-cli.adoc new file mode 100644 index 000000000000..1c2367347cc8 --- /dev/null +++ b/modules/rosa-adding-tags-cli.adoc @@ -0,0 +1,73 @@ +// Module included in the following assemblies: +// +// * rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc + +:_mod-docs-content-type: PROCEDURE +[id="rosa-adding-tags-cli{context}"] += Adding tags to a machine pool using the ROSA CLI + +You can add tags to a machine pool for your {product-title} cluster by using the ROSA command line interface (CLI). + +[IMPORTANT] +==== +You must ensure that your tag keys are not `aws`, `red-hat-managed`, `red-hat-clustertype`, or `Name`. In addition, you must not set a tag key that begins with `kubernetes.io/cluster/`. Your tag's key cannot be longer than 128 characters, while your tag's value cannot be longer than 256 characters. Red{nbsp}Hat reserves the right to add additional reserved tags in the future. +==== + +.Prerequisites + +* You installed and configured the latest AWS (`aws`), ROSA (`rosa`), and OpenShift (`oc`) CLIs on your workstation. +* You logged in to your Red{nbsp}Hat account by using the `rosa` CLI. +* You created a {product-title} (ROSA) cluster. + +.Procedure + +* Create a machine pool with a custom tag by running the following command: ++ +-- +[source,terminal] +---- +$ rosa create machinepools --cluster= --replicas= \ + --name --tags=' , ' \ <1> +---- +<1> Replace ` , ` with a key and value for each tag. +-- ++ +.Example output +[source,terminal] +---- +$ rosa create machinepools --cluster=mycluster --replicas 2 --tags='tagkey1 tagvalue1,tagkey2 tagvaluev2' + +I: Checking available instance types for machine pool 'mp-1' +I: Machine pool 'mp-1' created successfully on cluster 'mycluster' +I: To view the machine pool details, run 'rosa describe machinepool --cluster mycluster --machinepool mp-1' +I: To view all machine pools, run 'rosa list machinepools --cluster mycluster' +---- + +.Verification + +* Use the `describe` command to see the details of the machine pool with the tags, and verify that the tags are included for your machine pool in the output: ++ +[source,terminal] +---- +$ rosa describe machinepool --cluster= +---- ++ +.Example output +[source,terminal] +---- +$ rosa describe machinepool --cluster classic-rosa --machinepool mp-1 + +ID: mp-1 +Cluster ID: 2baiirqa2141oreotoivp4sipq84vp5g +Autoscaling: No +Replicas: 2 +Instance type: m5.xlarge +Labels: +Taints: +Availability zones: us-east-1a +Subnets: +Spot instances: No +Disk size: 300 GiB +Additional Security Group IDs: +Tags: red-hat-clustertype=rosa, red-hat-managed=true, tagkey1=tagvalue1, tagkey2=tagvaluev2 +---- \ No newline at end of file diff --git a/modules/rosa-adding-tags.adoc b/modules/rosa-adding-tags.adoc new file mode 100644 index 000000000000..e824185373a8 --- /dev/null +++ b/modules/rosa-adding-tags.adoc @@ -0,0 +1,9 @@ +// Module included in the following assemblies: +// +// * rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc + +:_mod-docs-content-type: PROCEDURE +[id="rosa-adding-tags_{context}"] += Adding tags to a machine pool + +You can add tags for compute nodes, also known as worker nodes, in a machine pool to introduce custom user tags for AWS resources that are generated when you provision your machine pool. \ No newline at end of file diff --git a/modules/rosa-create-objects.adoc b/modules/rosa-create-objects.adoc index 7d2ab405fe03..1d2c521b1029 100644 --- a/modules/rosa-create-objects.adoc +++ b/modules/rosa-create-objects.adoc @@ -717,6 +717,9 @@ a|--cluster \| |--replicas |Required when autoscaling is not configured. The number (integer) of machines for this machine pool. +|--tags +|Apply user defined tags to all resources created by ROSA in AWS. Tags are comma separated, for example: `'key value, foo bar'`. + |--taints |Taints for the machine pool. This string value should be formatted as a comma-separated list of `key=value:ScheduleType`. This list will overwrite any modifications made to Node taints on an ongoing basis. |=== @@ -768,6 +771,13 @@ Add a machine pool with labels to a cluster. $ rosa create machinepool --cluster=mycluster --replicas=2 --instance-type=r5.2xlarge --labels=foo=bar,bar=baz --name=mp-1 ---- +Add a machine pool with tags to a cluster. + +[source,terminal] +---- +$ rosa create machinepool --cluster=mycluster --replicas=2 --instance-type=r5.2xlarge --tags='foo bar,bar baz' --name=mp-1 +---- + [id="rosa-create-ocm-role_{context}"] == create ocm-role diff --git a/rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc b/rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc index a765ea36347c..76306b2736ba 100644 --- a/rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc +++ b/rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc @@ -53,6 +53,8 @@ include::modules/rosa-adding-node-labels.adoc[leveloffset=+2] // include::modules/rosa-imds-machine-pools-ui.adoc[leveloffset=+2] // include::modules/rosa-imds-machine-pools-cli.adoc[leveloffset=+2] +include::modules/rosa-adding-tags.adoc[leveloffset=+1] +include::modules/rosa-adding-tags-cli.adoc[leveloffset=+2] include::modules/rosa-adding-taints.adoc[leveloffset=+1] include::modules/rosa-adding-taints-ocm.adoc[leveloffset=+2] include::modules/rosa-adding-taints-cli.adoc[leveloffset=+2] diff --git a/rosa_cluster_admin/rosa_nodes/rosa-nodes-machinepools-about.adoc b/rosa_cluster_admin/rosa_nodes/rosa-nodes-machinepools-about.adoc index 32d4f4caccab..5d92a8e1a041 100644 --- a/rosa_cluster_admin/rosa_nodes/rosa-nodes-machinepools-about.adoc +++ b/rosa_cluster_admin/rosa_nodes/rosa-nodes-machinepools-about.adoc @@ -57,6 +57,9 @@ You can override this default setting and create a machine pool in a Single-AZ o Similarly, deleting a machine pool will delete it from all zones. Due to this multiplicative effect, using machine pools in Multi-AZ cluster can consume more of your project's quota for a specific region when creating machine pools. +// ROSA HCP content applies to the following subsection +include::modules/machine-pools-hcp.adoc[leveloffset=+1] + == Additional resources ifdef::openshift-rosa[] * xref:../../rosa_cluster_admin/rosa_nodes/rosa-managing-worker-nodes.adoc#rosa-managing-worker-nodes[Managing compute nodes] From ad0c2d7c8f63ff504fd092983264af866d136046 Mon Sep 17 00:00:00 2001 From: Andreas Gerstmayr Date: Thu, 7 Mar 2024 12:17:44 +0100 Subject: [PATCH 044/339] OBSDOCS-873/TRACING-3799: Documentation for the Tempo monolithic CRD Signed-off-by: Andreas Gerstmayr --- .../distr-tracing-tempo-config-default.adoc | 2 +- modules/distr-tracing-tempo-install-cli.adoc | 153 +--------------- ...ing-tempo-install-tempomonolithic-cli.adoc | 116 ++++++++++++ ...o-install-tempomonolithic-web-console.adoc | 77 ++++++++ ...-tracing-tempo-install-tempostack-cli.adoc | 169 ++++++++++++++++++ ...-tempo-install-tempostack-web-console.adoc | 124 +++++++++++++ ...str-tracing-tempo-install-web-console.adoc | 118 +----------- .../distr-tracing-tempo-installing.adoc | 59 +++++- ...cing-tempo-required-secret-parameters.adoc | 3 +- ...tempo-tempomonolithic-custom-resource.adoc | 32 ++++ 10 files changed, 589 insertions(+), 264 deletions(-) create mode 100644 modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc create mode 100644 modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc create mode 100644 modules/distr-tracing-tempo-install-tempostack-cli.adoc create mode 100644 modules/distr-tracing-tempo-install-tempostack-web-console.adoc create mode 100644 snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc diff --git a/modules/distr-tracing-tempo-config-default.adoc b/modules/distr-tracing-tempo-config-default.adoc index 7717e6676bc1..eaceeb332669 100644 --- a/modules/distr-tracing-tempo-config-default.adoc +++ b/modules/distr-tracing-tempo-config-default.adoc @@ -6,7 +6,7 @@ [id="distr-tracing-tempo-config-default_{context}"] = Default configuration options -The Tempo custom resource (CR) defines the architecture and settings to be used when creating the {TempoShortName} resources. You can modify these parameters to customize your {TempoShortName} implementation to your business needs. +The `TempoStack` custom resource (CR) defines the architecture and settings to be used when creating the {TempoShortName} resources. You can modify these parameters to customize your {TempoShortName} implementation to your business needs. .Example of a generic Tempo YAML file [source,yaml] diff --git a/modules/distr-tracing-tempo-install-cli.adoc b/modules/distr-tracing-tempo-install-cli.adoc index 082db5bb1f43..e41645978088 100644 --- a/modules/distr-tracing-tempo-install-cli.adoc +++ b/modules/distr-tracing-tempo-install-cli.adoc @@ -1,12 +1,12 @@ // Module included in the following assemblies: // -//* observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc :_mod-docs-content-type: PROCEDURE [id="distr-tracing-tempo-install-cli_{context}"] -= Installing by using the CLI += Installing the {TempoOperator} by using the CLI -You can install the {TempoShortName} from the command line. +You can install the {TempoOperator} from the command line. .Prerequisites @@ -24,7 +24,7 @@ $ oc login --username= ---- ==== -* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[Red Hat OpenShift Data Foundation], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". +* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". + [WARNING] ==== @@ -33,9 +33,7 @@ Object storage is required and not included with the {TempoShortName}. You must .Procedure -. Install the {TempoOperator}: - -.. Create a project for the {TempoOperator} by running the following command: +. Create a project for the {TempoOperator} by running the following command: + [source,terminal] ---- @@ -50,7 +48,7 @@ metadata: EOF ---- -.. Create an Operator group by running the following command: +. Create an Operator group by running the following command: + [source,terminal] ---- @@ -65,7 +63,7 @@ spec: EOF ---- -.. Create a subscription by running the following command: +. Create a subscription by running the following command: + [source,terminal] ---- @@ -84,144 +82,11 @@ spec: EOF ---- -.. Check the Operator status by running the following command: -+ -[source,terminal] ----- -$ oc get csv -n openshift-tempo-operator ----- - -. Run the following command to create a project of your choice for the TempoStack instance that you will create in a subsequent step: -+ -[source,terminal] ----- -$ oc apply -f - << EOF -apiVersion: project.openshift.io/v1 -kind: Project -metadata: - name: -EOF ----- - -. In the project that you created for the TempoStack instance, create a secret for your object storage bucket by running the following command: -+ -[source,terminal] ----- -$ oc apply -f - << EOF - -EOF ----- -+ -For more information, see "Object storage setup". -+ --- -include::snippets/distr-tracing-tempo-secret-example.adoc[] --- - -. Create a TempoStack instance in the project that you created for the TempoStack instance. -+ -[NOTE] -==== -You can create multiple TempoStack instances in separate projects on the same cluster. -==== -+ -.. Customize the `TempoStack` custom resource (CR): -+ -[source,yaml] ----- -apiVersion: tempo.grafana.com/v1alpha1 -kind: TempoStack -metadata: - name: sample - namespace: -spec: - storageSize: 1Gi - storage: - secret: # <1> - name: # <2> - type: # <3> - template: - queryFrontend: - jaegerQuery: - enabled: true - ingress: - route: - termination: edge - type: route ----- -<1> The secret you created in step 3. -<2> The value of the `name` in the `metadata` of the secret. -<3> The accepted values are `azure` for Azure Blob Storage; `gcs` for Google Cloud Storage; and `s3` for Amazon S3, MinIO, or Red Hat OpenShift Data Foundation. -+ -.Example of a `TempoStack` CR for AWS S3 and MinIO storage -[source,yaml] ----- -apiVersion: tempo.grafana.com/v1alpha1 -kind: TempoStack -metadata: - name: simplest - namespace: project_of_tempostack_instance -spec: - storageSize: 1Gi - storage: # <1> - secret: - name: minio-test - type: s3 - resources: - total: - limits: - memory: 2Gi - cpu: 2000m - template: - queryFrontend: - jaegerQuery: # <2> - enabled: true - ingress: - route: - termination: edge - type: route ----- -<1> In this example, the object storage was set up as one of the prerequisites, and the object storage secret was created in step 3. -<2> The stack deployed in this example is configured to receive Jaeger Thrift over HTTP and OpenTelemetry Protocol (OTLP), which permits visualizing the data with the Jaeger UI. - -.. Apply the customized CR by running the following command. -+ -[source,terminal] ----- -$ oc apply -f - << EOF - -EOF ----- - - .Verification -. Verify that the `status` of all TempoStack `components` is `Running` and the `conditions` are `type: Ready` by running the following command: +* Check the Operator status by running the following command: + [source,terminal] ---- -$ oc get tempostacks.tempo.grafana.com simplest -o yaml ----- - -. Verify that all the TempoStack component pods are running by running the following command: -+ -[source,terminal] ----- -$ oc get pods ----- - -. Access the Tempo console: - -.. Query the route details by running the following command: -+ -[source,terminal] ----- -$ oc get route +$ oc get csv -n openshift-tempo-operator ---- - -.. Open `\https://` in a web browser. -+ -[NOTE] -==== -The Tempo console initially shows no trace data following the Tempo console installation. -==== diff --git a/modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc b/modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc new file mode 100644 index 000000000000..34b27da6424d --- /dev/null +++ b/modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc @@ -0,0 +1,116 @@ +// Module included in the following assemblies: +// +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc + +:_mod-docs-content-type: PROCEDURE +[id="distr-tracing-tempo-install-tempomonolithic-cli_{context}"] += Installing a TempoMonolithic instance by using the CLI + +:FeatureName: The TempoMonolithic instance +include::snippets/technology-preview.adoc[] + +You can install a TempoMonolithic instance from the command line. + +.Prerequisites + +* An active {oc-first} session by a cluster administrator with the `cluster-admin` role. ++ +[TIP] +==== +* Ensure that your {oc-first} version is up to date and matches your {product-title} version. + +* Run the `oc login` command: ++ +[source,terminal] +---- +$ oc login --username= +---- +==== + +.Procedure + +. Run the following command to create a project of your choice for the TempoMonolithic instance that you will create in a subsequent step: ++ +[source,terminal] +---- +$ oc apply -f - << EOF +apiVersion: project.openshift.io/v1 +kind: Project +metadata: + name: +EOF +---- + +. Decide which type of supported storage to use for storing traces: in-memory storage, a persistent volume, or object storage. ++ +[IMPORTANT] +==== +Object storage is not included with the {TempoShortName} and requires setting up an object store by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], or link:https://cloud.google.com/storage/[Google Cloud Storage]. + +Additionally, opting for object storage requires creating a secret for your object storage bucket in the project that you created for the TempoMonolithic instance. You can do this by running the following command: + +[source,terminal] +---- +$ oc apply -f - << EOF + +EOF +---- + +For more information, see "Object storage setup". + +-- +include::snippets/distr-tracing-tempo-secret-example.adoc[] +-- + +==== + +. Create a TempoMonolithic instance in the project that you created for it. ++ +[TIP] +==== +You can create multiple TempoMonolithic instances in separate projects on the same cluster. +==== + +.. Customize the `TempoMonolithic` custom resource (CR). ++ +include::snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc[] + +.. Apply the customized CR by running the following command: ++ +[source,terminal] +---- +$ oc apply -f - << EOF + +EOF +---- + +.Verification + +. Verify that the `status` of all TempoMonolithic `components` is `Running` and the `conditions` are `type: Ready` by running the following command: ++ +[source,terminal] +---- +$ oc get tempomonolithic.tempo.grafana.com -o yaml +---- + +. Run the following command to verify that the pod of the TempoMonolithic instance is running: ++ +[source,terminal] +---- +$ oc get pods +---- + +. Access the Jaeger UI: + +.. Query the route details for the `tempo--jaegerui` route by running the following command: ++ +[source,terminal] +---- +$ oc get route +---- + +.. Open `\https://` in a web browser. + +. When the pod of the TempoMonolithic instance is ready, you can send traces to the `tempo-:4317` (OTLP/gRPC) and `tempo-:4318` (OTLP/HTTP) endpoints inside the cluster. ++ +The Tempo API is available at the `tempo-:3200` endpoint inside the cluster. diff --git a/modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc b/modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc new file mode 100644 index 000000000000..6542e4037a28 --- /dev/null +++ b/modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc @@ -0,0 +1,77 @@ +// Module included in the following assemblies: +// +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc + +:_mod-docs-content-type: PROCEDURE +[id="distr-tracing-tempo-install-tempomonolithic-web-console_{context}"] += Installing a TempoMonolithic instance by using the web console + +:FeatureName: The TempoMonolithic instance +include::snippets/technology-preview.adoc[] + +You can install a TempoMonolithic instance from the *Administrator* view of the web console. + +.Prerequisites + +* You are logged in to the {product-title} web console as a cluster administrator with the `cluster-admin` role. + +* For {product-dedicated}, you must be logged in using an account with the `dedicated-admin` role. + +.Procedure + +. Go to *Home* -> *Projects* -> *Create Project* to create a project of your choice for the *TempoMonolithic* instance that you will create in a subsequent step. + +. Decide which type of supported storage to use for storing traces: in-memory storage, a persistent volume, or object storage. ++ +[IMPORTANT] +==== +Object storage is not included with the {TempoShortName} and requires setting up an object store by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], or link:https://cloud.google.com/storage/[Google Cloud Storage]. + +Additionally, opting for object storage requires creating a secret for your object storage bucket in the project that you created for the *TempoMonolithic* instance. You can do this in *Workloads* -> *Secrets* -> *Create* -> *From YAML*. + +For more information, see "Object storage setup". + +-- +include::snippets/distr-tracing-tempo-secret-example.adoc[] +-- +==== + +. Create a *TempoMonolithic* instance: ++ +[NOTE] +==== +You can create multiple *TempoMonolithic* instances in separate projects on the same cluster. +==== + +.. Go to *Operators* -> *Installed Operators*. + +.. Select *TempoMonolithic* -> *Create TempoMonolithic* -> *YAML view*. + +.. In the *YAML view*, customize the `TempoMonolithic` custom resource (CR). ++ +include::snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc[] + +.. Select *Create*. + +.Verification + +. Use the *Project:* dropdown list to select the project of the *TempoMonolithic* instance. + +. Go to *Operators* -> *Installed Operators* to verify that the *Status* of the *TempoMonolithic* instance is *Condition: Ready*. + +. Go to *Workloads* -> *Pods* to verify that the pod of the *TempoMonolithic* instance is running. + +. Access the Jaeger UI: + +.. Go to *Networking* -> *Routes* and kbd:[Ctrl+F] to search for `jaegerui`. ++ +[NOTE] +==== +The Jaeger UI uses the `tempo--jaegerui` route. +==== + +.. In the *Location* column, open the URL to access the Jaeger UI. + +. When the pod of the *TempoMonolithic* instance is ready, you can send traces to the `tempo-:4317` (OTLP/gRPC) and `tempo-:4318` (OTLP/HTTP) endpoints inside the cluster. ++ +The Tempo API is available at the `tempo-:3200` endpoint inside the cluster. diff --git a/modules/distr-tracing-tempo-install-tempostack-cli.adoc b/modules/distr-tracing-tempo-install-tempostack-cli.adoc new file mode 100644 index 000000000000..a3fb6fbb97c5 --- /dev/null +++ b/modules/distr-tracing-tempo-install-tempostack-cli.adoc @@ -0,0 +1,169 @@ +// Module included in the following assemblies: +// +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc + +:_mod-docs-content-type: PROCEDURE +[id="distr-tracing-tempo-install-tempostack-cli_{context}"] += Installing a TempoStack instance by using the CLI + +You can install a TempoStack instance from the command line. + +.Prerequisites + +* An active {oc-first} session by a cluster administrator with the `cluster-admin` role. ++ +[TIP] +==== +* Ensure that your {oc-first} version is up to date and matches your {product-title} version. + +* Run the `oc login` command: ++ +[source,terminal] +---- +$ oc login --username= +---- +==== + +* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". ++ +[WARNING] +==== +Object storage is required and not included with the {TempoShortName}. You must choose and set up object storage by a supported provider before installing the {TempoShortName}. +==== + +.Procedure + +. Run the following command to create a project of your choice for the TempoStack instance that you will create in a subsequent step: ++ +[source,terminal] +---- +$ oc apply -f - << EOF +apiVersion: project.openshift.io/v1 +kind: Project +metadata: + name: +EOF +---- + +. In the project that you created for the TempoStack instance, create a secret for your object storage bucket by running the following command: ++ +[source,terminal] +---- +$ oc apply -f - << EOF + +EOF +---- ++ +For more information, see "Object storage setup". ++ +-- +include::snippets/distr-tracing-tempo-secret-example.adoc[] +-- + +. Create a TempoStack instance in the project that you created for it: ++ +[NOTE] +==== +You can create multiple TempoStack instances in separate projects on the same cluster. +==== ++ +.. Customize the `TempoStack` custom resource (CR): ++ +[source,yaml] +---- +apiVersion: tempo.grafana.com/v1alpha1 +kind: TempoStack +metadata: + name: sample + namespace: +spec: + storageSize: 1Gi + storage: + secret: # <1> + name: # <2> + type: # <3> + template: + queryFrontend: + jaegerQuery: + enabled: true + ingress: + route: + termination: edge + type: route +---- +<1> The secret you created in step 2 for the object storage that had been set up as one of the prerequisites. +<2> The value of the `name` in the `metadata` of the secret. +<3> The accepted values are `azure` for Azure Blob Storage; `gcs` for Google Cloud Storage; and `s3` for Amazon S3, MinIO, or {odf-full}. ++ +.Example of a `TempoStack` CR for AWS S3 and MinIO storage +[source,yaml] +---- +apiVersion: tempo.grafana.com/v1alpha1 +kind: TempoStack +metadata: + name: simplest + namespace: +spec: + storageSize: 1Gi + storage: # <1> + secret: + name: minio-test + type: s3 + resources: + total: + limits: + memory: 2Gi + cpu: 2000m + template: + queryFrontend: + jaegerQuery: # <2> + enabled: true + ingress: + route: + termination: edge + type: route +---- +<1> In this example, the object storage was set up as one of the prerequisites, and the object storage secret was created in step 2. +<2> The stack deployed in this example is configured to receive Jaeger Thrift over HTTP and OpenTelemetry Protocol (OTLP), which permits visualizing the data with the Jaeger UI. + +.. Apply the customized CR by running the following command: ++ +[source,terminal] +---- +$ oc apply -f - << EOF + +EOF +---- + + +.Verification + +. Verify that the `status` of all TempoStack `components` is `Running` and the `conditions` are `type: Ready` by running the following command: ++ +[source,terminal] +---- +$ oc get tempostacks.tempo.grafana.com simplest -o yaml +---- + +. Verify that all the TempoStack component pods are running by running the following command: ++ +[source,terminal] +---- +$ oc get pods +---- + +. Access the Tempo console: + +.. Query the route details by running the following command: ++ +[source,terminal] +---- +$ oc get route +---- + +.. Open `\https://` in a web browser. ++ +[NOTE] +==== +The Tempo console initially shows no trace data following the Tempo console installation. +==== diff --git a/modules/distr-tracing-tempo-install-tempostack-web-console.adoc b/modules/distr-tracing-tempo-install-tempostack-web-console.adoc new file mode 100644 index 000000000000..900ca3d999fb --- /dev/null +++ b/modules/distr-tracing-tempo-install-tempostack-web-console.adoc @@ -0,0 +1,124 @@ +// Module included in the following assemblies: +// +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc + +:_mod-docs-content-type: PROCEDURE +[id="distr-tracing-tempo-install-tempostack-web-console_{context}"] += Installing a TempoStack instance by using the web console + +You can install a TempoStack instance from the *Administrator* view of the web console. + +.Prerequisites + +* You are logged in to the {product-title} web console as a cluster administrator with the `cluster-admin` role. + +* For {product-dedicated}, you must be logged in using an account with the `dedicated-admin` role. + +* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". ++ +[WARNING] +==== +Object storage is required and not included with the {TempoShortName}. You must choose and set up object storage by a supported provider before installing the {TempoShortName}. +==== + +.Procedure + +. Go to *Home* -> *Projects* -> *Create Project* to create a project of your choice for the TempoStack instance that you will create in a subsequent step. + +. Go to *Workloads* -> *Secrets* -> *Create* -> *From YAML* to create a secret for your object storage bucket in the project that you created for the TempoStack instance. For more information, see "Object storage setup". ++ +-- +include::snippets/distr-tracing-tempo-secret-example.adoc[] +-- + +. Create a TempoStack instance. ++ +[NOTE] +==== +You can create multiple TempoStack instances in separate projects on the same cluster. +==== + +.. Go to *Operators* -> *Installed Operators*. + +.. Select *TempoStack* -> *Create TempoStack* -> *YAML view*. + +.. In the *YAML view*, customize the `TempoStack` custom resource (CR): ++ +[source,yaml] +---- +apiVersion: tempo.grafana.com/v1alpha1 +kind: TempoStack +metadata: + name: sample + namespace: +spec: + storageSize: 1Gi + storage: + secret: # <1> + name: # <2> + type: # <3> + template: + queryFrontend: + jaegerQuery: + enabled: true + ingress: + route: + termination: edge + type: route +---- +<1> The secret you created in step 2 for the object storage that had been set up as one of the prerequisites. +<2> The value of the `name` in the `metadata` of the secret. +<3> The accepted values are `azure` for Azure Blob Storage; `gcs` for Google Cloud Storage; and `s3` for Amazon S3, MinIO, or {odf-full}. ++ +.Example of a `TempoStack` CR for AWS S3 and MinIO storage +[source,yaml] +---- +apiVersion: tempo.grafana.com/v1alpha1 +kind: TempoStack +metadata: + name: simplest + namespace: +spec: + storageSize: 1Gi + storage: # <1> + secret: + name: minio-test + type: s3 + resources: + total: + limits: + memory: 2Gi + cpu: 2000m + template: + queryFrontend: + jaegerQuery: # <2> + enabled: true + ingress: + route: + termination: edge + type: route +---- +<1> In this example, the object storage was set up as one of the prerequisites, and the object storage secret was created in step 2. +<2> The stack deployed in this example is configured to receive Jaeger Thrift over HTTP and OpenTelemetry Protocol (OTLP), which permits visualizing the data with the Jaeger UI. + +.. Select *Create*. + + +.Verification + +. Use the *Project:* dropdown list to select the project of the *TempoStack* instance. + +. Go to *Operators* -> *Installed Operators* to verify that the *Status* of the *TempoStack* instance is *Condition: Ready*. + +. Go to *Workloads* -> *Pods* to verify that all the component pods of the *TempoStack* instance are running. + +. Access the Tempo console: + +.. Go to *Networking* -> *Routes* and kbd:[Ctrl+F] to search for `tempo`. + +.. In the *Location* column, open the URL to access the Tempo console. ++ +[NOTE] +==== +The Tempo console initially shows no trace data following the Tempo console installation. +==== diff --git a/modules/distr-tracing-tempo-install-web-console.adoc b/modules/distr-tracing-tempo-install-web-console.adoc index 7f6591eb406f..cd7b6ed8cb72 100644 --- a/modules/distr-tracing-tempo-install-web-console.adoc +++ b/modules/distr-tracing-tempo-install-web-console.adoc @@ -1,12 +1,12 @@ // Module included in the following assemblies: // -//* observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc +// * observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc :_mod-docs-content-type: PROCEDURE [id="distr-tracing-tempo-install-web-console_{context}"] -= Installing by using the web console += Installing the {TempoOperator} by using the web console -You can install the {TempoShortName} from the *Administrator* view of the web console. +You can install the {TempoOperator} from the *Administrator* view of the web console. .Prerequisites @@ -14,7 +14,7 @@ You can install the {TempoShortName} from the *Administrator* view of the web co * For {product-dedicated}, you must be logged in using an account with the `dedicated-admin` role. -* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[Red Hat OpenShift Data Foundation], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". +* You have completed setting up the required object storage by a supported provider: link:https://www.redhat.com/en/technologies/cloud-computing/openshift-data-foundation[{odf-full}], link:https://min.io/[MinIO], link:https://aws.amazon.com/s3/[Amazon S3], link:https://azure.microsoft.com/en-us/products/storage/blobs/[Azure Blob Storage], link:https://cloud.google.com/storage/[Google Cloud Storage]. For more information, see "Object storage setup". + [WARNING] ==== @@ -23,11 +23,9 @@ Object storage is required and not included with the {TempoShortName}. You must .Procedure -. Install the {TempoOperator}: +. Go to *Operators* -> *OperatorHub* and search for `{TempoOperator}`. -.. Go to *Operators* -> *OperatorHub* and search for `{TempoOperator}`. - -.. Select the *{TempoOperator}* that is *provided by Red Hat*. +. Select the *{TempoOperator}* that is *provided by Red Hat*. + [IMPORTANT] ==== @@ -39,108 +37,10 @@ The following selections are the default presets for this Operator: * *Update approval* -> *Automatic* ==== -.. Select the *Enable Operator recommended cluster monitoring on this Namespace* checkbox. - -.. Select *Install* -> *Install* -> *View Operator*. - -.. In the *Details* tab of the page of the installed Operator, under *ClusterServiceVersion details*, verify that the installation *Status* is *Succeeded*. - -. Create a project of your choice for the *TempoStack* instance that you will create in a subsequent step: go to *Home* -> *Projects* -> *Create Project*. - -. In the project that you created for the *TempoStack* instance, create a secret for your object storage bucket: go to *Workloads* -> *Secrets* -> *Create* -> *From YAML*. For more information, see "Object storage setup". -+ --- -include::snippets/distr-tracing-tempo-secret-example.adoc[] --- - -. Create a *TempoStack* instance. -+ -[NOTE] -==== -You can create multiple *TempoStack* instances in separate projects on the same cluster. -==== - -.. Go to *Operators* -> *Installed Operators*. - -.. Select *TempoStack* -> *Create TempoStack* -> *YAML view*. - -.. In the *YAML view*, customize the `TempoStack` custom resource (CR): -+ -[source,yaml] ----- -apiVersion: tempo.grafana.com/v1alpha1 -kind: TempoStack -metadata: - name: sample - namespace: -spec: - storageSize: 1Gi - storage: - secret: # <1> - name: # <2> - type: # <3> - template: - queryFrontend: - jaegerQuery: - enabled: true - ingress: - route: - termination: edge - type: route ----- -<1> The secret you created in step 3. -<2> The value of the `name` in the `metadata` of the secret. -<3> The accepted values are `azure` for Azure Blob Storage; `gcs` for Google Cloud Storage; and `s3` for Amazon S3, MinIO, or Red Hat OpenShift Data Foundation. -+ -.Example of a `TempoStack` CR for AWS S3 and MinIO storage -[source,yaml] ----- -apiVersion: tempo.grafana.com/v1alpha1 -kind: TempoStack -metadata: - name: simplest - namespace: -spec: - storageSize: 1Gi - storage: # <1> - secret: - name: minio-test - type: s3 - resources: - total: - limits: - memory: 2Gi - cpu: 2000m - template: - queryFrontend: - jaegerQuery: # <2> - enabled: true - ingress: - route: - termination: edge - type: route ----- -<1> In this example, the object storage was set up as one of the prerequisites, and the object storage secret was created in step 3. -<2> The stack deployed in this example is configured to receive Jaeger Thrift over HTTP and OpenTelemetry Protocol (OTLP), which permits visualizing the data with the Jaeger UI. - -.. Select *Create*. +. Select the *Enable Operator recommended cluster monitoring on this Namespace* checkbox. +. Select *Install* -> *Install* -> *View Operator*. .Verification -. Use the *Project:* dropdown list to select the project of the *TempoStack* instance. - -. Go to *Operators* -> *Installed Operators* to verify that the *Status* of the *TempoStack* instance is *Condition: Ready*. - -. Go to *Workloads* -> *Pods* to verify that all the component pods of the *TempoStack* instance are running. - -. Access the Tempo console: - -.. Go to *Networking* -> *Routes* and kbd:[Ctrl+F] to search for `tempo`. - -.. In the *Location* column, open the URL to access the Tempo console. -+ -[NOTE] -==== -The Tempo console initially shows no trace data following the Tempo console installation. -==== +* In the *Details* tab of the page of the installed Operator, under *ClusterServiceVersion details*, verify that the installation *Status* is *Succeeded*. diff --git a/observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc b/observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc index ca3f3be753df..56b2f35879d9 100644 --- a/observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc +++ b/observability/distr_tracing/distr_tracing_tempo/distr-tracing-tempo-installing.adoc @@ -6,19 +6,60 @@ include::_attributes/common-attributes.adoc[] toc::[] -Installing the {TempoShortName} involves the following steps: +Installing the {TempoShortName} requires the {TempoOperator} and choosing which type of deployment is best for your use case: -. Setting up supported object storage. -. Installing the {TempoOperator}. -. Creating a secret for the object storage credentials. -. Creating a namespace for a TempoStack instance. -. Creating a `TempoStack` custom resource to deploy at least one TempoStack instance. +* For microservices mode, deploy a TempoStack instance in a dedicated OpenShift project. +* For monolithic mode, deploy a TempoMonolithic instance in a dedicated OpenShift project. -include::modules/distr-tracing-tempo-storage-ref.adoc[leveloffset=+1] +[IMPORTANT] +==== +Using object storage requires setting up a supported object store and creating a secret for the object store credentials before deploying a TempoStack or TempoMonolithic instance. +==== + +[id="installing-the-tempo-operator"] +== Installing the {TempoOperator} + +You can install the {TempoOperator} by using the web console or the command line. + +include::modules/distr-tracing-tempo-install-web-console.adoc[leveloffset=+2] + +include::modules/distr-tracing-tempo-install-cli.adoc[leveloffset=+2] + +[id="installing-a-tempostack-instance"] +== Installing a TempoStack instance + +You can install a TempoStack instance by using the web console or the command line. + +include::modules/distr-tracing-tempo-install-tempostack-web-console.adoc[leveloffset=+2] + +include::modules/distr-tracing-tempo-install-tempostack-cli.adoc[leveloffset=+2] -include::modules/distr-tracing-tempo-install-web-console.adoc[leveloffset=+1] +[id="installing-a-tempomonolithic-instance"] +== Installing a TempoMonolithic instance -include::modules/distr-tracing-tempo-install-cli.adoc[leveloffset=+1] +:FeatureName: The TempoMonolithic instance +include::snippets/technology-preview.adoc[] + +You can install a TempoMonolithic instance by using the web console or the command line. + +The `TempoMonolithic` custom resource (CR) creates a Tempo deployment in monolithic mode. +All components of the Tempo deployment, such as the compactor, distributor, ingester, querier, and query frontend, are contained in a single container. + +A TempoMonolithic instance supports storing traces in in-memory storage, a persistent volume, or object storage. + +Tempo deployment in monolithic mode is preferred for a small deployment, demonstration, testing, and as a migration path of the {JaegerName} all-in-one deployment. + +[NOTE] +==== +The monolithic deployment of Tempo does not scale horizontally. +If you require horizontal scaling, use the `TempoStack` CR for a Tempo deployment in microservices mode. +==== + +include::modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc[leveloffset=+2] + +include::modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc[leveloffset=+2] + +include::modules/distr-tracing-tempo-storage-ref.adoc[leveloffset=+1] [role="_additional-resources"] [id="additional-resources_dist-tracing-tempo-installing"] diff --git a/snippets/distr-tracing-tempo-required-secret-parameters.adoc b/snippets/distr-tracing-tempo-required-secret-parameters.adoc index dd3712b459a5..2656b961d5bc 100644 --- a/snippets/distr-tracing-tempo-required-secret-parameters.adoc +++ b/snippets/distr-tracing-tempo-required-secret-parameters.adoc @@ -5,6 +5,7 @@ :_mod-docs-content-type: SNIPPET +[id="required_secret_parameters_{context}"] .Required secret parameters [cols="25h,~"] |=== @@ -12,7 +13,7 @@ //source: https://github.com/grafana/tempo-operator/blob/main/docs/tempostack/object_storage.md -|link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/[Red Hat OpenShift Data Foundation] +|link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/[{odf-full}] | `name: tempostack-dev-odf # example` diff --git a/snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc b/snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc new file mode 100644 index 000000000000..6fd6b0216318 --- /dev/null +++ b/snippets/distr-tracing-tempo-tempomonolithic-custom-resource.adoc @@ -0,0 +1,32 @@ +// :_mod-docs-content-type: SNIPPET +// Text snippet included in the following modules: +// +// * modules/distr-tracing-tempo-install-tempomonolithic-web-console.adoc +// * modules/distr-tracing-tempo-install-tempomonolithic-cli.adoc +The following `TempoMonolithic` CR creates a TempoMonolithic deployment with trace ingestion over OTLP/gRPC and OTLP/HTTP, storing traces in a supported type of storage and exposing Jaeger UI via a route: ++ +[source,yaml] +---- +apiVersion: tempo.grafana.com/v1alpha1 +kind: TempoMonolithic +metadata: + name: + namespace: +spec: + storage: + traces: + backend: # <1> + size: Gi # <2> + s3: # <3> + secret: # <4> + jaegerui: + enabled: true # <5> + route: + enabled: true # <6> +---- +<1> Type of storage for storing traces: in-memory storage, a persistent volume, or object storage. The value for the `tmpfs` in-memory storage is `memory`. The value for a persistent volume is `pv`. The accepted values for object storage are `s3`, `gcs`, or `azure`, depending on the used object store type. +<2> Memory size: For in-memory storage, this means the size of the `tmpfs` volume, where the default is `2Gi`. For a persistent volume, this means the size of the persistent volume claim, where the default is `10Gi`. For object storage, this means the size of the persistent volume claim for the Tempo WAL, where the default is `10Gi`. +<3> Optional: For object storage, the type of object storage. The accepted values are `s3`, `gcs`, and `azure`, depending on the used object store type. +<4> Optional: For object storage, the value of the `name` in the `metadata` of the storage secret. The storage secret must be in the same namespace as the TempoMonolithic instance and contain the fields specified in "Table 1. Required secret parameters" in the section "Object storage setup". +<5> Enables the Jaeger UI. +<6> Enables creation of a route for the Jaeger UI. From 948a49232e35516a684e3e79a7e312fd62e09482 Mon Sep 17 00:00:00 2001 From: Pavol Loffay Date: Tue, 13 Feb 2024 18:53:41 +0100 Subject: [PATCH 045/339] Configure OTEL to srape in-cluster monitoring stack review https://github.com/openshift/openshift-docs/pull/71580 --- _topic_maps/_topic_map.yml | 4 +- ...nfig-receive-metrics-monitoring-stack.adoc | 83 +++++++++++++++++++ ...-config-send-metrics-monitoring-stack.adoc | 29 ++++--- ...figuring-metrics-for-monitoring-stack.adoc | 31 +++++++ 4 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 modules/otel-config-receive-metrics-monitoring-stack.adoc rename {observability/otel => modules}/otel-config-send-metrics-monitoring-stack.adoc (57%) create mode 100644 observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 495594f28be5..06ef3805d3c8 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2876,8 +2876,8 @@ Topics: File: otel-configuration-of-instrumentation - Name: Sending traces and metrics to the Collector File: otel-sending-traces-and-metrics-to-otel-collector - - Name: Sending metrics to the monitoring stack - File: otel-config-send-metrics-monitoring-stack + - Name: Configuring metrics for the monitoring stack + File: otel-configuring-metrics-for-monitoring-stack - Name: Forwarding traces to a TempoStack File: otel-forwarding - Name: Configuring the Collector metrics diff --git a/modules/otel-config-receive-metrics-monitoring-stack.adoc b/modules/otel-config-receive-metrics-monitoring-stack.adoc new file mode 100644 index 000000000000..077a1bf7568f --- /dev/null +++ b/modules/otel-config-receive-metrics-monitoring-stack.adoc @@ -0,0 +1,83 @@ +// Module included in the following assemblies: +// +// * observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc + +:_mod-docs-content-type: REFERENCE +[id="configuration-for-receiving-metrics-from-the-monitoring-stack_{context}"] += Configuration for receiving metrics from the monitoring stack + +A configured OpenTelemetry Collector custom resource (CR) can set up the Prometheus receiver to scrape metrics from the in-cluster monitoring stack. + +.Example of the OpenTelemetry Collector CR for scraping metrics from the in-cluster monitoring stack +[source,yaml] +---- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: otel-collector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-monitoring-view # <1> +subjects: + - kind: ServiceAccount + name: otel-collector + namespace: observability +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: cabundle + namespce: observability + annotations: + service.beta.openshift.io/inject-cabundle: "true" # <2> +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: otel + namespace: observability +spec: + volumeMounts: + - name: cabundle-volume + mountPath: /etc/pki/ca-trust/source/service-ca + readOnly: true + volumes: + - name: cabundle-volume + configMap: + name: cabundle + mode: deployment + config: | + receivers: + prometheus: # <3> + config: + scrape_configs: + - job_name: 'federate' + scrape_interval: 15s + scheme: https + tls_config: + ca_file: /etc/pki/ca-trust/source/service-ca/service-ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + honor_labels: false + params: + 'match[]': + - '{__name__=""}' # <4> + metrics_path: '/federate' + static_configs: + - targets: + - "prometheus-k8s.openshift-monitoring.svc.cluster.local:9091" + exporters: + debug: # <5> + verbosity: detailed + service: + pipelines: + metrics: + receivers: [prometheus] + processors: [] + exporters: [debug] +---- +<1> Assigns the `cluster-monitoring-view` cluster role to the service account of the OpenTelemetry Collector so that it can access the metrics data. +<2> Injects the OpenShift service CA for configuring the TLS in the Prometheus receiver. +<3> Configures the Prometheus receiver to scrape the federate endpoint from the in-cluster monitoring stack. +<4> Uses the Prometheus query language to select the metrics to be scraped. See the in-cluster monitoring documentation for more details and limitations of the federate endpoint. +<5> Configures the debug exporter to print the metrics to the standard output. diff --git a/observability/otel/otel-config-send-metrics-monitoring-stack.adoc b/modules/otel-config-send-metrics-monitoring-stack.adoc similarity index 57% rename from observability/otel/otel-config-send-metrics-monitoring-stack.adoc rename to modules/otel-config-send-metrics-monitoring-stack.adoc index 34adbd5ed799..4c0bc1c80efc 100644 --- a/observability/otel/otel-config-send-metrics-monitoring-stack.adoc +++ b/modules/otel-config-send-metrics-monitoring-stack.adoc @@ -1,14 +1,23 @@ -:_mod-docs-content-type: ASSEMBLY -[id="otel-configuration-for-sending-metrics-to-the-monitoring-stack"] +// Module included in the following assemblies: +// +// * observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc + +:_mod-docs-content-type: REFERENCE +[id="configuration-for-sending-metrics-to-the-monitoring-stack_{context}"] = Configuration for sending metrics to the monitoring stack -include::_attributes/common-attributes.adoc[] -:context: otel-configuration-for-sending-metrics-to-the-monitoring-stack -The OpenTelemetry Collector custom resource (CR) can be configured to create a Prometheus `ServiceMonitor` CR for scraping the Collector's pipeline metrics and the enabled Prometheus exporters. +One of two following custom resources (CR) configures the sending of metrics to the monitoring stack: + +* OpenTelemetry Collector CR +* Prometheus `PodMonitor` CR + +A configured OpenTelemetry Collector CR can create a Prometheus `ServiceMonitor` CR for scraping the Collector's pipeline metrics and the enabled Prometheus exporters. -.Example of the OpenTelemetry Collector custom resource with the Prometheus exporter +.Example of the OpenTelemetry Collector CR with the Prometheus exporter [source,yaml] ---- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector spec: mode: deployment observability: @@ -31,9 +40,9 @@ spec: ---- <1> Configures the Operator to create the Prometheus `ServiceMonitor` CR to scrape the Collector's internal metrics endpoint and Prometheus exporter metric endpoints. The metrics will be stored in the OpenShift monitoring stack. -Alternatively, a manually created Prometheus `PodMonitor` can provide fine control, for example removing duplicated labels added during Prometheus scraping. +Alternatively, a manually created Prometheus `PodMonitor` CR can provide fine control, for example removing duplicated labels added during Prometheus scraping. -.Example of the `PodMonitor` custom resource that configures the monitoring stack to scrape the Collector metrics +.Example of the `PodMonitor` CR that configures the monitoring stack to scrape the Collector metrics [source,yaml] ---- apiVersion: monitoring.coreos.com/v1 @@ -43,7 +52,7 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: `-collector` # <1> + app.kubernetes.io/name: -collector # <1> podMetricsEndpoints: - port: metrics # <2> - port: promexporter # <3> @@ -60,6 +69,6 @@ spec: - action: labeldrop regex: job ---- -<1> The name of the OpenTelemetry Collector custom resource. +<1> The name of the OpenTelemetry Collector CR. <2> The name of the internal metrics port for the OpenTelemetry Collector. This port name is always `metrics`. <3> The name of the Prometheus exporter port for the OpenTelemetry Collector. diff --git a/observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc b/observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc new file mode 100644 index 000000000000..7c36bb042a5f --- /dev/null +++ b/observability/otel/otel-configuring-metrics-for-monitoring-stack.adoc @@ -0,0 +1,31 @@ +:_mod-docs-content-type: ASSEMBLY +[id="otel-configuring-metrics-for-monitoring-stack"] += Configuring metrics for the monitoring stack +include::_attributes/common-attributes.adoc[] +:context: otel-configuring-metrics-for-monitoring-stack + +toc::[] + +As a cluster administrator, you can configure the OpenTelemetry Collector custom resource (CR) to perform the following tasks: + +* Create a Prometheus `ServiceMonitor` CR for scraping the Collector’s pipeline metrics and the enabled Prometheus exporters. + +* Configure the Prometheus receiver to scrape metrics from the in-cluster monitoring stack. + +include::modules/otel-config-send-metrics-monitoring-stack.adoc[leveloffset=+1] +include::modules/otel-config-receive-metrics-monitoring-stack.adoc[leveloffset=+1] + +[id="additional-resources_otel-configuring-metrics-for-monitoring-stack"] +== Additional resources + +// * xref:../monitoring/accessing-third-party-monitoring-apis.adoc#monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus[Querying metrics by using the federation endpoint for Prometheus] + +//* xref:../monitoring/accessing-third-party-monitoring-apis.adoc#monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus_accessing-third-party-monitoring-apis[Querying metrics by using the federation endpoint for Prometheus] + +//* xref:../monitoring/accessing-third-party-monitoring-apis.adoc#monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus[Querying metrics by using the federation endpoint for Prometheus] + +//* xref:../monitoring/accessing-third-party-monitoring-apis.adoc#monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus_accessing-monitoring-apis-by-using-the-cli[Querying metrics by using the federation endpoint for Prometheus] + +//* xref:../monitoring/accessing-third-party-monitoring-apis.adoc#accessing-third-party-monitoring-apis_monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus[Querying metrics by using the federation endpoint for Prometheus] + +* xref:../monitoring/accessing-third-party-monitoring-apis.adoc#monitoring-querying-metrics-by-using-the-federation-endpoint-for-prometheus_accessing-monitoring-apis-by-using-the-cli[Querying metrics by using the federation endpoint for Prometheus] From ea3b9b7467efd0064a1533e015d3e283e44c5e1a Mon Sep 17 00:00:00 2001 From: Andreas Gerstmayr Date: Mon, 22 Apr 2024 13:43:40 +0200 Subject: [PATCH 046/339] TRACING-4106: add note that tempo gateway service only supports OTLP/gRPC Signed-off-by: Andreas Gerstmayr --- modules/distr-tracing-tempo-config-multitenancy.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/distr-tracing-tempo-config-multitenancy.adoc b/modules/distr-tracing-tempo-config-multitenancy.adoc index 001211eb72b0..68ee12be6263 100644 --- a/modules/distr-tracing-tempo-config-multitenancy.adoc +++ b/modules/distr-tracing-tempo-config-multitenancy.adoc @@ -9,6 +9,11 @@ Multitenancy with authentication and authorization is provided in the Tempo Gateway service. The authentication uses OpenShift OAuth and the Kubernetes `TokenReview` API. The authorization uses the Kubernetes `SubjectAccessReview` API. +[NOTE] +==== +The Tempo Gateway service supports ingestion of traces only via the OTLP/gRPC. The OTLP/HTTP is not supported. +==== + .Sample Tempo CR with two tenants, `dev` and `prod` [source,yaml] ---- From 193dce59a92cba90618194102d6beace81787ed9 Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 22 May 2024 12:29:58 +0200 Subject: [PATCH 047/339] OBSDOCS-1024: Write documentation for loadbalancer exporter component Signed-off-by: Benedikt Bongartz --- modules/otel-collector-components.adoc | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/modules/otel-collector-components.adoc b/modules/otel-collector-components.adoc index 2b8452d259d2..fc922f2fb366 100644 --- a/modules/otel-collector-components.adoc +++ b/modules/otel-collector-components.adoc @@ -651,6 +651,46 @@ The Debug exporter prints traces and metrics to the standard output. ---- <1> Verbosity of the debug export: `detailed` or `normal` or `basic`. When set to `detailed`, pipeline data is verbosely logged. Defaults to `normal`. +[id="load-balancing-exporter_{context}"] +=== Load Balancing Exporter + +The Load Balancing Exporter consistently exports spans, metrics, and logs according to the `routing_key` configuration. + +:FeatureName: The Load Balancing Exporter +include::snippets/technology-preview.adoc[leveloffset=+1] + +.OpenTelemetry Collector custom resource with an enabled Load Balancing Exporter +[source,yaml] +---- +# ... + config: | + exporters: + loadbalancing: + routing_key: "service" # <1> + protocol: + otlp: # <2> + timeout: 1s + resolver: # <3> + static: # <4> + hostnames: + - backend-1:4317 + - backend-2:4317 + dns: # <5> + hostname: otelcol-headless.observability.svc.cluster.local + k8s: # <6> + service: lb-svc.kube-public + ports: + - 15317 + - 16317 +# ... +---- +<1> The `routing_key: service` exports spans for the same service name to the same Collector instance to provide accurate aggregation. The `routing_key: traceID` exports spans based on their `traceID`. The implicit default is `traceID` based routing. +<2> The OTLP is the only supported load-balancing protocol. All options of the OTLP exporter are supported. +<3> You can configure only one resolver. +<4> The static resolver distributes the load across the listed endpoints. +<5> You can use the DNS resolver only with a Kubernetes headless service. +<6> The Kubernetes resolver is recommended. + [id="prometheus-exporter_{context}"] === Prometheus exporter From 99a5e2fbf8ef1e45363594af33ec7b6bc82c470e Mon Sep 17 00:00:00 2001 From: GroceryBoyJr Date: Tue, 21 May 2024 13:37:09 -0400 Subject: [PATCH 048/339] FIO 1.3.4: Update of the File Integrity Operator --- .../file-integrity-operator-release-notes.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/security/file_integrity_operator/file-integrity-operator-release-notes.adoc b/security/file_integrity_operator/file-integrity-operator-release-notes.adoc index fd4019ae59f9..4e50806c3d34 100644 --- a/security/file_integrity_operator/file-integrity-operator-release-notes.adoc +++ b/security/file_integrity_operator/file-integrity-operator-release-notes.adoc @@ -15,6 +15,18 @@ For an overview of the File Integrity Operator, see xref:../../security/file_int To access the latest release, see xref:../../security/file_integrity_operator/file-integrity-operator-updating.adoc#olm-preparing-upgrade_file-integrity-operator-updating[Updating the File Integrity Operator]. +[id="file-integrity-operator-release-notes-1-3-4"] +== OpenShift File Integrity Operator 1.3.4 + +The following advisory is available for the OpenShift File Integrity Operator 1.3.4: + +* link:https://access.redhat.com/errata/RHBA-2024:2946[RHBA-2024:2946 OpenShift File Integrity Operator Bug Fix and Enhancement Update] + +[id="file-integrity-operator-1-3-4-bug-fixes"] +=== Bug fixes + +Previously, File Integrity Operator would issue a `NodeHasIntegrityFailure` alert due to multus certificate rotation. With this release, the alert and failing status are now correctly triggered. (link:https://issues.redhat.com/browse/OCPBUGS-31257[*OCPBUGS-31257*]) + [id="file-integrity-operator-release-notes-1-3-3"] == OpenShift File Integrity Operator 1.3.3 From 24c8fad0c32db4f8505540225b6133addc9607d7 Mon Sep 17 00:00:00 2001 From: Israel Blancas Date: Fri, 22 Mar 2024 16:55:53 +0100 Subject: [PATCH 049/339] TRACING-4066: add documentation for forward connector Signed-off-by: Israel Blancas --- modules/otel-collector-components.adoc | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/modules/otel-collector-components.adoc b/modules/otel-collector-components.adoc index fc922f2fb366..879b556fc5a9 100644 --- a/modules/otel-collector-components.adoc +++ b/modules/otel-collector-components.adoc @@ -780,6 +780,49 @@ The Kafka exporter exports logs, metrics, and traces to Kafka. This exporter use Connectors connect two pipelines. +[id="forward-connector_{context}"] +=== Forward Connector + +:FeatureName: The Forward Connector +include::snippets/technology-preview.adoc[] + +The Forward Connector merges two pipelines of the same type. + +.OpenTelemetry Collector custom resource with an enabled Forward Connector +[source,yaml] +---- +receivers: + otlp: + protocols: + grpc: + jaeger: + protocols: + grpc: +processors: + batch: +exporters: + otlp: + endpoint: tempo-simplest-distributor:4317 + tls: + insecure: true +connectors: + forward: +service: + pipelines: + traces/regiona: + receivers: [otlp] + processors: [] + exporters: [forward] + traces/regionb: + receivers: [jaeger] + processors: [] + exporters: [forward] + traces: + receivers: [forward] + processors: [batch] + exporters: [otlp] +---- + [id="spanmetrics-connector_{context}"] === Spanmetrics connector From ea946d1470405158d6dd445bf12f3fcaaab1fea1 Mon Sep 17 00:00:00 2001 From: Talia Shwartzberg Date: Mon, 20 May 2024 13:03:07 +0300 Subject: [PATCH 050/339] HCIDOCS-128: vCPU mismatch in installation with the Assisted Installer --- modules/lvms-about-lvm-storage-installation.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/lvms-about-lvm-storage-installation.adoc b/modules/lvms-about-lvm-storage-installation.adoc index 708badfd21f6..1c01f3fb3ec3 100644 --- a/modules/lvms-about-lvm-storage-installation.adoc +++ b/modules/lvms-about-lvm-storage-installation.adoc @@ -22,6 +22,8 @@ The prerequisites to install {lvms} are as follows: * Ensure that you have a minimum of 10 milliCPU and 100 MiB of RAM. +* Ensure that you have a minimum of 9 vCPU cores. + * Ensure that every managed cluster has dedicated disks that are used to provision storage. {lvms} uses only those disks that are empty and do not contain file system signatures. To ensure that the disks are empty and do not contain file system signatures, wipe the disks before using them. * Before installing {lvms} in a private CI environment where you can reuse the storage devices that you configured in the previous {lvms} installation, ensure that you have wiped the disks that are not in use. If you do not wipe the disks before installing {lvms}, you cannot reuse the disks without manual intervention. From cc8f83b3ad20d4c0dbdc5db9884f561cde1dd5ee Mon Sep 17 00:00:00 2001 From: Ruben Vargas Date: Tue, 26 Mar 2024 22:07:45 -0600 Subject: [PATCH 051/339] [TRACING-4077] Add documentation for kubernetes cluster receiver Signed-off-by: Ruben Vargas --- modules/otel-collector-components.adoc | 137 +++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/modules/otel-collector-components.adoc b/modules/otel-collector-components.adoc index 879b556fc5a9..677a5dcdf88d 100644 --- a/modules/otel-collector-components.adoc +++ b/modules/otel-collector-components.adoc @@ -172,6 +172,143 @@ The Kafka receiver receives traces, metrics, and logs from Kafka in the OTLP for <6> Disables verifying the server's certificate chain and host name. The default is `+false+`. <7> ServerName indicates the name of the server requested by the client to support virtual hosting. +[id="k8scluster-receiver_{context}"] +=== Kubernetes Cluster Receiver + +:FeatureName: The Kubernetes Cluster Receiver +include::snippets/technology-preview.adoc[] + +The Kubernetes Cluster Receiver gathers cluster metrics and entity events from the Kubernetes API server. It uses the Kubernetes API to receive information about updates. Authentication for this receiver is only supported through service accounts. + +.OpenTelemetry Collector custom resource with the enabled Kubernetes Cluster Receiver +[source,yaml] +---- +# ... + receivers: + k8s_cluster: + distribution: openshift + collection_interval: 10s + exporters: + debug: + service: + pipelines: + metrics: + receivers: [k8s_cluster] + exporters: [debug] + logs/entity_events: + receivers: [k8s_cluster] + exporters: [debug] +# ... +---- + +This receiver requires a configured service account, RBAC rules for the cluster role, and the cluster role binding that binds the RBAC with the service account. + +.`ServiceAccount` object +[source,yaml] +---- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: otelcontribcol + name: otelcontribcol +---- + +.RBAC rules for the `ClusterRole` object +[source,yaml] +---- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: otelcontribcol + labels: + app: otelcontribcol +rules: +- apiGroups: + - quota.openshift.io + resources: + - clusterresourcequotas + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + - namespaces + - namespaces/status + - nodes + - nodes/spec + - pods + - pods/status + - replicationcontrollers + - replicationcontrollers/status + - resourcequotas + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +---- + +.`ClusterRoleBinding` object +[source,yaml] +---- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: otelcontribcol + labels: + app: otelcontribcol +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: otelcontribcol +subjects: +- kind: ServiceAccount + name: otelcontribcol + namespace: default +---- + [id="opencensus-receiver_{context}"] === OpenCensus receiver From b0b2f3598e1636f4ee7b31c026a1a6ad4a719f37 Mon Sep 17 00:00:00 2001 From: libander Date: Wed, 29 May 2024 08:47:23 -0500 Subject: [PATCH 052/339] OBSDOCS-780 - Collector Alerts --- modules/logging-collector-alerts.adoc | 29 +++++++++++++++++++ .../default-logging-alerts.adoc | 1 + 2 files changed, 30 insertions(+) create mode 100644 modules/logging-collector-alerts.adoc diff --git a/modules/logging-collector-alerts.adoc b/modules/logging-collector-alerts.adoc new file mode 100644 index 000000000000..db65573383bc --- /dev/null +++ b/modules/logging-collector-alerts.adoc @@ -0,0 +1,29 @@ +// Module included in the following assemblies: +// +// * logging/logging_alerts/default-logging-alerts.adoc + +:_content-type: REFERENCE +[id="logging-collector-alerts_{context}"] += Logging collector alerts + +In logging 5.8 and later versions, the following alerts are generated by the {clo}. You can view these alerts in the {product-title} web console. + +[cols="4", options="header"] +|=== +| Alert Name | Message | Description | Severity + +| CollectorNodeDown +| Prometheus could not scrape `namespace`/`pod` collector component for more than 10m. +| Collector cannot be scraped. +| Critical + +| CollectorHighErrorRate +| `value`% of records have resulted in an error by `namespace`/`pod` collector component. +| `namespace`/`pod` collector component errors are high. +| Critical + +| CollectorVeryHighErrorRate +| `value`% of records have resulted in an error by `namespace`/`pod` collector component. +| `namespace`/`pod` collector component errors are very high. +| Critical +|=== diff --git a/observability/logging/logging_alerts/default-logging-alerts.adoc b/observability/logging/logging_alerts/default-logging-alerts.adoc index a7077f517327..68c6fbce9ccb 100644 --- a/observability/logging/logging_alerts/default-logging-alerts.adoc +++ b/observability/logging/logging_alerts/default-logging-alerts.adoc @@ -11,6 +11,7 @@ Logging alerts are installed as part of the {clo} installation. Alerts depend on Default logging alerts are sent to the {product-title} monitoring stack Alertmanager in the `openshift-monitoring` namespace, unless you have disabled the local Alertmanager instance. include::modules/monitoring-accessing-the-alerting-ui.adoc[leveloffset=+1] +include::modules/logging-collector-alerts.adoc[leveloffset=+1] include::modules/logging-vector-collector-alerts.adoc[leveloffset=+1] include::modules/logging-fluentd-collector-alerts.adoc[leveloffset=+1] include::modules/cluster-logging-elasticsearch-rules.adoc[leveloffset=+1] From 582f3b8bc5149ee6a23cb2f1df725678522cca33 Mon Sep 17 00:00:00 2001 From: Ruben Vargas Date: Tue, 26 Mar 2024 22:36:46 -0600 Subject: [PATCH 053/339] TRACING-4069: Add docs for filelog receiver component Signed-off-by: Ruben Vargas --- modules/otel-collector-components.adoc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/modules/otel-collector-components.adoc b/modules/otel-collector-components.adoc index 677a5dcdf88d..326f604ed806 100644 --- a/modules/otel-collector-components.adoc +++ b/modules/otel-collector-components.adoc @@ -336,6 +336,32 @@ The OpenCensus receiver provides backwards compatibility with the OpenCensus pro Wildcards with `+*+` are accepted under the `cors_allowed_origins`. To match any origin, enter only `+*+`. +[id="filelog-receiver_{context}"] +=== Filelog Receiver + +:FeatureName: The Filelog Receiver +include::snippets/technology-preview.adoc[] + +The Filelog Receiver tails and parses logs from files. + +.OpenTelemetry Collector custom resource with the enabled Filelog Receiver that tails a text file +[source,yaml] +---- +receivers: + filelog: + include: [ /simple.log ] # <1> + operators: # <2> + - type: regex_parser + regex: '^(?P+g|k~Nr+$MHi`Y_D=qP> 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 Nt?^L3^xpH3{{$+~OyK|k literal 0 HcmV?d00001 From 16ec2b22627d7ecd25f819612b487a342fd2f795 Mon Sep 17 00:00:00 2001 From: Eric Ponvelle Date: Thu, 13 Jun 2024 12:10:42 -0400 Subject: [PATCH 162/339] Revert "OSDOCS#8394: Migrated the Networking topic for the Deploying your Application docs" --- _topic_maps/_topic_map_rosa.yml | 2 - ...erts-deploying-application-networking.adoc | 62 ------------------ images/deploying-networking-arch.png | Bin 59581 -> 0 bytes images/deploying-networking-dns.png | Bin 38622 -> 0 bytes images/deploying-networking-example.png | Bin 128277 -> 0 bytes 5 files changed, 64 deletions(-) delete mode 100644 cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc delete mode 100644 images/deploying-networking-arch.png delete mode 100644 images/deploying-networking-dns.png delete mode 100644 images/deploying-networking-example.png diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index ffa6a0bde0fb..a8f154523974 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -186,8 +186,6 @@ Topics: File: cloud-experts-deploying-application-prerequisites - Name: Lab Overview File: cloud-experts-deploying-application-lab-overview - - Name: Networking - File: cloud-experts-deploying-application-networking --- Name: Getting started Dir: rosa_getting_started diff --git a/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc deleted file mode 100644 index c8f3251644cb..000000000000 --- a/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc +++ /dev/null @@ -1,62 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="cloud-experts-deploying-application-networking"] -= Tutorial: Networking -include::_attributes/attributes-openshift-dedicated.adoc[] -:context: cloud-experts-deploying-application-networking - -toc::[] - -//rosaworkshop.io content metadata -//Brought into ROSA product docs 2023-12-14 - -This tutorial shows how the OSToy app uses intra-cluster networking to separate functions by using microservices and visualize the scaling of pods. - -image::deploying-networking-arch.png[OSToy Diagram] - -The diagram shows there are at least two separate pods, each with its own service. - -One pod functions as the front end web application with a service and a publicly accessible route. The other pod functions as the backend microservice with a service object so that the front end pod can communicate with the microservice. This communication occurs across the pods if more than one. Because of these communication limits, this microservice is not accessible from outside this cluster or from other namespaces or projects if these are configured. The sole purpose of this microservice is to serve internal web requests and return a JSON object containing the current hostname, which is the pod's name, and a randomly generated color string. This color string is used to display a box with that color displayed in the tile titled "Intra-cluster Communication". - -For more information about the networking limitations, see xref:../../networking/openshift_network_security/network_policy/about-network-policy.adoc#about-network-policy[About network policy]. - -== Intra-cluster networking - -You can view your networking configurations in your OSToy application. - -.Procedure -. In the OSToy application, click *Networking* in the left menu. -. Review the networking configuration. The right tile titled "Hostname Lookup" illustrates how the service name created for a pod can be used to translate into an internal ClusterIP address. -+ -image::deploying-networking-example.png[OSToy Networking page] - -. Enter the name of the microservice created in the right tile ("Hostname Lookup") following the format of `..svc.cluster.local`. You can find this service name in the service definition of `ostoy-microservice.yaml` by running the following command: -+ -[source,terminal] ----- -$ oc get service -o yaml ----- -+ -.Example output -[source,yaml] ----- -apiVersion: v1 -kind: Service -metadata: - name: ostoy-microservice-svc - labels: - app: ostoy-microservice -spec: - type: ClusterIP - ports: - - port: 8080 - targetPort: 8080 - protocol: TCP - selector: - app: ostoy-microservice ----- -+ -In this example, the full hostname is `ostoy-microservice-svc.ostoy.svc.cluster.local`. - -. You see an IP address returned. In this example it is `172.30.165.246`. This is the intra-cluster IP address, which is only accessible from within the cluster. -+ -image::deploying-networking-dns.png[OSToy DNS] \ No newline at end of file diff --git a/images/deploying-networking-arch.png b/images/deploying-networking-arch.png deleted file mode 100644 index 31bd0393efda0a712731a076fe8a0febd7dd0d0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59581 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 Bp0WS{ diff --git a/images/deploying-networking-dns.png b/images/deploying-networking-dns.png deleted file mode 100644 index 321062961dbd66d43877729dc8dd6ed62943251e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38622 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%0D5W4C(*#PS@9N!y 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 TnM&ss2*AhO_!z#z$T{YJXB!>x diff --git a/images/deploying-networking-example.png b/images/deploying-networking-example.png deleted file mode 100644 index e7168c7d2103ab77f124eae30bb349d98b064682..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128277 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 Nt?^L3^xpH3{{$+~OyK|k From 847265828d19d230fbe3b74d5718297bce7bc0d4 Mon Sep 17 00:00:00 2001 From: SNiemann15 Date: Wed, 5 Jun 2024 14:11:38 +0200 Subject: [PATCH 163/339] Add installation IBM Z in an LPAR --- _topic_maps/_topic_map.yml | 2 ++ ...machine-user-infra-machines-ibm-z-kvm.adoc | 14 +++++------ .../machine-user-infra-machines-ibm-z.adoc | 18 ++++++------- ...g-multi-arch-compute-nodes-ibm-z-lpar.adoc | 25 +++++++++++++++++++ 4 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-lpar.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index e7b9c6aa62e4..6f8b16481e15 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -601,6 +601,8 @@ Topics: File: creating-multi-arch-compute-nodes-bare-metal - Name: Creating a cluster with multi-architecture compute machines on IBM Z and IBM LinuxONE with z/VM File: creating-multi-arch-compute-nodes-ibm-z + - Name: Creating a cluster with multi-architecture compute machines on IBM Z and IBM LinuxONE in an LPAR + File: creating-multi-arch-compute-nodes-ibm-z-lpar - Name: Creating a cluster with multi-architecture compute machines on IBM Z and IBM LinuxONE with RHEL KVM File: creating-multi-arch-compute-nodes-ibm-z-kvm - Name: Creating a cluster with multi-architecture compute machines on IBM Power diff --git a/modules/machine-user-infra-machines-ibm-z-kvm.adoc b/modules/machine-user-infra-machines-ibm-z-kvm.adoc index 72471a526914..d90215ae2a3a 100644 --- a/modules/machine-user-infra-machines-ibm-z-kvm.adoc +++ b/modules/machine-user-infra-machines-ibm-z-kvm.adoc @@ -89,7 +89,7 @@ $ virt-install \ --connect qemu:///system \ --name \ --autostart \ - --os-variant rhel9.2 \ <1> + --os-variant rhel9.4 \ <1> --cpu host \ --vcpus \ --memory \ @@ -98,15 +98,15 @@ $ virt-install \ --location ,kernel=,initrd= \ <2> --extra-args "rd.neednet=1" \ --extra-args "coreos.inst.install_dev=/dev/vda" \ - --extra-args "coreos.inst.ignition_url=" \ <3> - --extra-args "coreos.live.rootfs_url=" \ <4> - --extra-args "ip=::::::none:" \ <5> + --extra-args "coreos.inst.ignition_url=http:///worker.ign " \ <3> + --extra-args "coreos.live.rootfs_url=http:///rhcos--live-rootfs..img" \ <4> + --extra-args "ip=::::::none" \ <5> --extra-args "nameserver=" \ --extra-args "console=ttysclp0" \ --noautoconsole \ --wait ---- -<1> For `os-variant`, specify the {op-system-base} version for the {op-system} compute machine. `rhel9.2` is the recommended version. To query the supported {op-system-base} version of your operating system, run the following command: +<1> For `os-variant`, specify the {op-system-base} version for the {op-system} compute machine. `rhel9.4` is the recommended version. To query the supported {op-system-base} version of your operating system, run the following command: + [source,terminal] ---- @@ -119,8 +119,8 @@ The `os-variant` is case sensitive. ==== + <2> For `--location`, specify the location of the kernel/initrd on the HTTP or HTTPS server. -<3> For `coreos.inst.ignition_url=`, specify the `worker.ign` Ignition file for the machine role. Only HTTP and HTTPS protocols are supported. -<4> For `coreos.live.rootfs_url=`, specify the matching rootfs artifact for the `kernel` and `initramfs` you are booting. Only HTTP and HTTPS protocols are supported. +<3> Specify the location of the `worker.ign` config file. Only HTTP and HTTPS protocols are supported. +<4> Specify the location of the `rootfs` artifact for the `kernel` and `initramfs` you are booting. Only HTTP and HTTPS protocols are supported <5> Optional: For `hostname`, specify the fully qualified hostname of the client machine. -- + diff --git a/modules/machine-user-infra-machines-ibm-z.adoc b/modules/machine-user-infra-machines-ibm-z.adoc index d303036e488b..44c215613d49 100644 --- a/modules/machine-user-infra-machines-ibm-z.adoc +++ b/modules/machine-user-infra-machines-ibm-z.adoc @@ -53,7 +53,7 @@ $ oc extract -n openshift-machine-api secret/worker-user-data-managed --keys=use + [source,terminal] ---- -$ curl -k http:///worker.ign +$ curl -k http:///worker.ign ---- . Download the {op-system-base} live `kernel`, `initramfs`, and `rootfs` files by running the following commands: @@ -93,7 +93,7 @@ $ curl -LO $(oc -n openshift-machine-config-operator get configmap/coreos-bootim ** For installations on DASD-type disks, complete the following tasks: ... For `coreos.inst.install_dev=`, specify `/dev/dasda`. ... Use `rd.dasd=` to specify the DASD where {op-system} is to be installed. -... Leave all other parameters unchanged. +... You can adjust further parameters if required. + The following is an example parameter file, `additional-worker-dasd.parm`: + @@ -102,9 +102,9 @@ The following is an example parameter file, `additional-worker-dasd.parm`: rd.neednet=1 \ console=ttysclp0 \ coreos.inst.install_dev=/dev/dasda \ -coreos.live.rootfs_url=http://cl1.provide.example.com:8080/assets/rhcos-live-rootfs.s390x.img \ -coreos.inst.ignition_url=http://cl1.provide.example.com:8080/ignition/worker.ign \ -ip=172.18.78.2::172.18.78.1:255.255.255.0:::none nameserver=172.18.78.1 \ +coreos.live.rootfs_url=http:///rhcos--live-rootfs..img \ +coreos.inst.ignition_url=http:///worker.ign \ +ip=::::::none nameserver= \ rd.znet=qeth,0.0.bdf0,0.0.bdf1,0.0.bdf2,layer2=1,portno=0 \ zfcp.allow_lun_scan=0 \ rd.dasd=0.0.3490 @@ -125,7 +125,7 @@ When you install with multiple paths, you must enable multipathing directly afte ==== If additional LUNs are configured with NPIV, FCP requires `zfcp.allow_lun_scan=0`. If you must enable `zfcp.allow_lun_scan=1` because you use a CSI driver, for example, you must configure your NPIV so that each node cannot access the boot partition of another node. ==== -... Leave all other parameters unchanged. +... You can adjust further parameters if required. + [IMPORTANT] ==== @@ -140,9 +140,9 @@ The following is an example parameter file, `additional-worker-fcp.parm` for a w rd.neednet=1 \ console=ttysclp0 \ coreos.inst.install_dev=/dev/sda \ -coreos.live.rootfs_url=http://cl1.provide.example.com:8080/assets/rhcos-live-rootfs.s390x.img \ -coreos.inst.ignition_url=http://cl1.provide.example.com:8080/ignition/worker.ign \ -ip=172.18.78.2::172.18.78.1:255.255.255.0:::none nameserver=172.18.78.1 \ +coreos.live.rootfs_url=http:///rhcos--live-rootfs..img \ +coreos.inst.ignition_url=http:///worker.ign \ +ip=::::::none nameserver= \ rd.znet=qeth,0.0.bdf0,0.0.bdf1,0.0.bdf2,layer2=1,portno=0 \ zfcp.allow_lun_scan=0 \ rd.zfcp=0.0.1987,0x50050763070bc5e3,0x4008400B00000000 \ diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-lpar.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-lpar.adoc new file mode 100644 index 000000000000..1f14102109e9 --- /dev/null +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-lpar.adoc @@ -0,0 +1,25 @@ +:_mod-docs-content-type: ASSEMBLY +:context: creating-multi-arch-compute-nodes-ibm-z-lpar +include::_attributes/common-attributes.adoc[] +[id="creating-multi-arch-compute-nodes-ibm-z-lpar"] += Creating a cluster with multi-architecture compute machines on {ibm-z-title} and {ibm-linuxone-title} in an LPAR + +toc::[] + +To create a cluster with multi-architecture compute machines on {ibm-z-name} and {ibm-linuxone-name} (`s390x`) in an LPAR, you must have an existing single-architecture `x86_64` cluster. You can then add `s390x` compute machines to your {product-title} cluster. + +Before you can add `s390x` nodes to your cluster, you must upgrade your cluster to one that uses the multi-architecture payload. For more information on migrating to the multi-architecture payload, see xref:../../updating/updating_a_cluster/migrating-to-multi-payload.adoc#migrating-to-multi-payload[Migrating to a cluster with multi-architecture compute machines]. + +The following procedures explain how to create a {op-system} compute machine using an LPAR instance. This will allow you to add `s390x` nodes to your cluster and deploy a cluster with multi-architecture compute machines. + +[NOTE] +==== +To create an {ibm-z-name} or {ibm-linuxone-name} (`s390x`) cluster with multi-architecture compute machines on `x86_64`, follow the instructions for +xref:../../installing/installing_ibm_z/preparing-to-install-on-ibm-z.adoc#preparing-to-install-on-ibm-z[Installing a cluster on {ibm-z-name} and {ibm-linuxone-name}]. You can then add `x86_64` compute machines as described in xref:./creating-multi-arch-compute-nodes-bare-metal.adoc#creating-multi-arch-compute-nodes-bare-metal[Creating a cluster with multi-architecture compute machines on bare metal, {ibm-power-title}, or {ibm-z-title}]. +==== + +include::modules/multi-architecture-verifying-cluster-compatibility.adoc[leveloffset=+1] + +include::modules/machine-user-infra-machines-ibm-z.adoc[leveloffset=+1] + +include::modules/installation-approve-csrs.adoc[leveloffset=+1] \ No newline at end of file From 05ea421e659c775169384bfee681483c5c323751 Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Fri, 3 May 2024 11:30:23 -0400 Subject: [PATCH 164/339] OSDOCS-10416: Support cluster migration to Entra Workload ID --- modules/cco-ccoctl-configuring.adoc | 51 +++- modules/cco-ccoctl-install-verifying.adoc | 69 ++++- ...ng-entra-workload-id-existing-cluster.adoc | 249 ++++++++++++++++++ .../cluster-tasks.adoc | 22 ++ 4 files changed, 365 insertions(+), 26 deletions(-) create mode 100644 modules/enabling-entra-workload-id-existing-cluster.adoc diff --git a/modules/cco-ccoctl-configuring.adoc b/modules/cco-ccoctl-configuring.adoc index 727a6b8d1253..635d49f47fc5 100644 --- a/modules/cco-ccoctl-configuring.adoc +++ b/modules/cco-ccoctl-configuring.adoc @@ -1,11 +1,14 @@ // Module included in the following assemblies: // +//Postinstall and update content +// * post_installation_configuration/cluster-tasks.adoc +// * updating/preparing_for_updates/preparing-manual-creds-update.adoc +// //Platforms that must use `ccoctl` and update content // * installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc // * installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.doc // * installing/installing_alibaba/manually-creating-alibaba-ram.adoc // * installing/installing_nutanix/preparing-to-install-on-nutanix.adoc -// * updating/preparing_for_updates/preparing-manual-creds-update.adoc // // AWS assemblies: // * installing/installing_aws/installing-aws-customizations.adoc @@ -34,7 +37,15 @@ // * installing/installing_azure/installing-azure-vnet.adoc // * installing/installing_azure/installing-restricted-networks-azure-installer-provisioned.adoc -//Platforms that must use `ccoctl` and update content +//Postinstall and update content +ifeval::["{context}" == "post-install-cluster-tasks"] +:postinstall: +endif::[] +ifeval::["{context}" == "preparing-manual-creds-update"] +:update: +endif::[] + +//Platforms that must use `ccoctl` ifeval::["{context}" == "configuring-iam-ibm-cloud"] :ibm-cloud: endif::[] @@ -44,9 +55,6 @@ endif::[] ifeval::["{context}" == "preparing-to-install-on-nutanix"] :nutanix: endif::[] -ifeval::["{context}" == "preparing-manual-creds-update"] -:update: -endif::[] ifeval::["{context}" == "preparing-to-install-on-ibm-power-vs"] :ibm-power-vs: endif::[] @@ -138,10 +146,15 @@ ifdef::ibm-power-vs[] The Cloud Credential Operator (CCO) manages cloud provider credentials as Kubernetes custom resource definitions (CRDs). To install a cluster on {ibm-power-server-name}, you must set the CCO to `manual` mode as part of the installation process. endif::ibm-power-vs[] -//Alibaba Cloud uses ccoctl, but creates different kinds of resources than other clouds, so this applies to everyone else. The upgrade procs also have a different intro, so they are excluded here. -ifndef::alibabacloud,update[] +//Alibaba Cloud uses ccoctl, but creates different kinds of resources than other clouds, so this applies to everyone else. The upgrade and postinstall procs also have a different intro, so they are excluded here. +ifndef::alibabacloud,update,postinstall[] To create and manage cloud credentials from outside of the cluster when the Cloud Credential Operator (CCO) is operating in manual mode, extract and prepare the CCO utility (`ccoctl`) binary. -endif::alibabacloud,update[] +endif::alibabacloud,update,postinstall[] + +//Intro for the postinstall procs. +ifdef::postinstall[] +To configure an existing cluster to create and manage cloud credentials from outside of the cluster, extract and prepare the Cloud Credential Operator utility (`ccoctl`) binary. +endif::postinstall[] //Intro for the upgrade procs. ifdef::update[] @@ -317,14 +330,19 @@ endif::google-cloud-platform[] .Procedure -ifndef::update[] -. Obtain the {product-title} release image by running the following command: +. Set a variable for the {product-title} release image by running the following command: + [source,terminal] +ifndef::update,postinstall[] ---- $ RELEASE_IMAGE=$(./openshift-install version | awk '/release image/ {print $3}') ---- -endif::update[] +endif::update,postinstall[] +ifdef::update,postinstall[] +---- +$ RELEASE_IMAGE=$(oc get clusterversion -o jsonpath={..desired.image}) +---- +endif::update,postinstall[] . Obtain the CCO container image from the {product-title} release image by running the following command: + @@ -384,6 +402,14 @@ Flags: Use "ccoctl [command] --help" for more information about a command. ---- +//Postinstall and update content +ifeval::["{context}" == "post-install-cluster-tasks"] +:!postinstall: +endif::[] +ifeval::["{context}" == "preparing-manual-creds-update"] +:!update: +endif::[] + //Platforms that must use `ccoctl` and update content ifeval::["{context}" == "configuring-iam-ibm-cloud"] :!ibm-cloud: @@ -394,9 +420,6 @@ endif::[] ifeval::["{context}" == "preparing-to-install-on-nutanix"] :!nutanix: endif::[] -ifeval::["{context}" == "preparing-manual-creds-update"] -:!update: -endif::[] ifeval::["{context}" == "preparing-to-install-on-ibm-power-vs"] :!ibm-power-vs: endif::[] diff --git a/modules/cco-ccoctl-install-verifying.adoc b/modules/cco-ccoctl-install-verifying.adoc index 1226e3d4104d..26f40cc6d7c6 100644 --- a/modules/cco-ccoctl-install-verifying.adoc +++ b/modules/cco-ccoctl-install-verifying.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // // * installing/validating-an-installation.adoc +// * post_installation_configuration/cluster-tasks.adoc :_mod-docs-content-type: PROCEDURE [id="cco-ccoctl-install-verifying_{context}"] -= Clusters that use short-term credentials: Verifying the credentials configuration += Verifying that a cluster uses short-term credentials -You can verify that your cluster is using short-term security credentials for individual components. +You can verify that a cluster uses short-term security credentials for individual components by checking the Cloud Credential Operator (CCO) configuration and other values in the cluster. .Prerequisites @@ -14,16 +15,32 @@ You can verify that your cluster is using short-term security credentials for in * You installed the {oc-first}. +* You are logged in as a user with `cluster-admin` privileges. .Procedure -. Log in as a user with `cluster-admin` privileges. +* Verify that the CCO is configured to operate in manual mode by running the following command: ++ +[source,terminal] +---- +$ oc get cloudcredentials cluster \ + -o=jsonpath={.spec.credentialsMode} +---- ++ +The following output confirms that the CCO is operating in manual mode: ++ +.Example output +[source,text] +---- +Manual +---- -. Verify that the cluster does not have `root` credentials by running the following command: +* Verify that the cluster does not have `root` credentials by running the following command: + [source,terminal] ---- -$ oc get secrets -n kube-system +$ oc get secrets \ + -n kube-system ---- + where `` is the name of the root secret for your cloud provider. @@ -33,26 +50,26 @@ where `` is the name of the root secret for your cloud provider. |Platform |Secret name -|AWS +|{aws-first} |`aws-creds` -|Azure +|{azure-first} |`azure-credentials` -|GCP +|{gcp-first} |`gcp-credentials` |=== + -An error confirms that the root secret is not present on the cluster. The following example shows the expected output from an AWS cluster: +An error confirms that the root secret is not present on the cluster. + -.Example output +.Example output for an {aws-short} cluster [source,text] ---- Error from server (NotFound): secrets "aws-creds" not found ---- -. Verify that the components are using short-term security credentials for individual components by running the following command: +* Verify that the components are using short-term security credentials for individual components by running the following command: + [source,terminal] ---- @@ -61,4 +78,32 @@ $ oc get authentication cluster \ --template='{ .spec.serviceAccountIssuer }' ---- + -This command displays the value of the `.spec.serviceAccountIssuer` parameter in the cluster `Authentication` object. An output of a URL that is associated with your cloud provider indicates that the cluster is using manual mode with short-term credentials that are created and managed from outside of the cluster. \ No newline at end of file +This command displays the value of the `.spec.serviceAccountIssuer` parameter in the cluster `Authentication` object. +An output of a URL that is associated with your cloud provider indicates that the cluster is using manual mode with short-term credentials that are created and managed from outside of the cluster. + +* {azure-short} clusters: Verify that the components are assuming the {azure-short} client ID that is specified in the secret manifests by running the following command: ++ +[source,terminal] +---- +$ oc get secrets \ + -n openshift-image-registry installer-cloud-credentials \ + -o jsonpath='{.data}' +---- ++ +An output that contains the `azure_client_id` and `azure_federated_token_file` felids confirms that the components are assuming the {azure-short} client ID. + +* {azure-short} clusters: Verify that the pod identity webhook is running by running the following command: ++ +[source,terminal] +---- +$ oc get pods \ + -n openshift-cloud-credential-operator +---- ++ +.Example output +[source,text] +---- +NAME READY STATUS RESTARTS AGE +cloud-credential-operator-59cf744f78-r8pbq 2/2 Running 2 71m +pod-identity-webhook-548f977b4c-859lz 1/1 Running 1 70m +---- \ No newline at end of file diff --git a/modules/enabling-entra-workload-id-existing-cluster.adoc b/modules/enabling-entra-workload-id-existing-cluster.adoc new file mode 100644 index 000000000000..3bef1bf59627 --- /dev/null +++ b/modules/enabling-entra-workload-id-existing-cluster.adoc @@ -0,0 +1,249 @@ +// Module included in the following assemblies: +// +// * post_installation_configuration/cluster-tasks.adoc + +:_mod-docs-content-type: PROCEDURE +[id="enabling-entra-workload-id-existing-cluster_{context}"] += Enabling {entra-first} on an existing cluster + +If you did not configure your {azure-first} {product-title} cluster to use {entra-first} during installation, you can enable this authentication method on an existing cluster. + +[IMPORTANT] +==== +The process to enable {entra-short} on an existing cluster is disruptive and takes a significant amount of time. +Before proceeding, observe the following considerations: + +* Read the following steps and ensure that you understand and accept the time requirement. +The exact time requirement varies depending on the individual cluster, but it is likely to require at least one hour. + +* During this process, you must refresh all service accounts and restart all pods on the cluster. +These actions are disruptive to workloads. +To mitigate this impact, you can temporarily halt these services and then redeploy them when the cluster is ready. + +* After starting this process, do not attempt to update the cluster until it is complete. +If an update is triggered, the process to enable {entra-short} on an existing cluster fails. +==== + +.Prerequisites + +* You have installed an {product-title} cluster on {azure-first}. +* You have access to the cluster using an account with `cluster-admin` permissions. +* You have installed the {oc-first}. +* You have extracted and prepared the Cloud Credential Operator utility (`ccoctl`) binary. +* You have access to your {azure-short} account by using the {azure-short} CLI (`az`). + +.Procedure + +. Create an output directory for the manifests that the `ccoctl` utility generates. +This procedure uses `./output_dir` as an example. + +. Extract the service account public signing key for the cluster to the output directory by running the following command: ++ +[source,terminal] +---- +$ oc get configmap \ + --namespace openshift-kube-apiserver bound-sa-token-signing-certs \ + --output 'go-template={{index .data "service-account-001.pub"}}' > ./output_dir/serviceaccount-signer.public <1> +---- +<1> This procedure uses a file named `serviceaccount-signer.public` as an example. + +. Use the extracted service account public signing key to create an OpenID Connect (OIDC) issuer and {azure-short} blob storage container with OIDC configuration files by running the following command: ++ +[source,terminal] +---- +$ ./ccoctl azure create-oidc-issuer \ + --name \// <1> + --output-dir ./output_dir \ + --region \// <2> + --subscription-id \// <3> + --tenant-id \ + --public-key-file ./output_dir/serviceaccount-signer.public <4> +---- +<1> The value of the `name` parameter is used to create an Azure resource group. +To use an existing Azure resource group instead of creating a new one, specify the `--oidc-resource-group-name` argument with the existing group name as its value. +<2> Specify the region of the existing cluster. +<3> Specify the subscription ID of the existing cluster. +<4> Specify the file that contains the service account public signing key for the cluster. + +. Verify that the configuration file for the Azure pod identity webhook was created by running the following command: ++ +[source,terminal] +---- +$ ll ./output_dir/manifests +---- ++ +.Example output ++ +[source,text] +---- +total 8 +-rw-------. 1 cloud-user cloud-user 193 May 22 02:29 azure-ad-pod-identity-webhook-config.yaml <1> +-rw-------. 1 cloud-user cloud-user 165 May 22 02:29 cluster-authentication-02-config.yaml +---- +<1> The file `azure-ad-pod-identity-webhook-config.yaml` contains the Azure pod identity webhook configuration. + +. Set an `OIDC_ISSUER_URL` variable with the OIDC issuer URL from the generated manifests in the output directory by running the following command: ++ +[source,terminal] +---- +$ OIDC_ISSUER_URL=`awk '/serviceAccountIssuer/ { print $2 }' ./output_dir/manifests/cluster-authentication-02-config.yaml` +---- + +. Update the `spec.serviceAccountIssuer` parameter of the cluster `authentication` configuration by running the following command: ++ +[source,terminal] +---- +$ oc patch authentication cluster \ + --type=merge \ + -p "{\"spec\":{\"serviceAccountIssuer\":\"${OIDC_ISSUER_URL}\"}}" +---- + +. Monitor the configuration update progress by running the following command: ++ +[source,terminal] +---- +$ oc adm wait-for-stable-cluster +---- ++ +This process might take 15 minutes or longer. +The following output indicates that the process is complete: ++ +[source,text] +---- +All clusteroperators are stable +---- + +. Restart all of the pods in the cluster by running the following command: ++ +[source,terminal] +---- +$ oc adm reboot-machine-config-pool mcp/worker mcp/master +---- ++ +Restarting a pod updates the `serviceAccountIssuer` field and refreshes the service account public signing key. + +. Monitor the restart and update process by running the following command: ++ +[source,terminal] +---- +$ oc adm wait-for-node-reboot nodes --all +---- ++ +This process might take 15 minutes or longer. +The following output indicates that the process is complete: ++ +[source,text] +---- +All nodes rebooted +---- + +. Update the Cloud Credential Operator `spec.credentialsMode` parameter to `Manual` by running the following command: ++ +[source,terminal] +---- +$ oc patch cloudcredential cluster \ + --type=merge \ + --patch '{"spec":{"credentialsMode":"Manual"}}' +---- + +. Extract the list of `CredentialsRequest` objects from the {product-title} release image by running the following command: ++ +[source,terminal] +---- +$ oc adm release extract \ + --credentials-requests \ + --included \ + --to \ + --registry-config ~/.pull-secret +---- ++ +[NOTE] +==== +This command might take a few moments to run. +==== + +. Set an `AZURE_INSTALL_RG` variable with the {azure-short} resource group name by running the following command: ++ +[source,terminal] +---- +$ AZURE_INSTALL_RG=`oc get infrastructure cluster -o jsonpath --template '{ .status.platformStatus.azure.resourceGroupName }'` +---- + +. Use the `ccoctl` utility to create managed identities for all `CredentialsRequest` objects by running the following command: ++ +[source,terminal] +---- +$ ccoctl azure create-managed-identities \ + --name \ + --output-dir ./output_dir \ + --region \ + --subscription-id \ + --credentials-requests-dir \ + --issuer-url "${OIDC_ISSUER_URL}" \ + --dnszone-resource-group-name \// <1> + --installation-resource-group-name "${AZURE_INSTALL_RG}" +---- +<1> Specify the name of the resource group that contains the DNS zone. + +. Apply the {azure-short} pod identity webhook configuration for {entra-short} by running the following command: ++ +[source,terminal] +---- +$ oc apply -f ./output_dir/manifests/azure-ad-pod-identity-webhook-config.yaml +---- + +. Apply the secrets generated by the `ccoctl` utility by running the following command: ++ +[source,terminal] +---- +$ find ./output_dir/manifests -iname "openshift*yaml" -print0 | xargs -I {} -0 -t oc replace -f {} +---- ++ +This process might take several minutes. + + +. Restart all of the pods in the cluster by running the following command: ++ +[source,terminal] +---- +$ oc adm reboot-machine-config-pool mcp/worker mcp/master +---- ++ +Restarting a pod updates the `serviceAccountIssuer` field and refreshes the service account public signing key. + +. Monitor the restart and update process by running the following command: ++ +[source,terminal] +---- +$ oc adm wait-for-node-reboot nodes --all +---- ++ +This process might take 15 minutes or longer. +The following output indicates that the process is complete: ++ +[source,text] +---- +All nodes rebooted +---- + +. Monitor the configuration update progress by running the following command: ++ +[source,terminal] +---- +$ oc adm wait-for-stable-cluster +---- ++ +This process might take 15 minutes or longer. +The following output indicates that the process is complete: ++ +[source,text] +---- +All clusteroperators are stable +---- + +. Optional: Remove the {azure-short} root credentials secret by running the following command: ++ +[source,terminal] +---- +$ oc delete secret -n kube-system azure-credentials +---- \ No newline at end of file diff --git a/post_installation_configuration/cluster-tasks.adoc b/post_installation_configuration/cluster-tasks.adoc index 682b17fa7ff1..052ad07aa9dc 100644 --- a/post_installation_configuration/cluster-tasks.adoc +++ b/post_installation_configuration/cluster-tasks.adoc @@ -717,6 +717,28 @@ include::modules/manually-removing-cloud-creds.adoc[leveloffset=+2] * xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#about-cloud-credential-operator[About the Cloud Credential Operator] * xref:../authentication/managing_cloud_provider_credentials/cco-mode-passthrough.adoc#admin-credentials-root-secret-formats_cco-mode-passthrough[Admin credentials root secret format] +[id="post-install-enable-token-auth"] +== Enabling token-based authentication +//Today, just Entra. But this should be a section that anticipates the addition of AWS STS and GCP WID. + +After installing an {azure-first} {product-title} cluster, you can enable {entra-first} to use short-term credentials. + +To determine which cloud credentials strategy your cluster uses, see xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#cco-determine-mode_about-cloud-credential-operator[Determining the Cloud Credential Operator mode]. + +//Configuring the Cloud Credential Operator utility +include::modules/cco-ccoctl-configuring.adoc[leveloffset=+2] + +//Enabling {entra-first} on an existing cluster +include::modules/enabling-entra-workload-id-existing-cluster.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources +* xref:../authentication/managing_cloud_provider_credentials/cco-short-term-creds.adoc#cco-short-term-creds-azure_cco-short-term-creds[Microsoft Entra Workload ID] +* xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-with-short-term-creds_installing-azure-customizations[Configuring an Azure cluster to use short-term credentials] + +//Verifying the credentials configuration +include::modules/cco-ccoctl-install-verifying.adoc[leveloffset=+2] + [id="post-install-must-gather-disconnected"] == Configuring image streams for a disconnected cluster From 1d4edd58598216044d2e28c1a36fc094e28f32a2 Mon Sep 17 00:00:00 2001 From: Laura Hinson Date: Tue, 11 Jun 2024 13:32:38 -0400 Subject: [PATCH 165/339] [OSDOCS-10861]: Adding database sizing requirements to etcd docs --- modules/etcd-increase-db.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/etcd-increase-db.adoc b/modules/etcd-increase-db.adoc index 6ea6338ea666..7d2f39563a34 100644 --- a/modules/etcd-increase-db.adoc +++ b/modules/etcd-increase-db.adoc @@ -12,7 +12,9 @@ You might want to increase the disk quota if you encounter a `low space` alert. Another scenario where you might want to increase the disk quota is if you encounter an `excessive database growth` alert. This alert is a warning that the database might grow too large in the next four hours. In this scenario, consider increasing the disk quota so that you do not eventually encounter a `low space` alert and possible write fails. -When you increase the disk quota, the amount of space that you specify is not immediately reserved. Instead, etcd can grow to that size if needed. Ensure that etcd is running on a dedicated disk that is larger than the value that you specify for the disk quota. +If you increase the disk quota, the disk space that you specify is not immediately reserved. Instead, etcd can grow to that size if needed. Ensure that etcd is running on a dedicated disk that is larger than the value that you specify for the disk quota. + +For large etcd databases, the control plane nodes must have additional memory and storage. Because you must account for the API server cache, the minimum memory required is at least three times the configured size of the etcd database. :FeatureName: Increasing the database size for etcd include::snippets/technology-preview.adoc[] From 70a686a6a1cc9aa9a1a01cd09978dba67a78d352 Mon Sep 17 00:00:00 2001 From: Shane Lovern Date: Fri, 3 May 2024 15:20:24 +0100 Subject: [PATCH 166/339] TELCODOCS-1682 - MetalLB - FRRK8s integration --- _topic_maps/_topic_map.yml | 2 + ...nShift MetalLB_FRRK8s integration_0624.png | Bin 0 -> 50249 bytes modules/nw-metallb-configuring-frr-8ks.adoc | 30 ++ modules/nw-metallb-frr-configurations.adoc | 59 +++ .../nw-metallb-frr-k8s-configuration-crd.adoc | 408 ++++++++++++++++++ ...frr-k8s-merge-multiple-configurations.adoc | 46 ++ networking/metallb/metallb-frr-k8s.adoc | 30 ++ 7 files changed, 575 insertions(+) create mode 100644 images/695_OpenShift MetalLB_FRRK8s integration_0624.png create mode 100644 modules/nw-metallb-configuring-frr-8ks.adoc create mode 100644 modules/nw-metallb-frr-configurations.adoc create mode 100644 modules/nw-metallb-frr-k8s-configuration-crd.adoc create mode 100644 modules/nw-metallb-frr-k8s-merge-multiple-configurations.adoc create mode 100644 networking/metallb/metallb-frr-k8s.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 6f8b16481e15..803765f42eb6 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1619,6 +1619,8 @@ Topics: File: metallb-configure-services - Name: Managing symmetric routing with MetalLB File: metallb-configure-return-traffic + - Name: Configuring the integration of MetalLB and FRR-K8s + File: metallb-frr-k8s - Name: MetalLB logging, troubleshooting, and support File: metallb-troubleshoot-support - Name: Associating secondary interfaces metrics to network attachments diff --git a/images/695_OpenShift MetalLB_FRRK8s integration_0624.png b/images/695_OpenShift MetalLB_FRRK8s integration_0624.png new file mode 100644 index 0000000000000000000000000000000000000000..301f53b56d91187527caaffb77d46ba8a2d42db6 GIT binary patch literal 50249 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 literal 0 HcmV?d00001 diff --git a/modules/nw-metallb-configuring-frr-8ks.adoc b/modules/nw-metallb-configuring-frr-8ks.adoc new file mode 100644 index 000000000000..34697a818166 --- /dev/null +++ b/modules/nw-metallb-configuring-frr-8ks.adoc @@ -0,0 +1,30 @@ +// Module included in the following assemblies: +// +// * networking/metallb/metallb-frr-k8s.adoc + +:_mod-docs-content-type: PROCEDURE +[id="nw-metallb-configuring-frr-k8s_{context}"] += Activating the integration of MetalLB and FRR-K8s + +The following procedure shows you how to activate `FRR-K8s` as the backend for `MetalLB`. + +.Prerequisites + +* You have a cluster installed on bare-metal hardware. +* You have installed the OpenShift CLI (`oc`). +* You have logged in as a user with `cluster-admin` privileges. + +.Procedure + +* Set the `bgpBackend` field of the `MetalLB` CR to `frr-k8s` as in the following example: ++ +[source,yaml] +---- +apiVersion: metallb.io/v1beta1 +kind: MetalLB +metadata: + name: metallb + namespace: metallb-system +spec: + bgpBackend: frr-k8s +---- \ No newline at end of file diff --git a/modules/nw-metallb-frr-configurations.adoc b/modules/nw-metallb-frr-configurations.adoc new file mode 100644 index 000000000000..a449e8e71588 --- /dev/null +++ b/modules/nw-metallb-frr-configurations.adoc @@ -0,0 +1,59 @@ +// Module included in the following assemblies: +// +// * networking/metallb/metallb-frr-k8s.adoc + +:_mod-docs-content-type: REFERENCE +[id="nw-metallb-configuring-frr-k8s-configuratons_{context}"] += FRR configurations + +You can create multiple `FRRConfiguration` CRs to use `FRR` services in `MetalLB`. +`MetalLB` generates an `FRRConfiguration` object which `FRR-K8s` merges with all other configurations that all users have created. + +For example, you can configure `FRR-K8s` to receive all of the prefixes advertised by a given neighbor. +The following example configures `FRR-K8s` to receive all of the prefixes advertised by a `BGPPeer` with host `172.18.0.5`: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: metallb-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.18.0.5 + asn: 64512 + toReceive: + allowed: + mode: all +---- + +You can also configure FRR-K8s to always block a set of prefixes, regardless of the configuration applied. +This can be useful to avoid routes towards the pods or `ClusterIPs` CIDRs that might result in cluster malfunctions. +The following example blocks the set of prefixes `192.168.1.0/24`: + +.Example MetalLB CR +[source,yaml] +---- +apiVersion: metallb.io/v1beta1 +kind: MetalLB +metadata: + name: metallb + namespace: metallb-system +spec: + bgpBackend: frr-k8s + frrk8sConfig: + alwaysBlock: + - 192.168.1.0/24 +---- +You can set `FRR-K8s` to block the `Cluster Network` CIDR and `Service Network` CIDR. +You can view the values for these CIDR address specifications by running the following command: + +[source,terminal] +---- +$ oc describe network.config/cluster +---- \ No newline at end of file diff --git a/modules/nw-metallb-frr-k8s-configuration-crd.adoc b/modules/nw-metallb-frr-k8s-configuration-crd.adoc new file mode 100644 index 000000000000..45c46717bccf --- /dev/null +++ b/modules/nw-metallb-frr-k8s-configuration-crd.adoc @@ -0,0 +1,408 @@ +// Module included in the following assemblies: +// +// * networking/metallb/metallb-frr-k8s.adoc + +:_mod-docs-content-type: REFERENCE +[id="nw-metallb-frrconfiguration-crd_{context}"] += Configuring the FRRConfiguration CRD + +The following section provides reference examples that use the `FRRConfiguration` custom resource (CR). + +[id="nw-metallb-frrconfiguration-crd-routers_{context}"] +== The routers field + +You can use the `routers` field to configure multiple routers, one for each Virtual Routing and Forwarding (VRF) resource. +For each router, you must define the Autonomous System Number (ASN). + +You can also define a list of Border Gateway Protocol (BGP) neighbors to connect to, as in the following example: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.30.0.3 + asn: 4200000000 + ebgpMultiHop: true + port: 180 + - address: 172.18.0.6 + asn: 4200000000 + port: 179 +---- + +[id="nw-metallb-frrconfiguration-crd-toadvertise_{context}"] +== The toAdvertise field + +By default, `FRR-K8s` does not advertise the prefixes configured as part of a router configuration. +In order to advertise them, you use the `toAdvertise` field. + +You can advertise a subset of the prefixes, as in the following example: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.30.0.3 + asn: 4200000000 + ebgpMultiHop: true + port: 180 + toAdvertise: + allowed: + prefixes: <1> + - 192.168.2.0/24 + prefixes: + - 192.168.2.0/24 + - 192.169.2.0/24 +---- +<1> Advertises a subset of prefixes. + +The following example shows you how to advertise all of the prefixes: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.30.0.3 + asn: 4200000000 + ebgpMultiHop: true + port: 180 + toAdvertise: + allowed: + mode: all <1> + prefixes: + - 192.168.2.0/24 + - 192.169.2.0/24 +---- +<1> Advertises all prefixes. + +[id="nw-metallb-frrconfiguration-crd-toreceive_{context}"] +== The toReceive field + +By default, `FRR-K8s` does not process any prefixes advertised by a neighbor. +You can use the `toReceive` field to process such addresses. + +You can configure for a subset of the prefixes, as in this example: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.18.0.5 + asn: 64512 + port: 179 + toReceive: + allowed: + prefixes: + - prefix: 192.168.1.0/24 + - prefix: 192.169.2.0/24 + ge: 25 <1> + le: 28 <1> +---- +<1> The prefix is applied if the prefix length is less than or equal to the `le` prefix length and greater than or equal to the `ge` prefix length. + +The following example configures FRR to handle all the prefixes announced: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.18.0.5 + asn: 64512 + port: 179 + toReceive: + allowed: + mode: all +---- + +[id="nw-metallb-frrconfiguration-crd-bgp_{context}"] +== The bgp field + +You can use the `bgp` field to define various `BFD` profiles and associate them with a neighbor. +In the following example, `BFD` backs up the `BGP` session and `FRR` can detect link failures: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + neighbors: + - address: 172.30.0.3 + asn: 64512 + port: 180 + bfdProfile: defaultprofile + bfdProfiles: + - name: defaultprofile +---- + +[id="nw-metallb-frrconfiguration-crd-nodeselector_{context}"] +== The nodeSelector field + +By default, `FRR-K8s` applies the configuration to all nodes where the daemon is running. +You can use the `nodeSelector` field to specify the nodes to which you want to apply the configuration. For example: + +.Example FRRConfiguration CR +[source,yaml] +---- +apiVersion: frrk8s.metallb.io/v1beta1 +kind: FRRConfiguration +metadata: + name: test + namespace: frr-k8s-system +spec: + bgp: + routers: + - asn: 64512 + nodeSelector: + labelSelector: + foo: "bar" +---- + +The fields for the `FRRConfiguration` custom resource are described in the following table: + +.MetalLB FRRConfiguration custom resource +[cols="1,1,3a", options="header"] +|=== + +|Field +|Type +|Description + +|`spec.bgp.routers` +|`array` +|Specifies the routers that FRR is to configure (one per VRF). + +|`spec.bgp.routers.asn` +|`integer` +|The autonomous system number to use for the local end of the session. + +|`spec.bgp.routers.id` +|`string` +|Specifies the ID of the `bgp` router. + +|`spec.bgp.routers.vrf` +|`string` +|Specifies the host vrf used to establish sessions from this router. + +|`spec.bgp.routers.neighbors` +|`array` +|Specifies the neighbors to establish BGP sessions with. + +|`spec.bgp.routers.neighbors.asn` +|`integer` +|Specifies the autonomous system number to use for the local end of the session. + +|`spec.bgp.routers.neighbors.address` +|`string` +|Specifies the IP address to establish the session with. + +|`spec.bgp.routers.neighbors.port` +|`integer` +|Specifies the port to dial when establishing the session. +Defaults to 179. + +|`spec.bgp.routers.neighbors.password` +|`string` +|Specifies the password to use for establishing the BGP session. +`Password` and `PasswordSecret` are mutually exclusive. + +|`spec.bgp.routers.neighbors.passwordSecret` +|`string` +|Specifies the name of the authentication secret for the neighbor. +The secret must be of type "kubernetes.io/basic-auth", and in the same namespace as the FRR-K8s daemon. +The key "password" stores the password in the secret. +`Password` and `PasswordSecret` are mutually exclusive. + +|`spec.bgp.routers.neighbors.holdTime` +|`duration` +|Specifies the requested BGP hold time, per RFC4271. +Defaults to 180s. + +|`spec.bgp.routers.neighbors.keepaliveTime` +|`duration` +|Specifies the requested BGP keepalive time, per RFC4271. +Defaults to `60s`. + +|`spec.bgp.routers.neighbors.connectTime` +|`duration` +|Specifies how long BGP waits between connection attempts to a neighbor. + +|`spec.bgp.routers.neighbors.ebgpMultiHop` +|`boolean` +|Indicates if the BGPPeer is multi-hops away. + +|`spec.bgp.routers.neighbors.bfdProfile` +|`string` +|Specifies the name of the BFD Profile to use for the BFD session associated with the BGP session. +If not set, the BFD session is not set up. + +|`spec.bgp.routers.neighbors.toAdvertise.allowed` +|`array` +|Represents the list of prefixes to advertise to a neighbor, and the associated properties. + +|`spec.bgp.routers.neighbors.toAdvertise.allowed.prefixes` +|`string array` +|Specifies the list of prefixes to advertise to a neighbor. +This list must match the prefixes that you define in the router. + +|`spec.bgp.routers.neighbors.toAdvertise.allowed.mode` +|`string` +|Specifies the mode to use when handling the prefixes. +You can set to `filtered` to allow only the prefixes in the prefixes list. +You can set to `all` to allow all the prefixes configured on the router. + +|`spec.bgp.routers.neighbors.toAdvertise.withLocalPref` +|`array` +|Specifies the prefixes associated with an advertised local preference. +You must specify the prefixes associated with a local preference in the prefixes allowed to be advertised. + +|`spec.bgp.routers.neighbors.toAdvertise.withLocalPref.prefixes` +|`string array` +|Specifies the prefixes associated with the local preference. + +|`spec.bgp.routers.neighbors.toAdvertise.withLocalPref.localPref` +|`integer` +|Specifies the local preference associated with the prefixes. + +|`spec.bgp.routers.neighbors.toAdvertise.withCommunity` +|`array` +|Specifies the prefixes associated with an advertised BGP community. +You must include the prefixes associated with a local preference in the list of prefixes that you want to advertise. + +|`spec.bgp.routers.neighbors.toAdvertise.withCommunity.prefixes` +|`string array` +|Specifies the prefixes associated with the community. + +|`spec.bgp.routers.neighbors.toAdvertise.withCommunity.community` +|`string` +|Specifies the community associated with the prefixes. + +|`spec.bgp.routers.neighbors.toReceive` +|`array` +|Specifies the prefixes to receive from a neighbor. + +|`spec.bgp.routers.neighbors.toReceive.allowed` +|`array` +|Specifies the information that you want to receive from a neighbor. + +|`spec.bgp.routers.neighbors.toReceive.allowed.prefixes` +|`array` +|Specifies the prefixes allowed from a neighbor. + +|`spec.bgp.routers.neighbors.toReceive.allowed.mode` +|`string` +|Specifies the mode to use when handling the prefixes. +When set to `filtered`, only the prefixes in the `prefixes` list are allowed. +When set to `all`, all the prefixes configured on the router are allowed. + +|`spec.bgp.routers.neighbors.disableMP` +|`boolean` +|Disables MP BGP to prevent it from separating IPv4 and IPv6 route exchanges into distinct BGP sessions. + +|`spec.bgp.routers.prefixes` +|`string array` +|Specifies all prefixes to advertise from this router instance. + +|`spec.bgp.bfdProfiles` +|`array` +|Specifies the list of bfd profiles to use when configuring the neighbors. + +|`spec.bgp.bfdProfiles.name` +|`string` +|The name of the BFD Profile to be referenced in other parts of the configuration. + +|`spec.bgp.bfdProfiles.receiveInterval` +|`integer` +|Specifies the minimum interval at which this system can receive control packets, in milliseconds. +Defaults to `300ms`. + +|`spec.bgp.bfdProfiles.transmitInterval` +|`integer` +|Specifies the minimum transmission interval, excluding jitter, that this system wants to use to send BFD control packets, in milliseconds. +Defaults to `300ms`. + +|`spec.bgp.bfdProfiles.detectMultiplier` +|`integer` +|Configures the detection multiplier to determine packet loss. +To determine the connection loss-detection timer, multiply the remote transmission interval by this value. + +|`spec.bgp.bfdProfiles.echoInterval` +|`integer` +|Configures the minimal echo receive transmission-interval that this system can handle, in milliseconds. +Defaults to `50ms`. + +|`spec.bgp.bfdProfiles.echoMode` +|`boolean` +|Enables or disables the echo transmission mode. +This mode is disabled by default, and not supported on multihop setups. + +|`spec.bgp.bfdProfiles.passiveMode` +|`boolean` +|Mark session as passive. A passive session does not attempt to start the connection and waits for control packets from peers before it begins replying. + +|`spec.bgp.bfdProfiles.MinimumTtl` +|`integer` +|For multihop sessions only. +Configures the minimum expected TTL for an incoming BFD control packet. + +|`spec.nodeSelector` +|`string` +|Limits the nodes that attempt to apply this configuration. +If specified, only those nodes whose labels match the specified selectors attempt to apply the configuration. +If it is not specified, all nodes attempt to apply this configuration. + +|`status` +|`string` +|Defines the observed state of FRRConfiguration. + +|=== diff --git a/modules/nw-metallb-frr-k8s-merge-multiple-configurations.adoc b/modules/nw-metallb-frr-k8s-merge-multiple-configurations.adoc new file mode 100644 index 000000000000..d9439e2a585f --- /dev/null +++ b/modules/nw-metallb-frr-k8s-merge-multiple-configurations.adoc @@ -0,0 +1,46 @@ +// Module included in the following assemblies: +// +// * networking/metallb/metallb-frr-k8s.adoc + +:_mod-docs-content-type: REFERENCE +[id="nw-metallb-frr-k8s-merge-multiple-configurations_{context}"] += How FRR-K8s merges multiple configurations + +In a case where multiple users add configurations that select the same node, `FRR-K8s` merges the configurations. +Each configuration can only extend others. +This means that it is possible to add a new neighbor to a router, or to advertise an additional prefix to a neighbor, but not possible to remove a component added by another configuration. + +[id="nw-metallb-frr-k8s-merge-multiple-configuration-conflicts_{context}"] +== Configuration conflicts + +Certain configurations can cause conflicts, leading to errors, for example: + +* different ASN for the same router (in the same VRF) +* different ASN for the same neighbor (with the same IP / port) +* multiple BFD profiles with the same name but different values + +When the daemon finds an invalid configuration for a node, it reports the configuration as invalid and reverts to the previous valid `FRR` configuration. + +[id="nw-metallb-frr-k8s-merge-multiple-configurations-merging_{context}"] +== Merging + +When merging, it is possible to do the following actions: + +* Extend the set of IPs that you want to advertise to a neighbor. +* Add an extra neighbor with its set of IPs. +* Extend the set of IPs to which you want to associate a community. +* Allow incoming routes for a neighbor. + +Each configuration must be self contained. This means, for example, that it is not possible to allow prefixes that are not defined in the router section by leveraging prefixes coming from another configuration. + +If the configurations to be applied are compatible, merging works as follows: + +* `FRR-K8s` combines all the routers. +* `FRR-K8s` merges all prefixes and neighbors for each router. +* `FRR-K8s` merges all filters for each neighbor. + +[NOTE] +==== +A less restrictive filter has precedence over a stricter one. For example, a filter accepting some prefixes has precedence over a filter not accepting any, and a filter accepting all prefixes has precedence over one that accepts some. +==== + diff --git a/networking/metallb/metallb-frr-k8s.adoc b/networking/metallb/metallb-frr-k8s.adoc new file mode 100644 index 000000000000..ba98590e8826 --- /dev/null +++ b/networking/metallb/metallb-frr-k8s.adoc @@ -0,0 +1,30 @@ +:_mod-docs-content-type: ASSEMBLY +[id="metallb-configure-frr-k8s"] += Configuring the integration of MetalLB and FRR-K8s +include::_attributes/common-attributes.adoc[] +:context: configure-metallb-frr-k8s + +toc::[] + +:FeatureName: The `FRRConfiguration` custom resource +include::snippets/technology-preview.adoc[] + +FRRouting (FRR) is a free, open source internet routing protocol suite for Linux and UNIX platforms. +`FRR-K8s` is a Kubernetes based DaemonSet that exposes a subset of the `FRR` API in a Kubernetes-compliant manner. +As a cluster administrator, you can use the `FRRConfiguration` custom resource (CR) to configure `MetalLB` to use `FRR-K8s` as the backend. +You can use this to avail of FRR services, for example, receiving routes. +If you run `MetalLB` with `FRR-K8s` as a backend, `MetalLB` generates the `FRR-K8s` configuration corresponding to the MetalLB configuration applied. + +image::695_OpenShift MetalLB_FRRK8s integration_0624.png[MetalLB integration with FRR] + +// Activating integration of MetalLB and FRR-K8s +include::modules/nw-metallb-configuring-frr-8ks.adoc[leveloffset=+1] + +// FRR configurations +include::modules/nw-metallb-frr-configurations.adoc[leveloffset=+1] + +// The FRRConfiguration CRD +include::modules/nw-metallb-frr-k8s-configuration-crd.adoc[leveloffset=+1] + +//How multiple configurations are merged together +include::modules/nw-metallb-frr-k8s-merge-multiple-configurations.adoc[leveloffset=+1] From c0866bc735290c199e12646dd491e91148f4eb3a Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Thu, 30 May 2024 12:47:38 -0400 Subject: [PATCH 167/339] OSDOCS-5779: vSphere CAPI TP --- _topic_maps/_topic_map.yml | 2 + .../cluster-api-about.adoc | 2 +- .../cluster-api-configuration.adoc | 4 +- .../cluster-api-getting-started.adoc | 5 +- .../cluster-api-managing-machines.adoc | 4 +- .../cluster-api-config-options-vsphere.adoc | 37 +++++++++++ modules/capi-creating-cluster-resource.adoc | 1 + ...capi-creating-infrastructure-resource.adoc | 3 +- modules/capi-creating-machine-template.adoc | 1 + modules/capi-limitations.adoc | 2 +- modules/capi-modifying-machine-template.adoc | 1 + modules/capi-yaml-cluster.adoc | 17 +++-- modules/capi-yaml-infrastructure-aws.adoc | 7 +- modules/capi-yaml-infrastructure-gcp.adoc | 7 +- modules/capi-yaml-infrastructure-vsphere.adoc | 38 +++++++++++ modules/capi-yaml-machine-set-aws.adoc | 7 +- modules/capi-yaml-machine-set-gcp.adoc | 7 +- modules/capi-yaml-machine-set-vsphere.adoc | 64 +++++++++++++++++++ modules/capi-yaml-machine-template-aws.adoc | 13 ++-- modules/capi-yaml-machine-template-gcp.adoc | 13 ++-- .../capi-yaml-machine-template-vsphere.adoc | 59 +++++++++++++++++ modules/cluster-capi-operator.adoc | 12 +++- ...l-vsphere-zones-regions-configuration.adoc | 2 +- 23 files changed, 273 insertions(+), 35 deletions(-) create mode 100644 machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc create mode 100644 modules/capi-yaml-infrastructure-vsphere.adoc create mode 100644 modules/capi-yaml-machine-set-vsphere.adoc create mode 100644 modules/capi-yaml-machine-template-vsphere.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 803765f42eb6..74bcc141ecf0 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2341,6 +2341,8 @@ Topics: File: cluster-api-config-options-aws - Name: Cluster API configuration options for Google Cloud Platform File: cluster-api-config-options-gcp + - Name: Cluster API configuration options for VMware vSphere + File: cluster-api-config-options-vsphere # - Name: Cluster API resiliency and recovery # File: cluster-api-resiliency - Name: Troubleshooting Cluster API clusters diff --git a/machine_management/cluster_api_machine_management/cluster-api-about.adoc b/machine_management/cluster_api_machine_management/cluster-api-about.adoc index 9e9973fadced..caf2bf4279e6 100644 --- a/machine_management/cluster_api_machine_management/cluster-api-about.adoc +++ b/machine_management/cluster_api_machine_management/cluster-api-about.adoc @@ -9,7 +9,7 @@ toc::[] :FeatureName: Managing machines with the Cluster API include::snippets/technology-preview.adoc[] -The link:https://cluster-api.sigs.k8s.io/[Cluster API] is an upstream project that is integrated into {product-title} as a Technology Preview for Amazon Web Services (AWS) and Google Cloud Platform (GCP). +The link:https://cluster-api.sigs.k8s.io/[Cluster API] is an upstream project that is integrated into {product-title} as a Technology Preview for {aws-first}, {gcp-first}, and {vmw-first}. //Cluster API overview include::modules/capi-overview.adoc[leveloffset=+1] diff --git a/machine_management/cluster_api_machine_management/cluster-api-configuration.adoc b/machine_management/cluster_api_machine_management/cluster-api-configuration.adoc index 9b021072efb7..088719c6fc9b 100644 --- a/machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +++ b/machine_management/cluster_api_machine_management/cluster-api-configuration.adoc @@ -22,4 +22,6 @@ For provider-specific configuration options for your cluster, see the following * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#cluster-api-config-options-aws[Cluster API configuration options for {aws-full}] -* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#cluster-api-config-options-gcp[Cluster API configuration options for {gcp-full}] \ No newline at end of file +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#cluster-api-config-options-gcp[Cluster API configuration options for {gcp-full}] + +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#cluster-api-config-options-vsphere[Cluster API configuration options for {vmw-full}] \ No newline at end of file diff --git a/machine_management/cluster_api_machine_management/cluster-api-getting-started.adoc b/machine_management/cluster_api_machine_management/cluster-api-getting-started.adoc index 9c7642f201fd..d1a4748f996f 100644 --- a/machine_management/cluster_api_machine_management/cluster-api-getting-started.adoc +++ b/machine_management/cluster_api_machine_management/cluster-api-getting-started.adoc @@ -33,6 +33,7 @@ include::modules/capi-creating-infrastructure-resource.adoc[leveloffset=+2] .Additional resources * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#capi-yaml-infrastructure-aws_cluster-api-config-options-aws[Sample YAML for a Cluster API infrastructure resource on {aws-full}] * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-infrastructure-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API infrastructure resource on {gcp-full}] +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#capi-yaml-infrastructure-vsphere_cluster-api-config-options-vsphere[Sample YAML for a Cluster API infrastructure resource on {vmw-full}] //Creating a Cluster API machine template include::modules/capi-creating-machine-template.adoc[leveloffset=+2] @@ -40,10 +41,12 @@ include::modules/capi-creating-machine-template.adoc[leveloffset=+2] .Additional resources * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#capi-yaml-machine-template-aws_cluster-api-config-options-aws[Sample YAML for a Cluster API machine template resource on {aws-full}] * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-template-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API machine template resource on {gcp-full}] +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#capi-yaml-machine-template-vsphere_cluster-api-config-options-vsphere[Sample YAML for a Cluster API machine template resource on {vmw-full}] //Creating a Cluster API compute machine set include::modules/capi-creating-machine-set.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#capi-yaml-machine-set-aws_cluster-api-config-options-aws[Sample YAML for a Cluster API compute machine set resource on {aws-full}] -* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-set-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API compute machine set resource on {gcp-full}] \ No newline at end of file +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-set-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API compute machine set resource on {gcp-full}] +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#capi-yaml-machine-set-vsphere_cluster-api-config-options-vsphere[Sample YAML for a Cluster API compute machine set resource on {vmw-full}] \ No newline at end of file diff --git a/machine_management/cluster_api_machine_management/cluster-api-managing-machines.adoc b/machine_management/cluster_api_machine_management/cluster-api-managing-machines.adoc index d912fb4bbe8b..606fcad55482 100644 --- a/machine_management/cluster_api_machine_management/cluster-api-managing-machines.adoc +++ b/machine_management/cluster_api_machine_management/cluster-api-managing-machines.adoc @@ -15,6 +15,7 @@ include::modules/capi-modifying-machine-template.adoc[leveloffset=+1] .Additional resources * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#capi-yaml-machine-template-aws_cluster-api-config-options-aws[Sample YAML for a Cluster API machine template resource on {aws-full}] * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-template-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API machine template resource on {gcp-full}] +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#capi-yaml-machine-template-vsphere_cluster-api-config-options-vsphere[Sample YAML for a Cluster API machine template resource on {vmw-full}] * xref:../../machine_management/cluster_api_machine_management/cluster-api-managing-machines.adoc#machineset-modifying_cluster-api-managing-machines[Modifying a compute machine set by using the CLI] //Modifying a compute machine set by using the CLI @@ -23,4 +24,5 @@ include::modules/machineset-modifying.adoc[leveloffset=+1,tag=!MAPI] [role="_additional-resources"] .Additional resources * xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc#capi-yaml-machine-set-aws_cluster-api-config-options-aws[Sample YAML for a Cluster API compute machine set resource on {aws-full}] -* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-set-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API compute machine set resource on {gcp-full}] \ No newline at end of file +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc#capi-yaml-machine-set-gcp_cluster-api-config-options-gcp[Sample YAML for a Cluster API compute machine set resource on {gcp-full}] +* xref:../../machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc#capi-yaml-machine-set-vsphere_cluster-api-config-options-vsphere[Sample YAML for a Cluster API compute machine set resource on {vmw-full}] \ No newline at end of file diff --git a/machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc b/machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc new file mode 100644 index 000000000000..d3eb50c59ae9 --- /dev/null +++ b/machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc @@ -0,0 +1,37 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cluster-api-config-options-vsphere"] += Cluster API configuration options for VMware vSphere +include::_attributes/common-attributes.adoc[] +:context: cluster-api-config-options-vsphere + +toc::[] + +:FeatureName: Managing machines with the Cluster API +include::snippets/technology-preview.adoc[] + +You can change the configuration of your {vmw-first} Cluster API machines by updating values in the Cluster API custom resource manifests. + +[id="cluster-api-sample-yaml-vsphere_{context}"] +== Sample YAML for configuring {vmw-full} clusters + +The following example YAML files show configurations for a {vmw-full} cluster. + +//Sample YAML for a CAPI vSphere infrastructure resource +include::modules/capi-yaml-infrastructure-vsphere.adoc[leveloffset=+2] + +//Sample YAML for CAPI vSphere machine template resource +include::modules/capi-yaml-machine-template-vsphere.adoc[leveloffset=+2] + +//Sample YAML for a CAPI vSphere compute machine set resource +include::modules/capi-yaml-machine-set-vsphere.adoc[leveloffset=+2] +// This additional resources section can be added if this configuration is validated. (see also: callout in capi-yaml-machine-set-vsphere.adoc) +// [role="_additional-resources"] +// .Additional resources +// * xref:../../../post_installation_configuration/post-install-vsphere-zones-regions-configuration.adoc#post-install-vsphere-zones-regions-configuration[Multiple regions and zones configuration for a cluster on {vmw-full}] + +// [id="cluster-api-supported-features-vsphere_{context}"] +// == Enabling {vmw-full} features with the Cluster API + +// You can enable the following features by updating values in the Cluster API custom resource manifests. + +//Not sure what, if anything, we can add here at this time. \ No newline at end of file diff --git a/modules/capi-creating-cluster-resource.adoc b/modules/capi-creating-cluster-resource.adoc index 9ba168ed62aa..793d18157045 100644 --- a/modules/capi-creating-cluster-resource.adoc +++ b/modules/capi-creating-cluster-resource.adoc @@ -45,6 +45,7 @@ The following values are valid: + * `AWSCluster`: The cluster is running on {aws-first}. * `GCPCluster`: The cluster is running on {gcp-first}. +* `VSphereCluster`: The cluster is running on {vmw-first}. -- . Create the cluster CR by running the following command: diff --git a/modules/capi-creating-infrastructure-resource.adoc b/modules/capi-creating-infrastructure-resource.adoc index 7457d78faa86..c1c2df11dc8a 100644 --- a/modules/capi-creating-infrastructure-resource.adoc +++ b/modules/capi-creating-infrastructure-resource.adoc @@ -39,13 +39,14 @@ spec: # <4> <1> The `apiVersion` varies by platform. For more information, see the sample Cluster API infrastructure resource YAML for your provider. The following values are valid: -* `infrastructure.cluster.x-k8s.io/v1beta1`: The version that {gcp-first} clusters use. * `infrastructure.cluster.x-k8s.io/v1beta2`: The version that {aws-first} clusters use. +* `infrastructure.cluster.x-k8s.io/v1beta1`: The version that {gcp-first} and {vmw-first} clusters use. <2> Specify the infrastructure kind for the cluster. This value must match the value for your platform. The following values are valid: * `AWSCluster`: The cluster is running on {aws-short}. * `GCPCluster`: The cluster is running on {gcp-short}. +* `VSphereCluster`: The cluster is running on {vmw-short}. <3> Specify the name of the cluster. <4> Specify the details for your environment. These parameters are provider specific. diff --git a/modules/capi-creating-machine-template.adoc b/modules/capi-creating-machine-template.adoc index d33710addc8b..0591043ccd2d 100644 --- a/modules/capi-creating-machine-template.adoc +++ b/modules/capi-creating-machine-template.adoc @@ -39,6 +39,7 @@ spec: <1> Specify the machine template kind. This value must match the value for your platform. The following values are valid: * `AWSMachineTemplate`: The cluster is running on {aws-first}. * `GCPMachineTemplate`: The cluster is running on {gcp-first}. +* `VSphereMachineTemplate`: The cluster is running on {vmw-first}. <2> Specify a name for the machine template. <3> Specify the details for your environment. These parameters are provider specific. For more information, see the sample Cluster API machine template YAML for your provider. -- diff --git a/modules/capi-limitations.adoc b/modules/capi-limitations.adoc index 342d6e1c55ae..d15bbbf6a5d4 100644 --- a/modules/capi-limitations.adoc +++ b/modules/capi-limitations.adoc @@ -15,7 +15,7 @@ Using the Cluster API to manage machines is a Technology Preview feature and has Enabling this feature set cannot be undone and prevents minor version updates. ==== -* Only {aws-short} and {gcp-short} clusters can use the Cluster API. +* Only {aws-first}, {gcp-first}, and {vmw-first} clusters can use the Cluster API. * You must manually create the primary resources that the Cluster API requires. For more information, see "Getting started with the Cluster API". diff --git a/modules/capi-modifying-machine-template.adoc b/modules/capi-modifying-machine-template.adoc index 2eca15b0d94b..8e6a8afda7a5 100644 --- a/modules/capi-modifying-machine-template.adoc +++ b/modules/capi-modifying-machine-template.adoc @@ -28,6 +28,7 @@ $ oc get <1> <1> Specify the value that corresponds to your platform. The following values are valid: * `AWSMachineTemplate`: The cluster is running on {aws-first}. * `GCPMachineTemplate`: The cluster is running on {gcp-first}. +* `VSphereMachineTemplate`: The cluster is running on {vmw-first}. -- + .Example output diff --git a/modules/capi-yaml-cluster.adoc b/modules/capi-yaml-cluster.adoc index 0e67850dbcec..7f26d8515c42 100644 --- a/modules/capi-yaml-cluster.adoc +++ b/modules/capi-yaml-cluster.adoc @@ -6,7 +6,8 @@ [id="capi-yaml-cluster_{context}"] = Sample YAML for a Cluster API cluster resource -The cluster resource defines the name and infrastructure provider for the cluster and is managed by the Cluster API. This resource has the same structure for all providers. +The cluster resource defines the name and infrastructure provider for the cluster and is managed by the Cluster API. +This resource has the same structure for all providers. [source,yaml] ---- @@ -16,16 +17,22 @@ metadata: name: # <1> namespace: openshift-cluster-api spec: + controlPlaneEndpoint: # <2> + host: + port: 6443 infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 - kind: # <2> + kind: # <3> name: namespace: openshift-cluster-api ---- <1> Specify the name of the cluster. -<2> Specify the infrastructure kind for the cluster. Valid values are: +<2> Specify the IP address of the control plane endpoint and the port used to access it. +<3> Specify the infrastructure kind for the cluster. +Valid values are: + -- -* `AWSCluster`: The cluster is running on Amazon Web Services (AWS). -* `GCPCluster`: The cluster is running on Google Cloud Platform (GCP). +* `AWSCluster`: The cluster is running on {aws-full}. +* `GCPCluster`: The cluster is running on {gcp-full}. +* `VSphereCluster`: The cluster is running on {vmw-full}. -- \ No newline at end of file diff --git a/modules/capi-yaml-infrastructure-aws.adoc b/modules/capi-yaml-infrastructure-aws.adoc index f0abf1020a0d..cfb20233b206 100644 --- a/modules/capi-yaml-infrastructure-aws.adoc +++ b/modules/capi-yaml-infrastructure-aws.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-infrastructure-aws_{context}"] -= Sample YAML for a Cluster API infrastructure resource on Amazon Web Services += Sample YAML for a Cluster API infrastructure resource on {aws-full} -The infrastructure resource is provider-specific and defines properties that are shared by all the compute machine sets in the cluster, such as the region and subnets. The compute machine set references this resource when creating machines. +The infrastructure resource is provider-specific and defines properties that are shared by all the compute machine sets in the cluster, such as the region and subnets. +The compute machine set references this resource when creating machines. [source,yaml] ---- diff --git a/modules/capi-yaml-infrastructure-gcp.adoc b/modules/capi-yaml-infrastructure-gcp.adoc index 8a4b1f7501a2..96d0a3733118 100644 --- a/modules/capi-yaml-infrastructure-gcp.adoc +++ b/modules/capi-yaml-infrastructure-gcp.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-infrastructure-gcp_{context}"] -= Sample YAML for a Cluster API infrastructure resource on Google Cloud Platform += Sample YAML for a Cluster API infrastructure resource on {gcp-full} -The infrastructure resource is provider-specific and defines properties that are shared by all the compute machine sets in the cluster, such as the region and subnets. The compute machine set references this resource when creating machines. +The infrastructure resource is provider-specific and defines properties that are shared by all the compute machine sets in the cluster, such as the region and subnets. +The compute machine set references this resource when creating machines. [source,yaml] ---- diff --git a/modules/capi-yaml-infrastructure-vsphere.adoc b/modules/capi-yaml-infrastructure-vsphere.adoc new file mode 100644 index 000000000000..403af3240647 --- /dev/null +++ b/modules/capi-yaml-infrastructure-vsphere.adoc @@ -0,0 +1,38 @@ +// Module included in the following assemblies: +// +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc + +:_mod-docs-content-type: REFERENCE +[id="capi-yaml-infrastructure-vsphere_{context}"] += Sample YAML for a Cluster API infrastructure resource on {vmw-full} + +The infrastructure resource is provider-specific and defines properties that are shared by all the compute machine sets in the cluster, such as the region and subnets. +The compute machine set references this resource when creating machines. + +[source,yaml] +---- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereCluster # <1> +metadata: + name: # <2> +spec: + controlPlaneEndpoint: # <3> + host: + port: 6443 + identityRef: + kind: Secret + name: + server: # <4> +---- +<1> Specify the infrastructure kind for the cluster. +This value must match the value for your platform. +<2> Specify the cluster ID as the name of the cluster. +<3> Specify the IP address of the control plane endpoint and the port used to access it. +<4> Specify the {vmw-short} server for the cluster. +You can find this value on an existing {vmw-short} cluster by running the following command: ++ +[source,terminal] +---- +$ oc get infrastructure cluster \ + -o jsonpath="{.spec.platformSpec.vsphere.vcenters[0].server}" +---- \ No newline at end of file diff --git a/modules/capi-yaml-machine-set-aws.adoc b/modules/capi-yaml-machine-set-aws.adoc index d540c3c107df..468aea4cbea0 100644 --- a/modules/capi-yaml-machine-set-aws.adoc +++ b/modules/capi-yaml-machine-set-aws.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-machine-set-aws_{context}"] -= Sample YAML for a Cluster API compute machine set resource on Amazon Web Services += Sample YAML for a Cluster API compute machine set resource on {aws-full} -The compute machine set resource defines additional properties of the machines that it creates. The compute machine set also references the infrastructure resource and machine template when creating machines. +The compute machine set resource defines additional properties of the machines that it creates. +The compute machine set also references the infrastructure resource and machine template when creating machines. [source,yaml] ---- diff --git a/modules/capi-yaml-machine-set-gcp.adoc b/modules/capi-yaml-machine-set-gcp.adoc index d77908a244c4..784629644233 100644 --- a/modules/capi-yaml-machine-set-gcp.adoc +++ b/modules/capi-yaml-machine-set-gcp.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-machine-set-gcp_{context}"] -= Sample YAML for a Cluster API compute machine set resource on Google Cloud Platform += Sample YAML for a Cluster API compute machine set resource on {gcp-full} -The compute machine set resource defines additional properties of the machines that it creates. The compute machine set also references the infrastructure resource and machine template when creating machines. +The compute machine set resource defines additional properties of the machines that it creates. +The compute machine set also references the infrastructure resource and machine template when creating machines. [source,yaml] ---- diff --git a/modules/capi-yaml-machine-set-vsphere.adoc b/modules/capi-yaml-machine-set-vsphere.adoc new file mode 100644 index 000000000000..124ca3124779 --- /dev/null +++ b/modules/capi-yaml-machine-set-vsphere.adoc @@ -0,0 +1,64 @@ +// Module included in the following assemblies: +// +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc + +:_mod-docs-content-type: REFERENCE +[id="capi-yaml-machine-set-vsphere_{context}"] += Sample YAML for a Cluster API compute machine set resource on {vmw-full} + +The compute machine set resource defines additional properties of the machines that it creates. +The compute machine set also references the infrastructure resource and machine template when creating machines. + +[source,yaml] +---- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineSet +metadata: + name: # <1> + namespace: openshift-cluster-api +spec: + clusterName: # <2> + replicas: 1 + selector: + matchLabels: + test: example + template: + metadata: + labels: + test: example + spec: + bootstrap: + dataSecretName: worker-user-data # <3> + clusterName: + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: VSphereMachineTemplate # <4> + name: # <5> + failureDomain: # <6> + - name: + region: + zone: + server: + topology: + datacenter: + computeCluster: "" + resourcePool: "" + datastore: "" + networks: + - port-group +---- +<1> Specify a name for the compute machine set. +<2> Specify the cluster ID as the name of the cluster. +<3> For the Cluster API Technology Preview, the Operator can use the worker user data secret from the `openshift-machine-api` namespace. +<4> Specify the machine template kind. +This value must match the value for your platform. +<5> Specify the machine template name. +<6> Specify the failure domain configuration details. ++ +[NOTE] +==== +Using multiple regions and zones on a {vmw-short} cluster that uses the Cluster API is not a validated configuration. +==== +// This callout section can be updated if this configuration is validated. (see also: additional resources in cluster-api-config-options-vsphere.adoc) +// <6> Specify one or more failure domains. +// For more information about specifying multiple regions and zones on a {vmw-short} cluster, see "Multiple regions and zones configuration for a cluster on {vmw-full}." \ No newline at end of file diff --git a/modules/capi-yaml-machine-template-aws.adoc b/modules/capi-yaml-machine-template-aws.adoc index fa083bd3a820..d1e8edece2a6 100644 --- a/modules/capi-yaml-machine-template-aws.adoc +++ b/modules/capi-yaml-machine-template-aws.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-aws.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-machine-template-aws_{context}"] -= Sample YAML for a Cluster API machine template resource on Amazon Web Services += Sample YAML for a Cluster API machine template resource on {aws-full} -The machine template resource is provider-specific and defines the basic properties of the machines that a compute machine set creates. The compute machine set references this template when creating machines. +The machine template resource is provider-specific and defines the basic properties of the machines that a compute machine set creates. +The compute machine set references this template when creating machines. [source,yaml] ---- @@ -37,6 +38,8 @@ spec: values: - # ... ---- -<1> Specify the machine template kind. This value must match the value for your platform. +<1> Specify the machine template kind. +This value must match the value for your platform. <2> Specify a name for the machine template. -<3> Specify the details for your environment. The values here are examples. \ No newline at end of file +<3> Specify the details for your environment. +The values here are examples. \ No newline at end of file diff --git a/modules/capi-yaml-machine-template-gcp.adoc b/modules/capi-yaml-machine-template-gcp.adoc index e6863daa4793..34205e814ff9 100644 --- a/modules/capi-yaml-machine-template-gcp.adoc +++ b/modules/capi-yaml-machine-template-gcp.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * machine_management/cluster_api_machine_management/cluster-api-configuration.adoc +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-gcp.adoc :_mod-docs-content-type: REFERENCE [id="capi-yaml-machine-template-gcp_{context}"] -= Sample YAML for a Cluster API machine template resource on Google Cloud Platform += Sample YAML for a Cluster API machine template resource on {gcp-full} -The machine template resource is provider-specific and defines the basic properties of the machines that a compute machine set creates. The compute machine set references this template when creating machines. +The machine template resource is provider-specific and defines the basic properties of the machines that a compute machine set creates. +The compute machine set references this template when creating machines. [source,yaml] ---- @@ -33,6 +34,8 @@ spec: - -worker ipForwarding: Disabled ---- -<1> Specify the machine template kind. This value must match the value for your platform. +<1> Specify the machine template kind. +This value must match the value for your platform. <2> Specify a name for the machine template. -<3> Specify the details for your environment. The values here are examples. +<3> Specify the details for your environment. +The values here are examples. diff --git a/modules/capi-yaml-machine-template-vsphere.adoc b/modules/capi-yaml-machine-template-vsphere.adoc new file mode 100644 index 000000000000..6b68c24f284b --- /dev/null +++ b/modules/capi-yaml-machine-template-vsphere.adoc @@ -0,0 +1,59 @@ +// Module included in the following assemblies: +// +// * machine_management/cluster_api_machine_management/cluster_api_provider_configurations/cluster-api-config-options-vsphere.adoc + +:_mod-docs-content-type: REFERENCE +[id="capi-yaml-machine-template-vsphere_{context}"] += Sample YAML for a Cluster API machine template resource on {vmw-full} + +The machine template resource is provider-specific and defines the basic properties of the machines that a compute machine set creates. +The compute machine set references this template when creating machines. + +[source,yaml] +---- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: VSphereMachineTemplate # <1> +metadata: + name: # <2> + namespace: openshift-cluster-api +spec: + template: + spec: # <3> + template: # <4> + server: # <5> + diskGiB: 128 + cloneMode: linkedClone # <6> + datacenter: # <7> + datastore: # <8> + folder: # <9> + resourcePool: # <10> + numCPUs: 4 + memoryMiB: 16384 + network: + devices: + - dhcp4: true + networkName: "" # <11> +---- +<1> Specify the machine template kind. +This value must match the value for your platform. +<2> Specify a name for the machine template. +<3> Specify the details for your environment. +The values here are examples. +<4> Specify the vSphere VM template to use, such as `user-5ddjd-rhcos`. +<5> Specify the vCenter server IP or fully qualified domain name. +<6> Specify the type of VM clone to use. +The following values are valid: ++ +-- +* `fullClone` +* `linkedClone` +-- ++ +When using the `linkedClone` type, the disk size matches the clone source instead of using the `diskGiB` value. +For more information, see the {vmw-short} documentation about VM clone types. +<7> Specify the vCenter Datacenter to deploy the compute machine set on. +<8> Specify the vCenter Datastore to deploy the compute machine set on. +<9> Specify the path to the vSphere VM folder in vCenter, such as `/dc1/vm/user-inst-5ddjd`. +<10> Specify the vSphere resource pool for your VMs. +<11> Specify the vSphere VM network to deploy the compute machine set to. +This VM network must be where other compute machines reside in the cluster. \ No newline at end of file diff --git a/modules/cluster-capi-operator.adoc b/modules/cluster-capi-operator.adoc index 961811c31c97..73c69f313d43 100644 --- a/modules/cluster-capi-operator.adoc +++ b/modules/cluster-capi-operator.adoc @@ -7,7 +7,7 @@ [NOTE] ==== -This Operator is available as a link:https://access.redhat.com/support/offerings/techpreview[Technology Preview] for Amazon Web Services (AWS) and Google Cloud Platform (GCP) clusters. +This Operator is available as a link:https://access.redhat.com/support/offerings/techpreview[Technology Preview] for {aws-first}, {gcp-first}, and {vmw-first} clusters. ==== [discrete] @@ -33,6 +33,11 @@ link:https://github.com/openshift/cluster-capi-operator[cluster-capi-operator] ** CR: `gcpmachine` ** Validation: No +* `vspheremachines.infrastructure.cluster.x-k8s.io` +** Scope: Namespaced +** CR: `vspheremachine` +** Validation: No + * `awsmachinetemplates.infrastructure.cluster.x-k8s.io` ** Scope: Namespaced ** CR: `awsmachinetemplate` @@ -41,4 +46,9 @@ link:https://github.com/openshift/cluster-capi-operator[cluster-capi-operator] * `gcpmachinetemplates.infrastructure.cluster.x-k8s.io` ** Scope: Namespaced ** CR: `gcpmachinetemplate` +** Validation: No + +* `vspheremachinetemplates.infrastructure.cluster.x-k8s.io` +** Scope: Namespaced +** CR: `vspheremachinetemplate` ** Validation: No \ No newline at end of file diff --git a/post_installation_configuration/post-install-vsphere-zones-regions-configuration.adoc b/post_installation_configuration/post-install-vsphere-zones-regions-configuration.adoc index 437bc6d47563..6b97cfce72cb 100644 --- a/post_installation_configuration/post-install-vsphere-zones-regions-configuration.adoc +++ b/post_installation_configuration/post-install-vsphere-zones-regions-configuration.adoc @@ -1,7 +1,7 @@ :_mod-docs-content-type: ASSEMBLY :context: post-install-vsphere-zones-regions-configuration [id="post-install-vsphere-zones-regions-configuration"] -= Multiple regions and zones configuration for a cluster on {vmw-short} += Multiple regions and zones configuration for a cluster on VMware vSphere include::_attributes/common-attributes.adoc[] toc::[] From 1506866c56ede978c9cb29d0cba414dea66ae4ca Mon Sep 17 00:00:00 2001 From: EricPonvelle Date: Thu, 13 Jun 2024 13:09:34 -0400 Subject: [PATCH 168/339] OSDOCS#8394: Second attempt at Networking migration --- _topic_maps/_topic_map_rosa.yml | 2 + ...erts-deploying-application-networking.adoc | 62 ++++++++++++++++++ images/deploying-networking-arch.png | Bin 0 -> 59581 bytes images/deploying-networking-dns.png | Bin 0 -> 38622 bytes images/deploying-networking-example.png | Bin 0 -> 128277 bytes 5 files changed, 64 insertions(+) create mode 100644 cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc create mode 100644 images/deploying-networking-arch.png create mode 100644 images/deploying-networking-dns.png create mode 100644 images/deploying-networking-example.png diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index a8f154523974..ffa6a0bde0fb 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -186,6 +186,8 @@ Topics: File: cloud-experts-deploying-application-prerequisites - Name: Lab Overview File: cloud-experts-deploying-application-lab-overview + - Name: Networking + File: cloud-experts-deploying-application-networking --- Name: Getting started Dir: rosa_getting_started diff --git a/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc new file mode 100644 index 000000000000..13044b27a6b5 --- /dev/null +++ b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-networking.adoc @@ -0,0 +1,62 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cloud-experts-deploying-application-networking"] += Tutorial: Networking +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: cloud-experts-deploying-application-networking + +toc::[] + +//rosaworkshop.io content metadata +//Brought into ROSA product docs 2023-12-14 + +This tutorial shows how the OSToy app uses intra-cluster networking to separate functions by using microservices and visualize the scaling of pods. + +image::deploying-networking-arch.png[OSToy Diagram] + +The diagram shows there are at least two separate pods, each with its own service. + +One pod functions as the front end web application with a service and a publicly accessible route. The other pod functions as the backend microservice with a service object so that the front end pod can communicate with the microservice. This communication occurs across the pods if more than one. Because of these communication limits, this microservice is not accessible from outside this cluster or from other namespaces or projects if these are configured. The sole purpose of this microservice is to serve internal web requests and return a JSON object containing the current hostname, which is the pod's name, and a randomly generated color string. This color string is used to display a box with that color displayed in the tile titled "Intra-cluster Communication". + +For more information about the networking limitations, see xref:../../networking/network_security/network_policy/about-network-policy.adoc[About network policy]. + +== Intra-cluster networking + +You can view your networking configurations in your OSToy application. + +.Procedure +. In the OSToy application, click *Networking* in the left menu. +. Review the networking configuration. The right tile titled "Hostname Lookup" illustrates how the service name created for a pod can be used to translate into an internal ClusterIP address. ++ +image::deploying-networking-example.png[OSToy Networking page] + +. Enter the name of the microservice created in the right tile ("Hostname Lookup") following the format of `..svc.cluster.local`. You can find this service name in the service definition of `ostoy-microservice.yaml` by running the following command: ++ +[source,terminal] +---- +$ oc get service -o yaml +---- ++ +.Example output +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: ostoy-microservice-svc + labels: + app: ostoy-microservice +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + selector: + app: ostoy-microservice +---- ++ +In this example, the full hostname is `ostoy-microservice-svc.ostoy.svc.cluster.local`. + +. You see an IP address returned. In this example it is `172.30.165.246`. This is the intra-cluster IP address, which is only accessible from within the cluster. ++ +image::deploying-networking-dns.png[OSToy DNS] \ No newline at end of file diff --git a/images/deploying-networking-arch.png b/images/deploying-networking-arch.png new file mode 100644 index 0000000000000000000000000000000000000000..31bd0393efda0a712731a076fe8a0febd7dd0d0f GIT binary patch literal 59581 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 Bp0WS{ literal 0 HcmV?d00001 diff --git a/images/deploying-networking-dns.png b/images/deploying-networking-dns.png new file mode 100644 index 0000000000000000000000000000000000000000..321062961dbd66d43877729dc8dd6ed62943251e GIT binary patch literal 38622 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%0D5W4C(*#PS@9N!y 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 TnM&ss2*AhO_!z#z$T{YJXB!>x literal 0 HcmV?d00001 diff --git a/images/deploying-networking-example.png b/images/deploying-networking-example.png new file mode 100644 index 0000000000000000000000000000000000000000..e7168c7d2103ab77f124eae30bb349d98b064682 GIT binary patch literal 128277 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 Nt?^L3^xpH3{{$+~OyK|k literal 0 HcmV?d00001 From e069836c78ce5b2072a79cac5a6b09bda4b7edd9 Mon Sep 17 00:00:00 2001 From: Sabrina Jess Date: Fri, 7 Jun 2024 10:46:54 -0400 Subject: [PATCH 169/339] new content --- _topic_maps/_topic_map.yml | 2 ++ modules/virt-enabling-multi-queue.adoc | 25 +++++++++++++++++++ .../virt-about-multi-queue.adoc | 25 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 modules/virt-enabling-multi-queue.adoc create mode 100644 virt/virtual_machines/advanced_vm_management/virt-about-multi-queue.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 74bcc141ecf0..9d1de9899e4c 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -4177,6 +4177,8 @@ Topics: File: virt-assigning-compute-resources - Name: Running real-time workloads File: virt-configuring-cluster-realtime-workloads + - Name: About multi-queue functionality + File: virt-about-multi-queue - Name: VM disks Dir: virtual_disks Topics: diff --git a/modules/virt-enabling-multi-queue.adoc b/modules/virt-enabling-multi-queue.adoc new file mode 100644 index 000000000000..7edf545073bd --- /dev/null +++ b/modules/virt-enabling-multi-queue.adoc @@ -0,0 +1,25 @@ +// Module included in the following assemblies: +// +// * virt/virtual_machines/virtual_disks/virt-configuring-shared-volumes-for-vms.adoc + +:_content-type: PROCEDURE +[id="virt-enabling-multi-queue_{context}"] += Enabling multi-queue functionality + +Enable multi-queue functionality for interfaces configured with a VirtIO model. + +.Procedure + +. Set the `networkInterfaceMultiqueue` value to `true` in the `VirtualMachine` manifest file of your VM to enable multi-queue functionality: ++ +[source,yaml] +---- +apiVersion: kubevirt.io/v1 +kind: VM +spec: + domain: + devices: + networkInterfaceMultiqueue: true +---- + +. Save the `VirtualMachine` manifest file to apply your changes. \ No newline at end of file diff --git a/virt/virtual_machines/advanced_vm_management/virt-about-multi-queue.adoc b/virt/virtual_machines/advanced_vm_management/virt-about-multi-queue.adoc new file mode 100644 index 000000000000..e1ae254e12c2 --- /dev/null +++ b/virt/virtual_machines/advanced_vm_management/virt-about-multi-queue.adoc @@ -0,0 +1,25 @@ +:_mod-docs-content-type: ASSEMBLY +[id="virt-about-multi-queue"] += About multi-queue functionality +include::_attributes/common-attributes.adoc[] +:context: virt-about-multi-queue + +toc::[] + +Use multi-queue functionality to scale network throughput and performance on virtual machines (VMs) with multiple vCPUs. + +By default, the `queueCount` value, which is derived from the domain XML, is determined by the number of vCPUs allocated to a VM. Network performance does not scale as the number of vCPUs increases. Additionally, because virtio-net has only one Tx and Rx queue, guests cannot transmit or retrieve packs in parallel. + +[NOTE] +==== +Enabling virtio-net multiqueue does not offer significant improvements when the number of vNICs in a guest instance is proportional to the number of vCPUs. +==== + +[id="virt-about-multi-queue-_{context}"] +== Known limitations + +* MSI vectors are still consumed if virtio-net multiqueue is enabled in the host but not enabled in the guest operating system by the administrator. +* Each virtio-net queue consumes 64 KiB of kernel memory for the vhost driver. +* Starting a VM with more than 16 CPUs results in no connectivity if `networkInterfaceMultiqueue` is set to 'true' (link:https://issues.redhat.com/browse/CNV-16107[CNV-16107]). + +include::modules/virt-enabling-multi-queue.adoc[leveloffset=+1] From 5461c4e15508583e06a18e2c818db81099861f98 Mon Sep 17 00:00:00 2001 From: subhtk Date: Tue, 28 May 2024 17:52:08 +0530 Subject: [PATCH 170/339] Updated v1 documentation for oc-mirror. --- .../installing-mirroring-disconnected.adoc | 114 +++++++-------- ...tallation-adding-registry-pull-secret.adoc | 13 +- modules/oc-mirror-about-image-set-config.adoc | 33 +++++ modules/oc-mirror-about.adoc | 15 +- .../oc-mirror-creating-image-set-config.adoc | 41 +++--- modules/oc-mirror-disk-to-mirror.adoc | 17 ++- modules/oc-mirror-dry-run.adoc | 6 +- modules/oc-mirror-fully-disconnected.adoc | 11 ++ .../oc-mirror-image-set-config-examples.adoc | 132 +++++++++++------- modules/oc-mirror-imageset-config-params.adoc | 85 +++++------ modules/oc-mirror-installing-plugin.adoc | 15 +- modules/oc-mirror-mirror-to-disk.adoc | 16 +-- modules/oc-mirror-mirror-to-mirror.adoc | 19 ++- modules/oc-mirror-mirroring-image-set.adoc | 15 ++ modules/oc-mirror-oci-format.adoc | 11 +- ...-mirror-setting-incremental-mirroring.adoc | 53 +++++++ modules/oc-mirror-support.adoc | 4 +- .../oc-mirror-updating-cluster-manifests.adoc | 4 +- .../oc-mirror-updating-registry-about.adoc | 20 +-- modules/oc-mirror-updating-use-cases.adoc | 90 ++++++++---- 20 files changed, 444 insertions(+), 270 deletions(-) create mode 100644 modules/oc-mirror-about-image-set-config.adoc create mode 100644 modules/oc-mirror-fully-disconnected.adoc create mode 100644 modules/oc-mirror-mirroring-image-set.adoc create mode 100644 modules/oc-mirror-setting-incremental-mirroring.adoc diff --git a/installing/disconnected_install/installing-mirroring-disconnected.adoc b/installing/disconnected_install/installing-mirroring-disconnected.adoc index bedd847aba29..43698be0a2d1 100644 --- a/installing/disconnected_install/installing-mirroring-disconnected.adoc +++ b/installing/disconnected_install/installing-mirroring-disconnected.adoc @@ -1,14 +1,12 @@ :_mod-docs-content-type: ASSEMBLY -[id="installing-mirroring-disconnected"] -= Mirroring images for a disconnected installation using the oc-mirror plugin +[id="installing-mirroring-disconnected_{context}"] += Mirroring images for a disconnected installation using the oc-mirror plugin v1 include::_attributes/common-attributes.adoc[] :context: installing-mirroring-disconnected toc::[] -Running your cluster in a restricted network without direct internet connectivity is possible by installing the cluster from a mirrored set of {product-title} container images in a private registry. This registry must be running at all times as long as the cluster is running. See the xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#prerequisites_installing-mirroring-disconnected[Prerequisites] section for more information. - -You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror images to a mirror registry in your fully or partially disconnected environments. You must run oc-mirror from a system with internet connectivity in order to download the required images from the official Red Hat registries. +Running your cluster in a restricted network without direct internet connectivity is possible by installing the cluster from a mirrored set of {product-title} container images in a private registry. This registry must be running at all times as long as the cluster is running. See "Prerequisites" section for more information. // About the oc-mirror plugin include::modules/oc-mirror-about.adoc[leveloffset=+1] @@ -16,76 +14,68 @@ include::modules/oc-mirror-about.adoc[leveloffset=+1] // oc-mirror compatibility and support include::modules/oc-mirror-support.adoc[leveloffset=+1] -[role="_additional-resources"] -.Additional resources - -* For information on updating oc-mirror, see xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source]. - -// About the mirror registry -include::modules/installation-about-mirror-registry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* For information about viewing the CRI-O logs to view the image source, see xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source]. - -[id="prerequisites_installing-mirroring-disconnected"] +[id="prerequisites_installing-mirroring-disconnected_{context}"] == Prerequisites -* You must have a container image registry that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2] in the location that will host the {product-title} cluster, such as Red Hat Quay. +* You must have a container image registry, which is referred as the mirror registry, that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2] in the location that hosts the {product-title} cluster, such as {quay}. + [NOTE] ==== -If you use Red Hat Quay, you must use version 3.6 or later with the oc-mirror plugin. If you have an entitlement to Red Hat Quay, see the documentation on deploying Red Hat Quay link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploy_red_hat_quay_for_proof-of-concept_non-production_purposes/[for proof-of-concept purposes] or link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploying_the_red_hat_quay_operator_on_openshift_container_platform/index[by using the Red Hat Quay Operator]. If you need additional assistance selecting and installing a registry, contact your sales representative or Red Hat Support. +If you use {quay}, you must use version 3.6 or later with the oc-mirror plugin. If you have an entitlement to {quay}, see the documentation on deploying {quay} link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploy_red_hat_quay_for_proof-of-concept_non-production_purposes/[for proof-of-concept purposes] or link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploying_the_red_hat_quay_operator_on_openshift_container_platform/index[by using the Red Hat Quay Operator]. If you need additional assistance selecting and installing a registry, contact your sales representative or Red Hat Support. ==== + -If you do not already have an existing solution for a container image registry, subscribers of {product-title} are provided a xref:../../installing/disconnected_install/installing-mirroring-creating-registry.adoc#installing-mirroring-creating-registry[mirror registry for Red Hat OpenShift]. The _mirror registry for Red Hat OpenShift_ is included with your subscription and is a small-scale container registry that can be used to mirror the required container images of {product-title} in disconnected installations. +If you do not already have an existing solution for a mirror registry, the subscribers of {product-title} are provided in "Creating a mirror registry with mirror registry for Red Hat OpenShift". -[id="mirroring-preparing-your-hosts"] -== Preparing your mirror hosts +* The mirror registry must be reachable by every machine in the clusters that you provision. If the registry is unreachable, installation, updating, or normal operations such as workload relocation might fail. For this reason, you must run mirror registries ensuring highly availability. The mirror registries must meet or exceed the production availability of your {product-title} clusters. -Before you can use the oc-mirror plugin to mirror images, you must install the plugin and create a container image registry credentials file to allow the mirroring from Red Hat to your mirror. - -// Installing the oc-mirror OpenShift CLI plugin -include::modules/oc-mirror-installing-plugin.adoc[leveloffset=+2] +* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. [role="_additional-resources"] .Additional resources -* xref:../../cli_reference/openshift_cli/extending-cli-plugins.adoc#cli-installing-plugins_cli-extend-plugins[Installing and using CLI plugins] +* xref:../../installing/disconnected_install/installing-mirroring-creating-registry.adoc#installing-mirroring-creating-registry[Creating a mirror registry with mirror registry for Red Hat OpenShift] + +[id="mirroring-preparing-your-hosts_{context}"] +== Preparing your mirror hosts + +To use the oc-mirror plugin v1 to mirror images, you need to install the plugin and create a container image registry credentials file to enable mirroring from Red Hat to your mirror. + +// Installing the oc-mirror OpenShift CLI plugin v1 +include::modules/oc-mirror-installing-plugin.adoc[leveloffset=+2] // Configuring credentials that allow images to be mirrored include::modules/installation-adding-registry-pull-secret.adoc[leveloffset=+2] -// Creating the image set configuration -include::modules/oc-mirror-creating-image-set-config.adoc[leveloffset=+1] +// About Image set configuration +include::modules/oc-mirror-about-image-set-config.adoc[leveloffset=+1] -[role="_additional-resources"] -.Additional resources +// Creating the image set configuration +include::modules/oc-mirror-creating-image-set-config.adoc[leveloffset=+2] -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-imageset-config-params_installing-mirroring-disconnected[Image set configuration parameters] -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-image-set-examples_installing-mirroring-disconnected[Image set configuration examples] -* xref:../../updating/updating_a_cluster/updating_disconnected_cluster/disconnected-update-osus.adoc#update-service-overview_updating-restricted-network-cluster-osus[Using the OpenShift Update Service in a disconnected environment] +// Image set configuration parameters +include::modules/oc-mirror-imageset-config-params.adoc[leveloffset=+2] -[id="mirroring-image-set"] -== Mirroring an image set to a mirror registry +// Image set configuration examples +include::modules/oc-mirror-image-set-config-examples.adoc[leveloffset=+2] -You can use the oc-mirror CLI plugin to mirror images to a mirror registry in a xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-partial[partially disconnected environment] or in a xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-full[fully disconnected environment]. +// Setting up for incremental mirroring +include::modules/oc-mirror-setting-incremental-mirroring.adoc[leveloffset=+1] -These procedures assume that you already have your mirror registry set up. +[role="_additional-resources"] +.Additional resources -[id="mirroring-image-set-partial"] -=== Mirroring an image set in a partially disconnected environment +* xref:../../updating/updating_a_cluster/updating_disconnected_cluster/disconnected-update-osus.adoc#update-service-overview_updating-restricted-network-cluster-osus[Updating a cluster in a disconnected environment using the OpenShift Update Service] -In a partially disconnected environment, you can mirror an image set directly to the target mirror registry. +* xref:../../cli_reference/openshift_cli/extending-cli-plugins.adoc#cli-installing-plugins_cli-extend-plugins[Extending the OpenShift CLI with plugins] -// Mirroring from mirror to mirror -include::modules/oc-mirror-mirror-to-mirror.adoc[leveloffset=+3] +// Mirroring an image set to a mirror registry +include::modules/oc-mirror-mirroring-image-set.adoc[leveloffset=+1] -[id="mirroring-image-set-full"] -=== Mirroring an image set in a fully disconnected environment +// Mirroring from partially disconnected environment:mirror to mirror +include::modules/oc-mirror-mirror-to-mirror.adoc[leveloffset=+2] -To mirror an image set in a fully disconnected environment, you must first xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-mirror-to-disk_installing-mirroring-disconnected[mirror the image set to disk], then xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-disk-to-mirror_installing-mirroring-disconnected[mirror the image set file on disk to a mirror]. +// Mirroring from fully disconnected environment +include::modules/oc-mirror-fully-disconnected.adoc[leveloffset=+2] // Mirroring from mirror to disk include::modules/oc-mirror-mirror-to-disk.adoc[leveloffset=+3] @@ -96,42 +86,34 @@ include::modules/oc-mirror-disk-to-mirror.adoc[leveloffset=+3] // Configuring your cluster to use the resources generated by oc-mirror include::modules/oc-mirror-updating-cluster-manifests.adoc[leveloffset=+1] +[role="_additional-resources"] +.Additional resources + +* xref:../../updating/understanding_updates/intro-to-updates.adoc#update-service-about_understanding-openshift-updates[About the OpenShift Update Service] + // About updating your mirror registry content include::modules/oc-mirror-updating-registry-about.adoc[leveloffset=+1] +// Use-cases include::modules/oc-mirror-updating-use-cases.adoc[leveloffset=+2] -[role="_additional-resources"] -.Additional resources - -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-image-set-examples_installing-mirroring-disconnected[Image set configuration examples] -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-partial[Mirroring an image set in a partially disconnected environment] -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-full[Mirroring an image set in a fully disconnected environment] -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-updating-cluster-manifests_installing-mirroring-disconnected[Configuring your cluster to use the resources generated by oc-mirror] - // Performing a dry run include::modules/oc-mirror-dry-run.adoc[leveloffset=+1] // Including local OCI Operator catalogs include::modules/oc-mirror-oci-format.adoc[leveloffset=+1] -[role="_additional-resources"] -.Additional resources +// Additional resources // TODO: This title might need to update per sebastian's PR -* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-updating-cluster-manifests_installing-mirroring-disconnected[Configuring your cluster to use the resources generated by oc-mirror] - -// Image set configuration parameters -include::modules/oc-mirror-imageset-config-params.adoc[leveloffset=+1] - -// Image set configuration examples -include::modules/oc-mirror-image-set-config-examples.adoc[leveloffset=+1] +// Configuring your cluster to use the resources generated by oc-mirror // Command reference for oc-mirror include::modules/oc-mirror-command-reference.adoc[leveloffset=+1] [role="_additional-resources"] -[id="additional-resources_installing-mirroring-disconnected"] == Additional resources * xref:../../updating/updating_a_cluster/updating_disconnected_cluster/index.adoc#about-restricted-network-updates[About cluster updates in a disconnected environment] + +* xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source] diff --git a/modules/installation-adding-registry-pull-secret.adoc b/modules/installation-adding-registry-pull-secret.adoc index a3918c0cb846..802ccab21bea 100644 --- a/modules/installation-adding-registry-pull-secret.adoc +++ b/modules/installation-adding-registry-pull-secret.adoc @@ -22,23 +22,18 @@ endif::[] :_mod-docs-content-type: PROCEDURE [id="installation-adding-registry-pull-secret_{context}"] -= Configuring credentials that allow images to be mirrored += Configuring credentials to enable mirroring images -Create a container image registry credentials file that allows mirroring -images from Red Hat to your mirror. +Follow the procedure to create a container image registry credentials file for mirroring images from Red Hat to your mirror registry. ifdef::restricted[] [WARNING] ==== -Do not use this image registry credentials file as the pull secret when you install a cluster. If you provide this file when you install cluster, all of the machines in the cluster will have write access to your mirror registry. +Do not use this image registry credentials file as the pull secret when installing a cluster. Using this file will grant write access to your mirror registry for all machines in the cluster. ==== endif::restricted[] ifdef::restricted[] -[WARNING] -==== -This process requires that you have write access to a container image registry on the mirror registry and adds the credentials to a registry pull secret. -==== endif::restricted[] @@ -52,6 +47,8 @@ endif::openshift-rosa,openshift-dedicated[] ifdef::restricted[] * You identified an image repository location on your mirror registry to mirror images into. * You provisioned a mirror registry account that allows images to be uploaded to that image repository. +* You have write access to the mirror registry. +* You included the credentials in the registry pull secret. endif::restricted[] .Procedure diff --git a/modules/oc-mirror-about-image-set-config.adoc b/modules/oc-mirror-about-image-set-config.adoc new file mode 100644 index 000000000000..e3897f8ecf4e --- /dev/null +++ b/modules/oc-mirror-about-image-set-config.adoc @@ -0,0 +1,33 @@ +// Module included in the following assemblies: +// +// * installing/disconnected_install/installing-mirroring-disconnected.adoc +// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc + +:_mod-docs-content-type: CONCEPT +[id="oc-mirror-about-image-set-config_{context}"] += About the Image Set Configuration + +An `ImageSetConfiguration` (ISC) file is a collection of container images for mirroring. The ISC specifies the images, their versions, and any additional configuration needed for mirroring. ISCs provide a structured way to manage image mirroring tasks, allowing users to easily define, organize, and execute mirroring operations within their {product-title} environment. + +[id="oc-mirror-possibile-deployment-scenarios_{context}"] +== Possible deployment scenarios + +[id="oc-mirror-getting-image-set-config-specific-release_{context}"] +=== Scenario 1: Obtaining the `ImageSetConfiguration` file for a specific release + +To obtain the `ImageSetConfiguration` file for a specific release, follow one of these methods: + +* Set `minVersion` at the channel level to your target deployment version. +* Alternatively, set `minVersion` to the latest version in the default channel and keep it unchanged. +* Set the `maxVersion` to limit versions being mirrored. +* Use the same version for both `minVersion` and `maxVersion` to mirror only one version. + +When you run the `oc-mirror` plugin v1 with the `ImageSetConfiguration` file, it evaluates the latest release of the `stable-` channel. + +[id="oc-mirror-image-set-config-local-storage-shortest-path_{context}"] +=== Scenario 2: Using local storage and including all {product-title} versions with the shortest update path + +When using local storage and including all {product-title} versions with the shortest update path, consider the following options: + +* Set `maxVersion` to a valid version that exists in the channel you are setting it on, or include a different channel that has this version. +* If `minVersion` and `maxVersion` are not the same, the default behavior is to mirror the shortest valid upgrade path between them. \ No newline at end of file diff --git a/modules/oc-mirror-about.adoc b/modules/oc-mirror-about.adoc index bffe8ae767f0..4bf152aaeb27 100644 --- a/modules/oc-mirror-about.adoc +++ b/modules/oc-mirror-about.adoc @@ -5,7 +5,7 @@ :_mod-docs-content-type: CONCEPT [id="installation-oc-mirror-about_{context}"] -= About the oc-mirror plugin += About the oc-mirror plugin v1 You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror all required {product-title} content and other images to your mirror registry by using a single tool. It provides the following features: @@ -21,27 +21,28 @@ You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror all required {pr * Optionally generates supporting artifacts for OpenShift Update Service (OSUS) usage. -When using the oc-mirror plugin, you specify which content to mirror in an image set configuration file. In this YAML file, you can fine-tune the configuration to only include the {product-title} releases and Operators that your cluster needs. This reduces the amount of data that you need to download and transfer. The oc-mirror plugin can also mirror arbitrary helm charts and additional container images to assist users in seamlessly synchronizing their workloads onto mirror registries. +When using the oc-mirror plugin v1, you specify the content to mirror in an image set configuration file. This YAML file allows you to configure which {product-title} releases and Operators your cluster requires, reducing the amount of data to download and transfer. The plugin can also mirror helm charts and additional container images to facilitate workload synchronization onto mirror registries. -The first time you run the oc-mirror plugin, it populates your mirror registry with the required content to perform your disconnected cluster installation or update. In order for your disconnected cluster to continue receiving updates, you must keep your mirror registry updated. To update your mirror registry, you run the oc-mirror plugin using the same configuration as the first time you ran it. The oc-mirror plugin references the metadata from the storage backend and only downloads what has been released since the last time you ran the tool. This provides update paths for {product-title} and Operators and performs dependency resolution as required. +The first time you run the oc-mirror plugin v1, it populates your mirror registry with the necessary content for your disconnected cluster installation or update. To continue receiving updates, it's essential to keep your mirror registry updated. Running the oc-mirror plugin v1 with the same configuration as the initial run allows for referencing metadata from the storage backend and downloading only the releases since the last run, providing update paths for {product-title} and Operators, and performing necessary dependency resolution. [id="installation-oc-mirror-workflow_{context}"] == High level workflow -The following steps outline the high-level workflow on how to use the oc-mirror plugin to mirror images to a mirror registry: + +The following steps outline the high-level workflow on how to use the oc-mirror plugin v1 to mirror images to a mirror registry: . Create an image set configuration file. -. Mirror the image set to the target mirror registry by using one of the following methods: +. Mirror the image set to the target mirror registry by using one of the following workflows: ** Mirror an image set directly to the target mirror registry. ** Mirror an image set to disk, transfer the image set to the target environment, then upload the image set to the target mirror registry. -. Configure your cluster to use the resources generated by the oc-mirror plugin. +. Configure your cluster to use the resources generated by the oc-mirror plugin v1. . Repeat these steps to update your target mirror registry as necessary. [IMPORTANT] ==== -When using the oc-mirror CLI plugin to populate a mirror registry, any further updates to the target mirror registry must be made by using the oc-mirror plugin. +When using the oc-mirror CLI plugin to populate a mirror registry, any further updates to the target mirror registry must be made by using the oc-mirror plugin v1. ==== diff --git a/modules/oc-mirror-creating-image-set-config.adoc b/modules/oc-mirror-creating-image-set-config.adoc index fbc04b196dac..72e39af106b7 100644 --- a/modules/oc-mirror-creating-image-set-config.adoc +++ b/modules/oc-mirror-creating-image-set-config.adoc @@ -7,18 +7,11 @@ [id="oc-mirror-creating-image-set-config_{context}"] = Creating the image set configuration -Before you can use the oc-mirror plugin to mirror image sets, you must create an image set configuration file. This image set configuration file defines which {product-title} releases, Operators, and other images to mirror, along with other configuration settings for the oc-mirror plugin. - -You must specify a storage backend in the image set configuration file. This storage backend can be a local directory or a registry that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2]. The oc-mirror plugin stores metadata in this storage backend during image set creation. - -[IMPORTANT] -==== -Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. -==== +In order to use the oc-mirror plugin v1 to mirror image sets, you must create an image set configuration file that specifies the {product-title} releases, Operators, and additional images for mirroring, along with various configuration parameters for the oc-mirror plugin v1. .Prerequisites -* You have created a container image registry credentials file. For instructions, see _Configuring credentials that allow images to be mirrored_. +* You have created a container image registry credentials file. For instructions, see "Configuring credentials that allow images to be mirrored". .Procedure @@ -28,7 +21,7 @@ Do not delete or modify the metadata that is generated by the oc-mirror plugin. ---- $ oc mirror init --registry example.com/mirror/oc-mirror-metadata > imageset-config.yaml <1> ---- -<1> Replace `example.com/mirror/oc-mirror-metadata` with the location of your registry for the storage backend. +<1> Replace `example.com/mirror/oc-mirror-metadata` with the location you have created for the storage backend image of oc-mirror on your mirror registry. . Edit the file and adjust the settings as necessary: + @@ -36,35 +29,37 @@ $ oc mirror init --registry example.com/mirror/oc-mirror-metadata > imageset-con ---- kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v1alpha2 -archiveSize: 4 <1> +archiveSize: 4 #<1> storageConfig: <2> registry: - imageURL: example.com/mirror/oc-mirror-metadata <3> + imageURL: example.com/mirror/oc-mirror-metadata #<3> skipTLS: false mirror: platform: channels: - - name: stable-{product-version} <4> + - name: stable-{product-version} #<4> type: ocp - graph: true <5> + graph: true #<5> operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} <6> + - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} #<6> packages: - - name: serverless-operator <7> + - name: serverless-operator #<7> channels: - - name: stable <8> + - name: stable #<8> additionalImages: - - name: registry.redhat.io/ubi9/ubi:latest <9> + - name: registry.redhat.io/ubi9/ubi:latest #<9> helm: {} ---- -<1> Add `archiveSize` to set the maximum size, in GiB, of each file within the image set. +<1> Add `archiveSize` to set the maximum size, in GiB, of each archive generated. This setup is only valid when mirroring to a fully disconnected environment. <2> Set the back-end location to save the image set metadata to. This location can be a registry or local directory. It is required to specify `storageConfig` values. <3> Set the registry URL for the storage backend. <4> Set the channel to retrieve the {product-title} images from. -<5> Add `graph: true` to build and push the graph-data image to the mirror registry. The graph-data image is required to create OpenShift Update Service (OSUS). The `graph: true` field also generates the `UpdateService` custom resource manifest. The `oc` command-line interface (CLI) can use the `UpdateService` custom resource manifest to create OSUS. For more information, see _About the OpenShift Update Service_. -<6> Set the Operator catalog to retrieve the {product-title} images from. +<5> Add `graph: true` to build and push the graph-data image to the mirror registry. The graph-data image is required to create OpenShift Update Service (OSUS). The `graph: true` field also generates the `UpdateService` custom resource manifest. The `oc` command-line interface (CLI) can use the `UpdateService` custom resource manifest to create OSUS. For more information, see "About the OpenShift Update Service". +<6> Set the Operator catalog to retrieve the {product-title} images from; retrieves the latest version of all Operators of this catalog. <7> Specify only certain Operator packages to include in the image set. Remove this field to retrieve all packages in the catalog. -<8> Specify only certain channels of the Operator packages to include in the image set. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. You can find the default channel by running the following command: `oc mirror list operators --catalog= --package=`. +<8> Specify only certain channels of the Operator packages to include in the image set. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. +You can find the default channel by running the following command: +`oc mirror list operators --catalog= --package=`. <9> Specify any additional images to include in image set. + [NOTE] @@ -72,7 +67,7 @@ mirror: The `graph: true` field also mirrors the `ubi-micro` image along with other mirrored images. ==== + -See _Image set configuration parameters_ for the full list of parameters and _Image set configuration examples_ for various mirroring use cases. +See "Image set configuration parameters" for the full list of parameters and "Image set configuration examples" for various mirroring use cases. . Save the updated file. + diff --git a/modules/oc-mirror-disk-to-mirror.adoc b/modules/oc-mirror-disk-to-mirror.adoc index 7164bf5da7d5..808635963d35 100644 --- a/modules/oc-mirror-disk-to-mirror.adoc +++ b/modules/oc-mirror-disk-to-mirror.adoc @@ -5,16 +5,18 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-disk-to-mirror_{context}"] -= Mirroring from disk to mirror += Mirroring from disk-to-mirror -You can use the oc-mirror plugin to mirror the contents of a generated image set to the target mirror registry. +You can use the oc-mirror plugin v1 to mirror the contents of a generated image set to the target mirror registry. .Prerequisites * You have installed the OpenShift CLI (`oc`) in the disconnected environment. -* You have installed the `oc-mirror` CLI plugin in the disconnected environment. +* You have installed the `oc-mirror` CLI plugin v1 in the disconnected environment. * You have generated the image set file by using the `oc mirror` command. +* You have access to the target mirror registry. * You have transferred the image set file to the disconnected environment. +* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. // TODO: Confirm prereq about not needing a cluster, but need pull secret misc .Procedure @@ -26,9 +28,14 @@ You can use the oc-mirror plugin to mirror the contents of a generated image set $ oc mirror --from=./mirror_seq1_000000.tar \// <1> docker://registry.example:5000 <2> ---- -<1> Pass in the image set .tar file to mirror, named `mirror_seq1_000000.tar` in this example. If an `archiveSize` value was specified in the image set configuration file, the image set might be broken up into multiple .tar files. In this situation, you can pass in a directory that contains the image set .tar files. +<1> Pass in the image set `.tar` file to mirror, named `mirror_seq1_000000.tar` in this example. If an `archiveSize` value was specified in the image set configuration file, the image set might be broken up into multiple `.tar` files. In this situation, you can pass in a directory that contains the image set `.tar` files. <2> Specify the registry to mirror the image set file to. The registry must start with `docker://`. If you specify a top-level namespace for the mirror registry, you must also use this same namespace on subsequent executions. + +[NOTE] +==== +The generated image sets follow a sequential order and must be pushed to the target mirror registry accordingly. You can determine the sequence number from the file name of the generated image set archive file. +==== ++ This command updates the mirror registry with the image set and generates the `ImageContentSourcePolicy` and `CatalogSource` resources. .Verification @@ -45,5 +52,5 @@ This command updates the mirror registry with the image set and generates the `I .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. +* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] diff --git a/modules/oc-mirror-dry-run.adoc b/modules/oc-mirror-dry-run.adoc index aa2c7fa4d3e3..f81565278dd9 100644 --- a/modules/oc-mirror-dry-run.adoc +++ b/modules/oc-mirror-dry-run.adoc @@ -8,13 +8,13 @@ [id="oc-mirror-dry-run_{context}"] = Performing a dry run -You can use oc-mirror to perform a dry run, without actually mirroring any images. This allows you to review the list of images that would be mirrored, as well as any images that would be pruned from the mirror registry. A dry run also allows you to catch any errors with your image set configuration early or use the generated list of images with other tools to carry out the mirroring operation. +You can use oc-mirror plugin v1 to perform a dry run, without actually mirroring any images. This allows you to review the list of images that would be mirrored, as well as any images that would be pruned from the mirror registry. A dry run also allows you to catch any errors with your image set configuration early or use the generated list of images with other tools to carry out the mirroring operation. .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin. +* You have installed the `oc-mirror` CLI plugin v1. * You have created the image set configuration file. .Procedure @@ -66,5 +66,5 @@ This file contains a list of all images that would be pruned from the mirror reg + [NOTE] ==== -The `pruning-plan.json` file is only generated if your oc-mirror command points to your mirror registry and there are images to be pruned. +The `pruning-plan.json` file is only generated if your oc-mirror plugin v1 command points to your mirror registry and there are images to be pruned. ==== diff --git a/modules/oc-mirror-fully-disconnected.adoc b/modules/oc-mirror-fully-disconnected.adoc new file mode 100644 index 000000000000..a5c944b5fc61 --- /dev/null +++ b/modules/oc-mirror-fully-disconnected.adoc @@ -0,0 +1,11 @@ +// Module included in the following assemblies: +// +// * installing/disconnected_install/installing-mirroring-disconnected.adoc +// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc +// * microshift_running_apps/microshift_operators/microshift-operators-oc-mirror.adoc + +:_mod-docs-content-type: CONCEPT +[id="oc-mirror-fully-disconnected_{context}"] += Mirroring an image set in a fully disconnected environment + +To mirror an image set in a fully disconnected environment, you must first mirror the image set to disk, then mirror the image set file on disk to a mirror. \ No newline at end of file diff --git a/modules/oc-mirror-image-set-config-examples.adoc b/modules/oc-mirror-image-set-config-examples.adoc index 769de6e520e9..0549d16b3364 100644 --- a/modules/oc-mirror-image-set-config-examples.adoc +++ b/modules/oc-mirror-image-set-config-examples.adoc @@ -5,16 +5,21 @@ :_mod-docs-content-type: REFERENCE [id="oc-mirror-image-set-examples_{context}"] -= Image set configuration examples += Optimizing the image set configuration The following `ImageSetConfiguration` file examples show the configuration for various mirroring use cases. -// Moved to first; unchanged -[discrete] -[id="oc-mirror-image-set-examples-shortest-upgrade-path_{context}"] -== Use case: Including the shortest {product-title} update path +[id="oc-mirror-image-set-example-specific-ocp-release_{context}"] +== Use case: Preparing for installing a specific {product-title} release + +See "About ImageSetConfiguration" for further information. + +[NOTE] +==== +Regularly running oc-mirror plugin v1 facilitates the automatic retrieval of the latest {product-title} releases. +==== -The following `ImageSetConfiguration` file uses a local storage backend and includes all {product-title} versions along the shortest update path from the minimum version of `4.11.37` to the maximum version of `4.12.15`. +The following example `ImageSetConfiguration` file uses a local storage backend, including all {product-title} versions from the minimum version of 4.15.13: .Example `ImageSetConfiguration` file [source,yaml] @@ -27,20 +32,19 @@ storageConfig: mirror: platform: channels: - - name: stable-4.12 - minVersion: 4.11.37 - maxVersion: 4.12.15 - shortestPath: true + - name: stable-4.15 + minVersion: 4.15.13 ---- -// Moved to second; unchanged -[discrete] -[id="oc-mirror-image-set-examples-minimum-to-latest_{context}"] -== Use case: Including all versions of {product-title} from a minimum to the latest version for multi-architecture releases +[id="oc-mirror-image-set-example-multi-architecture_{context}"] +== Use case: Preparing for installing for multiple architectures -The following `ImageSetConfiguration` file uses a registry storage backend and includes all {product-title} versions starting at a minimum version of `4.13.4` to the latest version in the channel. On every invocation of oc-mirror with this image set configuration, the latest release of the `stable-4.13` channel is evaluated, so running oc-mirror at regular intervals ensures that you automatically receive the latest releases of {product-title} images. +If you set the architectures to `multi` in the `imageSetConfiguration` file, it implies that the images in the set support multiple architectures. -By setting the value of `platform.architectures` to `multi`, you can ensure that the mirroring is supported for multi-architecture releases. +[NOTE] +==== +The `multi` value only supports the {product-title} releases and not the Operators. +==== .Example `ImageSetConfiguration` file [source,yaml] @@ -56,25 +60,47 @@ mirror: architectures: - "multi" channels: - - name: stable-4.13 - minVersion: 4.13.4 - maxVersion: 4.13.6 + - name: stable-4.15 + minVersion: 4.15.13 ---- -// Updated: -// - Added a note below about the maxVersion -// - Added a note about not necessarily getting all versions in the range -[discrete] +[id="oc-mirror-image-set-examples-shortest-upgrade-path_{context}"] +== Use case: Preparing for an {product-title} upgrade including the shortest update path + +The following `ImageSetConfiguration` file uses a local storage backend and includes all {product-title} versions along with the shortest update path from the minimum version of 4.14.25 to the maximum version of 4.15.13: + +.Example `ImageSetConfiguration` file +[source,yaml] +---- +apiVersion: mirror.openshift.io/v1alpha2 +kind: ImageSetConfiguration +storageConfig: + local: + path: /home/user/metadata +mirror: + platform: + channels: + - name: stable-4.15 + minVersion: 4.14.25 + maxVersion: 4.15.13 + shortestPath: true +---- + +[IMPORTANT] +==== +When using EUS channels and more than one channel is specified in the `imagesetconfig`, you might need to include non-EUS channels to make sure that all required intermediate versions are included in the `imageset`. See link:https://access.redhat.com/labs/ocpupgradegraph/update_path[Red Hat OpenShift Container Platform Update Graph] to check all versions forming the upgrade graph. +==== + [id="oc-mirror-image-set-examples-operator-versions_{context}"] == Use case: Including Operator versions from a minimum to the latest -The following `ImageSetConfiguration` file uses a local storage backend and includes only the Red Hat Advanced Cluster Security for Kubernetes Operator, versions starting at 4.0.1 and later in the `stable` channel. +The following `ImageSetConfiguration` file uses a local storage backend and includes only the Red Hat Advanced Cluster Security for Kubernetes Operator, versions starting at 4.0.1 and later regardless of the channel. [NOTE] ==== When you specify a minimum or maximum version range, you might not receive all Operator versions in that range. -By default, oc-mirror excludes any versions that are skipped or replaced by a newer version in the Operator Lifecycle Manager (OLM) specification. Operator versions that are skipped might be affected by a CVE or contain bugs. Use a newer version instead. For more information on skipped and replaced versions, see link:https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/[Creating an update graph with OLM]. +By default, oc-mirror plugin v1 excludes any versions that are skipped or replaced by a newer version in the Operator Lifecycle Manager (OLM) specification. Operator versions that are skipped might be affected by a CVE or contain bugs. Use a newer version instead. For more information on skipped and replaced versions, see link:https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/[Creating an update graph with OLM]. To receive all Operator versions in a specified range, you can set the `mirror.operators.full` field to `true`. ==== @@ -92,11 +118,15 @@ mirror: - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} packages: - name: rhacs-operator - channels: - - name: stable - minVersion: 4.0.1 + - minVersion: 4.0.1 ---- +In this example, if you set the `minVersion` to the latest possible version and omit the `maxVersion`, no additional versions are mirrored. + +The oc-mirror plugin v1 automatically evaluates the latest Operator version with each use. Running the oc-mirror plugin v1 regularly ensures automatic updates to receive the latest versions of the Red Hat Advanced Cluster Security for Kubernetes Operator. + +When selecting channels for your package, consider their suitability. Enabling all channels within `minVersion` and `maxVersion` or specifying only `minVersion` allows for gradual updates with minimal configuration changes. + [NOTE] ==== To specify a maximum version instead of the latest, set the `mirror.operators.packages.channels.maxVersion` field. @@ -105,6 +135,7 @@ To specify a maximum version instead of the latest, set the `mirror.operators.pa [discrete] [id="oc-mirror-image-set-examples-nutanix-operator_{context}"] == Use case: Including the Nutanix CSI Operator + The following `ImageSetConfiguration` file uses a local storage backend and includes the Nutanix CSI Operator, the OpenShift Update Service (OSUS) graph image, and an additional Red Hat Universal Base Image (UBI). .Example `ImageSetConfiguration` file @@ -132,12 +163,12 @@ mirror: - name: registry.redhat.io/ubi9/ubi:latest ---- -// New example; including the default channel -[discrete] [id="oc-mirror-image-set-examples-default-channel_{context}"] -== Use case: Including the default Operator channel +== Use case: Including an Operator version that is not available in the default channel + +To include an Operator version not available in the default channel, consider installing `aws-load-balancer-operator`, specifically version 0.2.0. -The following `ImageSetConfiguration` file includes the `stable-5.7` and `stable` channels for the OpenShift Elasticsearch Operator. Even if only the packages from the `stable-5.7` channel are needed, the `stable` channel must also be included in the `ImageSetConfiguration` file, because it is the default channel for the Operator. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. +In the `ImageSetConfiguration` file, include the `stable-v0.2` and `stable-v1` channels for the AWS Load Balancer Operator. Even if only the packages from the `stable-v0.2` channel are needed, you must include the `stable-v1` channel in the `ImageSetConfiguration` file, as it is the default channel for the Operator. It's important to always include the default channel for the Operator package, even if you do not use the bundles in that channel. [TIP] ==== @@ -155,23 +186,22 @@ storageConfig: skipTLS: false mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} + - catalog: registry.redhat.io/redhat/redhat-operator-index:{product-version} packages: - - name: elasticsearch-operator + - name: aws-load-balancer-operator channels: - - name: stable-5.7 - - name: stable + - name: stable-v0.2 + - name: stable-v1 ---- -// New example; Entire catalog; all versions -[discrete] -[id="oc-mirror-image-set-examples-entire-catalog-full_{context}"] -== Use case: Including an entire catalog (all versions) +[id="oc-mirror-image-set-examples-default-channel-alternative_{context}"] +== Use case: Alternative example to include an Operator version that is not available in the default channel -The following `ImageSetConfiguration` file sets the `mirror.operators.full` field to `true` to include all versions for an entire Operator catalog. +Another possibility is to redefine the default channel as follows: .Example `ImageSetConfiguration` file -[source,yaml,subs=attributes+] + +[source,yaml] ---- apiVersion: mirror.openshift.io/v1alpha2 kind: ImageSetConfiguration @@ -181,19 +211,21 @@ storageConfig: skipTLS: false mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} - full: true + - catalog: registry.redhat.io/redhat/redhat-operator-index:{product-version} + packages: + - name: aws-load-balancer-operator + defaultChannel: stable-v0.2 <1> + channels: + - name: stable-v0.2 ---- +<1> The value for `defaultChannel` must be specified in the `channels` list. -// New example; Entire catalog; heads only -// - Included 'targetCatalog' in example -[discrete] -[id="oc-mirror-image-set-examples-entire-catalog-heads_{context}"] +[id="oc-mirror-image-set-examples-entire-catalog-full_{context}"] == Use case: Including an entire catalog (channel heads only) The following `ImageSetConfiguration` file includes the channel heads for an entire Operator catalog. -By default, for each Operator in the catalog, oc-mirror includes the latest Operator version (channel head) from the default channel. If you want to mirror all Operator versions, and not just the channel heads, you must set the `mirror.operators.full` field to `true`. +By default, for each Operator in the catalog, oc-mirror plugin v1 includes the latest Operator version (channel head) from the default channel. If you want to mirror all Operator versions, and not just the channel heads, you must set the `mirror.operators.full` field to `true`. This example also uses the `targetCatalog` field to specify an alternative namespace and name to mirror the catalog as. @@ -212,8 +244,6 @@ mirror: targetCatalog: my-namespace/my-operator-catalog ---- -// Moved to last; unchanged -[discrete] [id="oc-mirror-image-set-examples-helm_{context}"] == Use case: Including arbitrary images and helm charts diff --git a/modules/oc-mirror-imageset-config-params.adoc b/modules/oc-mirror-imageset-config-params.adoc index b52d9cfad959..63342545143f 100644 --- a/modules/oc-mirror-imageset-config-params.adoc +++ b/modules/oc-mirror-imageset-config-params.adoc @@ -8,7 +8,7 @@ [id="oc-mirror-imageset-config-params_{context}"] = Image set configuration parameters -The oc-mirror plugin requires an image set configuration file that defines what images to mirror. The following table lists the available parameters for the `ImageSetConfiguration` resource. +The oc-mirror plugin v1 requires an image set configuration file that defines what images to mirror. The following table lists the available parameters for the `ImageSetConfiguration` resource. // TODO: Consider adding examples for the general "Object" params @@ -21,13 +21,13 @@ The oc-mirror plugin requires an image set configuration file that defines what |`apiVersion` |The API version for the `ImageSetConfiguration` content. -|String. For example: `mirror.openshift.io/v1alpha2`. +|String. For example, `mirror.openshift.io/v1alpha2`. ifndef::microshift[] |`archiveSize` |The maximum size, in GiB, of each archive file within the image set. -|Integer. For example: `4` +|Integer. For example, `4` endif::microshift[] @@ -37,7 +37,7 @@ endif::microshift[] |`mirror.additionalImages` |The additional images configuration of the image set. -|Array of objects. For example: +|Array of objects. For example, [source,yaml] ---- @@ -47,11 +47,11 @@ additionalImages: |`mirror.additionalImages.name` |The tag or digest of the image to mirror. -|String. For example: `registry.redhat.io/ubi8/ubi:latest` +|String. For example, `registry.redhat.io/ubi8/ubi:latest` |`mirror.blockedImages` |The full tag, digest, or pattern of images to block from mirroring. -|Array of strings. For example: `docker.io/library/alpine` +|Array of strings. For example, `docker.io/library/alpine` ifndef::microshift[] @@ -61,7 +61,7 @@ ifndef::microshift[] |`mirror.helm.local` |The local helm charts to mirror. -|Array of objects. For example: +|Array of objects. For example, [source,yaml] ---- @@ -72,15 +72,15 @@ local: |`mirror.helm.local.name` |The name of the local helm chart to mirror. -|String. For example: `podinfo`. +|String. For example, `podinfo`. |`mirror.helm.local.path` |The path of the local helm chart to mirror. -|String. For example: `/test/podinfo-5.0.0.tar.gz`. +|String. For example, `/test/podinfo-5.0.0.tar.gz`. |`mirror.helm.repositories` |The remote helm repositories to mirror from. -|Array of objects. For example: +|Array of objects. For example, [source,yaml] ---- @@ -94,11 +94,11 @@ repositories: |`mirror.helm.repositories.name` |The name of the helm repository to mirror from. -|String. For example: `podinfo`. +|String. For example, `podinfo`. |`mirror.helm.repositories.url` |The URL of the helm repository to mirror from. -|String. For example: [x-]`https://example.github.io/podinfo`. +|String. For example, [x-]`https://example.github.io/podinfo`. |`mirror.helm.repositories.charts` |The remote helm charts to mirror. @@ -106,17 +106,17 @@ repositories: |`mirror.helm.repositories.charts.name` |The name of the helm chart to mirror. -|String. For example: `podinfo`. +|String. For example, `podinfo`. |`mirror.helm.repositories.charts.version` |The version of the named helm chart to mirror. -|String. For example: `5.0.0`. +|String. For example, `5.0.0`. endif::microshift[] |`mirror.operators` |The Operators configuration of the image set. -|Array of objects. For example: +|Array of objects. For example, [source,yaml,subs="attributes+"] ---- @@ -129,7 +129,7 @@ operators: |`mirror.operators.catalog` |The Operator catalog to include in the image set. -|String. For example: `registry.redhat.io/redhat/redhat-operator-index:v4.15`. +|String. For example, `registry.redhat.io/redhat/redhat-operator-index:v4.15`. |`mirror.operators.full` |When `true`, downloads the full catalog, Operator package, or Operator channel. @@ -137,7 +137,7 @@ operators: |`mirror.operators.packages` |The Operator packages configuration. -|Array of objects. For example: +|Array of objects. For example, [source,yaml,subs="attributes+"] ---- @@ -150,7 +150,7 @@ operators: |`mirror.operators.packages.name` |The Operator package name to include in the image set -|String. For example: `elasticsearch-operator`. +|String. For example, `elasticsearch-operator`. |`mirror.operators.packages.channels` |The Operator package channel configuration. @@ -158,27 +158,32 @@ operators: |`mirror.operators.packages.channels.name` |The Operator channel name, unique within a package, to include in the image set. -|String. For example: `fast` or `stable-v4.15`. +|String. For example, `fast` or `stable-v4.15`. |`mirror.operators.packages.channels.maxVersion` -|The highest version of the Operator mirror across all channels in which it exists. See the following note for further information. -|String. For example: `5.2.3-31` +|The highest version of the Operator mirror across all channels in which it exists. See the note that follows the table for further information. +|String. For example, `5.2.3-31` |`mirror.operators.packages.channels.minBundle` |The name of the minimum bundle to include, plus all bundles in the update graph to the channel head. Set this field only if the named bundle has no semantic version metadata. -|String. For example: `bundleName` +|String. For example, `bundleName` |`mirror.operators.packages.channels.minVersion` -|The lowest version of the Operator to mirror across all channels in which it exists. See the following note for further information. -|String. For example: `5.2.3-31` +|The lowest version of the Operator to mirror across all channels in which it exists. See the note that follows the table for further information. +|String. For example, `5.2.3-31` + +|`mirrors.operators.packages.defaultChannel` +|The `defaultChannel` overrides the channel that is selected as default for this Operator in the catalog. +|String. For example, `stable-5.8`. +See "Use case: Including an operator version that is not available in the default channel" for an example. |`mirror.operators.packages.maxVersion` -|The highest version of the Operator to mirror across all channels in which it exists. See the following note for further information. -|String. For example: `5.2.3-31`. +|The highest version of the Operator to mirror in this channel. See the following note for further information. +|String. For example, `5.2.3-31`. |`mirror.operators.packages.minVersion` -|The lowest version of the Operator to mirror across all channels in which it exists. See the following note for further information. -|String. For example: `5.2.3-31`. +|The lowest version of the Operator to mirror in this channel. See the note that follows the table for further information. +|String. For example, `5.2.3-31`. |`mirror.operators.skipDependencies` |If `true`, dependencies of bundles are not included. @@ -186,18 +191,18 @@ operators: |`mirror.operators.targetCatalog` |An alternative name and optional namespace hierarchy to mirror the referenced catalog as. -|String. For example: `my-namespace/my-operator-catalog` +|String. For example, `my-namespace/my-operator-catalog` |`mirror.operators.targetName` |An alternative name to mirror the referenced catalog as. The `targetName` parameter is deprecated. Use the `targetCatalog` parameter instead. -|String. For example: `my-operator-catalog` +|String. For example, `my-operator-catalog` |`mirror.operators.targetTag` |An alternative tag to append to the `targetName` or `targetCatalog`. -|String. For example: `v1` +|String. For example, `v1` ifndef::microshift[] @@ -207,7 +212,7 @@ ifndef::microshift[] |`mirror.platform.architectures` |The architecture of the platform release payload to mirror. -|Array of strings. For example: +|Array of strings. For example, [source,yaml] ---- @@ -223,7 +228,7 @@ The default value is `amd64`. The value `multi` ensures that the mirroring is su |`mirror.platform.channels` |The platform channel configuration of the image set. -|Array of objects. For example: +|Array of objects. For example, [source,yaml,subs="attributes+"] ---- @@ -238,15 +243,15 @@ channels: |`mirror.platform.channels.name` |The name of the release channel. -|String. For example: `stable-4.15` +|String. For example, `stable-4.15` |`mirror.platform.channels.minVersion` |The minimum version of the referenced platform to be mirrored. -|String. For example: `4.12.6` +|String. For example, `4.12.6` |`mirror.platform.channels.maxVersion` |The highest version of the referenced platform to be mirrored. -|String. For example: `4.15.1` +|String. For example, `4.15.1` |`mirror.platform.channels.shortestPath` |Toggles shortest path mirroring or full range mirroring. @@ -254,7 +259,7 @@ channels: |`mirror.platform.channels.type` |The type of the platform to be mirrored. -|String. For example: `ocp` or `okd`. The default is `ocp`. +|String. For example, `ocp` or `okd`. The default is `ocp`. |`mirror.platform.graph` |Indicates whether the OSUS graph is added to the image set and subsequently published to the mirror. @@ -272,7 +277,7 @@ endif::microshift[] |`storageConfig.local.path` |The path of the directory to contain the image set metadata. -|String. For example: `./path/to/dir/`. +|String. For example, `./path/to/dir/`. |`storageConfig.registry` |The registry back-end configuration of the image set. @@ -280,7 +285,7 @@ endif::microshift[] |`storageConfig.registry.imageURL` |The back-end registry URI. Can optionally include a namespace reference in the URI. -|String. For example: `quay.io/myuser/imageset:metadata`. +|String. For example, `quay.io/myuser/imageset:metadata`. |`storageConfig.registry.skipTLS` |Optionally skip TLS verification of the referenced back-end registry. @@ -292,7 +297,7 @@ endif::microshift[] ==== Using the `minVersion` and `maxVersion` properties to filter for a specific Operator version range can result in a multiple channel heads error. The error message states that there are `multiple channel heads`. This is because when the filter is applied, the update graph of the Operator is truncated. -Operator Lifecycle Manager requires that every Operator channel contains versions that form an update graph with exactly one end point, that is, the latest version of the Operator. When the filter range is applied, that graph can turn into two or more separate graphs or a graph that has more than one end point. +Operator Lifecycle Manager [OLM] requires that every Operator channel contains versions that form an update graph with exactly one end point, that is, the latest version of the Operator. When the filter range is applied, that graph can turn into two or more separate graphs or a graph that has more than one end point. To avoid this error, do not filter out the latest version of an Operator. If you still run into the error, depending on the Operator, either the `maxVersion` property must be increased or the `minVersion` property must be decreased. Because every Operator graph can be different, you might need to adjust these values until the error resolves. ==== diff --git a/modules/oc-mirror-installing-plugin.adoc b/modules/oc-mirror-installing-plugin.adoc index 1139197e7875..2058f7e42412 100644 --- a/modules/oc-mirror-installing-plugin.adoc +++ b/modules/oc-mirror-installing-plugin.adoc @@ -11,22 +11,23 @@ * You have installed the OpenShift CLI (`oc`). If you are mirroring image sets in a fully disconnected environment, ensure the following: -** You have installed the oc-mirror plugin on the host that has internet access. +** You have installed the oc-mirror plugin v1 on the host that has internet access. ** The host in the disconnected environment has access to the target mirror registry. -* You have set the `umask` parameter to `0022` on the operating system that uses oc-mirror. - * You have installed the correct binary for the {op-system-base} version that you are using. .Procedure -. Download the oc-mirror CLI plugin. +. Download the oc-mirror CLI plugin v1: .. Navigate to the link:https://console.redhat.com/openshift/downloads[Downloads] page of the {cluster-manager-url}. -.. Under the *OpenShift disconnected installation tools* section, click *Download* for *OpenShift Client (oc) mirror plugin* and save the file. +.. Under the *OpenShift disconnected installation tools* section, follow the steps to save the file: +* Select your operating system and architecture type: +** Choose *{op-system-base-full} 9* for FIPS compliance. +* Click *Download* to get the oc-mirror plugin v1 and save the file. . Extract the archive: + @@ -35,7 +36,7 @@ $ tar xvzf oc-mirror.tar.gz ---- -. If necessary, update the plugin file to be executable: +. If necessary, update the oc-mirror plugin v1 file to be executable: + [source,terminal] ---- @@ -56,7 +57,7 @@ $ sudo mv oc-mirror /usr/local/bin/. .Verification -* Run `oc mirror help` to verify that the plugin was successfully installed: +* Run the `oc mirror help` command to verify that the oc-mirror plugin v1 was successfully installed: + [source,terminal] ---- diff --git a/modules/oc-mirror-mirror-to-disk.adoc b/modules/oc-mirror-mirror-to-disk.adoc index 831b0937c974..3e515318f0b8 100644 --- a/modules/oc-mirror-mirror-to-disk.adoc +++ b/modules/oc-mirror-mirror-to-disk.adoc @@ -5,30 +5,31 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-mirror-to-disk_{context}"] -= Mirroring from mirror to disk += Mirroring from mirror-to-disk -You can use the oc-mirror plugin to generate an image set and save the contents to disk. The generated image set can then be transferred to the disconnected environment and mirrored to the target registry. +You can use the oc-mirror plugin v1 to generate an image set and save the contents to disk. The generated image set can then be transferred to the disconnected environment and mirrored to the target registry. [IMPORTANT] ==== Depending on the configuration specified in the image set configuration file, using oc-mirror to mirror images might download several hundreds of gigabytes of data to disk. -The initial image set download when you populate the mirror registry is often the largest. Because you only download the images that changed since the last time you ran the command, when you run the oc-mirror plugin again, the generated image set is often smaller. +When configuring the mirror registry, the initial image set tends to be the largest. Subsequent uses of the oc-mirror plugin v1 result in smaller downloads, as only the changed images are retrieved since the last execution. ==== -You are required to specify a storage backend in the image set configuration file. This storage backend can be a local directory or a docker v2 registry. The oc-mirror plugin stores metadata in this storage backend during image set creation. +You must specify a storage backend in the image set configuration file. See "Setting up incremental mirroring". [IMPORTANT] ==== -Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. +Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. You must use the same storage backend every time you run the oc-mirror plugin v1 for the same mirror registry. ==== .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin. +* You have installed the `oc-mirror` CLI plugin v1. * You have created the image set configuration file. +* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. // TODO: Don't need a running cluster, but need some pull secrets. Sync w/ team on this .Procedure @@ -71,5 +72,4 @@ mirror_seq1_000000.tar .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. - +* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] \ No newline at end of file diff --git a/modules/oc-mirror-mirror-to-mirror.adoc b/modules/oc-mirror-mirror-to-mirror.adoc index 72e8683a37f5..5f968e42c5ea 100644 --- a/modules/oc-mirror-mirror-to-mirror.adoc +++ b/modules/oc-mirror-mirror-to-mirror.adoc @@ -6,23 +6,28 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-mirror-to-mirror_{context}"] -= Mirroring from mirror to mirror += Mirroring an image set in a partially disconnected environment: -You can use the oc-mirror plugin to mirror an image set directly to a target mirror registry that is accessible during image set creation. +You can use the oc-mirror plugin v1 to mirror an image set directly to a target mirror registry that is accessible during image set creation. -You are required to specify a storage backend in the image set configuration file. This storage backend can be a local directory or a Docker v2 registry. The oc-mirror plugin stores metadata in this storage backend during image set creation. +[NOTE] +==== +You must specify a storage backend in the image set configuration file. See "Setting up incremental mirroring". +==== [IMPORTANT] ==== -Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. +Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. You must use the same storage backend every time you run the oc-mirror plugin v1 for the same mirror registry. ==== .Prerequisites * You have access to the internet to get the necessary container images. +* You have access to the target mirror registry. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin. +* You have installed the `oc-mirror` CLI plugin v1. * You have created the image set configuration file. +* You have set the umask parameter to `0022` on the underlying operating system that uses oc-mirror plugin v1. .Procedure @@ -70,8 +75,8 @@ ifdef::microshift[] * Convert the `ImageContentSourcePolicy` YAML content for use in manually configuring CRI-O. * If required, mirror the images from mirror to disk for disconnected or offline use. endif::microshift[] -* Configure your cluster to use the resources generated by oc-mirror. +* Configure your cluster to use the resources generated by the oc-mirror plugin. See "Configuring your cluster to use the resources generated by oc-mirror". .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. +* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] \ No newline at end of file diff --git a/modules/oc-mirror-mirroring-image-set.adoc b/modules/oc-mirror-mirroring-image-set.adoc new file mode 100644 index 000000000000..5adde9b94e0b --- /dev/null +++ b/modules/oc-mirror-mirroring-image-set.adoc @@ -0,0 +1,15 @@ +// Module included in the following assemblies: +// +// * installing/disconnected_install/installing-mirroring-disconnected.adoc +// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc +// * microshift_running_apps/microshift_operators/microshift-operators-oc-mirror.adoc + +:_mod-docs-content-type: CONCEPT +[id="mirroring-image-set_{context}"] += Mirroring an image set to a mirror registry + +To populate your mirror registry with {product-title} images, you can use one of the following scenarios: + +* *Partially disconnected environment*: The host can access both the internet and your mirror registry, but not your cluster nodes. This setup enables you to mirror content directly from the host machine. + +* *Fully disconnected environment*: The host cannot access the internet, your mirror registry, or the cluster nodes. In this setup, you must mirror the images to a file system and then bring that host or removable media into your restricted environment. \ No newline at end of file diff --git a/modules/oc-mirror-oci-format.adoc b/modules/oc-mirror-oci-format.adoc index a716103c9c28..9f9e295bdc92 100644 --- a/modules/oc-mirror-oci-format.adoc +++ b/modules/oc-mirror-oci-format.adoc @@ -15,21 +15,16 @@ The local catalog and its contents are mirrored to your target mirror registry b ==== When mirroring local OCI catalogs, any {product-title} releases or additional images that you want to mirror along with the local OCI-formatted catalog must be pulled from a registry. -You cannot mirror OCI catalogs along with an oc-mirror image set file on disk. +You cannot mirror OCI catalogs along with an oc-mirror plugin v1 image set file on disk. ==== One example use case for using the OCI feature is if you have a CI/CD system building an OCI catalog to a location on disk, and you want to mirror that OCI catalog along with an {product-title} release to your mirror registry. -[NOTE] -==== -If you used the Technology Preview OCI local catalogs feature for the oc-mirror plugin for {product-title} 4.12, you can no longer use the OCI local catalogs feature of the oc-mirror plugin to copy a catalog locally and convert it to OCI format as a first step to mirroring to a fully disconnected cluster. -==== - .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin. +* You have installed the `oc-mirror` CLI plugin v1. .Procedure @@ -100,4 +95,4 @@ Optionally, you can specify other flags to adjust the behavior of the OCI featur .Next steps -* Configure your cluster to use the resources generated by oc-mirror. +* Configure your cluster to use the resources generated by oc-mirror plugin v1. diff --git a/modules/oc-mirror-setting-incremental-mirroring.adoc b/modules/oc-mirror-setting-incremental-mirroring.adoc new file mode 100644 index 000000000000..3dde1d957b8c --- /dev/null +++ b/modules/oc-mirror-setting-incremental-mirroring.adoc @@ -0,0 +1,53 @@ +// Module included in the following assemblies: +// +// * installing/disconnected_install/installing-mirroring-disconnected.adoc + +:_mod-docs-content-type: PROCEDURE +[id="setting-incremental-mirroring_{context}"] += Setting up for incremental mirroring + +You mirror images to install, upgrade, and maintain {product-title} in a disconnected environment. Because the volume of the image set needed to install or upgrade {product-title} can be substantial, oc-mirror plugin v1 stores the metadata of the previously mirrored images in its storage backend thus reducing the volume of the image sets to the recent images only. + +You can specify the following storage backends: + +* A local directory ++ +[NOTE] +==== +Using a local directory is not recommended for enterprise scenarios because it does not scale effectively. This method is suitable only for small-scale environments or testing purposes. +==== ++ +.Example `ImageSetConfiguration` file +[source,terminal] +---- +kind: ImageSetConfiguration +apiVersion: mirror.openshift.io/v1alpha2 +storageConfig: + local: + path: <1> +---- +<1> Specify your target workspace path. + +* A registry that supports Docker v2-2 ++ +.Example `ImageSetConfiguration` file +[source,terminal] +---- +kind: ImageSetConfiguration +apiVersion: mirror.openshift.io/v1alpha2 +storageConfig: + registry: + imageURL: <1> + skipTLS: false +---- +<1> Specifies the location of your storage backend, such as `example.com/mirror/oc-mirror-metadata`. + +When mirroring content with the oc-mirror plugin v1, consider the following: + +* Ensure you always use the same storage backend and the same image set configuration for a given mirror registry location, so that the metadata remains consistent. + +* Do not attempt to push or prune images of that mirror registry location manually, without using oc-mirror plugin v1. + +* Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. + +* Keep a backup of the storage backend when mirroring content to a given location on your mirror registry with the oc-mirror plugin v1. \ No newline at end of file diff --git a/modules/oc-mirror-support.adoc b/modules/oc-mirror-support.adoc index 5db4fcdc9df4..21bb74a4af52 100644 --- a/modules/oc-mirror-support.adoc +++ b/modules/oc-mirror-support.adoc @@ -7,11 +7,11 @@ [id="oc-mirror-support_{context}"] = oc-mirror compatibility and support -The oc-mirror plugin supports mirroring {product-title} payload images and Operator catalogs for {product-title} versions 4.10 and later. +The oc-mirror plugin v1 supports mirroring {product-title} payload images and Operator catalogs for {product-title} versions 4.12 and later. [NOTE] ==== -On `aarch64`, `ppc64le`, and `s390x` architectures the oc-mirror plugin is only supported for {product-title} versions 4.14 and later. +On `aarch64`, `ppc64le`, and `s390x` architectures the oc-mirror plugin v1 is only supported for {product-title} versions 4.14 and later. ==== Use the latest available version of the oc-mirror plugin regardless of which versions of {product-title} you need to mirror. \ No newline at end of file diff --git a/modules/oc-mirror-updating-cluster-manifests.adoc b/modules/oc-mirror-updating-cluster-manifests.adoc index 56b673f2d8aa..3b5b287187a8 100644 --- a/modules/oc-mirror-updating-cluster-manifests.adoc +++ b/modules/oc-mirror-updating-cluster-manifests.adoc @@ -9,7 +9,9 @@ After you have mirrored your image set to the mirror registry, you must apply the generated `ImageContentSourcePolicy`, `CatalogSource`, and release image signature resources into the cluster. -The `ImageContentSourcePolicy` resource associates the mirror registry with the source registry and redirects image pull requests from the online registries to the mirror registry. The `CatalogSource` resource is used by Operator Lifecycle Manager (OLM) to retrieve information about the available Operators in the mirror registry. The release image signatures are used to verify the mirrored release images. +If you set `graph:true` in your `ImageSetConfiguration` file, the oc-mirror plugin v1 generates an `UpdateService.yaml` file. The `UpdateService` resource can be used to configure the OSUS service on the cluster side. See "About the OpenShift Update Service" for more information. + +The `ImageContentSourcePolicy` resource associates the mirror registry with the source registry and redirects image pull requests from the online registries to the mirror registry. The `CatalogSource` resource is used by OLM to retrieve information about the available Operators in the mirror registry. The release image signatures are used to verify the mirrored release images. .Prerequisites diff --git a/modules/oc-mirror-updating-registry-about.adoc b/modules/oc-mirror-updating-registry-about.adoc index 5a6fc76ce630..d85fe28a60ba 100644 --- a/modules/oc-mirror-updating-registry-about.adoc +++ b/modules/oc-mirror-updating-registry-about.adoc @@ -7,24 +7,24 @@ [id="oc-mirror-updating-registry-about_{context}"] = Updating your mirror registry content -You can update your mirror registry content by updating the image set configuration file and mirroring the image set to the mirror registry. The next time that you run the oc-mirror plugin, an image set is generated that only contains new and updated images since the previous execution. +In order to upgrade your disconnected {product-title} cluster, you must update your mirror registry content with updated content from the Red Hat registries. + +You can update your registry content by updating the image set configuration file and mirroring the image set to the mirror registry. Every time you run the oc-mirror plugin v1, an image set is generated that only contains new and updated images since the previous execution. While updating the mirror registry, you must take into account the following considerations: -* Images are pruned from the target mirror registry if they are no longer included in the latest image set that was generated and mirrored. Therefore, ensure that you are updating images for the same combination of the following key components so that only a differential image set is created and mirrored: +* Images are pruned from the target mirror registry if they are no longer included in the latest image set that was generated and mirrored. Therefore, ensure that you are updating images for the same combination of the following key components: -** Image set configuration +** Image set configuration: Modify your existing `ImageSetConfiguration` file to update channels and version selections to align with the desired content in your disconnected registry after completing the mirror operation. -** Destination registry +** Target mirror registry: If you specified a top-level namespace for the mirror registry during the initial image set creation, use the same namespace every time you run the oc-mirror plugin v1 for that mirror registry. -** Storage configuration +** Storage configuration: Retain the exact metadata, either container image or file directory, from your `storageConfig` across runs on the connected side. -* The images can be pruned in case of disk to mirror or mirror to mirror workflow. +* The images can be pruned during the disk-to-mirror or mirror-to-mirror workflow. * The generated image sets must be pushed to the target mirror registry in sequence. You can derive the sequence number from the file name of the generated image set archive file. -* Do not delete or modify the metadata image that is generated by the oc-mirror plugin. - -* If you specified a top-level namespace for the mirror registry during the initial image set creation, then you must use this same namespace every time you run the oc-mirror plugin for the same mirror registry. +* Do not delete or modify the metadata image that is generated by the oc-mirror plugin v1. -For more information about the workflow to update the mirror registry content, see the "High level workflow" section. \ No newline at end of file +For more information about the workflow to update the mirror registry content, see "High level workflow" section. \ No newline at end of file diff --git a/modules/oc-mirror-updating-use-cases.adoc b/modules/oc-mirror-updating-use-cases.adoc index 8ef2f66c8d77..9fa9d4603146 100644 --- a/modules/oc-mirror-updating-use-cases.adoc +++ b/modules/oc-mirror-updating-use-cases.adoc @@ -6,10 +6,9 @@ [id="oc-mirror-image-set-examples-add-images_{context}"] = Mirror registry update examples -This section covers the use cases for updating the mirror registry from disk to mirror. - -.Example `ImageSetConfiguration` file that was previously used for mirroring: +This section covers the use cases for updating the mirror registry by using the disk-to-mirror workflows. +.Example `ImageSetConfiguration` file that was previously used for mirroring [source, yaml] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -29,13 +28,15 @@ mirror: - name: rhacs-operator channels: - name: stable + minVersion: 1.0.1 ---- -[discrete] -== Mirroring a specific {product-title} version by pruning the existing images +[id="mirror-latest-version-upgrading_{context}"] +== Upgrading to the latest {product-title} version -.Updated `ImageSetConfiguration` file: +You can upgrade to the latest {product-title} version by running the mirroring workflow without changing the `ImageSetConfiguration` file. +.Updated `ImageSetConfiguration` file [source,yaml] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -46,21 +47,60 @@ storageConfig: mirror: platform: channels: - - name: stable-4.13 #<1> + - name: stable-4.12 + minVersion: 4.12.1 + maxVersion: 4.12.1 + - name: stable-4.14 operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 packages: - name: rhacs-operator channels: - name: stable + minVersion: 1.0.1 ---- -<1> Replacing by `stable-4.13` prunes all the images of `stable-4.12`. -[discrete] -== Updating to the latest version of an Operator by pruning the existing images +This image set configuration mirrors all the necessary {product-title} releases for upgrading the cluster from version 4.12.1 to the latest version in the `stable-4.14` channel. + +When adding `stable-4.14` alongside 4.12.1 while you are still using 4.12.1, note that a cluster reboot may occur after a mirror refresh, but before an upgrade, due to routine operations. It is crucial to ensure that you have the images you are currently using. -.Updated `ImageSetConfiguration` file: +[id="mirror-specific-version-prune-existing_{context}"] +== Mirroring a specific {product-title} version and pruning the existing images +You can mirror a specific {product-title} version while pruning images from an older version. In this scenario, you remove the images of {product-title} 4.12.1, as the cluster was previously upgraded to 4.14.25 during the prior mirroring process. + +.Updated `ImageSetConfiguration` file +[source,yaml] +---- +apiVersion: mirror.openshift.io/v1alpha2 +kind: ImageSetConfiguration +storageConfig: + local: + path: /home/user/metadata +mirror: + platform: + channels: + - name: stable-4.14 <1> + minVersion: 4.14.25 + - name: stable-4.15 + operators: + - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 + packages: + - name: rhacs-operator + channels: + - name: stable + minVersion: 1.0.1 +---- +<1> Replacing `stable-4.12` with `stable-4.14` prunes all the images of `stable-4.12`. + +[id="mirror-latest-version-prune-existing_{context}"] +== Updating to the latest version of an Operator and pruning the existing images + +You can update to the latest version of an Operator while pruning existing images using an updated `ImageSetConfiguration` file. By following this method, you ensure that only the necessary images for the specific upgrade path are retained. + +If the initial `ImageSetConfiguration` file contains only a specified `minVersion`, oc-mirror plugin v1 includes these versions and valid upgrade paths in its processing. To ensure only the latest versions are mirrored, and oc-mirror plugin v1 retains only the images necessary for the specific upgrade path, avoid specifying any `minVersion`. + +.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -79,17 +119,15 @@ mirror: packages: - name: rhacs-operator channels: - - name: stable #<1> + - name: stable ---- -<1> Using the same channel without specifying a version prunes the existing images and updates with the latest version of images. - -[discrete] [id="oc-mirror-image-set-examples-operator-pruning-versions_{context}"] -== Mirroring a new Operator by pruning the existing Operator +== Mirroring a new Operator and pruning the existing Operator -.Updated `ImageSetConfiguration` file: +You can mirror a new Operator and prune an existing one using an `ImageSetConfiguration` file. +.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -110,13 +148,15 @@ mirror: channels: - name: stable ---- -<1> Replacing `rhacs-operator` with `new_operator_name` prunes the Red Hat Advanced Cluster Security for Kubernetes Operator. +<1> Replacing `rhacs-operator` with `` prunes the Red Hat Advanced Cluster Security for Kubernetes Operator. -[discrete] -== Pruning all the {product-title} images -.Updated `ImageSetConfiguration` file: +[id="mirror-non-ideal-practice-pruning_{context}"] +== Pruning All {product-title} Images +You can prune all {product-title} images by running the mirroring workflow without altering the `ImageSetConfiguration` file. + +.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -125,9 +165,11 @@ storageConfig: local: path: /home/user/metadata mirror: - platform: - channels: operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 packages: ----- \ No newline at end of file +---- + +If you remove the platform section from your `ImageSetConfiguration` file, the `oc-mirror` plugin v1 removes all {product-title} images from the mirror registry. This action may disrupt the cluster's functionality, especially during a cluster reboot due to a `MachineConfiguration` change or other routine tasks. + +To avoid unintended disruptions, use the `--dry-run` flag with the mirror-to-mirror or disk-to-mirror workflows. Running `--dry-run` allows you to verify the intended actions and ensure they do not negatively impact any disconnected clusters, even if you choose to skip pruning during the actual workflow. \ No newline at end of file From 0558b7199aea88d6365043fddb36a3878404ea25 Mon Sep 17 00:00:00 2001 From: JoeAldinger Date: Mon, 20 May 2024 15:54:40 -0400 Subject: [PATCH 171/339] OSDOCS-1005:removes limitation of InFW on ROSA and AWS --- _topic_maps/_topic_map_rosa.yml | 5 ++++- modules/nw-infw-operator-cr.adoc | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index ffa6a0bde0fb..1ab9d376d46a 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -1059,8 +1059,9 @@ Topics: File: configuring-cluster-wide-proxy - Name: CIDR range definitions File: cidr-range-definitions -- Name: Network security +- Name: Network security Dir: network_security + Distros: openshift-rosa Topics: - Name: Understanding network policy APIs File: network-policy-apis @@ -1090,6 +1091,8 @@ Topics: File: default-network-policy - Name: Configuring multitenant isolation with network policy File: multitenant-network-policy + - Name: Understanding the Ingress Node Firewall Operator + File: ingress-node-firewall-operator - Name: OVN-Kubernetes network plugin Dir: ovn_kubernetes_network_provider Topics: diff --git a/modules/nw-infw-operator-cr.adoc b/modules/nw-infw-operator-cr.adoc index c6f26992a09b..0e87fc0a4fcb 100644 --- a/modules/nw-infw-operator-cr.adoc +++ b/modules/nw-infw-operator-cr.adoc @@ -17,6 +17,4 @@ The Ingress Node Firewall Operator supports only stateless firewall rules. Network interface controllers (NICs) that do not support native XDP drivers will run at a lower performance. For {product-title} 4.14 or later, you must run Ingress Node Firewall Operator on {op-system-base} 9.0 or later. - -Ingress Node Firewall Operator is not supported on {aws-first} with the default OpenShift installation or on {product-rosa} (ROSA). For more information on {product-rosa} support and ingress, see link:https://docs.openshift.com/rosa/networking/ingress-operator.html[Ingress Operator in Red Hat OpenShift Service on AWS]. ==== From 4a8509fc5eba0df1d1007cd6d12bd8c5ae9debfd Mon Sep 17 00:00:00 2001 From: Olivia Brown Date: Wed, 10 Apr 2024 12:06:45 -0400 Subject: [PATCH 172/339] OSDOCS-10218: Docs for renaming supported but not recommended to known issues --- modules/understanding-update-channels.adoc | 2 +- modules/update-availability-faq.adoc | 8 ++-- modules/update-cluster-version-object.adoc | 43 ++++++++++++++------- modules/update-conditional-updates.adoc | 2 +- modules/update-conditional-web-console.adoc | 5 +-- modules/update-evaluate-availability.adoc | 2 +- modules/update-service-overview.adoc | 2 +- modules/update-upgrading-cli.adoc | 2 +- 8 files changed, 38 insertions(+), 28 deletions(-) diff --git a/modules/understanding-update-channels.adoc b/modules/understanding-update-channels.adoc index 0e0b1ddcc78d..f8617017b3af 100644 --- a/modules/understanding-update-channels.adoc +++ b/modules/understanding-update-channels.adoc @@ -75,7 +75,7 @@ Red Hat monitors newly released versions and update paths associated with those If Red Hat removes update recommendations from any supported release, a superseding update recommendation will be provided to a future version that corrects the regression. There may however be a delay while the defect is corrected, tested, and promoted to your selected channel. -Beginning in {product-title} 4.10, when update risks are confirmed, they are declared as Conditional Update risks for the relevant updates. Each known risk may apply to all clusters or only clusters matching certain conditions. Some examples include having the `Platform` set to `None` or the CNI provider set to `OpenShiftSDN`. The Cluster Version Operator (CVO) continually evaluates known risks against the current cluster state. If no risks match, the update is recommended. If the risk matches, those updates are supported but not recommended, and a reference link is provided. The reference link helps the cluster admin decide if they would like to accept the risk and update anyway. +Beginning in {product-title} 4.10, when update risks are confirmed, they are declared as Conditional Update risks for the relevant updates. Each known risk may apply to all clusters or only clusters matching certain conditions. Some examples include having the `Platform` set to `None` or the CNI provider set to `OpenShiftSDN`. The Cluster Version Operator (CVO) continually evaluates known risks against the current cluster state. If no risks match, the update is recommended. If the risk matches, those update paths are labeled as _updates with known issues_, and a reference link to the known issues is provided. The reference link helps the cluster admin decide if they want to accept the risk and continue to update their cluster. When Red Hat chooses to declare Conditional Update risks, that action is taken in all relevant channels simultaneously. Declaration of a Conditional Update risk may happen either before or after the update has been promoted to supported channels. diff --git a/modules/update-availability-faq.adoc b/modules/update-availability-faq.adoc index 62c38970ef83..5f4a138b4990 100644 --- a/modules/update-availability-faq.adoc +++ b/modules/update-availability-faq.adoc @@ -35,18 +35,16 @@ The primary purpose of the `eus` channel is to serve as a convenience for cluste * A release that is available on the `fast` channel always becomes available on the `stable` channel after this delay. [id="supported-updates_{context}"] -*What does it mean if an update is supported but not recommended?* +*What does it mean if an update has known issues?* -* Red Hat continuously evaluates data from multiple sources to determine whether updates from one version to another lead to issues. -If an issue is identified, an update path may no longer be recommended to users. -However, even if the update path is not recommended, customers are still supported if they perform the update. +* Red{nbsp}Hat continuously evaluates data from multiple sources to determine whether updates from one version to another have any declared issues. Identified issues are typically documented in the version's release notes. +Even if the update path has known issues, customers are still supported if they perform the update. * Red Hat does not block users from updating to a certain version. Red Hat may declare conditional update risks, which may or may not apply to a particular cluster. ** Declared risks provide cluster administrators more context about a supported update. Cluster administrators can still accept the risk and update to that particular target version. -This update is always supported despite not being recommended in the context of the conditional risk. [id="removed-recommendation_{context}"] *What if I see that an update to a particular release is no longer recommended?* diff --git a/modules/update-cluster-version-object.adoc b/modules/update-cluster-version-object.adoc index 05dc37f545fd..e2466ffb6a13 100644 --- a/modules/update-cluster-version-object.adoc +++ b/modules/update-cluster-version-object.adoc @@ -37,32 +37,45 @@ $ oc adm upgrade --include-not-recommended + [NOTE] ==== -The additional `--include-not-recommended` parameter includes updates that are available but not recommended due to a known risk that applies to the cluster. +The additional `--include-not-recommended` parameter includes updates that are available with known issues that apply to the cluster. ==== + .Example output [source,terminal] ---- -Cluster version is 4.10.22 +Cluster version is 4.13.40 Upstream is unset, so the cluster will use an appropriate default. -Channel: fast-4.11 (available channels: candidate-4.10, candidate-4.11, eus-4.10, fast-4.10, fast-4.11, stable-4.10) +Channel: stable-4.14 (available channels: candidate-4.13, candidate-4.14, eus-4.14, fast-4.13, fast-4.14, stable-4.13, stable-4.14) Recommended updates: VERSION IMAGE - 4.10.26 quay.io/openshift-release-dev/ocp-release@sha256:e1fa1f513068082d97d78be643c369398b0e6820afab708d26acda2262940954 - 4.10.25 quay.io/openshift-release-dev/ocp-release@sha256:ed84fb3fbe026b3bbb4a2637ddd874452ac49c6ead1e15675f257e28664879cc - 4.10.24 quay.io/openshift-release-dev/ocp-release@sha256:aab51636460b5a9757b736a29bc92ada6e6e6282e46b06e6fd483063d590d62a - 4.10.23 quay.io/openshift-release-dev/ocp-release@sha256:e40e49d722cb36a95fa1c03002942b967ccbd7d68de10e003f0baa69abad457b - -Supported but not recommended updates: - - Version: 4.11.0 - Image: quay.io/openshift-release-dev/ocp-release@sha256:300bce8246cf880e792e106607925de0a404484637627edf5f517375517d54a4 - Recommended: False - Reason: RPMOSTreeTimeout - Message: Nodes with substantial numbers of containers and CPU contention may not reconcile machine configuration https://bugzilla.redhat.com/show_bug.cgi?id=2111817#c22 + 4.14.27 quay.io/openshift-release-dev/ocp-release@sha256:4d30b359aa6600a89ed49ce6a9a5fdab54092bcb821a25480fdfbc47e66af9ec + 4.14.26 quay.io/openshift-release-dev/ocp-release@sha256:4fe7d4ccf4d967a309f83118f1a380a656a733d7fcee1dbaf4d51752a6372890 + 4.14.25 quay.io/openshift-release-dev/ocp-release@sha256:a0ef946ef8ae75aef726af1d9bbaad278559ad8cab2c1ed1088928a0087990b6 + 4.14.24 quay.io/openshift-release-dev/ocp-release@sha256:0a34eac4b834e67f1bca94493c237e307be2c0eae7b8956d4d8ef1c0c462c7b0 + 4.14.23 quay.io/openshift-release-dev/ocp-release@sha256:f8465817382128ec7c0bc676174bad0fb43204c353e49c146ddd83a5b3d58d92 + 4.13.42 quay.io/openshift-release-dev/ocp-release@sha256:dcf5c3ad7384f8bee3c275da8f886b0bc9aea7611d166d695d0cf0fff40a0b55 + 4.13.41 quay.io/openshift-release-dev/ocp-release@sha256:dbb8aa0cf53dc5ac663514e259ad2768d8c82fd1fe7181a4cfb484e3ffdbd3ba + +Updates with known issues: + + Version: 4.14.22 + Image: quay.io/openshift-release-dev/ocp-release@sha256:7093fa606debe63820671cc92a1384e14d0b70058d4b4719d666571e1fc62190 + Reason: MultipleReasons + Message: Exposure to AzureRegistryImageMigrationUserProvisioned is unknown due to an evaluation failure: client-side throttling: only 18.061µs has elapsed since the last match call completed for this cluster condition backend; this cached cluster condition request has been queued for later execution + In Azure clusters with the user-provisioned registry storage, the in-cluster image registry component may struggle to complete the cluster update. https://issues.redhat.com/browse/IR-468 + + Incoming HTTP requests to services exposed by Routes may fail while routers reload their configuration, especially when made with Apache HTTPClient versions before 5.0. The problem is more likely to occur in clusters with higher number of Routes and corresponding endpoints. https://issues.redhat.com/browse/NE-1689 + + Version: 4.14.21 + Image: quay.io/openshift-release-dev/ocp-release@sha256:6e3fba19a1453e61f8846c6b0ad3abf41436a3550092cbfd364ad4ce194582b7 + Reason: MultipleReasons + Message: Exposure to AzureRegistryImageMigrationUserProvisioned is unknown due to an evaluation failure: client-side throttling: only 33.991µs has elapsed since the last match call completed for this cluster condition backend; this cached cluster condition request has been queued for later execution + In Azure clusters with the user-provisioned registry storage, the in-cluster image registry component may struggle to complete the cluster update. https://issues.redhat.com/browse/IR-468 + + Incoming HTTP requests to services exposed by Routes may fail while routers reload their configuration, especially when made with Apache HTTPClient versions before 5.0. The problem is more likely to occur in clusters with higher number of Routes and corresponding endpoints. https://issues.redhat.com/browse/NE-1689 ---- + The `oc adm upgrade` command queries the `ClusterVersion` resource for information about available updates and presents it in a human-readable format. diff --git a/modules/update-conditional-updates.adoc b/modules/update-conditional-updates.adoc index 8ab611a15b42..f4bd01820b56 100644 --- a/modules/update-conditional-updates.adoc +++ b/modules/update-conditional-updates.adoc @@ -24,4 +24,4 @@ $ oc adm upgrade --include-not-recommended ---- $ oc adm upgrade --allow-not-recommended --to <.> ---- -<.> `` is the supported but not recommended update version that you obtained from the output of the previous command. +<.> `` is the update version that you obtained from the output of the previous command, which is supported but also has known issues or risks. diff --git a/modules/update-conditional-web-console.adoc b/modules/update-conditional-web-console.adoc index af456be09487..0bc5ff781575 100644 --- a/modules/update-conditional-web-console.adoc +++ b/modules/update-conditional-web-console.adoc @@ -22,12 +22,11 @@ You can view and assess the risks associated with particular updates with condit .Procedure . From the web console, click *Administration* -> *Cluster settings* page and review the contents of the *Details* tab. - -. You can enable `Include supported but not recommended versions` in the `Select new version` dropdown of the *Update cluster* modal to populate the dropdown list with conditional updates. +. You can enable the `Include versions with known issues` feature in the *Select new version* dropdown of the *Update cluster* modal to populate the dropdown list with conditional updates. + [NOTE] ==== -If a `Supported but not recommended` version is selected, more information is provided with potential issues with the version. +If a version with known issues is selected, more information is provided with potential risks that are associated with the version. ==== . Review the notification detailing the potential risks to updating. \ No newline at end of file diff --git a/modules/update-evaluate-availability.adoc b/modules/update-evaluate-availability.adoc index 276ccff75b2c..dac22ee1a41b 100644 --- a/modules/update-evaluate-availability.adoc +++ b/modules/update-evaluate-availability.adoc @@ -18,4 +18,4 @@ The CVO continuously evaluates its cluster characteristics against the condition If the CVO finds that the cluster does not match the risks of an update, or that there are no risks associated with the update, it stores the target version in the `availableUpdates` field of its `ClusterVersion` resource. The user interface, either the web console or the OpenShift CLI (`oc`), presents this information in sectioned headings to the administrator. -Each *supported but not recommended* update recommendation contains a link to further resources about the risk so that the administrator can make an informed decision about the update. +Each known issue associated with the update path contains a link to further resources about the risk so that the administrator can make an informed decision about the update. diff --git a/modules/update-service-overview.adoc b/modules/update-service-overview.adoc index 184c57f7dd2f..00104ecb332b 100644 --- a/modules/update-service-overview.adoc +++ b/modules/update-service-overview.adoc @@ -19,7 +19,7 @@ To allow the OpenShift Update Service to provide only compatible updates, a rele [IMPORTANT] ==== -The OpenShift Update Service displays all recommended updates for your current cluster. If an update path is not recommended by the OpenShift Update Service, it might be because of a known issue with the update or the target release. +The OpenShift Update Service displays all recommended updates for your current cluster. If an update path is not recommended by the OpenShift Update Service, it might be because of a known issue related to the update path, such as incompatibility or availability. ==== //// diff --git a/modules/update-upgrading-cli.adoc b/modules/update-upgrading-cli.adoc index 10e077e4c1d2..754e0ff8c283 100644 --- a/modules/update-upgrading-cli.adoc +++ b/modules/update-upgrading-cli.adoc @@ -66,7 +66,7 @@ endif::openshift-origin[] + [NOTE] ==== -* If there are no available updates, updates that are supported but not recommended might still be available. +* If there are no recommended updates, updates that have known issues might still be available. See _Updating along a conditional update path_ for more information. ifndef::openshift-origin[] * For details and information on how to perform an `EUS-to-EUS` channel update, please refer to the _Preparing to perform an EUS-to-EUS upgrade_ page, listed in the Additional resources section. From 623a78352931c2c1cba6ad84e44ac7df6d4f57a1 Mon Sep 17 00:00:00 2001 From: Audrey Spaulding Date: Tue, 14 May 2024 12:13:52 -0400 Subject: [PATCH 173/339] RHEL 9 --- modules/virt-viewing-downward-metrics-tool.adoc | 5 +++++ modules/virt-viewing-downward-metrics.adoc | 4 ++++ virt/monitoring/virt-exposing-downward-metrics.adoc | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/modules/virt-viewing-downward-metrics-tool.adoc b/modules/virt-viewing-downward-metrics-tool.adoc index bfb82c855eb6..f8890092571f 100644 --- a/modules/virt-viewing-downward-metrics-tool.adoc +++ b/modules/virt-viewing-downward-metrics-tool.adoc @@ -8,6 +8,11 @@ To view downward metrics, install the `vm-dump-metrics` tool and then use the tool to expose the metrics results. +[NOTE] +==== +On Red Hat Enterprise Linux (RHEL) 9, use the command line to view downward metrics. The vm-dump-metrics tool is not supported on the Red Hat Enterprise Linux (RHEL) 9 platform. +==== + .Procedure . Install the `vm-dump-metrics` tool by running the following command: diff --git a/modules/virt-viewing-downward-metrics.adoc b/modules/virt-viewing-downward-metrics.adoc index 0a2ff1dddcc6..bca0bb6666f0 100644 --- a/modules/virt-viewing-downward-metrics.adoc +++ b/modules/virt-viewing-downward-metrics.adoc @@ -11,3 +11,7 @@ You can view downward metrics by using either of the following options: * The command line interface (CLI) * The `vm-dump-metrics` tool +[NOTE] +==== +On Red Hat Enterprise Linux (RHEL) 9, use the command line to view downward metrics. The vm-dump-metrics tool is not supported on the Red Hat Enterprise Linux (RHEL) 9 platform. +==== \ No newline at end of file diff --git a/virt/monitoring/virt-exposing-downward-metrics.adoc b/virt/monitoring/virt-exposing-downward-metrics.adoc index 4eec7c783e73..f86fd50f5abd 100644 --- a/virt/monitoring/virt-exposing-downward-metrics.adoc +++ b/virt/monitoring/virt-exposing-downward-metrics.adoc @@ -10,6 +10,13 @@ As an administrator, you can expose a limited set of host and virtual machine (V Users can view the metrics results by using the command line or the `vm-dump-metrics tool`. +[NOTE] +==== +On Red Hat Enterprise Linux (RHEL) 9, use the command line to view downward metrics. See xref:../../virt/monitoring/virt-exposing-downward-metrics.adoc#virt-viewing-downward-metrics-cli_virt-exposing-downward-metrics[Viewing downward metrics by using the command line]. + +The vm-dump-metrics tool is not supported on the Red Hat Enterprise Linux (RHEL) 9 platform. +==== + [id="virt-enabling-disabling-feature-gate"] == Enabling or disabling the downwardMetrics feature gate From c3bf09ccbc40761bd7f381a98294260351666989 Mon Sep 17 00:00:00 2001 From: StephenJamesSmith Date: Fri, 7 Jun 2024 16:15:40 -0400 Subject: [PATCH 174/339] Telcodocs 1848: Add PreflightValidation v1beta2 --- modules/kmm-build-validation-stage.adoc | 4 +- modules/kmm-example-cr.adoc | 12 ++-- modules/kmm-image-validation-stage.adoc | 4 +- modules/kmm-sign-validation-stage.adoc | 6 +- modules/kmm-validation-kickoff.adoc | 17 +----- modules/kmm-validation-lifecycle.adoc | 2 +- modules/kmm-validation-status.adoc | 60 +++++++------------ .../kmm-preflight-validation.adoc | 3 +- 8 files changed, 37 insertions(+), 71 deletions(-) diff --git a/modules/kmm-build-validation-stage.adoc b/modules/kmm-build-validation-stage.adoc index caf7e07aaa5e..0d1dc597ede3 100644 --- a/modules/kmm-build-validation-stage.adoc +++ b/modules/kmm-build-validation-stage.adoc @@ -11,13 +11,15 @@ Build validation is executed only when image validation has failed and there is [NOTE] ==== You must specify the kernel version when running `depmod`, as shown here: + [source,terminal] ---- $ RUN depmod -b /opt ${KERNEL_VERSION} ---- ==== -If the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` custom resource (CR), it will also try to push the resulting image into its repository. The resulting image name is taken from the definition of the `containerImage` field of the `Module` CR. + +If the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` custom resource (CR), it also tries to push the resulting image into its repository. The resulting image name is taken from the definition of the `containerImage` field of the `Module` CR. [NOTE] ==== diff --git a/modules/kmm-example-cr.adoc b/modules/kmm-example-cr.adoc index 7ffda037c6f9..728630408775 100644 --- a/modules/kmm-example-cr.adoc +++ b/modules/kmm-example-cr.adoc @@ -8,22 +8,22 @@ This section shows an example of the `PreflightValidationOCP` resource in the YAML format. -The example verifies all the currently present modules against the upcoming kernel version included in the {product-title} release 4.11.18, which the following release image points to: +The example verifies all of the currently present modules against the upcoming kernel version included in the {product-title} release 4.11.18, which the following release image points to: [source,terminal] ---- quay.io/openshift-release-dev/ocp-release@sha256:22e149142517dfccb47be828f012659b1ccf71d26620e6f62468c264a7ce7863 ---- -Because `.spec.pushBuiltImage` is set to `true`, KMM pushes the resulting images of Build/Sign into the defined repositories. +Because `.spec.pushBuiltImage` is set to `true`, KMM pushes the resulting images of Build/Sign in to the defined repositories. [source,yaml] ---- -apiVersion: kmm.sigs.x-k8s.io/v1beta1 +apiVersion: kmm.sigs.x-k8s.io/v1beta2 kind: PreflightValidationOCP metadata: - name: preflight + name: preflight spec: - releaseImage: quay.io/openshift-release-dev/ocp-release@sha256:22e149142517dfccb47be828f012659b1ccf71d26620e6f62468c264a7ce7863 - pushBuiltImage: true + releaseImage: quay.io/openshift-release-dev/ocp-release@sha256:22e149142517dfccb47be828f012659b1ccf71d26620e6f62468c264a7ce7863 + pushBuiltImage: true ---- diff --git a/modules/kmm-image-validation-stage.adoc b/modules/kmm-image-validation-stage.adoc index 11d824a67d32..7f185f1810ca 100644 --- a/modules/kmm-image-validation-stage.adoc +++ b/modules/kmm-image-validation-stage.adoc @@ -12,6 +12,4 @@ Image validation consists of two stages: . Image existence and accessibility. The code tries to access the image defined for the upgraded kernel in the module and get its manifests. -. Verify the presence of the kernel module defined in the `Module` in the correct path for future `modprobe` execution. The correct path is `/lib/modules//`. - -If this validation is successful, it probably means that the kernel module was compiled with the correct Linux headers. +. Verify the presence of the kernel module defined in the `Module` in the correct path for future `modprobe` execution. If this validation is successful, it probably means that the kernel module was compiled with the correct Linux headers. The correct path is `/lib/modules//`. diff --git a/modules/kmm-sign-validation-stage.adoc b/modules/kmm-sign-validation-stage.adoc index 6a87ae084779..12fd190d3dc7 100644 --- a/modules/kmm-sign-validation-stage.adoc +++ b/modules/kmm-sign-validation-stage.adoc @@ -6,11 +6,9 @@ [id="kmm-sign-validation-stage_{context}"] = Sign validation stage -Sign validation is executed only when image validation has failed, there is a `sign` section in the `Module` that is relevant for the upgrade kernel, and build validation finished successfully in the event there was a `build` section in the `Module` relevant for the upgraded kernel. Sign validation will try to run the sign job and validate that it finishes successfully. +Sign validation is executed only when image validation has failed. There is a `sign` section in the `Module` resource that is relevant for the upgrade kernel, and build validation finishes successfully in case there was a `build` section in the `Module` relevant for the upgraded kernel. Sign validation attempts to run the sign job and validate that it finishes successfully. -If the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` CR, sign validation will also try to push the resulting image to its registry. - -The resulting image is always the image defined in the `containerImage` field of the `Module`. The input image is either the output of the Build stage, or an image defined in the `UnsignedImage` field. +If the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` CR, sign validation also tries to push the resulting image to its registry. The resulting image is always the image defined in the `ContainerImage` field of the `Module`. The input image is either the output of the Build stage, or an image defined in the `UnsignedImage` field. [NOTE] ==== diff --git a/modules/kmm-validation-kickoff.adoc b/modules/kmm-validation-kickoff.adoc index 906267f90490..c2636dc3ddbb 100644 --- a/modules/kmm-validation-kickoff.adoc +++ b/modules/kmm-validation-kickoff.adoc @@ -8,19 +8,6 @@ Preflight validation is triggered by creating a `PreflightValidationOCP` resource in the cluster. This spec contains two fields: -[source,terminal] ----- -type PreflightValidationOCPSpec struct { - // releaseImage describes the OCP release image that all Modules need to be checked against. - // +kubebuilder:validation:Required - ReleaseImage string `json:"releaseImage"` <1> - // Boolean flag that determines whether images build during preflight must also - // be pushed to a defined repository - // +optional - PushBuiltImage bool `json:"pushBuiltImage"` <2> -} ----- +`releaseImage`:: Mandatory field that provides the name of the release image for the {product-title} version the cluster is upgraded to. -<1> `ReleaseImage` - Mandatory field that provides the name of the release image for the {product-title} version the cluster is upgraded to. - -<2> `PushBuiltImage` - If `true`, then the images created during the Build and Sign validation are pushed to their repositories (`false` by default). +`pushBuiltImage`:: If `true`, then the images created during the Build and Sign validation are pushed to their repositories. This field is `false` by default. diff --git a/modules/kmm-validation-lifecycle.adoc b/modules/kmm-validation-lifecycle.adoc index fa7e39a7462f..4eed2e38a517 100644 --- a/modules/kmm-validation-lifecycle.adoc +++ b/modules/kmm-validation-lifecycle.adoc @@ -6,6 +6,6 @@ [id="kmm-validation-lifecycle_{context}"] = Validation lifecycle -Preflight validation attempts to validate every module loaded in the cluster. Preflight will stop running validation on a `Module` resource after the validation is successful. In case module validation has failed, you can change the module definitions and Preflight will try to validate the module again in the next loop. +Preflight validation attempts to validate every module loaded in the cluster. Preflight stops running validation on a `Module` resource after the validation is successful. If module validation fails, you can change the module definitions and Preflight tries to validate the module again in the next loop. If you want to run Preflight validation for an additional kernel, then you should create another `PreflightValidationOCP` resource for that kernel. After all the modules have been validated, it is recommended to delete the `PreflightValidationOCP` resource. diff --git a/modules/kmm-validation-status.adoc b/modules/kmm-validation-status.adoc index f3d50623702e..970b8f5aabb8 100644 --- a/modules/kmm-validation-status.adoc +++ b/modules/kmm-validation-status.adoc @@ -6,43 +6,23 @@ [id="kmm-validation-status_{context}"] = Validation status -Preflight reports the status and progress of each module in the cluster that it attempts to -validate. - -[source,terminal] ----- -type CRStatus struct { - // Status of Module CR verification: true (verified), false (verification failed), - // error (error during verification process), unknown (verification has not started yet) - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum=True;False - VerificationStatus string `json:"verificationStatus"` <1> - // StatusReason contains a string describing the status source. - // +optional - StatusReason string `json:"statusReason,omitempty"` <2> - // Current stage of the verification process: - // image (image existence verification), build(build process verification) - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum=Image;Build;Sign;Requeued;Done - VerificationStage string `json:"verificationStage"` <3> - // LastTransitionTime is the last time the CR status transitioned from one status to another. - // This should be when the underlying status changed. If that is not known, then using the time when the API field changed is acceptable. - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=date-time - LastTransitionTime metav1.Time `json:"lastTransitionTime" protobuf:"bytes,4,opt,name=lastTransitionTime"` <4> -} ----- - -The following fields apply to each module: - -<1> `VerificationStatus` - `true` or `false`, validated or not. - -<2> `StatusReason` - Verbal explanation regarding the status. - -<3> `VerificationStage` - Describes the validation stage being executed (Image, Build, Sign). - -<4> `LastTransitionTime` - The time of the last update to the status. +A `PreflightValidationOCP` resource reports the status and progress of each module in the cluster that it attempts or has attempted to validate in its `.status.modules` list. Elements of that list contain the following fields: + +`lastTransitionTime`:: The last time the `Module` resource status transitioned from one status to another. This should be when the underlying status has changed. If that is not known, then using the time when the API field changed is acceptable. + +`name`:: The name of the `Module` resource. + +`namespace`:: The namespace of the `Module` resource. + +`statusReason`:: Verbal explanation regarding the status. + +`verificationStage`:: Describes the validation stage being executed: + +* `image`: Image existence verification +* `build`: Build process verification +* `sign`: Sign process verification + +`verificationStatus`:: The status of the Module verification: + +* `true`: Verified +* `false`: Verification failed +* `error`: Error during the verification process +* `unknown`: Verfication has not started diff --git a/updating/preparing_for_updates/kmm-preflight-validation.adoc b/updating/preparing_for_updates/kmm-preflight-validation.adoc index 5d5da309c730..50077bddc0bd 100644 --- a/updating/preparing_for_updates/kmm-preflight-validation.adoc +++ b/updating/preparing_for_updates/kmm-preflight-validation.adoc @@ -11,8 +11,9 @@ WARNING: This assembly has been moved into a subdirectory for 4.14+. Changes to To do: Remove this comment once 4.13 docs are EOL. //// +// Updated for TELCODOCS-1848 -Before performing an upgrade on the cluster with applied KMM modules, the administrator must verify that kernel modules installed using KMM are able to be installed on the nodes after the cluster upgrade and possible kernel upgrade. Preflight attempts to validate every `Module` loaded in the cluster, in parallel. Preflight does not wait for validation of one `Module` to complete before starting validation of another `Module`. +Before performing an upgrade on the cluster with applied KMM modules, you must verify that kernel modules installed using KMM are able to be installed on the nodes after the cluster upgrade and possible kernel upgrade. Preflight attempts to validate every `Module` loaded in the cluster, in parallel. Preflight does not wait for validation of one `Module` to complete before starting validation of another `Module`. :FeatureName: Kernel Module Management Operator Preflight validation From 9b0337b8fd579458ee239cea72db65cefed833a4 Mon Sep 17 00:00:00 2001 From: srir Date: Wed, 29 May 2024 16:13:38 +0530 Subject: [PATCH 175/339] OSDOCS#10702: Docs for Multiarch Tuning Operator --- _topic_maps/_topic_map.yml | 2 + ...creating-podplacment-config-using-cli.adoc | 58 ++++++++ ...-podplacment-config-using-web-console.adoc | 44 +++++++ ...ulti-arch-creating-podplacment-config.adoc | 52 ++++++++ ...deleting-podplacment-config-using-cli.adoc | 49 +++++++ ...-podplacment-config-using-web-console.adoc | 43 ++++++ ...ulti-arch-deleting-podplacment-config.adoc | 9 ++ modules/multi-arch-installing-using-cli.adoc | 124 ++++++++++++++++++ ...lti-arch-installing-using-web-console.adoc | 48 +++++++ .../multi-arch-uninstalling-using-cli.adoc | 80 +++++++++++ ...i-arch-uninstalling-using-web-console.adoc | 34 +++++ ...i-architecture-modify-machine-set-aws.adoc | 6 +- ...i-architecture-modify-machine-set-gcp.adoc | 2 + ...multi-architecture-modify-machine-set.adoc | 2 + ...creating-multi-arch-compute-nodes-aws.adoc | 2 + ...eating-multi-arch-compute-nodes-azure.adoc | 4 +- ...g-multi-arch-compute-nodes-bare-metal.adoc | 5 + ...creating-multi-arch-compute-nodes-gcp.adoc | 4 +- ...ng-multi-arch-compute-nodes-ibm-power.adoc | 7 +- ...ng-multi-arch-compute-nodes-ibm-z-kvm.adoc | 6 +- ...eating-multi-arch-compute-nodes-ibm-z.adoc | 6 +- .../multi-architecture-compute-managing.adoc | 6 +- .../multiarch-tuning-operator.adoc | 63 +++++++++ snippets/about-multiarch-tuning-operator.adoc | 12 ++ .../migrating-to-multi-payload.adoc | 5 +- 25 files changed, 659 insertions(+), 14 deletions(-) create mode 100644 modules/multi-arch-creating-podplacment-config-using-cli.adoc create mode 100644 modules/multi-arch-creating-podplacment-config-using-web-console.adoc create mode 100644 modules/multi-arch-creating-podplacment-config.adoc create mode 100644 modules/multi-arch-deleting-podplacment-config-using-cli.adoc create mode 100644 modules/multi-arch-deleting-podplacment-config-using-web-console.adoc create mode 100644 modules/multi-arch-deleting-podplacment-config.adoc create mode 100644 modules/multi-arch-installing-using-cli.adoc create mode 100644 modules/multi-arch-installing-using-web-console.adoc create mode 100644 modules/multi-arch-uninstalling-using-cli.adoc create mode 100644 modules/multi-arch-uninstalling-using-web-console.adoc create mode 100644 post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc create mode 100644 snippets/about-multiarch-tuning-operator.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 9d1de9899e4c..492051e3541e 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -609,6 +609,8 @@ Topics: File: creating-multi-arch-compute-nodes-ibm-power - Name: Managing your cluster with multi-architecture compute machines File: multi-architecture-compute-managing + - Name: Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator + File: multiarch-tuning-operator - Name: Enabling encryption on a vSphere cluster File: vsphere-post-installation-encryption - Name: Configuring the vSphere connection settings after an installation diff --git a/modules/multi-arch-creating-podplacment-config-using-cli.adoc b/modules/multi-arch-creating-podplacment-config-using-cli.adoc new file mode 100644 index 000000000000..1db44cf1bd57 --- /dev/null +++ b/modules/multi-arch-creating-podplacment-config-using-cli.adoc @@ -0,0 +1,58 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-creating-podplacement-config-using-cli_{context}"] += Creating the ClusterPodPlacementConfig object by using the CLI + +You can create the `ClusterPodPlacementConfig` object by using the {oc-first}. + +.Prerequisites + +* You have installed `oc`. +* You have logged in to `oc` as a user with `cluster-admin` privileges. +* You have installed the Multiarch Tuning Operator. + +.Procedure + +. Create a `ClusterPodPlacementConfig` object YAML file: ++ +.Example `ClusterPodPlacementConfig` object configuration +[source,yaml] +---- +apiVersion: multiarch.openshift.io/v1beta1 +kind: ClusterPodPlacementConfig +metadata: + name: cluster +spec: + logVerbosityLevel: Normal + namespaceSelector: + matchExpressions: + - key: multiarch.openshift.io/exclude-pod-placement + operator: DoesNotExist +---- + +. Create the `ClusterPodPlacementConfig` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f <1> +---- +<1> Replace `` with the name of the `ClusterPodPlacementConfig` object YAML file. + +.Verification + +* To check that the `ClusterPodPlacementConfig` object is created, run the following command: ++ +[source,terminal] +---- +$ oc get clusterpodplacementconfig +---- ++ +.Example output +[source,terminal] +---- +NAME AGE +cluster 29s +---- \ No newline at end of file diff --git a/modules/multi-arch-creating-podplacment-config-using-web-console.adoc b/modules/multi-arch-creating-podplacment-config-using-web-console.adoc new file mode 100644 index 000000000000..c831903ad9b1 --- /dev/null +++ b/modules/multi-arch-creating-podplacment-config-using-web-console.adoc @@ -0,0 +1,44 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-creating-podplacement-config-using-web-console_{context}"] + += Creating the ClusterPodPlacementConfig object by using the web console + +You can create the `ClusterPodPlacementConfig` object by using the {product-title} web console. + +.Prerequisites + +* You have access to the cluster with `cluster-admin` privileges. +* You have access to the {product-title} web console. +* You have installed the Multiarch Tuning Operator. + +.Procedure + +. Log in to the {product-title} web console. + +. Click *Operators* → *Installed Operators*. + +. On the *Installed Operators* page, click *Multiarch Tuning Operator*. + +. Click the *Cluster Pod Placement Config* tab. + +. Select either *Form view* or *YAML view*. + +. Configure the `ClusterPodPlacementConfig` object parameters. + +. Click *Create*. + +. Optional: If you want to edit the `ClusterPodPlacementConfig` object, perform the following actions: + +.. Click the *Cluster Pod Placement Config* tab. +.. Select *Edit ClusterPodPlacementConfig* from the options menu. +.. Click *YAML* and edit the `ClusterPodPlacementConfig` object parameters. +.. Click *Save*. + +.Verification + +* On the *Cluster Pod Placement Config* page, check that the `ClusterPodPlacementConfig` object is in the `Ready` state. + diff --git a/modules/multi-arch-creating-podplacment-config.adoc b/modules/multi-arch-creating-podplacment-config.adoc new file mode 100644 index 000000000000..29fe31924c9f --- /dev/null +++ b/modules/multi-arch-creating-podplacment-config.adoc @@ -0,0 +1,52 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: CONCEPT +[id="multi-architecture-creating-podplacement-config_{context}"] += Creating the ClusterPodPlacementConfig object + +After installing the Multiarch Tuning Operator, you must create the `ClusterPodPlacementConfig` object. + +[NOTE] +==== +You can create only a single instance of the `ClusterPodPlacementConfig` object. +==== + +The `ClusterPodPlacementConfig` object is used to enable or disable the pod placement operand of the Multiarch Tuning Operator. + +.Example `ClusterPodPlacementConfig` object configuration +[source,yaml] +---- +apiVersion: multiarch.openshift.io/v1beta1 +kind: ClusterPodPlacementConfig +metadata: + name: cluster <1> +spec: + logVerbosityLevel: Normal <2> + namespaceSelector: <3> + matchExpressions: + - key: multiarch.openshift.io/exclude-pod-placement + operator: DoesNotExist +---- +<1> You must set this field value to `cluster`. +<2> Optional: You can set the field value to `Normal`, `Debug`, `Trace`, or `TraceAll`. The value is set to `Normal` by default. +<3> Optional: You can configure the `namespaceSelector` to select the namespaces in which the Multiarch Tuning Operator's pod placement operand must process the `nodeAffinity` of the pods. All namespaces are considered by default. + +In this example, the `operator` field value is set to `DoesNotExist`. Therefore, if the `key` field value (`multiarch.openshift.io/exclude-pod-placement`) is set as a label in a namespace, the operand does not process the `nodeAffinity` of the pods in that namespace. Instead, the operand processes the `nodeAffinity` of the pods in namespaces that do not contain the label. + +If you want the operand to process the `nodeAffinity` of the pods only in specific namespaces, you can configure the `namespaceSelector` as follows: +[source,yaml] +---- +namespaceSelector: + matchExpressions: + - key: multiarch.openshift.io/include-pod-placement + operator: Exists +---- + +In this example, the `operator` field value is set to `Exists`. Therefore, the operand processes the `nodeAffinity` of the pods only in namespaces that contain the `multiarch.openshift.io/include-pod-placement` label. + +[IMPORTANT] +==== +The namespaces starting with `openshift-`, `kube-`, and `hypershift-` are excluded. +==== \ No newline at end of file diff --git a/modules/multi-arch-deleting-podplacment-config-using-cli.adoc b/modules/multi-arch-deleting-podplacment-config-using-cli.adoc new file mode 100644 index 000000000000..194b452c1715 --- /dev/null +++ b/modules/multi-arch-deleting-podplacment-config-using-cli.adoc @@ -0,0 +1,49 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-deleting-podplacement-config-using-cli_{context}"] += Deleting the ClusterPodPlacementConfig object by using the CLI + +You can delete the `ClusterPodPlacementConfig` object by using the {oc-first}. + +.Prerequisites + +* You have installed `oc`. +* You have logged in to `oc` as a user with `cluster-admin` privileges. + +.Procedure + +. Log in to the {oc-first}. + +. Delete the `ClusterPodPlacementConfig` object by running the following command: ++ +[source,terminal] +---- +$ oc delete clusterpodplacementconfig cluster +---- + +.Verification + +* To check that the `ClusterPodPlacementConfig` object is deleted, run the following command: ++ +[source,terminal] +---- +$ oc get clusterpodplacementconfig +---- ++ +.Example output +[source,terminal] +---- +No resources found +---- + +.Next steps + +* After deleting the `ClusterPodPlacementConfig` object, ensure that none of the pods are in the `Pending` phase due to the `SchedulingGated` reason. You can delete the scheduling gate from all of the gated pods by running the following command: ++ +[source,terminal] +---- +$ oc get pods -A -l multiarch.openshift.io/scheduling-gate=gated -o json | jq 'del(.items[].spec.schedulingGates[] | select(.name=="multiarch.openshift.io/scheduling-gate"))' | oc apply -f - +---- \ No newline at end of file diff --git a/modules/multi-arch-deleting-podplacment-config-using-web-console.adoc b/modules/multi-arch-deleting-podplacment-config-using-web-console.adoc new file mode 100644 index 000000000000..643d2ddd33af --- /dev/null +++ b/modules/multi-arch-deleting-podplacment-config-using-web-console.adoc @@ -0,0 +1,43 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-deleting-podplacement-config-using-web-console_{context}"] + += Deleting the ClusterPodPlacementConfig object by using the web console + +You can delete the `ClusterPodPlacementConfig` object by using the {product-title} web console. + +.Prerequisites + +* You have access to the cluster with `cluster-admin` privileges. +* You have access to the {product-title} web console. +* You have created the `ClusterPodPlacementConfig` object. + +.Procedure + +. Log in to the {product-title} web console. + +. Click *Operators* → *Installed Operators*. + +. On the *Installed Operators* page, click *Multiarch Tuning Operator*. + +. Click the *Cluster Pod Placement Config* tab. + +. Select *Delete ClusterPodPlacementConfig* from the options menu. + +. Click *Delete*. + +.Verification + +* On the *Cluster Pod Placement Config* page, check that the `ClusterPodPlacementConfig` object has been deleted. + +.Next steps + +* After deleting the `ClusterPodPlacementConfig` object, ensure that none of the pods are in the `Pending` phase due to the `SchedulingGated` reason. You can delete the scheduling gate from all the gated pods by running the following command in the {oc-first}: ++ +[source,terminal] +---- +$ oc get pods -A -l multiarch.openshift.io/scheduling-gate=gated -o json | jq 'del(.items[].spec.schedulingGates[] | select(.name=="multiarch.openshift.io/scheduling-gate"))' | oc apply -f - +---- diff --git a/modules/multi-arch-deleting-podplacment-config.adoc b/modules/multi-arch-deleting-podplacment-config.adoc new file mode 100644 index 000000000000..5c975b19f354 --- /dev/null +++ b/modules/multi-arch-deleting-podplacment-config.adoc @@ -0,0 +1,9 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: CONCEPT +[id="multi-architecture-deleting-podplacement-config_{context}"] += Deleting the ClusterPodPlacementConfig object + +You can delete the `ClusterPodPlacementConfig` object by using the {product-title} CLI or the {product-title} web console. \ No newline at end of file diff --git a/modules/multi-arch-installing-using-cli.adoc b/modules/multi-arch-installing-using-cli.adoc new file mode 100644 index 000000000000..36a2062f8f68 --- /dev/null +++ b/modules/multi-arch-installing-using-cli.adoc @@ -0,0 +1,124 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-installing-using-cli_{context}"] += Installing the Multiarch Tuning Operator by using the CLI + +You can install the Multiarch Tuning Operator by using the {oc-first}. + +.Prerequisites + +* You have installed `oc`. +* You have logged in to `oc` as a user with `cluster-admin` privileges. + +.Procedure + +. Create a new project named `openshift-multiarch-tuning-operator` by running the following command: ++ +[source,terminal] +---- +$ oc new-project openshift-multiarch-tuning-operator +---- + +. Create an `OperatorGroup` object: + +.. Create a YAML file with the configuration for creating an `OperatorGroup` object. ++ +.Example YAML configuration for creating an `OperatorGroup` object: +[source,yaml] +---- +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: openshift-multiarch-tuning-operator + namespace: openshift-multiarch-tuning-operator +spec: {} +---- + +.. Create the `OperatorGroup` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f <1> +---- +<1> Replace `` with the name of the YAML file that contains the `OperatorGroup` object configuration. + +. Create a `Subscription` object: + +.. Create a YAML file with the configuration for creating a `Subscription` object. ++ +.Example YAML configuration for creating a `Subscription` object: +[source,yaml] +---- +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: openshift-multiarch-tuning-operator + namespace: openshift-multiarch-tuning-operator +spec: + channel: tech-preview + name: multiarch-tuning-operator + source: redhat-operators + sourceNamespace: openshift-marketplace + installPlanApproval: Automatic + startingCSV: multiarch-tuning-operator.v0.9.0 +---- + +.. Create the `Subscription` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f <1> +---- +<1> Replace `` with the name of the YAML file that contains the `Subscription` object configuration. + +[NOTE] +==== +For more details about configuring the `Subscription` object and `OperatorGroup` object, see "Installing from OperatorHub using the CLI". +==== + +.Verification + +. To verify that the Multiarch Tuning Operator is installed, run the following command: ++ +[source,terminal] +---- +$ oc get csv -n openshift-multiarch-tuning-operator +---- ++ +.Example output +[source,terminal] +---- +NAME DISPLAY VERSION REPLACES PHASE +multiarch-tuning-operator.v0.9.0 Multiarch Tuning Operator 0.9.0 Succeeded +---- + +. Optional: To verify that the `OperatorGroup` object is created, run the following command: ++ +[source,terminal] +---- +$ oc get operatorgroup -n openshift-multiarch-tuning-operator +---- ++ +.Example output +[source,terminal] +---- +NAME AGE +openshift-multiarch-tuning-operator-q8zbb 133m +---- + +. Optional: To verify that the `Subscription` object is created, run the following command: ++ +[source,terminal] +---- +$ oc get subscription -n openshift-multiarch-tuning-operator +---- ++ +.Example output +[source,terminal] +---- +NAME PACKAGE SOURCE CHANNEL +multiarch-tuning-operator multiarch-tuning-operator multiarch-tuning-operator-catalog tech-preview +---- diff --git a/modules/multi-arch-installing-using-web-console.adoc b/modules/multi-arch-installing-using-web-console.adoc new file mode 100644 index 000000000000..8f4a9c227cea --- /dev/null +++ b/modules/multi-arch-installing-using-web-console.adoc @@ -0,0 +1,48 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-installing-using-web-console_{context}"] += Installing the Multiarch Tuning Operator by using the web console + +You can install the Multiarch Tuning Operator by using the {product-title} web console. + +.Prerequisites + +* You have access to the cluster with `cluster-admin` privileges. + +* You have access to the {product-title} web console. + +.Procedure + +. Log in to the {product-title} web console. +. Click *Operators -> OperatorHub*. +. Enter *Multiarch Tuning Operator* in the search field. +. Click *Multiarch Tuning Operator*. +. Select the *Multiarch Tuning Operator* version from the *Version* list. +. Click *Install* +. Set the following options on the *Operator Installation* page: +.. *Update Channel* as *tech-preview*. +.. *Installation Mode* as *All namespaces on the cluster*. +.. *Installed Namespace* as *Operator recommended Namespace* or *Select a Namespace*. ++ +The recommended Operator namespace is `openshift-multiarch-tuning-operator`. If the `openshift-multiarch-tuning-operator` namespace does not exist, it is created during the operator installation. ++ +If you select *Select a namespace*, you must select a namespace for the Operator from the *Select Project* list. +.. *Update approval* as *Automatic* or *Manual*. ++ +[NOTE] +==== +If you select *Automatic* updates, Operator Lifecycle Manager (OLM) automatically updates the running instance of the Multiarch Tuning Operator without any intervention. + +If you select *Manual* updates, OLM creates an update request. +As a cluster administrator, you must manually approve the update request to update the Multiarch Tuning Operator to a newer version. +==== +. Optional: Select the *Enable Operator recommended cluster monitoring on this Namespace* checkbox. +. Click *Install*. + +.Verification + +. Navigate to *Operators* → *Installed Operators*. +. Verify that the *Multiarch Tuning Operator* is listed with the *Status* field as *Succeeded* in the `openshift-multiarch-tuning-operator` namespace. \ No newline at end of file diff --git a/modules/multi-arch-uninstalling-using-cli.adoc b/modules/multi-arch-uninstalling-using-cli.adoc new file mode 100644 index 000000000000..fff920fb64ba --- /dev/null +++ b/modules/multi-arch-uninstalling-using-cli.adoc @@ -0,0 +1,80 @@ +//Module included in the following assemblies +// +//post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-uninstalling-using-cli_{context}"] + += Uninstalling the Multiarch Tuning Operator by using the CLI +You can uninstall the Multiarch Tuning Operator by using the {oc-first}. + +.Prerequisites + +* You have installed `oc`. +* You have logged in to `oc` as a user with `cluster-admin` privileges. +* You deleted the `ClusterPodPlacementConfig` object. ++ +[IMPORTANT] +==== +You must delete the `ClusterPodPlacementConfig` object before uninstalling the Multiarch Tuning Operator. Uninstalling the Operator without deleting the `ClusterPodPlacementConfig` object can lead to unexpected behavior. +==== + +.Procedure + +. Get the `currentCSV` value for the Multiarch Tuning Operator by running the following command: ++ +[source,terminal] +---- +$ oc get subscription.operators.coreos.com multiarch-tuning-operator -n -o yaml | grep currentCSV <1> +---- +<1> Replace `` with the name of the namespace where you want to uninstall the Multiarch Tuning Operator. ++ +.Example output +[source,terminal] +---- +currentCSV: multiarch-tuning-operator.v0.9.0 +---- + +. Delete the `Subscription` object by running the following command: ++ +[source,terminal] +---- +$ oc delete subscription.operators.coreos.com openshift-multiarch-tuning-operator -n <1> +---- +<1> Replace `` with the name of the namespace where you want to uninstall the Multiarch Tuning Operator. ++ +.Example output +[source,terminal] +---- +subscription.operators.coreos.com "openshift-multiarch-tuning-operator" deleted +---- + +. Delete the CSV for the Multiarch Tuning Operator in the target namespace using the `currentCSV` value by running the following command: ++ +[source,terminal] +---- +$ oc delete clusterserviceversion -n <1> +---- +<1> Replace `` with the `currentCSV` value for the Multiarch Tuning Operator. For example: `multiarch-tuning-operator.v0.9.0`. Replace `` with the name of the namespace where you want to uninstall the Multiarch Tuning Operator. ++ +.Example output +[source,terminal] +---- +clusterserviceversion.operators.coreos.com "multiarch-tuning-operator.v0.9.0" deleted +---- + +.Verification + +* To verify that the Multiarch Tuning Operator is uninstalled, run the following command: ++ +[source,terminal] +---- +$ oc get csv -n <1> +---- +<1> Replace `` with the name of the namespace where you have uninstalled the Multiarch Tuning Operator. ++ +.Example output +[source,terminal] +---- +No resources found in openshift-multiarch-tuning-operator namespace. +---- diff --git a/modules/multi-arch-uninstalling-using-web-console.adoc b/modules/multi-arch-uninstalling-using-web-console.adoc new file mode 100644 index 000000000000..1b2842c2dad7 --- /dev/null +++ b/modules/multi-arch-uninstalling-using-web-console.adoc @@ -0,0 +1,34 @@ +// Module included in the following assemblies +// +// * post_installation_configuration/multiarch-tuning-operator.adoc + +:_mod-docs-content-type: PROCEDURE +[id="multi-architecture-uninstalling-using-web-console_{context}"] += Uninstalling the Multiarch Tuning Operator by using the web console + +You can uninstall the Multiarch Tuning Operator by using the {product-title} web console. + +.Prerequisites + +* You have access to the cluster with `cluster-admin` permissions. +* You deleted the `ClusterPodPlacementConfig` object. ++ +[IMPORTANT] +==== +You must delete the `ClusterPodPlacementConfig` object before uninstalling the Multiarch Tuning Operator. Uninstalling the Operator without deleting the `ClusterPodPlacementConfig` object can lead to unexpected behavior. +==== + +.Procedure + +. Log in to the {product-title} web console. +. Click *Operators -> OperatorHub*. +. Enter *Multiarch Tuning Operator* in the search field. +. Click *Multiarch Tuning Operator*. +. Click the *Details* tab. +. From the *Actions* menu, select *Uninstall Operator*. +. When prompted, click *Uninstall*. + +.Verification + +. Navigate to *Operators* → *Installed Operators*. +. On the *Installed Operators* page, verify that the *Multiarch Tuning Operator* is not listed. \ No newline at end of file diff --git a/modules/multi-architecture-modify-machine-set-aws.adoc b/modules/multi-architecture-modify-machine-set-aws.adoc index f4038ad6838f..966967422218 100644 --- a/modules/multi-architecture-modify-machine-set-aws.adoc +++ b/modules/multi-architecture-modify-machine-set-aws.adoc @@ -1,6 +1,6 @@ -//Module included in the following assembly +// Module included in the following assembly // -//post_installation_configuration/cluster-tasks.adoc +// * post_installation_configuration/cluster-tasks.adoc :_mod-docs-content-type: PROCEDURE [id="multi-architecture-modify-machine-set-aws_{context}"] @@ -9,6 +9,8 @@ To configure a cluster with multi-architecture compute machines, you must create a AWS ARM64 compute machine set. This adds ARM64 compute nodes to your cluster so that your cluster has multi-architecture compute machines. +include::snippets/about-multiarch-tuning-operator.adoc[] + .Prerequisites * You installed the OpenShift CLI (`oc`). diff --git a/modules/multi-architecture-modify-machine-set-gcp.adoc b/modules/multi-architecture-modify-machine-set-gcp.adoc index 2fbdabede970..a94901360bac 100644 --- a/modules/multi-architecture-modify-machine-set-gcp.adoc +++ b/modules/multi-architecture-modify-machine-set-gcp.adoc @@ -8,6 +8,8 @@ To configure a cluster with multi-architecture compute machines, you must create a GCP ARM64 compute machine set. This adds ARM64 compute nodes to your cluster. +include::snippets/about-multiarch-tuning-operator.adoc[] + .Prerequisites * You installed the {oc-first}. diff --git a/modules/multi-architecture-modify-machine-set.adoc b/modules/multi-architecture-modify-machine-set.adoc index 28db16583220..3ab8289058d7 100644 --- a/modules/multi-architecture-modify-machine-set.adoc +++ b/modules/multi-architecture-modify-machine-set.adoc @@ -9,6 +9,8 @@ To add ARM64 compute nodes to your cluster, you must create an Azure compute machine set that uses the ARM64 boot image. To create your own custom compute machine set on Azure, see "Creating a compute machine set on Azure". +include::snippets/about-multiarch-tuning-operator.adoc[] + .Prerequisites * You installed the OpenShift CLI (`oc`). diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-aws.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-aws.adoc index dbe3241ebd34..d76c532ac780 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-aws.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-aws.adoc @@ -16,3 +16,5 @@ include::modules/multi-architecture-modify-machine-set-aws.adoc[leveloffset=+1] .Additional resources * xref:../../installing/installing_aws/ipi/installing-aws-customizations.adoc#installation-aws-arm-tested-machine-types_installing-aws-customizations[Tested instance types for AWS 64-bit ARM] +* xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator] + diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-azure.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-azure.adoc index 8f193d3af1fe..79bf450a7ef8 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-azure.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-azure.adoc @@ -18,4 +18,6 @@ include::modules/multi-architecture-modify-machine-set.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* xref:../../machine_management/creating_machinesets/creating-machineset-azure.adoc#creating-machineset-azure[Creating a compute machine set on Azure] \ No newline at end of file +* xref:../../machine_management/creating_machinesets/creating-machineset-azure.adoc#creating-machineset-azure[Creating a compute machine set on Azure] + +* xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator] \ No newline at end of file diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-bare-metal.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-bare-metal.adoc index bf9bbcacf0d2..72a2963795f0 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-bare-metal.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-bare-metal.adoc @@ -16,6 +16,11 @@ Before you can add additional compute nodes to your cluster, you must upgrade yo The following procedures explain how to create a {op-system} compute machine using an ISO image or network PXE booting. This will allow you to add additional nodes to your cluster and deploy a cluster with multi-architecture compute machines. +[NOTE] +==== +Before adding a secondary architecture node to your cluster, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` object. For more information, see xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. +==== + include::modules/multi-architecture-verifying-cluster-compatibility.adoc[leveloffset=+1] include::modules/machine-user-infra-machines-iso.adoc[leveloffset=+1] diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-gcp.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-gcp.adoc index 9f245a080a85..fd4d4282d68e 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-gcp.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-gcp.adoc @@ -19,4 +19,6 @@ include::modules/multi-architecture-modify-machine-set-gcp.adoc[leveloffset=+1] .Additional resources -* xref:../../installing/installing_gcp/installing-gcp-customizations.adoc#installation-gcp-tested-machine-types-arm_installing-gcp-customizations[Tested instance types for GCP on 64-bit ARM infrastructures] \ No newline at end of file +* xref:../../installing/installing_gcp/installing-gcp-customizations.adoc#installation-gcp-tested-machine-types-arm_installing-gcp-customizations[Tested instance types for GCP on 64-bit ARM infrastructures] + +* xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator] \ No newline at end of file diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-power.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-power.adoc index aa04ae163944..32517a97a2ff 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-power.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-power.adoc @@ -15,12 +15,13 @@ Before you can add `ppc64le` nodes to your cluster, you must upgrade your cluste The following procedures explain how to create a {op-system} compute machine using an ISO image or network PXE booting. This will allow you to add `ppc64le` nodes to your cluster and deploy a cluster with multi-architecture compute machines. -[NOTE] -==== To create an {ibm-power-name} (`ppc64le`) cluster with multi-architecture compute machines on `x86_64`, follow the instructions for xref:../../installing/installing_ibm_power/preparing-to-install-on-ibm-power.adoc#preparing-to-install-on-ibm-power[Installing a cluster on {ibm-power-name}]. You can then add `x86_64` compute machines as described in xref:./creating-multi-arch-compute-nodes-bare-metal.adoc#creating-multi-arch-compute-nodes-bare-metal[Creating a cluster with multi-architecture compute machines on bare metal, {ibm-power-title}, or {ibm-z-title}]. -==== +[NOTE] +==== +Before adding a secondary architecture node to your cluster, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` object. For more information, see xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. +==== include::modules/multi-architecture-verifying-cluster-compatibility.adoc[leveloffset=+1] diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-kvm.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-kvm.adoc index db7bd393ad34..6e18e7f139d1 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-kvm.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z-kvm.adoc @@ -12,10 +12,12 @@ Before you can add `s390x` nodes to your cluster, you must upgrade your cluster The following procedures explain how to create a {op-system} compute machine using a {op-system-base} KVM instance. This will allow you to add `s390x` nodes to your cluster and deploy a cluster with multi-architecture compute machines. -[NOTE] -==== To create an {ibm-z-name} or {ibm-linuxone-name} (`s390x`) cluster with multi-architecture compute machines on `x86_64`, follow the instructions for xref:../../installing/installing_ibm_z/preparing-to-install-on-ibm-z.adoc#preparing-to-install-on-ibm-z[Installing a cluster on {ibm-z-name} and {ibm-linuxone-name}]. You can then add `x86_64` compute machines as described in xref:./creating-multi-arch-compute-nodes-bare-metal.adoc#creating-multi-arch-compute-nodes-bare-metal[Creating a cluster with multi-architecture compute machines on bare metal, {ibm-power-title}, or {ibm-z-title}]. + +[NOTE] +==== +Before adding a secondary architecture node to your cluster, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` object. For more information, see xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. ==== include::modules/multi-architecture-verifying-cluster-compatibility.adoc[leveloffset=+1] diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z.adoc index 6aaa8b504db7..3105d358058f 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/creating-multi-arch-compute-nodes-ibm-z.adoc @@ -12,10 +12,12 @@ Before you can add `s390x` nodes to your cluster, you must upgrade your cluster The following procedures explain how to create a {op-system} compute machine using a z/VM instance. This will allow you to add `s390x` nodes to your cluster and deploy a cluster with multi-architecture compute machines. -[NOTE] -==== To create an {ibm-z-name} or {ibm-linuxone-name} (`s390x`) cluster with multi-architecture compute machines on `x86_64`, follow the instructions for xref:../../installing/installing_ibm_z/preparing-to-install-on-ibm-z.adoc#preparing-to-install-on-ibm-z[Installing a cluster on {ibm-z-name} and {ibm-linuxone-name}]. You can then add `x86_64` compute machines as described in xref:./creating-multi-arch-compute-nodes-bare-metal.adoc#creating-multi-arch-compute-nodes-bare-metal[Creating a cluster with multi-architecture compute machines on bare metal, {ibm-power-title}, or {ibm-z-title}]. + +[NOTE] +==== +Before adding a secondary architecture node to your cluster, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` object. For more information, see xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. ==== include::modules/multi-architecture-verifying-cluster-compatibility.adoc[leveloffset=+1] diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/multi-architecture-compute-managing.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/multi-architecture-compute-managing.adoc index f0e3e4b8446c..d251bc7ba5b2 100644 --- a/post_installation_configuration/configuring-multi-arch-compute-machines/multi-architecture-compute-managing.adoc +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/multi-architecture-compute-managing.adoc @@ -1,7 +1,7 @@ :_mod-docs-content-type: ASSEMBLY :context: multi-architecture-compute-managing [id="multi-architecture-compute-managing"] -= Managing your cluster with multi-architecture compute machines += Managing a cluster with multi-architecture compute machines include::_attributes/common-attributes.adoc[] toc::[] @@ -10,7 +10,9 @@ toc::[] Deploying a workload on a cluster with compute nodes of different architectures requires attention and monitoring of your cluster. There might be further actions you need to take in order to successfully place pods in the nodes of your cluster. -For more detailed information on node affinity, scheduling, taints and tolerlations, see the following documentatinon: +You can use the Multiarch Tuning Operator to enable architecture-aware scheduling of workloads on clusters with multi-architecture compute machines. The Multiarch Tuning Operator implements additional scheduler predicates in the pods specifications based on the architectures that the pods can support at creation time. For more information, see xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. + +For more information on node affinity, scheduling, taints and tolerlations, see the following documentation: * xref:../../nodes/scheduling/nodes-scheduler-taints-tolerations.adoc#nodes-scheduler-taints-tolerations[Controlling pod placement using node taints]. diff --git a/post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc b/post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc new file mode 100644 index 000000000000..8090a56d2e30 --- /dev/null +++ b/post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc @@ -0,0 +1,63 @@ +:_mod-docs-content-type: ASSEMBLY +:context: multiarch-tuning-operator +[id="multiarch-tuning-operator"] += Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator +include::_attributes/common-attributes.adoc[] + +toc::[] + +[IMPORTANT] +==== +The Multiarch Tuning Operator is a Technology Preview feature only. Technology Preview features are not supported with Red{nbsp}Hat production service level agreements (SLAs) and might not be functionally complete. Red{nbsp}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{nbsp}Hat Technology Preview features, see link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview Features Support Scope]. +==== + +The Multiarch Tuning Operator enhances the operational experience within multi-architecture clusters, and single-architecture clusters that are migrating to a multi-architecture compute configuration. + +This Operator implements the `ClusterPodPlacementConfig` object to support architecture-aware workload scheduling. + +When you create the `ClusterPodPlacementConfig` object, the Multiarch Tuning Operator deploys an operand. This operand automates the configuration of scheduling predicates for the workloads based on their supported architectures. It uses the `kubernetes.io/arch` label set by the kubelet in the node objects. + +When a pod is created, the operand configures the `nodeAffinity` field in the pod specification by computing the subset of architectures that the pod can support. + +Before a pod enters the scheduling cycle, the operand adds the `multiarch.openshift.io/scheduling-gate` scheduling gate that prevents the scheduling of the pod until the operand completes the following actions: + +. Compute a predicate for the `kubernetes.io/arch` label. +. Integrate the predicate as a `nodeAffinity` requirement in the pod specification. +. Remove the scheduling gate. + +These operand actions restrict the scheduling of workloads to those nodes that have the supported architectures. + +[IMPORTANT] +==== +The Technology Preview version of the Multiarch Tuning Operator does not support clusters with restricted network scenarios. +==== + +//Installing Multiarch Tuning Operator +include::modules/multi-arch-installing-using-cli.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../operators/user/olm-installing-operators-in-namespace.adoc#olm-installing-operator-from-operatorhub-using-cli_olm-installing-operators-in-namespace[Installing from OperatorHub using the CLI] + +include::modules/multi-arch-installing-using-web-console.adoc[leveloffset=+1] + +//Creating the pod placement config object +include::modules/multi-arch-creating-podplacment-config.adoc[leveloffset=+1] + +include::modules/multi-arch-creating-podplacment-config-using-cli.adoc[leveloffset=+2] + +include::modules/multi-arch-creating-podplacment-config-using-web-console.adoc[leveloffset=+2] + +//Deleting the pod placement config object +include::modules/multi-arch-deleting-podplacment-config.adoc[leveloffset=+1] + +include::modules/multi-arch-deleting-podplacment-config-using-cli.adoc[leveloffset=+2] + +include::modules/multi-arch-deleting-podplacment-config-using-web-console.adoc[leveloffset=+2] + +//Uninstalling Multiarch Tuning Operator +include::modules/multi-arch-uninstalling-using-cli.adoc[leveloffset=+1] + +include::modules/multi-arch-uninstalling-using-web-console.adoc[leveloffset=+1] \ No newline at end of file diff --git a/snippets/about-multiarch-tuning-operator.adoc b/snippets/about-multiarch-tuning-operator.adoc new file mode 100644 index 000000000000..b196ca636b53 --- /dev/null +++ b/snippets/about-multiarch-tuning-operator.adoc @@ -0,0 +1,12 @@ +// Snippet included in the following modules + +// * post_installation_configuration/cluster-tasks.adoc/multi-architecture-modify-machine-set-aws.adoc +// * post_installation_configuration/cluster-tasks.adoc/multi-architecture-modify-machine-set-gcp.adoc +// * post_installation_configuration/cluster-tasks.adoc/multi-architecture-modify-machine-set.adoc + +:_mod-docs-content-type: SNIPPET + +[NOTE] +==== +Before adding a secondary architecture node to your cluster, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` custom resource. For more information, see "Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator". +==== diff --git a/updating/updating_a_cluster/migrating-to-multi-payload.adoc b/updating/updating_a_cluster/migrating-to-multi-payload.adoc index 869005a62142..0420a0052d7a 100644 --- a/updating/updating_a_cluster/migrating-to-multi-payload.adoc +++ b/updating/updating_a_cluster/migrating-to-multi-payload.adoc @@ -14,7 +14,9 @@ To do: Remove this comment once 4.13 docs are EOL. You can migrate your current cluster with single-architecture compute machines to a cluster with multi-architecture compute machines by updating to a multi-architecture, manifest-listed payload. This allows you to add mixed architecture compute nodes to your cluster. -For information about configuring your multi-architecture compute machines, see _Configuring multi-architecture compute machines on an {product-title} cluster_. +For information about configuring your multi-architecture compute machines, see "Configuring multi-architecture compute machines on an {product-title} cluster". + +Before migrating your single-architecture cluster to a cluster with multi-architecture compute machines, it is recommended to install the Multiarch Tuning Operator, and deploy a `ClusterPodPlacementConfig` custom resource. For more information, see "Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator [IMPORTANT] ==== @@ -27,6 +29,7 @@ include::modules/migrating-to-multi-arch-cli.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources * xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multi-architecture-configuration.adoc#multi-architecture-configuration[Configuring multi-architecture compute machines on an {product-title} cluster] +* xref:../../post_installation_configuration/configuring-multi-arch-compute-machines/multiarch-tuning-operator.adoc#multiarch-tuning-operator[Managing workloads on multi-architecture clusters by using the Multiarch Tuning Operator]. * xref:../../updating/updating_a_cluster/updating-cluster-web-console.adoc#updating-cluster-web-console[Updating a cluster using the web console] * xref:../../updating/updating_a_cluster/updating-cluster-cli.adoc#updating-cluster-cli[Updating a cluster using the CLI] * xref:../../updating/understanding_updates/intro-to-updates.adoc#understanding-clusterversion-conditiontypes_understanding-openshift-updates[Understanding cluster version condition types] From 6589353c03a9f88306136a69ccf3cbe92dcb05c5 Mon Sep 17 00:00:00 2001 From: srir Date: Thu, 6 Jun 2024 17:17:27 +0530 Subject: [PATCH 176/339] TELCODOCS#1894: Added Uninstalling LVM Stroage by using the CLI proc --- ...-manager-operator-using-openshift-cli.adoc | 68 +++++++++++++++++++ ...-operator-using-openshift-web-console.adoc | 2 +- .../persistent-storage-using-lvms.adoc | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-cli.adoc diff --git a/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-cli.adoc b/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-cli.adoc new file mode 100644 index 000000000000..ea0aa62c01ff --- /dev/null +++ b/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-cli.adoc @@ -0,0 +1,68 @@ +// Module included in the following assemblies: +// +// storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc + +:_mod-docs-content-type: PROCEDURE +[id="lvms-unstalling-lvms-using-cli_{context}"] += Uninstalling {lvms} by using the CLI + +You can uninstall {lvms} by using the {oc-first}. + +.Prerequisites + +* You have logged in to `oc` as a user with `cluster-admin` permissions. +* You deleted the persistent volume claims (PVCs), volume snapshots, and volume clones provisioned by {lvms}. You have also deleted the applications that are using these resources. +* You deleted the `LVMCluster` custom resource (CR). + +.Procedure + +. Get the `currentCSV` value for the {lvms} Operator by running the following command: ++ +[source,terminal] +---- +$ oc get subscription.operators.coreos.com lvms-operator -n -o yaml | grep currentCSV +---- ++ +.Example output +[source,terminal] +---- +currentCSV: lvms-operator.v4.15.3 +---- + +. Delete the subscription by running the following command: ++ +[source,terminal] +---- +$ oc delete subscription.operators.coreos.com lvms-operator -n +---- ++ +.Example output +[source,terminal] +---- +subscription.operators.coreos.com "lvms-operator" deleted +---- + +. Delete the CSV for the {lvms} Operator in the target namespace by running the following command: ++ +[source,terminal] +---- +$ oc delete clusterserviceversion -n <1> +---- +<1> Replace `` with the `currentCSV` value for the {lvms} Operator. ++ +.Example output +[source,terminal] +---- +clusterserviceversion.operators.coreos.com "lvms-operator.v4.15.3" deleted +---- + +.Verification + +* To verify that the {lvms} Operator is uninstalled, run the following command: ++ +[source,terminal] +---- +$ oc get csv -n +---- ++ +If the {lvms} Operator was successfully uninstalled, it does not appear in the output of this command. \ No newline at end of file diff --git a/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-web-console.adoc b/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-web-console.adoc index c9b1dd017f6a..9139ae563414 100644 --- a/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-web-console.adoc +++ b/modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-web-console.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="lvms-unstalling-lvms-with-web-console_{context}"] -= Uninstalling {lvms} using the web console += Uninstalling {lvms} by using the web console You can uninstall {lvms} using the {product-title} web console. diff --git a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc index 6d1efbf5e205..e14c3e3f826d 100644 --- a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc +++ b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc @@ -201,6 +201,7 @@ include::modules/lvms-monitoring-logical-volume-manager-operator.adoc[leveloffse // Uninstalling LVM Storage +include::modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-cli.adoc[leveloffset=+1] include::modules/lvms-uninstalling-logical-volume-manager-operator-using-openshift-web-console.adoc[leveloffset=+1] include::modules/lvms-uninstalling-logical-volume-manager-operator-using-rhacm.adoc[leveloffset=+1] From 710eaeffd865f4212c3446bfbcbf506dbd77a2f9 Mon Sep 17 00:00:00 2001 From: subhtk Date: Thu, 23 May 2024 11:48:34 +0530 Subject: [PATCH 177/339] Created new section for route secret load for external certificate --- ...-integrating-route-secret-certificate.adoc | 6 ++ ...gress-route-secret-load-external-cert.adoc | 82 +++++++++++++++++++ networking/routes/secured-routes.adoc | 7 ++ 3 files changed, 95 insertions(+) create mode 100644 modules/nw-ingress-integrating-route-secret-certificate.adoc create mode 100644 modules/nw-ingress-route-secret-load-external-cert.adoc diff --git a/modules/nw-ingress-integrating-route-secret-certificate.adoc b/modules/nw-ingress-integrating-route-secret-certificate.adoc new file mode 100644 index 000000000000..4ac39bf62fa0 --- /dev/null +++ b/modules/nw-ingress-integrating-route-secret-certificate.adoc @@ -0,0 +1,6 @@ +// +// * ingress/routes.adoc + +:_mod-docs-content-type: PROCEDURE +[id="nw-ingress-integrating-route-secret-certificate_{context}"] += Securing route with external certificates in TLS secrets diff --git a/modules/nw-ingress-route-secret-load-external-cert.adoc b/modules/nw-ingress-route-secret-load-external-cert.adoc new file mode 100644 index 000000000000..2b39444ff29c --- /dev/null +++ b/modules/nw-ingress-route-secret-load-external-cert.adoc @@ -0,0 +1,82 @@ +// Module included in the following assemblies: +// +// * networking/routes/secured-routes.adoc + +:_mod-docs-content-type: PROCEDURE +[id="nw-ingress-route-secret-load-external-cert_{context}"] += Creating a route with externally managed certificate + +:FeatureName: Securing route with external certificates in TLS secrets +include::snippets/technology-preview.adoc[] + +You can configure {product-title} routes with third-party certificate management solutions by using the `.spec.tls.externalCertificate` field of the route API. You can reference externally managed TLS certificates via secrets, eliminating the need for manual certificate management. Using the externally managed certificate reduces errors ensuring a smoother rollout of certificate updates, enabling the OpenShift router to serve renewed certificates promptly. + +[NOTE] +==== +This feature applies to both edge routes and re-encrypt routes. +==== + +.Prerequisites + +* You must enable the `RouteExternalCertificate` feature gate. +* You must have the `create` and `update` permissions on the `routes/custom-host`. +* You must have a secret containing a valid certificate/key pair in PEM-encoded format of type `kubernetes.io/tls`, which includes both `tls.key` and `tls.crt` keys. +* You must place the referenced secret in the same namespace as the route you want to secure. + +.Procedure + +. Create a `role` in the same namespace as the secret to allow the router service account read access by running the following command: ++ +[source,terminal] +---- +$ oc create role secret-reader --verb=get,list,watch --resource=secrets --resource-name= \ <1> +--namespace= <2> +---- +<1> Specify the actual name of your secret. +<2> Specify the namespace where both your secret and route reside. + +. Create a `rolebinding` in the same namespace as the secret and bind the router service account to the newly created role by running the following command: ++ +[source,terminal] +---- +$ oc create rolebinding secret-reader-binding --role=secret-reader --serviceaccount=openshift-ingress:router --namespace= <1> +---- +<1> Specify the namespace where both your secret and route reside. + +. Create a YAML file that defines the `route` and specifies the secret containing your certificate using the following example. ++ +.YAML definition of the secure route +[source,yaml] +---- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: myedge + namespace: test +spec: + host: myedge-test.apps.example.com + tls: + externalCertificate: + name: <1> + termination: edge + [...] +[...] +---- +<1> Specify the actual name of your secret. + +. Create a `route` resource by running the following command: ++ +[source,terminal] +---- +$ oc apply -f <1> +---- +<1> Specify the generated YAML filename. + +If the secret exists and has a certificate/key pair, the router will serve the generated certificate if all prerequisites are met. + +[NOTE] +==== +If `.spec.tls.externalCertificate` is not provided, the router will use default generated certificates. + +You cannot provide the `.spec.tls.certificate` field or the `.spec.tls.key` field when using the `.spec.tls.externalCertificate` field. +==== diff --git a/networking/routes/secured-routes.adoc b/networking/routes/secured-routes.adoc index 5cd7bef36113..7bd896457ff3 100644 --- a/networking/routes/secured-routes.adoc +++ b/networking/routes/secured-routes.adoc @@ -25,3 +25,10 @@ include::modules/nw-ingress-creating-a-reencrypt-route-with-a-custom-certificate include::modules/nw-ingress-creating-an-edge-route-with-a-custom-certificate.adoc[leveloffset=+1] include::modules/nw-ingress-creating-a-passthrough-route.adoc[leveloffset=+1] + +include::modules/nw-ingress-route-secret-load-external-cert.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For troubleshooting routes with externally managed certificates, check the {product-title} router pod logs for errors, see xref:../../support/troubleshooting/investigating-pod-issues.adoc[Investigating pod issues]. \ No newline at end of file From 31f7ff75110c8be73a4beec929d8a33e38c599a1 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Thu, 13 Jun 2024 09:22:37 -0400 Subject: [PATCH 178/339] Removes multi-nic egress IP condition --- modules/nw-egress-ips-about.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/nw-egress-ips-about.adoc b/modules/nw-egress-ips-about.adoc index 94253a4a9cff..2097acfda4bf 100644 --- a/modules/nw-egress-ips-about.adoc +++ b/modules/nw-egress-ips-about.adoc @@ -207,8 +207,6 @@ For users who want an egress IP and traffic to be routed over a particular inter * If a network interface is removed or if the IP address and subnet mask which allows the egress IP to be hosted on the interface is removed, then the egress IP is reconfigured. Consequently, it could be assigned to another node and interface. -* The Egress IP must be IPv4. IPv6 is currently unsupported. - * IP forwarding must be enabled for the network interface. To enable IP forwarding, you can use the `oc edit network.operator` command and edit the object like the following example: + [source,yaml] From 560f8d3c3b292b69ea41b3bbcc10bd1fb3a1b1b1 Mon Sep 17 00:00:00 2001 From: Ben Scott Date: Sun, 9 Jun 2024 21:20:21 -0400 Subject: [PATCH 179/339] OSDOCS-10086 reorganizing AWS UPI pre-install (UPI) --- _topic_maps/_topic_map.yml | 4 ++ .../upi/installing-aws-user-infra.adoc | 42 +---------------- .../installing-restricted-networks-aws.adoc | 35 ++------------ .../upi/upi-aws-installation-reqs.adoc | 32 +++++++++++++ .../upi/upi-aws-preparing-to-install.adoc | 46 +++++++++++++++++++ 5 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 installing/installing_aws/upi/upi-aws-installation-reqs.adoc create mode 100644 installing/installing_aws/upi/upi-aws-preparing-to-install.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 492051e3541e..b52dc17752f0 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -196,6 +196,10 @@ Topics: Dir: upi Distros: openshift-origin,openshift-enterprise Topics: + - Name: Preparing to install a cluster + File: upi-aws-preparing-to-install + - Name: Installation requirements + File: upi-aws-installation-reqs - Name: Installing a cluster using CloudFormation templates File: installing-aws-user-infra - Name: Installing a cluster in a restricted network with user-provisioned infrastructure diff --git a/installing/installing_aws/upi/installing-aws-user-infra.adoc b/installing/installing_aws/upi/installing-aws-user-infra.adoc index 3261096b5a5d..dbe0ef279466 100644 --- a/installing/installing_aws/upi/installing-aws-user-infra.adoc +++ b/installing/installing_aws/upi/installing-aws-user-infra.adoc @@ -26,6 +26,7 @@ The steps for performing a user-provisioned infrastructure installation are prov ==== If you have an AWS profile stored on your computer, it must not use a temporary session token that you generated while using a multi-factor authentication device. The cluster continues to use your current AWS credentials to create AWS resources for the entire life of the cluster, so you must use key-based, long-term credentials. To generate appropriate keys, see link:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html[Managing Access Keys for IAM Users] in the AWS documentation. You can supply the keys when you run the installation program. ==== +* You xref:../../../installing/installing_aws/upi/upi-aws-installation-reqs#upi-aws-installation-reqs[prepared the user-provisioned infrastructure.] * You downloaded the AWS CLI and installed it on your computer. See link:https://docs.aws.amazon.com/cli/latest/userguide/install-bundle.html[Install the AWS CLI Using the Bundled Installer (Linux, macOS, or UNIX)] in the AWS documentation. * If you use a firewall, you xref:../../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured it to allow the sites] that your cluster requires access to. + @@ -35,38 +36,6 @@ Be sure to also review this site list if you are configuring a proxy. ==== * If the cloud identity and access management (IAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the `kube-system` namespace, you can xref:../../../installing/installing_aws/ipi/installing-aws-customizations.adoc#manually-create-iam_installing-aws-customizations[manually create and maintain long-term credentials]. -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -[id="installation-requirements-user-infra_{context}"] -== Requirements for a cluster with user-provisioned infrastructure - -For a cluster that contains user-provisioned infrastructure, you must deploy all -of the required machines. - -This section describes the requirements for deploying {product-title} on user-provisioned infrastructure. - -include::modules/installation-machine-requirements.adoc[leveloffset=+2] -include::modules/installation-minimum-resource-requirements.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../../../scalability_and_performance/optimization/optimizing-storage.adoc#optimizing-storage[Optimizing storage] - -include::modules/installation-aws-tested-machine-types.adoc[leveloffset=+2] -include::modules/installation-aws-arm-tested-machine-types.adoc[leveloffset=+2] -include::modules/csr-management.adoc[leveloffset=+2] - -include::modules/installation-aws-user-infra-requirements.adoc[leveloffset=+1] - -include::modules/installation-aws-permissions.adoc[leveloffset=+2] - -include::modules/installation-aws-marketplace-subscribe.adoc[leveloffset=+1] - -include::modules/installation-obtaining-installer.adoc[leveloffset=+1] - -include::modules/ssh-agent-using.adoc[leveloffset=+1] - include::modules/installation-user-infra-generate.adoc[leveloffset=+1] include::modules/installation-disk-partitioning-upi-templates.adoc[leveloffset=+2] @@ -175,8 +144,6 @@ include::modules/installation-aws-user-infra-bootstrap.adoc[leveloffset=+1] * You can view details about the running instances that are created by using the link:https://console.aws.amazon.com/ec2[AWS EC2 console]. -include::modules/cli-installing-cli.adoc[leveloffset=+1] - include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] include::modules/installation-approve-csrs.adoc[leveloffset=+1] @@ -204,13 +171,6 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * See xref:../../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console. -include::modules/cluster-telemetry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* See xref:../../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service. - [role="_additional-resources"] [id="installing-aws-user-infra-additional-resources"] == Additional resources diff --git a/installing/installing_aws/upi/installing-restricted-networks-aws.adoc b/installing/installing_aws/upi/installing-restricted-networks-aws.adoc index edaf54a0e803..6a8dd6cb365a 100644 --- a/installing/installing_aws/upi/installing-restricted-networks-aws.adoc +++ b/installing/installing_aws/upi/installing-restricted-networks-aws.adoc @@ -42,6 +42,7 @@ Because the installation media is on the mirror host, you can use that computer ==== If you have an AWS profile stored on your computer, it must not use a temporary session token that you generated while using a multi-factor authentication device. The cluster continues to use your current AWS credentials to create AWS resources for the entire life of the cluster, so you must use key-based, long-term credentials. To generate appropriate keys, see link:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html[Managing Access Keys for IAM Users] in the AWS documentation. You can supply the keys when you run the installation program. ==== +* You xref:../../../installing/installing_aws/upi/upi-aws-installation-reqs#upi-aws-installation-reqs[prepared the user-provisioned infrastructure.] * You downloaded the AWS CLI and installed it on your computer. See link:https://docs.aws.amazon.com/cli/latest/userguide/install-bundle.html[Install the AWS CLI Using the Bundled Installer (Linux, macOS, or UNIX)] in the AWS documentation. * If you use a firewall and plan to use the Telemetry service, you xref:../../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured the firewall to allow the sites] that your cluster requires access to. + @@ -53,36 +54,8 @@ Be sure to also review this site list if you are configuring a proxy. include::modules/installation-about-restricted-network.adoc[leveloffset=+1] -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -[id="installation-requirements-user-infra_{context}"] -== Requirements for a cluster with user-provisioned infrastructure - -For a cluster that contains user-provisioned infrastructure, you must deploy all -of the required machines. - -This section describes the requirements for deploying {product-title} on user-provisioned infrastructure. - -include::modules/installation-machine-requirements.adoc[leveloffset=+2] -include::modules/installation-minimum-resource-requirements.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../../../scalability_and_performance/optimization/optimizing-storage.adoc#optimizing-storage[Optimizing storage] - -include::modules/installation-aws-tested-machine-types.adoc[leveloffset=+2] -include::modules/installation-aws-arm-tested-machine-types.adoc[leveloffset=+2] -include::modules/csr-management.adoc[leveloffset=+2] - -include::modules/installation-aws-user-infra-requirements.adoc[leveloffset=+1] - -include::modules/installation-aws-permissions.adoc[leveloffset=+2] - //You extract the installation program from the mirrored content. -include::modules/ssh-agent-using.adoc[leveloffset=+1] - include::modules/installation-user-infra-generate.adoc[leveloffset=+1] include::modules/installation-disk-partitioning-upi-templates.adoc[leveloffset=+2] @@ -163,8 +136,6 @@ include::modules/installation-aws-user-infra-bootstrap.adoc[leveloffset=+1] //You can install the CLI on the mirror host. -include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] - include::modules/installation-approve-csrs.adoc[leveloffset=+1] include::modules/installation-operators-config.adoc[leveloffset=+1] @@ -183,6 +154,8 @@ include::modules/installation-create-ingress-dns-records.adoc[leveloffset=+1] include::modules/installation-aws-user-infra-installation.adoc[leveloffset=+1] +include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] + include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] [role="_additional-resources"] @@ -190,8 +163,6 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * See xref:../../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console. -include::modules/cluster-telemetry.adoc[leveloffset=+1] - [role="_additional-resources"] .Additional resources diff --git a/installing/installing_aws/upi/upi-aws-installation-reqs.adoc b/installing/installing_aws/upi/upi-aws-installation-reqs.adoc new file mode 100644 index 000000000000..6364d09d344b --- /dev/null +++ b/installing/installing_aws/upi/upi-aws-installation-reqs.adoc @@ -0,0 +1,32 @@ +:_mod-docs-content-type: ASSEMBLY +[id="upi-aws-installation-reqs"] += Installation requirements for user-provisioned infrastructure on AWS +include::_attributes/common-attributes.adoc[] +:context: upi-aws-installation-reqs + +toc::[] + +Before you begin an installation on infrastructure that you provision, be sure that your AWS environment meets the following installation requirements. + +For a cluster that contains user-provisioned infrastructure, you must deploy all +of the required machines. + + +include::modules/installation-machine-requirements.adoc[leveloffset=+1] +include::modules/installation-minimum-resource-requirements.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../../scalability_and_performance/optimization/optimizing-storage.adoc#optimizing-storage[Optimizing storage] + +include::modules/installation-aws-tested-machine-types.adoc[leveloffset=+2] +include::modules/installation-aws-arm-tested-machine-types.adoc[leveloffset=+2] + +include::modules/csr-management.adoc[leveloffset=+1] + +include::modules/installation-aws-user-infra-requirements.adoc[leveloffset=+1] + +include::modules/installation-aws-permissions.adoc[leveloffset=+1] + +include::modules/installation-aws-marketplace-subscribe.adoc[leveloffset=+1] \ No newline at end of file diff --git a/installing/installing_aws/upi/upi-aws-preparing-to-install.adoc b/installing/installing_aws/upi/upi-aws-preparing-to-install.adoc new file mode 100644 index 000000000000..60228d484170 --- /dev/null +++ b/installing/installing_aws/upi/upi-aws-preparing-to-install.adoc @@ -0,0 +1,46 @@ +:_mod-docs-content-type: ASSEMBLY +[id="upi-aws-preparing-to-install"] += Preparing to install a cluster on AWS +include::_attributes/common-attributes.adoc[] +:context: upi-aws-preparing-to-install + +toc::[] + +You prepare to install an {product-title} cluster on AWS by completing the following steps: + +* Verifying internet connectivity for your cluster. + +* xref:../../../installing/installing_aws/installing-aws-account.adoc#installing-aws-account[Configuring an AWS account]. + +* Downloading the installation program. ++ +[NOTE] +==== +If you are installing in a disconnected environment, you extract the installation program from the mirrored content. For more information, see xref:../../../installing/disconnected_install/installing-mirroring-installation-images.adoc#installing-mirroring-installation-images[Mirroring images for a disconnected installation]. +==== +* Installing the {oc-first}. ++ +[NOTE] +==== +If you are installing in a disconnected environment, install `oc` to the mirror host. +==== +* Generating an SSH key pair. You can use this key pair to authenticate into the {product-title} cluster's nodes after it is deployed. + +* xref:../../../installing/installing_aws/upi/upi-aws-installation-reqs#upi-aws-installation-reqs[Preparing the user-provisioned infrastructure.] + +* If the cloud identity and access management (IAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the `kube-system` namespace, xref:../../../installing/installing_aws/ipi/installing-aws-customizations.adoc#manually-create-iam_installing-aws-customizations[manually creating long-term credentials for AWS] or xref:../../../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-with-short-term-creds_installing-aws-customizations[configuring an AWS cluster to use short-term credentials] with Amazon Web Services Security Token Service (AWS STS). + +include::modules/cluster-entitlements.adoc[leveloffset=+1] + +include::modules/installation-obtaining-installer.adoc[leveloffset=+1] + +include::modules/cli-installing-cli.adoc[leveloffset=+1] + +include::modules/ssh-agent-using.adoc[leveloffset=+1] + +include::modules/cluster-telemetry.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* See xref:../../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service. \ No newline at end of file From 065d3958eaf5d04f2e0474c27619c00b8ef2d448 Mon Sep 17 00:00:00 2001 From: Andrew Taylor Date: Fri, 14 Jun 2024 08:22:51 -0400 Subject: [PATCH 180/339] updates --- ...an-aws-iam-role-for-a-service-account.adoc | 2 +- .../install_config/enabling-cgroup-v1.adoc | 2 +- .../microshift-cli-tools-introduction.adoc | 2 +- .../microshift-cni-multus-using.adoc | 2 +- modules/about-developer-perspective.adoc | 2 +- modules/cpmso-openstack-with-az-config.adoc | 2 +- ...ting-config-files-cluster-install-oci.adoc | 4 +-- ...hosted-control-planes-version-support.adoc | 2 +- .../insights-operator-one-time-gather.adoc | 2 +- modules/installation-arm-bootstrap.adoc | 4 +-- modules/installation-arm-control-plane.adoc | 4 +-- modules/installation-arm-dns.adoc | 4 +-- modules/installation-arm-image-storage.adoc | 4 +-- modules/installation-arm-vnet.adoc | 4 +-- modules/installation-arm-worker.adoc | 4 +-- ...installation-cloudformation-bootstrap.adoc | 2 +- ...allation-cloudformation-control-plane.adoc | 2 +- modules/installation-cloudformation-dns.adoc | 2 +- .../installation-cloudformation-security.adoc | 2 +- modules/installation-cloudformation-vpc.adoc | 2 +- .../installation-cloudformation-worker.adoc | 2 +- ...allation-deployment-manager-bootstrap.adoc | 2 +- ...tion-deployment-manager-control-plane.adoc | 2 +- ...nstallation-deployment-manager-ext-lb.adoc | 2 +- ...ion-deployment-manager-firewall-rules.adoc | 2 +- ...ion-deployment-manager-iam-shared-vpc.adoc | 2 +- ...nstallation-deployment-manager-int-lb.adoc | 2 +- ...lation-deployment-manager-private-dns.adoc | 2 +- .../installation-deployment-manager-vpc.adoc | 2 +- ...nstallation-deployment-manager-worker.adoc | 2 +- .../installation-gcp-user-infra-rhcos.adoc | 2 +- .../installation-user-infra-machines-iso.adoc | 8 ++--- .../installation-user-infra-machines-pxe.adoc | 24 ++++++------- modules/installation-vsphere-machines.adoc | 2 +- .../k8s-nmstate-deploying-nmstate-CLI.adoc | 2 +- modules/logging-loki-storage-odf.adoc | 2 +- ...aintained-credentials-upgrade-extract.adoc | 2 +- ...icroshift-adding-service-to-blueprint.adoc | 16 ++++----- ...embed-microshift-image-offline-deploy.adoc | 8 ++--- modules/microshift-etcd-version.adoc | 4 +-- ...ft-oc-mirror-creating-imageset-config.adoc | 6 ++-- ...-oc-mirror-embed-ops-disconnected-use.adoc | 16 ++++----- ...ift-oc-mirror-install-catalog-cluster.adoc | 2 +- ...icroshift-oc-mirror-list-ops-catalogs.adoc | 4 +-- .../microshift-ops-config-embed-ostree.adoc | 2 +- modules/microshift-updating-rpms-y.adoc | 4 +-- ...e810-hardware-configuration-reference.adoc | 2 +- .../oadp-gcp-wif-cloud-authentication.adoc | 2 +- modules/oc-mirror-imageset-config-params.adoc | 8 ++--- modules/odc-accessing-perspectives.adoc | 2 +- modules/olm-catalogsource-image-template.adoc | 6 ++-- modules/olmv1-adding-a-catalog.adoc | 4 +-- modules/rosa-create-objects.adoc | 2 +- ...g-account-wide-iam-roles-and-policies.adoc | 6 ++-- modules/rosa-hcp-deleting-cluster.adoc | 2 +- ...g-a-cluster-external-auth-cluster-cli.adoc | 2 +- ...account-wide-role-and-policy-commands.adoc | 2 +- ...a-sts-account-wide-roles-and-policies.adoc | 2 +- ...a-sts-cluster-terraform-file-creation.adoc | 4 +-- ...ing-a-cluster-with-customizations-cli.adoc | 6 ++-- ...of-the-default-cluster-specifications.adoc | 2 +- .../sd-understanding-process-id-limits.adoc | 2 +- modules/serverless-quarkus-template.adoc | 2 +- modules/telco-core-power-management.adoc | 4 +-- modules/telco-core-scheduling.adoc | 6 ++-- modules/telco-core-sriov.adoc | 2 +- modules/telco-core-whats-new-ref-design.adoc | 2 +- modules/telco-ran-bios-tuning.adoc | 2 +- modules/telco-ran-node-tuning-operator.adoc | 6 ++-- modules/telco-ran-ptp-operator.adoc | 4 +-- ...hat-advanced-cluster-management-rhacm.adoc | 2 +- modules/update-preparing-ack.adoc | 6 ++-- ...sing-assisted-installer-oci-agent-iso.adoc | 2 +- ...fying-cluster-install-oci-agent-based.adoc | 6 ++-- .../virt-checking-storage-configuration.adoc | 4 +-- .../osd-persistent-storage-aws-efs-csi.adoc | 4 +-- .../rosa-persistent-storage-aws-efs-csi.adoc | 6 ++-- .../telco-core-ref-design-components.adoc | 34 +++++++++---------- .../ran/telco-ran-ref-du-components.adoc | 4 +-- .../ran/telco-ran-ref-du-crs.adoc | 2 +- virt/support/virt-collecting-virt-data.adoc | 2 +- 81 files changed, 166 insertions(+), 166 deletions(-) diff --git a/authentication/assuming-an-aws-iam-role-for-a-service-account.adoc b/authentication/assuming-an-aws-iam-role-for-a-service-account.adoc index 54484e2e03a9..b5ef85f33095 100644 --- a/authentication/assuming-an-aws-iam-role-for-a-service-account.adoc +++ b/authentication/assuming-an-aws-iam-role-for-a-service-account.adoc @@ -38,5 +38,5 @@ include::modules/verifying-the-assumed-iam-role-in-your-pod.adoc[leveloffset=+2] * For more information about installing and using the AWS Boto3 SDK for Python, see the link:https://boto3.amazonaws.com/v1/documentation/api/latest/index.html[AWS Boto3 documentation]. ifdef::openshift-rosa,openshift-dedicated[] -* For general information about webhook admission plugins for OpenShift, see link:https://docs.openshift.com/container-platform/4.15/architecture/admission-plug-ins.html#admission-webhooks-about_admission-plug-ins[Webhook admission plugins] in the OpenShift Container Platform documentation. +* For general information about webhook admission plugins for OpenShift, see link:https://docs.openshift.com/container-platform/4.16/architecture/admission-plug-ins.html#admission-webhooks-about_admission-plug-ins[Webhook admission plugins] in the OpenShift Container Platform documentation. endif::openshift-rosa,openshift-dedicated[] diff --git a/installing/install_config/enabling-cgroup-v1.adoc b/installing/install_config/enabling-cgroup-v1.adoc index f9df5f7c689a..9824f23511ed 100644 --- a/installing/install_config/enabling-cgroup-v1.adoc +++ b/installing/install_config/enabling-cgroup-v1.adoc @@ -7,7 +7,7 @@ include::_attributes/common-attributes.adoc[] toc::[] -As of {product-title} 4.14, {product-title} uses link:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html[Linux control group version 2] (cgroup v2) in your cluster. If you are using cgroup v1 on {product-title} 4.13 or earlier, migrating to {product-title} 4.15 will not automatically update your cgroup configuration to version 2. A fresh installation of {product-title} 4.14 or later will use cgroup v2 by default. However, you can enable link:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/index.html[Linux control group version 1] (cgroup v1) upon installation. Enabling cgroup v1 in {product-title} disables all cgroup v2 controllers and hierarchies in your cluster. +As of {product-title} 4.14, {product-title} uses link:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html[Linux control group version 2] (cgroup v2) in your cluster. If you are using cgroup v1 on {product-title} 4.13 or earlier, migrating to {product-title} {product-version} will not automatically update your cgroup configuration to version 2. A fresh installation of {product-title} 4.14 or later will use cgroup v2 by default. However, you can enable link:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/index.html[Linux control group version 1] (cgroup v1) upon installation. Enabling cgroup v1 in {product-title} disables all cgroup v2 controllers and hierarchies in your cluster. :FeatureName: cgroup v1 include::snippets/deprecated-feature.adoc[] diff --git a/microshift_cli_ref/microshift-cli-tools-introduction.adoc b/microshift_cli_ref/microshift-cli-tools-introduction.adoc index 892df03d33b5..bff9a0e0a50c 100644 --- a/microshift_cli_ref/microshift-cli-tools-introduction.adoc +++ b/microshift_cli_ref/microshift-cli-tools-introduction.adoc @@ -24,6 +24,6 @@ Commands for multi-node deployments, projects, and developer tooling are not sup == Additional resources * xref:..//microshift_cli_ref/microshift-oc-cli-install.adoc#microshift-oc-cli-install[Installing the OpenShift CLI tool for MicroShift]. -* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html/cli_tools/openshift-cli-oc[Detailed description of the OpenShift CLI (oc)]. +* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html/cli_tools/openshift-cli-oc[Detailed description of the OpenShift CLI (oc)]. * link:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9[Red Hat Enterprise Linux (RHEL) documentation for specific use cases]. * xref:../microshift_configuring/microshift-cluster-access-kubeconfig.adoc#microshift-kubeconfig[Cluster access with kubeconfig] \ No newline at end of file diff --git a/microshift_networking/microshift_multiple_networks/microshift-cni-multus-using.adoc b/microshift_networking/microshift_multiple_networks/microshift-cni-multus-using.adoc index 7b2076f5b695..a2d55f9403ad 100644 --- a/microshift_networking/microshift_multiple_networks/microshift-cni-multus-using.adoc +++ b/microshift_networking/microshift_multiple_networks/microshift-cni-multus-using.adoc @@ -26,4 +26,4 @@ include::modules/microshift-cni-multus-troubleshoot.adoc[leveloffset=+1] == Additional resources * xref:../../microshift_networking/microshift_multiple_networks/microshift-cni-multus.adoc#microshift-cni-multus[About using multiple networks] -* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html/networking/multiple-networks#nw-multus-ipam-object_configuring-additional-network[Configuration of IP address assignment for an additional network] \ No newline at end of file +* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html/networking/multiple-networks#nw-multus-ipam-object_configuring-additional-network[Configuration of IP address assignment for an additional network] \ No newline at end of file diff --git a/modules/about-developer-perspective.adoc b/modules/about-developer-perspective.adoc index b063e37d76a9..7dbc79b56c1a 100644 --- a/modules/about-developer-perspective.adoc +++ b/modules/about-developer-perspective.adoc @@ -31,4 +31,4 @@ The *Developer* perspective provides workflows specific to developer use cases, You can use the *Topology* view to display applications, components, and workloads of your project. If you have no workloads in the project, the *Topology* view will show some links to create or import them. You can also use the *Quick Search* to import components directly. .Additional Resources -See link:https://docs.openshift.com/container-platform/4.15/applications/odc-viewing-application-composition-using-topology-view.html[Viewing application composition using the Topology] view for more information on using the *Topology* view in *Developer* perspective. +See link:https://docs.openshift.com/container-platform/4.16/applications/odc-viewing-application-composition-using-topology-view.html[Viewing application composition using the Topology] view for more information on using the *Topology* view in *Developer* perspective. diff --git a/modules/cpmso-openstack-with-az-config.adoc b/modules/cpmso-openstack-with-az-config.adoc index 7ec702771972..28f9b244a952 100644 --- a/modules/cpmso-openstack-with-az-config.adoc +++ b/modules/cpmso-openstack-with-az-config.adoc @@ -43,7 +43,7 @@ providerSpec: name: openstack-cloud-credentials namespace: openshift-machine-api flavor: m1.xlarge - image: rhcos-4.15 + image: rhcos-4.16 kind: OpenstackProviderSpec metadata: creationTimestamp: null diff --git a/modules/creating-config-files-cluster-install-oci.adoc b/modules/creating-config-files-cluster-install-oci.adoc index fe314d57ee1c..6a8b8e5dca9b 100644 --- a/modules/creating-config-files-cluster-install-oci.adoc +++ b/modules/creating-config-files-cluster-install-oci.adoc @@ -38,9 +38,9 @@ $ ./openshift-install version .Example output for a shared registry binary [source,terminal,subs="quotes"] ---- -./openshift-install 4.15.0 +./openshift-install 4.16.0 built from commit ae7977b7d1ca908674a0d45c5c243c766fa4b2ca -release image registry.ci.openshift.org/origin/release:4.15ocp-release@sha256:0da6316466d60a3a4535d5fed3589feb0391989982fba59d47d4c729912d6363 +release image registry.ci.openshift.org/origin/release:4.16ocp-release@sha256:0da6316466d60a3a4535d5fed3589feb0391989982fba59d47d4c729912d6363 release architecture amd64 ---- ==== diff --git a/modules/hosted-control-planes-version-support.adoc b/modules/hosted-control-planes-version-support.adoc index 28be2770a07a..313cecfb66f7 100644 --- a/modules/hosted-control-planes-version-support.adoc +++ b/modules/hosted-control-planes-version-support.adoc @@ -22,7 +22,7 @@ You can host different versions of control planes on the same management cluster ---- apiVersion: v1 data: - supported-versions: '{"versions":["4.15"]}' + supported-versions: '{"versions":["4.16"]}' kind: ConfigMap metadata: labels: diff --git a/modules/insights-operator-one-time-gather.adoc b/modules/insights-operator-one-time-gather.adoc index e25ef62f76af..83132586135b 100644 --- a/modules/insights-operator-one-time-gather.adoc +++ b/modules/insights-operator-one-time-gather.adoc @@ -20,7 +20,7 @@ You must run a gather operation to create an Insights Operator archive. + [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/insights-operator/release-4.15/docs/gather-job.yaml[] +include::https://raw.githubusercontent.com/openshift/insights-operator/release-4.16/docs/gather-job.yaml[] ---- . Copy your `insights-operator` image version: + diff --git a/modules/installation-arm-bootstrap.adoc b/modules/installation-arm-bootstrap.adoc index 7d370f0e2aed..42a355385752 100644 --- a/modules/installation-arm-bootstrap.adoc +++ b/modules/installation-arm-bootstrap.adoc @@ -20,10 +20,10 @@ bootstrap machine that you need for your {product-title} cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/04_bootstrap.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/04_bootstrap.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/04_bootstrap.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/04_bootstrap.json[] endif::ash[] ---- ==== diff --git a/modules/installation-arm-control-plane.adoc b/modules/installation-arm-control-plane.adoc index e39c8656f86b..28e1b84df84e 100644 --- a/modules/installation-arm-control-plane.adoc +++ b/modules/installation-arm-control-plane.adoc @@ -20,10 +20,10 @@ control plane machines that you need for your {product-title} cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/05_masters.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/05_masters.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/05_masters.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/05_masters.json[] endif::ash[] ---- ==== diff --git a/modules/installation-arm-dns.adoc b/modules/installation-arm-dns.adoc index c767e54d3d97..7049e4ebf123 100644 --- a/modules/installation-arm-dns.adoc +++ b/modules/installation-arm-dns.adoc @@ -21,10 +21,10 @@ cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/03_infra.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/03_infra.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/03_infra.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/03_infra.json[] endif::ash[] ---- ==== diff --git a/modules/installation-arm-image-storage.adoc b/modules/installation-arm-image-storage.adoc index f5627f78a8e9..5039aaf70d86 100644 --- a/modules/installation-arm-image-storage.adoc +++ b/modules/installation-arm-image-storage.adoc @@ -20,10 +20,10 @@ stored {op-system-first} image that you need for your {product-title} cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/02_storage.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/02_storage.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/02_storage.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/02_storage.json[] endif::ash[] ---- ==== diff --git a/modules/installation-arm-vnet.adoc b/modules/installation-arm-vnet.adoc index b9130e79b53d..7fdf18d43a74 100644 --- a/modules/installation-arm-vnet.adoc +++ b/modules/installation-arm-vnet.adoc @@ -20,10 +20,10 @@ VNet that you need for your {product-title} cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/01_vnet.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/01_vnet.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/01_vnet.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/01_vnet.json[] endif::ash[] ---- ==== diff --git a/modules/installation-arm-worker.adoc b/modules/installation-arm-worker.adoc index 3966a73010e2..276dbed7f28a 100644 --- a/modules/installation-arm-worker.adoc +++ b/modules/installation-arm-worker.adoc @@ -20,10 +20,10 @@ worker machines that you need for your {product-title} cluster: [source,json] ---- ifndef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azure/06_workers.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azure/06_workers.json[] endif::ash[] ifdef::ash[] -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/azurestack/06_workers.json[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/azurestack/06_workers.json[] endif::ash[] ---- ==== diff --git a/modules/installation-cloudformation-bootstrap.adoc b/modules/installation-cloudformation-bootstrap.adoc index c7fce6247e49..2b509ba5a581 100644 --- a/modules/installation-cloudformation-bootstrap.adoc +++ b/modules/installation-cloudformation-bootstrap.adoc @@ -13,6 +13,6 @@ You can use the following CloudFormation template to deploy the bootstrap machin ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/04_cluster_bootstrap.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/04_cluster_bootstrap.yaml[] ---- ==== diff --git a/modules/installation-cloudformation-control-plane.adoc b/modules/installation-cloudformation-control-plane.adoc index 735119d573b6..3dd5d5c78771 100644 --- a/modules/installation-cloudformation-control-plane.adoc +++ b/modules/installation-cloudformation-control-plane.adoc @@ -14,6 +14,6 @@ machines that you need for your {product-title} cluster. ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/05_cluster_master_nodes.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/05_cluster_master_nodes.yaml[] ---- ==== diff --git a/modules/installation-cloudformation-dns.adoc b/modules/installation-cloudformation-dns.adoc index a285b88c408c..a438273a94bf 100644 --- a/modules/installation-cloudformation-dns.adoc +++ b/modules/installation-cloudformation-dns.adoc @@ -14,7 +14,7 @@ objects and load balancers that you need for your {product-title} cluster. ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/02_cluster_infra.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/02_cluster_infra.yaml[] ---- ==== diff --git a/modules/installation-cloudformation-security.adoc b/modules/installation-cloudformation-security.adoc index 4fa7f8899a8e..98698a461267 100644 --- a/modules/installation-cloudformation-security.adoc +++ b/modules/installation-cloudformation-security.adoc @@ -14,6 +14,6 @@ that you need for your {product-title} cluster. ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/03_cluster_security.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/03_cluster_security.yaml[] ---- ==== diff --git a/modules/installation-cloudformation-vpc.adoc b/modules/installation-cloudformation-vpc.adoc index 426237718bf4..3a2661b17175 100644 --- a/modules/installation-cloudformation-vpc.adoc +++ b/modules/installation-cloudformation-vpc.adoc @@ -14,6 +14,6 @@ you need for your {product-title} cluster. ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/01_vpc.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/01_vpc.yaml[] ---- ==== diff --git a/modules/installation-cloudformation-worker.adoc b/modules/installation-cloudformation-worker.adoc index 8c9e71011af4..6bec122b8301 100644 --- a/modules/installation-cloudformation-worker.adoc +++ b/modules/installation-cloudformation-worker.adoc @@ -14,6 +14,6 @@ that you need for your {product-title} cluster. ==== [source,yaml] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/aws/cloudformation/06_cluster_worker_node.yaml[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/aws/cloudformation/06_cluster_worker_node.yaml[] ---- ==== diff --git a/modules/installation-deployment-manager-bootstrap.adoc b/modules/installation-deployment-manager-bootstrap.adoc index 1375d54523a2..56b5096fe90f 100644 --- a/modules/installation-deployment-manager-bootstrap.adoc +++ b/modules/installation-deployment-manager-bootstrap.adoc @@ -14,6 +14,6 @@ machine that you need for your {product-title} cluster: ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/04_bootstrap.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/04_bootstrap.py[] ---- ==== diff --git a/modules/installation-deployment-manager-control-plane.adoc b/modules/installation-deployment-manager-control-plane.adoc index 6e9e12b12c4f..a9de6701729e 100644 --- a/modules/installation-deployment-manager-control-plane.adoc +++ b/modules/installation-deployment-manager-control-plane.adoc @@ -14,6 +14,6 @@ plane machines that you need for your {product-title} cluster: ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/05_control_plane.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/05_control_plane.py[] ---- ==== diff --git a/modules/installation-deployment-manager-ext-lb.adoc b/modules/installation-deployment-manager-ext-lb.adoc index 803507d584f5..3edbf1a0c283 100644 --- a/modules/installation-deployment-manager-ext-lb.adoc +++ b/modules/installation-deployment-manager-ext-lb.adoc @@ -12,6 +12,6 @@ You can use the following Deployment Manager template to deploy the external loa ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/02_lb_ext.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/02_lb_ext.py[] ---- ==== diff --git a/modules/installation-deployment-manager-firewall-rules.adoc b/modules/installation-deployment-manager-firewall-rules.adoc index 96baed764272..3608861774ce 100644 --- a/modules/installation-deployment-manager-firewall-rules.adoc +++ b/modules/installation-deployment-manager-firewall-rules.adoc @@ -12,6 +12,6 @@ You can use the following Deployment Manager template to deploy the firewall rue ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/03_firewall.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/03_firewall.py[] ---- ==== diff --git a/modules/installation-deployment-manager-iam-shared-vpc.adoc b/modules/installation-deployment-manager-iam-shared-vpc.adoc index 18742d3775c1..cebdffd31665 100644 --- a/modules/installation-deployment-manager-iam-shared-vpc.adoc +++ b/modules/installation-deployment-manager-iam-shared-vpc.adoc @@ -12,6 +12,6 @@ You can use the following Deployment Manager template to deploy the IAM roles th ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/03_iam.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/03_iam.py[] ---- ==== diff --git a/modules/installation-deployment-manager-int-lb.adoc b/modules/installation-deployment-manager-int-lb.adoc index 1fc098a08cd4..97ebf20b8d0a 100644 --- a/modules/installation-deployment-manager-int-lb.adoc +++ b/modules/installation-deployment-manager-int-lb.adoc @@ -12,7 +12,7 @@ You can use the following Deployment Manager template to deploy the internal loa ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/02_lb_int.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/02_lb_int.py[] ---- ==== diff --git a/modules/installation-deployment-manager-private-dns.adoc b/modules/installation-deployment-manager-private-dns.adoc index c48c47849635..b6a19b580866 100644 --- a/modules/installation-deployment-manager-private-dns.adoc +++ b/modules/installation-deployment-manager-private-dns.adoc @@ -12,6 +12,6 @@ You can use the following Deployment Manager template to deploy the private DNS ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/02_dns.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/02_dns.py[] ---- ==== diff --git a/modules/installation-deployment-manager-vpc.adoc b/modules/installation-deployment-manager-vpc.adoc index 6f5b6041520e..b5e24890ea24 100644 --- a/modules/installation-deployment-manager-vpc.adoc +++ b/modules/installation-deployment-manager-vpc.adoc @@ -14,6 +14,6 @@ you need for your {product-title} cluster: ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/01_vpc.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/01_vpc.py[] ---- ==== diff --git a/modules/installation-deployment-manager-worker.adoc b/modules/installation-deployment-manager-worker.adoc index 03bc8806711c..f287a589315b 100644 --- a/modules/installation-deployment-manager-worker.adoc +++ b/modules/installation-deployment-manager-worker.adoc @@ -14,6 +14,6 @@ that you need for your {product-title} cluster: ==== [source,python] ---- -include::https://raw.githubusercontent.com/openshift/installer/release-4.15/upi/gcp/06_worker.py[] +include::https://raw.githubusercontent.com/openshift/installer/release-4.16/upi/gcp/06_worker.py[] ---- ==== diff --git a/modules/installation-gcp-user-infra-rhcos.adoc b/modules/installation-gcp-user-infra-rhcos.adoc index 513533349047..1582ec723525 100644 --- a/modules/installation-gcp-user-infra-rhcos.adoc +++ b/modules/installation-gcp-user-infra-rhcos.adoc @@ -12,7 +12,7 @@ your {product-title} nodes. .Procedure ifndef::openshift-origin[] -. Obtain the {op-system} image from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.15/[{op-system} image mirror] page. +. Obtain the {op-system} image from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.16/[{op-system} image mirror] page. + [IMPORTANT] ==== diff --git a/modules/installation-user-infra-machines-iso.adoc b/modules/installation-user-infra-machines-iso.adoc index 7bea85e9ba9d..aecf008c32e9 100644 --- a/modules/installation-user-infra-machines-iso.adoc +++ b/modules/installation-user-infra-machines-iso.adoc @@ -85,10 +85,10 @@ $ openshift-install coreos print-stream-json | grep '\.iso[^.]' [source,terminal] ifndef::openshift-origin[] ---- -"location": "/art/storage/releases/rhcos-4.15-aarch64//aarch64/rhcos--live.aarch64.iso", -"location": "/art/storage/releases/rhcos-4.15-ppc64le//ppc64le/rhcos--live.ppc64le.iso", -"location": "/art/storage/releases/rhcos-4.15-s390x//s390x/rhcos--live.s390x.iso", -"location": "/art/storage/releases/rhcos-4.15//x86_64/rhcos--live.x86_64.iso", +"location": "/art/storage/releases/rhcos-4.16-aarch64//aarch64/rhcos--live.aarch64.iso", +"location": "/art/storage/releases/rhcos-4.16-ppc64le//ppc64le/rhcos--live.ppc64le.iso", +"location": "/art/storage/releases/rhcos-4.16-s390x//s390x/rhcos--live.s390x.iso", +"location": "/art/storage/releases/rhcos-4.16//x86_64/rhcos--live.x86_64.iso", ---- endif::openshift-origin[] ifdef::openshift-origin[] diff --git a/modules/installation-user-infra-machines-pxe.adoc b/modules/installation-user-infra-machines-pxe.adoc index 707e6e0ba6ae..b5bf251c97e9 100644 --- a/modules/installation-user-infra-machines-pxe.adoc +++ b/modules/installation-user-infra-machines-pxe.adoc @@ -101,18 +101,18 @@ $ openshift-install coreos print-stream-json | grep -Eo '"https.*(kernel-|initra [source,terminal] ifndef::openshift-origin[] ---- -"/art/storage/releases/rhcos-4.15-aarch64//aarch64/rhcos--live-kernel-aarch64" -"/art/storage/releases/rhcos-4.15-aarch64//aarch64/rhcos--live-initramfs.aarch64.img" -"/art/storage/releases/rhcos-4.15-aarch64//aarch64/rhcos--live-rootfs.aarch64.img" -"/art/storage/releases/rhcos-4.15-ppc64le/49.84.202110081256-0/ppc64le/rhcos--live-kernel-ppc64le" -"/art/storage/releases/rhcos-4.15-ppc64le//ppc64le/rhcos--live-initramfs.ppc64le.img" -"/art/storage/releases/rhcos-4.15-ppc64le//ppc64le/rhcos--live-rootfs.ppc64le.img" -"/art/storage/releases/rhcos-4.15-s390x//s390x/rhcos--live-kernel-s390x" -"/art/storage/releases/rhcos-4.15-s390x//s390x/rhcos--live-initramfs.s390x.img" -"/art/storage/releases/rhcos-4.15-s390x//s390x/rhcos--live-rootfs.s390x.img" -"/art/storage/releases/rhcos-4.15//x86_64/rhcos--live-kernel-x86_64" -"/art/storage/releases/rhcos-4.15//x86_64/rhcos--live-initramfs.x86_64.img" -"/art/storage/releases/rhcos-4.15//x86_64/rhcos--live-rootfs.x86_64.img" +"/art/storage/releases/rhcos-4.16-aarch64//aarch64/rhcos--live-kernel-aarch64" +"/art/storage/releases/rhcos-4.16-aarch64//aarch64/rhcos--live-initramfs.aarch64.img" +"/art/storage/releases/rhcos-4.16-aarch64//aarch64/rhcos--live-rootfs.aarch64.img" +"/art/storage/releases/rhcos-4.16-ppc64le/49.84.202110081256-0/ppc64le/rhcos--live-kernel-ppc64le" +"/art/storage/releases/rhcos-4.16-ppc64le//ppc64le/rhcos--live-initramfs.ppc64le.img" +"/art/storage/releases/rhcos-4.16-ppc64le//ppc64le/rhcos--live-rootfs.ppc64le.img" +"/art/storage/releases/rhcos-4.16-s390x//s390x/rhcos--live-kernel-s390x" +"/art/storage/releases/rhcos-4.16-s390x//s390x/rhcos--live-initramfs.s390x.img" +"/art/storage/releases/rhcos-4.16-s390x//s390x/rhcos--live-rootfs.s390x.img" +"/art/storage/releases/rhcos-4.16//x86_64/rhcos--live-kernel-x86_64" +"/art/storage/releases/rhcos-4.16//x86_64/rhcos--live-initramfs.x86_64.img" +"/art/storage/releases/rhcos-4.16//x86_64/rhcos--live-rootfs.x86_64.img" ---- endif::openshift-origin[] ifdef::openshift-origin[] diff --git a/modules/installation-vsphere-machines.adoc b/modules/installation-vsphere-machines.adoc index d331dc3015dc..90cba21cb835 100644 --- a/modules/installation-vsphere-machines.adoc +++ b/modules/installation-vsphere-machines.adoc @@ -79,7 +79,7 @@ If you plan to add more compute machines to your cluster after you finish instal ==== ifndef::openshift-origin[] -. Obtain the {op-system} OVA image. Images are available from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.15/[{op-system} image mirror] page. +. Obtain the {op-system} OVA image. Images are available from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.16/[{op-system} image mirror] page. + [IMPORTANT] ==== diff --git a/modules/k8s-nmstate-deploying-nmstate-CLI.adoc b/modules/k8s-nmstate-deploying-nmstate-CLI.adoc index 60d611848bb4..977795038b4a 100644 --- a/modules/k8s-nmstate-deploying-nmstate-CLI.adoc +++ b/modules/k8s-nmstate-deploying-nmstate-CLI.adoc @@ -84,7 +84,7 @@ $ oc get clusterserviceversion -n openshift-nmstate \ [source, terminal,subs="attributes+"] ---- Name Phase -kubernetes-nmstate-operator.4.15.0-202210210157 Succeeded +kubernetes-nmstate-operator.4.16.0-202210210157 Succeeded ---- . Create an instance of the `nmstate` Operator: diff --git a/modules/logging-loki-storage-odf.adoc b/modules/logging-loki-storage-odf.adoc index dc6e321aff3e..ca63c7d126ea 100644 --- a/modules/logging-loki-storage-odf.adoc +++ b/modules/logging-loki-storage-odf.adoc @@ -10,7 +10,7 @@ * You installed the {loki-op}. * You installed the {oc-first}. * You deployed link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/[{rh-storage}]. -* You configured your {rh-storage} cluster link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.15/html/managing_and_allocating_storage_resources/adding-file-and-object-storage-to-an-existing-external-ocs-cluster[for object storage]. +* You configured your {rh-storage} cluster link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.16/html/managing_and_allocating_storage_resources/adding-file-and-object-storage-to-an-existing-external-ocs-cluster[for object storage]. .Procedure diff --git a/modules/manually-maintained-credentials-upgrade-extract.adoc b/modules/manually-maintained-credentials-upgrade-extract.adoc index f1d721468f62..ed946477f7ce 100644 --- a/modules/manually-maintained-credentials-upgrade-extract.adoc +++ b/modules/manually-maintained-credentials-upgrade-extract.adoc @@ -32,7 +32,7 @@ The output of this command includes pull specs for the available updates similar Recommended updates: VERSION IMAGE -4.15.0 quay.io/openshift-release-dev/ocp-release@sha256:6a899c54dda6b844bb12a247e324a0f6cde367e880b73ba110c056df6d018032 +4.16.0 quay.io/openshift-release-dev/ocp-release@sha256:6a899c54dda6b844bb12a247e324a0f6cde367e880b73ba110c056df6d018032 ... ---- diff --git a/modules/microshift-adding-service-to-blueprint.adoc b/modules/microshift-adding-service-to-blueprint.adoc index 96deaa63dd42..1b35bec459dc 100644 --- a/modules/microshift-adding-service-to-blueprint.adoc +++ b/modules/microshift-adding-service-to-blueprint.adoc @@ -48,7 +48,7 @@ EOF + [NOTE] ==== -The wildcard `*` in the commands uses the latest {microshift-short} RPMs. If you need a specific version, substitute the wildcard for the version you want. For example, insert `4.15.0` to download the {microshift-short} 4.15.0 RPMs. +The wildcard `*` in the commands uses the latest {microshift-short} RPMs. If you need a specific version, substitute the wildcard for the version you want. For example, insert `4.16.0` to download the {microshift-short} 4.16.0 RPMs. ==== . Optional. Use the blueprint installed in the `/usr/share/microshift/blueprint` directory that is specific to your platform architecture. See the following example snippet for an explanation of the blueprint sections: @@ -58,14 +58,14 @@ The wildcard `*` in the commands uses the latest {microshift-short} RPMs. If you [source,text] ---- name = "microshift_blueprint" -description = "MicroShift 4.15.1 on x86_64 platform" +description = "MicroShift 4.16.1 on x86_64 platform" version = "0.0.1" modules = [] groups = [] [[packages]] <1> name = "microshift" -version = "4.15.1" +version = "4.16.1" ... ... @@ -115,11 +115,11 @@ $ sudo composer-cli blueprints depsolve ____ | grep micros [source,terminal] ---- blueprint: microshift_blueprint v0.0.1 - microshift-greenboot-4.15.1-202305250827.p0.g4105d3b.assembly.4.15.1.el9.noarch - microshift-networking-4.15.1-202305250827.p0.g4105d3b.assembly.4.15.1.el9.x86_64 - microshift-release-info-4.15.1-202305250827.p0.g4105d3b.assembly.4.15.1.el9.noarch - microshift-4.15.1-202305250827.p0.g4105d3b.assembly.4.15.1.el9.x86_64 - microshift-selinux-4.15.1-202305250827.p0.g4105d3b.assembly.4.15.1.el9.noarch + microshift-greenboot-4.16.1-202305250827.p0.g4105d3b.assembly.4.16.1.el9.noarch + microshift-networking-4.16.1-202305250827.p0.g4105d3b.assembly.4.16.1.el9.x86_64 + microshift-release-info-4.16.1-202305250827.p0.g4105d3b.assembly.4.16.1.el9.noarch + microshift-4.16.1-202305250827.p0.g4105d3b.assembly.4.16.1.el9.x86_64 + microshift-selinux-4.16.1-202305250827.p0.g4105d3b.assembly.4.16.1.el9.noarch ---- //need updated example output . Optional: Verify the Image Builder configuration listing all components to be installed by running the following command: diff --git a/modules/microshift-embed-microshift-image-offline-deploy.adoc b/modules/microshift-embed-microshift-image-offline-deploy.adoc index 33ca895a6227..0fb5ec30dcb7 100644 --- a/modules/microshift-embed-microshift-image-offline-deploy.adoc +++ b/modules/microshift-embed-microshift-image-offline-deploy.adoc @@ -28,7 +28,7 @@ You can use Image Builder to create `rpm-ostree` system images with embedded {mi ---- $ sudo dnf install -y microshift-release-info- ---- -Replace `` with the numerical value of the release you are deploying, using the entire version number, such as `4.15.0`. +Replace `` with the numerical value of the release you are deploying, using the entire version number, such as `4.16.0`. .. List the contents of the `/usr/share/microshift/release` directory to verify the presence of the release information files by running the following command: + @@ -54,14 +54,14 @@ If you installed the `microshift-release-info` RPM, you can proceed to step 4. ---- $ sudo dnf download microshift-release-info- ---- -Replace `` with the numerical value of the release you are deploying, using the entire version number, such as `4.15.0`. +Replace `` with the numerical value of the release you are deploying, using the entire version number, such as `4.16.0`. + .Example rpm [source,terminal] ---- -microshift-release-info-4.15.0.*.el9.noarch.rpm <1> +microshift-release-info-4.16.0.*.el9.noarch.rpm <1> ---- -<1> The `*` represents the date and commit ID. Your output should contain both, for example `-202311101230.p0.g7dc6a00.assembly.4.15.0`. +<1> The `*` represents the date and commit ID. Your output should contain both, for example `-202311101230.p0.g7dc6a00.assembly.4.16.0`. .. Unpack the RPM package without installing it by running the following command: + diff --git a/modules/microshift-etcd-version.adoc b/modules/microshift-etcd-version.adoc index 9e3f7aabd5d4..445e91d919bc 100644 --- a/modules/microshift-etcd-version.adoc +++ b/modules/microshift-etcd-version.adoc @@ -21,7 +21,7 @@ $ microshift-etcd version .Example output [source,terminal,subs="attributes+"] ---- -microshift-etcd Version: 4.15.1 +microshift-etcd Version: 4.16.1 Base etcd Version: 3.5.10 ---- @@ -38,7 +38,7 @@ $ microshift-etcd version -o json { "major": "4", "minor": "15", - "gitVersion": "4.15.1", + "gitVersion": "4.16.1", "gitCommit": "2e182312718cc9d267ec71f37dc2fbe2eed01ee2", "gitTreeState": "clean", "buildDate": "2024-01-09T06:51:40Z", diff --git a/modules/microshift-oc-mirror-creating-imageset-config.adoc b/modules/microshift-oc-mirror-creating-imageset-config.adoc index ba29f94a12d6..d87688ee6d5b 100644 --- a/modules/microshift-oc-mirror-creating-imageset-config.adoc +++ b/modules/microshift-oc-mirror-creating-imageset-config.adoc @@ -41,10 +41,10 @@ storageConfig: mirror: platform: # <1> channels: - - name: stable-4.15 + - name: stable-4.16 type: ocp operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.15 + - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.16 packages: - name: serverless-operator channels: @@ -70,7 +70,7 @@ storageConfig: <1> skipTLS: false mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.15 <3> + - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.16 <3> packages: - name: amq-broker-rhel8 <4> channels: diff --git a/modules/microshift-oc-mirror-embed-ops-disconnected-use.adoc b/modules/microshift-oc-mirror-embed-ops-disconnected-use.adoc index feecec7306ad..bd26f1b46c43 100644 --- a/modules/microshift-oc-mirror-embed-ops-disconnected-use.adoc +++ b/modules/microshift-oc-mirror-embed-ops-disconnected-use.adoc @@ -27,14 +27,14 @@ For catalogs made for proprietary Operators, you can format image references for + [source,terminal] ---- -jq -r --slurp '.[] | select(.relatedImages != null) | "[[containers]]\nsource = \"" + .relatedImages[].image + "\"\n"' ./oc-mirror-workspace/src/catalogs/registry.redhat.io/redhat/redhat-operator-index/v4.15/index/index.json +jq -r --slurp '.[] | select(.relatedImages != null) | "[[containers]]\nsource = \"" + .relatedImages[].image + "\"\n"' ./oc-mirror-workspace/src/catalogs/registry.redhat.io/redhat/redhat-operator-index/v4.16/index/index.json ---- .. If you want to filter out images that cannot be mirrored, filter and parse the catalog `index.json` file by running the following command: + [source,terminal] ---- -$ jq -r --slurp '.[] | select(.relatedImages != null) | .relatedImages[] | select(.name | contains("ppc") or contains("s390x") | not) | "[[containers]]\\nsource = \\"" + .image + "\\"\\n"' ./oc-mirror-workspace/src/catalogs/registry.redhat.io/redhat/redhat-operator-index/v4.15/index/index.json +$ jq -r --slurp '.[] | select(.relatedImages != null) | .relatedImages[] | select(.name | contains("ppc") or contains("s390x") | not) | "[[containers]]\\nsource = \\"" + .image + "\\"\\n"' ./oc-mirror-workspace/src/catalogs/registry.redhat.io/redhat/redhat-operator-index/v4.16/index/index.json ---- + [NOTE] @@ -84,21 +84,21 @@ storageConfig: imageURL: registry.example.com/microshift-mirror mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.15 <1> + - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.16 <1> packages: - name: amq-broker-rhel8 channels: - name: 7.11.x ---- -<1> Use the value in the `mirror.catalog` catalog image reference for the follwing `jq` command to get the image digest. In this example, __. +<1> Use the value in the `mirror.catalog` catalog image reference for the follwing `jq` command to get the image digest. In this example, __. . Get the SHA of the catalog index image by running the following command: + [source,terminal] ---- -$ skopeo inspect docker:// | jq `.Digest` <1> +$ skopeo inspect docker:// | jq `.Digest` <1> ---- -<1> Use the value in the `mirror.catalog` catalog image reference for the `jq` command to get the image digest. In this example, __. +<1> Use the value in the `mirror.catalog` catalog image reference for the `jq` command to get the image digest. In this example, __. + .Example output [source,terminal] @@ -120,14 +120,14 @@ source = "registry.redhat.io/redhat/redhat-operator-index@sha256:7a76c0880a83903 [source,text] ---- name = "microshift_blueprint" -description = "MicroShift 4.15.1 on x86_64 platform" +description = "MicroShift 4.16.1 on x86_64 platform" version = "0.0.1" modules = [] groups = [] [[packages]] <1> name = "microshift" -version = "4.15.1" +version = "4.16.1" ... ... diff --git a/modules/microshift-oc-mirror-install-catalog-cluster.adoc b/modules/microshift-oc-mirror-install-catalog-cluster.adoc index 61f94c09b765..d16a4c094564 100644 --- a/modules/microshift-oc-mirror-install-catalog-cluster.adoc +++ b/modules/microshift-oc-mirror-install-catalog-cluster.adoc @@ -32,7 +32,7 @@ metadata: namespace: openshift-marketplace <1> spec: sourceType: grpc - image: registry.example.com/redhat/redhat-operator-index:v4.15 + image: registry.example.com/redhat/redhat-operator-index:v4.16 updateStrategy: registryPoll: interval: 60m diff --git a/modules/microshift-oc-mirror-list-ops-catalogs.adoc b/modules/microshift-oc-mirror-list-ops-catalogs.adoc index 1025dc5b534d..f1ed5b8a4cb5 100644 --- a/modules/microshift-oc-mirror-list-ops-catalogs.adoc +++ b/modules/microshift-oc-mirror-list-ops-catalogs.adoc @@ -42,13 +42,13 @@ $ oc mirror list operators <--catalog=> <1> + [source,terminal] ---- -$ oc mirror list operators --catalog=registry.redhat.io/redhat/redhat-operator-index:v4.15 --package=amq-broker-rhel8 +$ oc mirror list operators --catalog=registry.redhat.io/redhat/redhat-operator-index:v4.16 --package=amq-broker-rhel8 ---- .. Get a list of versions within a channel by running the following command: + [source,terminal] ---- -$ oc mirror list operators --catalog=registry.redhat.io/redhat/redhat-operator-index:v4.15 --package=amq-broker-rhel8 --channel=7.11.x +$ oc mirror list operators --catalog=registry.redhat.io/redhat/redhat-operator-index:v4.16 --package=amq-broker-rhel8 --channel=7.11.x ---- .Next steps diff --git a/modules/microshift-ops-config-embed-ostree.adoc b/modules/microshift-ops-config-embed-ostree.adoc index 264405bd4a16..c6fcc708f021 100644 --- a/modules/microshift-ops-config-embed-ostree.adoc +++ b/modules/microshift-ops-config-embed-ostree.adoc @@ -26,7 +26,7 @@ metadata: name: cs-redhat-operator-index namespace: openshift-marketplace <1> spec: - image: registry.example.com/redhat/redhat-operator-index:v4.15 + image: registry.example.com/redhat/redhat-operator-index:v4.16 sourceType: grpc displayName: publisher: diff --git a/modules/microshift-updating-rpms-y.adoc b/modules/microshift-updating-rpms-y.adoc index a43ae5b6c500..6f4093e8b30d 100644 --- a/modules/microshift-updating-rpms-y.adoc +++ b/modules/microshift-updating-rpms-y.adoc @@ -6,11 +6,11 @@ [id="microshift-updating-rpms_{context}"] = Applying minor-version updates with RPMs -Updating a {microshift-short} minor version on non `rpm-ostree` systems such as {op-system-base-full} requires downloading then updating the RPMs. For example, use the following procedure to update from 4.14 to 4.15. +Updating a {microshift-short} minor version on non `rpm-ostree` systems such as {op-system-base-full} requires downloading then updating the RPMs. For example, use the following procedure to update from 4.15 to 4.16. [IMPORTANT] ==== -You can only update {microshift-short} from one version to the next in sequence. Jumping minor versions is not supported. For example, must update 4.14 to 4.15. +You can only update {microshift-short} from one version to the next in sequence. Jumping minor versions is not supported. For example, must update 4.15 to 4.16. ==== .Prerequisites diff --git a/modules/nw-ptp-e810-hardware-configuration-reference.adoc b/modules/nw-ptp-e810-hardware-configuration-reference.adoc index 7a46319ef59c..8e86bfcefcd3 100644 --- a/modules/nw-ptp-e810-hardware-configuration-reference.adoc +++ b/modules/nw-ptp-e810-hardware-configuration-reference.adoc @@ -6,7 +6,7 @@ [id="nw-ptp-wpc-hardware-pins-reference_{context}"] = Intel Westport Channel E810 hardware configuration reference -Use this information to understand how to use the link:https://github.com/openshift/linuxptp-daemon/blob/release-4.15/addons/intel/e810.go[Intel E810-XXVDA4T hardware plugin] to configure the E810 network interface as PTP grandmaster clock. +Use this information to understand how to use the link:https://github.com/openshift/linuxptp-daemon/blob/release-4.16/addons/intel/e810.go[Intel E810-XXVDA4T hardware plugin] to configure the E810 network interface as PTP grandmaster clock. Hardware pin configuration determines how the network interface interacts with other components and devices in the system. The E810-XXVDA4T NIC has four connectors for external 1PPS signals: `SMA1`, `SMA2`, `U.FL1`, and `U.FL2`. diff --git a/modules/oadp-gcp-wif-cloud-authentication.adoc b/modules/oadp-gcp-wif-cloud-authentication.adoc index a3061fdfaa2e..dcdbb35e7159 100644 --- a/modules/oadp-gcp-wif-cloud-authentication.adoc +++ b/modules/oadp-gcp-wif-cloud-authentication.adoc @@ -25,7 +25,7 @@ If you do not use Google workload identity federation cloud authentication, cont .Prerequisites -* You have installed a cluster in manual mode with link:https://docs.openshift.com/container-platform/4.15/installing/installing_gcp/installing-gcp-customizations.html#installing-gcp-with-short-term-creds_installing-gcp-customizations[GCP Workload Identity configured]. +* You have installed a cluster in manual mode with link:https://docs.openshift.com/container-platform/4.16/installing/installing_gcp/installing-gcp-customizations.html#installing-gcp-with-short-term-creds_installing-gcp-customizations[GCP Workload Identity configured]. * You have access to the Cloud Credential Operator utility (`ccoctl`) and to the associated workload identity pool. .Procedure diff --git a/modules/oc-mirror-imageset-config-params.adoc b/modules/oc-mirror-imageset-config-params.adoc index 63342545143f..0808985dbd38 100644 --- a/modules/oc-mirror-imageset-config-params.adoc +++ b/modules/oc-mirror-imageset-config-params.adoc @@ -129,7 +129,7 @@ operators: |`mirror.operators.catalog` |The Operator catalog to include in the image set. -|String. For example, `registry.redhat.io/redhat/redhat-operator-index:v4.15`. +|String. For example, `registry.redhat.io/redhat/redhat-operator-index:v4.16`. |`mirror.operators.full` |When `true`, downloads the full catalog, Operator package, or Operator channel. @@ -158,7 +158,7 @@ operators: |`mirror.operators.packages.channels.name` |The Operator channel name, unique within a package, to include in the image set. -|String. For example, `fast` or `stable-v4.15`. +|String. For example, `fast` or `stable-v4.16`. |`mirror.operators.packages.channels.maxVersion` |The highest version of the Operator mirror across all channels in which it exists. See the note that follows the table for further information. @@ -243,7 +243,7 @@ channels: |`mirror.platform.channels.name` |The name of the release channel. -|String. For example, `stable-4.15` +|String. For example, `stable-4.16` |`mirror.platform.channels.minVersion` |The minimum version of the referenced platform to be mirrored. @@ -251,7 +251,7 @@ channels: |`mirror.platform.channels.maxVersion` |The highest version of the referenced platform to be mirrored. -|String. For example, `4.15.1` +|String. For example, `4.16.1` |`mirror.platform.channels.shortestPath` |Toggles shortest path mirroring or full range mirroring. diff --git a/modules/odc-accessing-perspectives.adoc b/modules/odc-accessing-perspectives.adoc index e08aa38514e7..fd47ade7d8b3 100644 --- a/modules/odc-accessing-perspectives.adoc +++ b/modules/odc-accessing-perspectives.adoc @@ -13,7 +13,7 @@ You can access the *Administrator* and *Developer* perspective from the web cons To access a perspective, ensure that you have logged in to the web console. Your default perspective is automatically determined by the permission of the users. The *Administrator* perspective is selected for users with access to all projects, while the *Developer* perspective is selected for users with limited access to their own projects .Additional Resources -See link:https://docs.openshift.com/container-platform/4.15/web_console/adding-user-preferences.html[Adding User Preferences] for more information on changing perspectives. +See link:https://docs.openshift.com/container-platform/4.16/web_console/adding-user-preferences.html[Adding User Preferences] for more information on changing perspectives. .Procedure diff --git a/modules/olm-catalogsource-image-template.adoc b/modules/olm-catalogsource-image-template.adoc index b8a897a92968..cede83876b0d 100644 --- a/modules/olm-catalogsource-image-template.adoc +++ b/modules/olm-catalogsource-image-template.adoc @@ -14,18 +14,18 @@ endif::[] Operator compatibility with the underlying cluster can be expressed by a catalog source in various ways. One way, which is used for the default Red Hat-provided catalog sources, is to identify image tags for index images that are specifically created for a particular platform release, for example {product-title} {product-version}. -During a cluster upgrade, the index image tag for the default Red Hat-provided catalog sources are updated automatically by the Cluster Version Operator (CVO) so that Operator Lifecycle Manager (OLM) pulls the updated version of the catalog. For example during an upgrade from {product-title} 4.14 to 4.15, the `spec.image` field in the `CatalogSource` object for the `redhat-operators` catalog is updated from: +During a cluster upgrade, the index image tag for the default Red Hat-provided catalog sources are updated automatically by the Cluster Version Operator (CVO) so that Operator Lifecycle Manager (OLM) pulls the updated version of the catalog. For example during an upgrade from {product-title} 4.15 to 4.16, the `spec.image` field in the `CatalogSource` object for the `redhat-operators` catalog is updated from: [source,terminal] ---- -registry.redhat.io/redhat/redhat-operator-index:v4.14 +registry.redhat.io/redhat/redhat-operator-index:v4.15 ---- to: [source,terminal] ---- -registry.redhat.io/redhat/redhat-operator-index:v4.15 +registry.redhat.io/redhat/redhat-operator-index:v4.16 ---- However, the CVO does not automatically update image tags for custom catalogs. To ensure users are left with a compatible and supported Operator installation after a cluster upgrade, custom catalogs should also be kept updated to reference an updated index image. diff --git a/modules/olmv1-adding-a-catalog.adoc b/modules/olmv1-adding-a-catalog.adoc index 49e5377cecde..f5f95c536075 100644 --- a/modules/olmv1-adding-a-catalog.adoc +++ b/modules/olmv1-adding-a-catalog.adoc @@ -99,7 +99,7 @@ Spec: Source: Image: Pull Secret: redhat-cred - Ref: registry.redhat.io/redhat/redhat-operator-index:v4.15 + Ref: registry.redhat.io/redhat/redhat-operator-index:v4.16 Type: image Status: <1> Conditions: @@ -114,7 +114,7 @@ Status: <1> Resolved Source: Image: Last Poll Attempt: 2024-01-10T16:18:51Z - Ref: registry.redhat.io/redhat/redhat-operator-index:v4.15 + Ref: registry.redhat.io/redhat/redhat-operator-index:v4.16 Resolved Ref: registry.redhat.io/redhat/redhat-operator-index@sha256:7b536ae19b8e9f74bb521c4a61e5818e036ac1865a932f2157c6c9a766b2eea5 <4> Type: image Events: diff --git a/modules/rosa-create-objects.adoc b/modules/rosa-create-objects.adoc index 09c1ca259f54..9947cc7c0f3f 100644 --- a/modules/rosa-create-objects.adoc +++ b/modules/rosa-create-objects.adoc @@ -293,7 +293,7 @@ Tags that are added by Red{nbsp}Hat are required for clusters to stay in complia ==== |--version string -|The version of ROSA that will be used to install the cluster or cluster resources. For `cluster` use an `X.Y.Z` format, for example, `4.15.0`. For `account-role` use an `X.Y` format, for example, `4.15`. +|The version of ROSA that will be used to install the cluster or cluster resources. For `cluster` use an `X.Y.Z` format, for example, `4.16.0`. For `account-role` use an `X.Y` format, for example, `4.16`. |--worker-iam-role string |The ARN of the IAM role that will be attached to compute instances. diff --git a/modules/rosa-deleting-account-wide-iam-roles-and-policies.adoc b/modules/rosa-deleting-account-wide-iam-roles-and-policies.adoc index 0bf28b29a9bc..507527730205 100644 --- a/modules/rosa-deleting-account-wide-iam-roles-and-policies.adoc +++ b/modules/rosa-deleting-account-wide-iam-roles-and-policies.adoc @@ -75,9 +75,9 @@ ifdef::hcp[] ---- I: Fetching account roles ROLE NAME ROLE TYPE ROLE ARN OPENSHIFT VERSION AWS Managed -ManagedOpenShift-HCP-ROSA-Installer-Role Installer arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Installer-Role 4.15 Yes -ManagedOpenShift-HCP-ROSA-Support-Role Support arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Support-Role 4.15 Yes -ManagedOpenShift-HCP-ROSA-Worker-Role Worker arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Worker-Role 4.15 Yes +ManagedOpenShift-HCP-ROSA-Installer-Role Installer arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Installer-Role 4.16 Yes +ManagedOpenShift-HCP-ROSA-Support-Role Support arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Support-Role 4.16 Yes +ManagedOpenShift-HCP-ROSA-Worker-Role Worker arn:aws:iam:::role/ManagedOpenShift-HCP-ROSA-Worker-Role 4.16 Yes ---- endif::hcp[] .. Delete the account-wide roles: diff --git a/modules/rosa-hcp-deleting-cluster.adoc b/modules/rosa-hcp-deleting-cluster.adoc index 511317999d0e..22d5b3d0d1ca 100644 --- a/modules/rosa-hcp-deleting-cluster.adoc +++ b/modules/rosa-hcp-deleting-cluster.adoc @@ -40,7 +40,7 @@ Display Name: test_cluster ID: <1> External ID: Control Plane: ROSA Service Hosted -OpenShift Version: 4.15.0 +OpenShift Version: 4.16.0 Channel Group: stable DNS: test_cluster.l3cn.p3.openshiftapps.com AWS Account: diff --git a/modules/rosa-hcp-sts-creating-a-cluster-external-auth-cluster-cli.adoc b/modules/rosa-hcp-sts-creating-a-cluster-external-auth-cluster-cli.adoc index 64241544c3c9..1005ae8f4bb5 100644 --- a/modules/rosa-hcp-sts-creating-a-cluster-external-auth-cluster-cli.adoc +++ b/modules/rosa-hcp-sts-creating-a-cluster-external-auth-cluster-cli.adoc @@ -56,7 +56,7 @@ Display Name: rosa-ext-test ID: External ID: Control Plane: ROSA Service Hosted -OpenShift Version: 4.15.3 +OpenShift Version: 4.16.3 Channel Group: stable DNS: AWS Account: diff --git a/modules/rosa-sts-account-wide-role-and-policy-commands.adoc b/modules/rosa-sts-account-wide-role-and-policy-commands.adoc index 222ac3591115..1bd91e705794 100644 --- a/modules/rosa-sts-account-wide-role-and-policy-commands.adoc +++ b/modules/rosa-sts-account-wide-role-and-policy-commands.adoc @@ -11,7 +11,7 @@ This section lists the `aws` CLI commands that the `rosa` command generates in t [id="rosa-sts-account-wide-role-and-policy-aws-cli-manual-mode_{context}"] == Using manual mode for account role creation -The manual role creation mode generates the `aws` commands for you to review and run. The following command starts that process, where `` refers to your version of {product-title} (ROSA), such as `4.15`. +The manual role creation mode generates the `aws` commands for you to review and run. The following command starts that process, where `` refers to your version of {product-title} (ROSA), such as `4.16`. [source,terminal] ---- diff --git a/modules/rosa-sts-account-wide-roles-and-policies.adoc b/modules/rosa-sts-account-wide-roles-and-policies.adoc index 326fd2f88e6d..7732155b450a 100644 --- a/modules/rosa-sts-account-wide-roles-and-policies.adoc +++ b/modules/rosa-sts-account-wide-roles-and-policies.adoc @@ -7,7 +7,7 @@ This section provides details about the account-wide IAM roles and policies that are required for ROSA deployments that use STS, including the Operator policies. It also includes the JSON files that define the policies. -The account-wide roles and policies are specific to an OpenShift minor release version, for example OpenShift 4.15, and are backward compatible. You can minimize the required STS resources by reusing the account-wide roles and policies for multiple clusters of the same minor version, regardless of their patch version. +The account-wide roles and policies are specific to an OpenShift minor release version, for example OpenShift 4.16, and are backward compatible. You can minimize the required STS resources by reusing the account-wide roles and policies for multiple clusters of the same minor version, regardless of their patch version. [id="rosa-sts-account-wide-roles-and-policies-creation-methods_{context}"] == Methods of account-wide role creation diff --git a/modules/rosa-sts-cluster-terraform-file-creation.adoc b/modules/rosa-sts-cluster-terraform-file-creation.adoc index a3e0be382c79..b94fc342bece 100644 --- a/modules/rosa-sts-cluster-terraform-file-creation.adoc +++ b/modules/rosa-sts-cluster-terraform-file-creation.adoc @@ -369,8 +369,8 @@ endif::tf-defaults[] $ cat<<-EOF>variables.tf variable "rosa_openshift_version" { type = string - default = "4.15.0" - description = "Desired version of OpenShift for the cluster, for example '4.15.0'. If version is greater than the currently running version, an upgrade will be scheduled." + default = "4.16.0" + description = "Desired version of OpenShift for the cluster, for example '4.16.0'. If version is greater than the currently running version, an upgrade will be scheduled." } variable "account_role_policies" { diff --git a/modules/rosa-sts-creating-a-cluster-with-customizations-cli.adoc b/modules/rosa-sts-creating-a-cluster-with-customizations-cli.adoc index 5caaed0a91a2..274ca7939995 100644 --- a/modules/rosa-sts-creating-a-cluster-with-customizations-cli.adoc +++ b/modules/rosa-sts-creating-a-cluster-with-customizations-cli.adoc @@ -224,7 +224,7 @@ Any optional fields can be left empty and a default will be selected. ? Create cluster admin user: Yes <2> ? Username: user-admin <2> ? Password: [? for help] *************** <2> -? OpenShift version: 4.15.0 <3> +? OpenShift version: 4.16.0 <3> ? Configure the use of IMDSv2 for ec2 instances optional/required (optional): <4> I: Using arn:aws:iam:::role/ManagedOpenShift-Installer-Role for the Installer role <5> I: Using arn:aws:iam:::role/ManagedOpenShift-ControlPlane-Role for the ControlPlane role @@ -254,7 +254,7 @@ I: Using arn:aws:iam:::role/ManagedOpenShift-Support-Role for th ? Disable Workload monitoring (optional): No I: Creating cluster '' I: To create this cluster again in the future, you can run: - rosa create cluster --cluster-name --role-arn arn:aws:iam:::role/ManagedOpenShift-Installer-Role --support-role-arn arn:aws:iam:::role/ManagedOpenShift-Support-Role --master-iam-role arn:aws:iam:::role/ManagedOpenShift-ControlPlane-Role --worker-iam-role arn:aws:iam:::role/ManagedOpenShift-Worker-Role --operator-roles-prefix - --region us-east-1 --version 4.15.0 --additional-compute-security-group-ids sg-0e375ff0ec4a6cfa2 --additional-infra-security-group-ids sg-0e375ff0ec4a6cfa2 --additional-control-plane-security-group-ids sg-0e375ff0ec4a6cfa2 --replicas 2 --machine-cidr 10.0.0.0/16 --service-cidr 172.30.0.0/16 --pod-cidr 10.128.0.0/14 --host-prefix 23 <14> + rosa create cluster --cluster-name --role-arn arn:aws:iam:::role/ManagedOpenShift-Installer-Role --support-role-arn arn:aws:iam:::role/ManagedOpenShift-Support-Role --master-iam-role arn:aws:iam:::role/ManagedOpenShift-ControlPlane-Role --worker-iam-role arn:aws:iam:::role/ManagedOpenShift-Worker-Role --operator-roles-prefix - --region us-east-1 --version 4.16.0 --additional-compute-security-group-ids sg-0e375ff0ec4a6cfa2 --additional-infra-security-group-ids sg-0e375ff0ec4a6cfa2 --additional-control-plane-security-group-ids sg-0e375ff0ec4a6cfa2 --replicas 2 --machine-cidr 10.0.0.0/16 --service-cidr 172.30.0.0/16 --pod-cidr 10.128.0.0/14 --host-prefix 23 <14> I: To view a list of clusters and their status, run 'rosa list clusters' I: Cluster '' has been created. I: Once the cluster is installed you will need to add an Identity Provider before you can login into the cluster. See 'rosa create idp --help' for more information. @@ -262,7 +262,7 @@ I: Once the cluster is installed you will need to add an Identity Provider befor ---- <1> Optional. When creating your cluster, you can customize the subdomain for your cluster on `*.openshiftapps.com` using the `--domain-prefix` flag. The value for this flag must be unique within your organization, cannot be longer than 15 characters, and cannot be changed after cluster creation. If the flag is not supplied, an autogenerated value is created that depends on the length of the cluster name. If the cluster name is fewer than or equal to 15 characters, that name is used for the domain prefix. If the cluster name is longer than 15 characters, the domain prefix is randomly generated to a 15 character string. <2> When creating your cluster, you can create a local administrator user for your cluster. Selecting `Yes` then prompts you to create a user name and password for the cluster admin. The user name must not contain `/`, `:`, or `%`. The password must be at least 14 characters (ASCII-standard) without whitespaces. This process automatically configures an htpasswd identity provider. -<3> When creating the cluster, the listed `OpenShift version` options include the major, minor, and patch versions, for example `4.15.0`. +<3> When creating the cluster, the listed `OpenShift version` options include the major, minor, and patch versions, for example `4.16.0`. <4> Optional: Specify 'optional' to configure all EC2 instances to use both v1 and v2 endpoints of EC2 Instance Metadata Service (IMDS). This is the default value. Specify 'required' to configure all EC2 instances to use IMDSv2 only. + [IMPORTANT] diff --git a/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc b/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc index 1ead46b34acf..437ed75559ad 100644 --- a/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc +++ b/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc @@ -55,7 +55,7 @@ endif::rosa-terraform[] |Cluster settings | ifdef::rosa-terraform[] -* Default cluster version: `4.15.0` +* Default cluster version: `4.16.0` * Cluster name: `rosa-<6-digit-alphanumeric-string>` endif::rosa-terraform[] ifndef::rosa-terraform[] diff --git a/modules/sd-understanding-process-id-limits.adoc b/modules/sd-understanding-process-id-limits.adoc index 5123a87999be..7870bed09dff 100644 --- a/modules/sd-understanding-process-id-limits.adoc +++ b/modules/sd-understanding-process-id-limits.adoc @@ -14,7 +14,7 @@ The default value is 4,096 in {product-title} 4.11 and later. This value is cont * Maximum number of PIDs per node. + -The default value depends on link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/nodes/index#nodes-nodes-resources-configuring[node resources]. In {product-title}, this value is controlled by the link:https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved[`--system-reserved`] parameter, which reserves PIDs on each node based on the total resources of the node. +The default value depends on link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/nodes/index#nodes-nodes-resources-configuring[node resources]. In {product-title}, this value is controlled by the link:https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved[`--system-reserved`] parameter, which reserves PIDs on each node based on the total resources of the node. When a pod exceeds the allowed maximum number of PIDs per pod, the pod might stop functioning correctly and might be evicted from the node. See link:https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#eviction-signals-and-thresholds[the Kubernetes documentation for eviction signals and thresholds] for more information. diff --git a/modules/serverless-quarkus-template.adoc b/modules/serverless-quarkus-template.adoc index 19947bb04a9a..8954843deac3 100644 --- a/modules/serverless-quarkus-template.adoc +++ b/modules/serverless-quarkus-template.adoc @@ -45,7 +45,7 @@ Both `http` and `event` trigger functions have the same template structure: junit junit - 4.15 + 4.16 test diff --git a/modules/telco-core-power-management.adoc b/modules/telco-core-power-management.adoc index 136b86879f1a..b0cec97db640 100644 --- a/modules/telco-core-power-management.adoc +++ b/modules/telco-core-power-management.adoc @@ -11,12 +11,12 @@ New in this release:: Description:: -The link:https://docs.openshift.com/container-platform/4.15/rest_api/node_apis/performanceprofile-performance-openshift-io-v2.html#spec-workloadhints[Performance Profile] can be used to configure a cluster in a high power, low power, or mixed mode. +The link:https://docs.openshift.com/container-platform/4.16/rest_api/node_apis/performanceprofile-performance-openshift-io-v2.html#spec-workloadhints[Performance Profile] can be used to configure a cluster in a high power, low power, or mixed mode. The choice of power mode depends on the characteristics of the workloads running on the cluster, particularly how sensitive they are to latency. Configure the maximum latency for a low-latency pod by using the per-pod power management C-states feature. + -For more information, see link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes]. +For more information, see link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes]. Limits and requirements:: * Power configuration relies on appropriate BIOS configuration, for example, enabling C-states and P-states. Configuration varies between hardware vendors. diff --git a/modules/telco-core-scheduling.adoc b/modules/telco-core-scheduling.adoc index 156e23c11676..ecaef99dfee3 100644 --- a/modules/telco-core-scheduling.adoc +++ b/modules/telco-core-scheduling.adoc @@ -12,12 +12,12 @@ New in this release:: Description:: * The scheduler is a cluster-wide component responsible for selecting the right node for a given workload. It is a core part of the platform and does not require any specific configuration in the common deployment scenarios. However, there are few specific use cases described in the following section. NUMA-aware scheduling can be enabled through the NUMA Resources Operator. -For more information, see link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/cnf-numa-aware-scheduling.html[Scheduling NUMA-aware workloads]. +For more information, see link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/cnf-numa-aware-scheduling.html[Scheduling NUMA-aware workloads]. Limits and requirements:: -* The default scheduler does not understand the NUMA locality of workloads. It only knows about the sum of all free resources on a worker node. This might cause workloads to be rejected when scheduled to a node with https://docs.openshift.com/container-platform/4.15/scalability_and_performance/using-cpu-manager.html#topology_manager_policies_using-cpu-manager-and-topology_manager[Topology manager policy] set to `single-numa-node` or `restricted`. +* The default scheduler does not understand the NUMA locality of workloads. It only knows about the sum of all free resources on a worker node. This might cause workloads to be rejected when scheduled to a node with https://docs.openshift.com/container-platform/4.16/scalability_and_performance/using-cpu-manager.html#topology_manager_policies_using-cpu-manager-and-topology_manager[Topology manager policy] set to `single-numa-node` or `restricted`. ** For example, consider a pod requesting 6 CPUs and being scheduled to an empty node that has 4 CPUs per NUMA node. The total allocatable capacity of the node is 8 CPUs and the scheduler will place the pod there. The node local admission will fail, however, as there are only 4 CPUs available in each of the NUMA nodes. -** All clusters with multi-NUMA nodes are required to use the https://docs.openshift.com/container-platform/4.15/scalability_and_performance/cnf-numa-aware-scheduling.html#installing-the-numa-resources-operator_numa-aware[NUMA Resources Operator]. The `machineConfigPoolSelector` of the NUMA Resources Operator must select all nodes where NUMA aligned scheduling is needed. +** All clusters with multi-NUMA nodes are required to use the https://docs.openshift.com/container-platform/4.16/scalability_and_performance/cnf-numa-aware-scheduling.html#installing-the-numa-resources-operator_numa-aware[NUMA Resources Operator]. The `machineConfigPoolSelector` of the NUMA Resources Operator must select all nodes where NUMA aligned scheduling is needed. * All machine config pools must have consistent hardware configuration for example all nodes are expected to have the same NUMA zone count. Engineering considerations:: diff --git a/modules/telco-core-sriov.adoc b/modules/telco-core-sriov.adoc index c3c78e53e01a..aed4f1f68fcf 100644 --- a/modules/telco-core-sriov.adoc +++ b/modules/telco-core-sriov.adoc @@ -25,7 +25,7 @@ SR-IOV enables physical network interfaces (PFs) to be divided into multiple vir Limits and requirements:: -* The network interface controllers supported are listed in link:https://docs.openshift.com/container-platform/4.15/networking/hardware_networks/about-sriov.html#supported-devices_about-sriov[Supported devices] +* The network interface controllers supported are listed in link:https://docs.openshift.com/container-platform/4.16/networking/hardware_networks/about-sriov.html#supported-devices_about-sriov[Supported devices] * SR-IOV and IOMMU enablement in BIOS: The SR-IOV Network Operator automatically enables IOMMU on the kernel command line. * SR-IOV VFs do not receive link state updates from PF. If link down detection is needed, it must be done at the protocol level. * `MultiNetworkPolicy` CRs can be applied to `netdevice` networks only. diff --git a/modules/telco-core-whats-new-ref-design.adoc b/modules/telco-core-whats-new-ref-design.adoc index 234786f3ed28..87de86548f69 100644 --- a/modules/telco-core-whats-new-ref-design.adoc +++ b/modules/telco-core-whats-new-ref-design.adoc @@ -17,5 +17,5 @@ The following features that are included in {product-title} {product-version} an //CNF-5528 |Multi-network policy support for IPv6 Networks |You can now create multi-network policies for IPv6 networks. -For more information, see link:https://docs.openshift.com/container-platform/4.15/networking/multiple_networks/configuring-multi-network-policy.html#nw-multi-network-policy-ipv6-support_configuring-multi-network-policy[Supporting multi-network policies in IPv6 networks]. +For more information, see link:https://docs.openshift.com/container-platform/4.16/networking/multiple_networks/configuring-multi-network-policy.html#nw-multi-network-policy-ipv6-support_configuring-multi-network-policy[Supporting multi-network policies in IPv6 networks]. |==== diff --git a/modules/telco-ran-bios-tuning.adoc b/modules/telco-ran-bios-tuning.adoc index 3d6209522ed3..f85f86780e3a 100644 --- a/modules/telco-ran-bios-tuning.adoc +++ b/modules/telco-ran-bios-tuning.adoc @@ -11,7 +11,7 @@ New in this release:: Description:: Configure system level performance. -See link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] for recommended settings. +See link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] for recommended settings. + If Ironic inspection is enabled, the firmware setting values are available from the per-cluster `BareMetalHost` CR on the hub cluster. You enable Ironic inspection with a label in the `spec.clusters.nodes` field in the `SiteConfig` CR that you use to install the cluster. diff --git a/modules/telco-ran-node-tuning-operator.adoc b/modules/telco-ran-node-tuning-operator.adoc index 9dae6ee2912f..447446de377a 100644 --- a/modules/telco-ran-node-tuning-operator.adoc +++ b/modules/telco-ran-node-tuning-operator.adoc @@ -10,7 +10,7 @@ New in this release:: * No reference design updates in this release Description:: -You tune the cluster performance by link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/cnf-create-performance-profiles.html[creating a performance profile]. +You tune the cluster performance by link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/cnf-create-performance-profiles.html[creating a performance profile]. Settings that you configure with a performance profile include: + * Selecting the realtime or non-realtime kernel. @@ -64,13 +64,13 @@ Variation must still meet the specified limits. * Hardware without IRQ affinity support impacts isolated CPUs. To ensure that pods with guaranteed whole CPU QoS have full use of the allocated CPU, all hardware in the server must support IRQ affinity. -For more information, see link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/cnf-low-latency-tuning.html#about_irq_affinity_setting_cnf-master[About support of IRQ affinity setting]. +For more information, see link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/cnf-low-latency-tuning.html#about_irq_affinity_setting_cnf-master[About support of IRQ affinity setting]. [NOTE] ==== In {product-title} {product-version}, any `PerformanceProfile` CR configured on the cluster causes the Node Tuning Operator to automatically set all cluster nodes to use cgroup v1. -For more information about cgroups, see link:https://docs.openshift.com/container-platform/4.15/nodes/clusters/nodes-cluster-cgroups-2.html#nodes-clusters-cgroups-2_nodes-cluster-cgroups-2[Configuring Linux cgroup]. +For more information about cgroups, see link:https://docs.openshift.com/container-platform/4.16/nodes/clusters/nodes-cluster-cgroups-2.html#nodes-clusters-cgroups-2_nodes-cluster-cgroups-2[Configuring Linux cgroup]. ==== :FeatureName: cgroup v1 diff --git a/modules/telco-ran-ptp-operator.adoc b/modules/telco-ran-ptp-operator.adoc index 8fc21ed321f1..14f8b1dbf230 100644 --- a/modules/telco-ran-ptp-operator.adoc +++ b/modules/telco-ran-ptp-operator.adoc @@ -10,7 +10,7 @@ New in this release:: * No reference design updates in this release Description:: -See link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-sno-du-configuring-ptp_sno-configure-for-vdu[PTP timing] for details of support and configuration of PTP in cluster nodes. +See link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-sno-du-configuring-ptp_sno-configure-for-vdu[PTP timing] for details of support and configuration of PTP in cluster nodes. The DU node can run in the following modes: + * As an ordinary clock (OC) synced to a grandmaster clock or boundary clock (T-BC) @@ -28,7 +28,7 @@ Highly available boundary clocks are not supported. + -- -Events and metrics for grandmaster clocks are a Tech Preview feature added in the 4.14 {rds} RDS. For more information see link:https://docs.openshift.com/container-platform/4.15/networking/ptp/using-ptp-events.html[Using the PTP hardware fast event notifications framework]. +Events and metrics for grandmaster clocks are a Tech Preview feature added in the 4.14 {rds} RDS. For more information see link:https://docs.openshift.com/container-platform/4.16/networking/ptp/using-ptp-events.html[Using the PTP hardware fast event notifications framework]. You can subscribe applications to PTP events that happen on the node where the DU application is running. -- diff --git a/modules/telco-ran-red-hat-advanced-cluster-management-rhacm.adoc b/modules/telco-ran-red-hat-advanced-cluster-management-rhacm.adoc index 1deeb5af4ffb..5ba7c6b1b09b 100644 --- a/modules/telco-ran-red-hat-advanced-cluster-management-rhacm.adoc +++ b/modules/telco-ran-red-hat-advanced-cluster-management-rhacm.adoc @@ -31,4 +31,4 @@ You can significantly reduce the number of policies by using a single group poli These configurations should be managed using {rh-rhacm} policy hub-side templating with values pulled from `ConfigMap` CRs based on the cluster name. * To save CPU resources on managed clusters, policies that apply static configurations should be unbound from managed clusters after {ztp} installation of the cluster. -For more information, see link:https://docs.openshift.com/container-platform/4.15/storage/understanding-persistent-storage.html#releasing_understanding-persistent-storage[Release a persistent volume]. +For more information, see link:https://docs.openshift.com/container-platform/4.16/storage/understanding-persistent-storage.html#releasing_understanding-persistent-storage[Release a persistent volume]. diff --git a/modules/update-preparing-ack.adoc b/modules/update-preparing-ack.adoc index aafb14da8e2a..c3b09e584952 100644 --- a/modules/update-preparing-ack.adoc +++ b/modules/update-preparing-ack.adoc @@ -6,7 +6,7 @@ [id="update-preparing-ack_{context}"] = Providing the administrator acknowledgment -After you have evaluated your cluster for any removed APIs and have migrated any removed APIs, you can acknowledge that your cluster is ready to upgrade from {product-title} 4.14 to 4.15. +After you have evaluated your cluster for any removed APIs and have migrated any removed APIs, you can acknowledge that your cluster is ready to upgrade from {product-title} 4.15 to 4.16. [WARNING] ==== @@ -19,9 +19,9 @@ Be aware that all responsibility falls on the administrator to ensure that all u .Procedure -* Run the following command to acknowledge that you have completed the evaluation and your cluster is ready for the Kubernetes API removals in {product-title} 4.15: +* Run the following command to acknowledge that you have completed the evaluation and your cluster is ready for the Kubernetes API removals in {product-title} 4.16: + [source,terminal] ---- -$ oc -n openshift-config patch cm admin-acks --patch '{"data":{"ack-4.13-kube-1.27-api-removals-in-4.15":"true"}}' --type=merge +$ oc -n openshift-config patch cm admin-acks --patch '{"data":{"ack-4.13-kube-1.27-api-removals-in-4.16":"true"}}' --type=merge ---- diff --git a/modules/using-assisted-installer-oci-agent-iso.adoc b/modules/using-assisted-installer-oci-agent-iso.adoc index 975969bda79e..7d0a8a343262 100644 --- a/modules/using-assisted-installer-oci-agent-iso.adoc +++ b/modules/using-assisted-installer-oci-agent-iso.adoc @@ -37,7 +37,7 @@ From the {oci} web console, you must create the following resources: |Specify the base domain of the cluster, such as `splat-oci.devcluster.openshift.com`. Provided you previously created a compartment on {oci}, you can get this information by going to *DNS management* -> *Zones* -> *List scope* and then selecting the parent compartment. Your base domain should show under the *Public zones* tab. |*OpenShift version* -| Specify `OpenShift 4.15` or a later version. +| Specify `OpenShift 4.16` or a later version. |*CPU architecture* | Specify `x86_64` or `Arm64`. diff --git a/modules/verifying-cluster-install-oci-agent-based.adoc b/modules/verifying-cluster-install-oci-agent-based.adoc index 6a24210cde90..a92844d8d0c4 100644 --- a/modules/verifying-cluster-install-oci-agent-based.adoc +++ b/modules/verifying-cluster-install-oci-agent-based.adoc @@ -63,8 +63,8 @@ $ oc get co [source,terminal] ---- NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE -authentication 4.15.0-0 True False False 6m18s -baremetal 4.15.0-0 True False False 2m42s -network 4.15.0-0 True True False 5m58s Progressing: … +authentication 4.16.0-0 True False False 6m18s +baremetal 4.16.0-0 True False False 2m42s +network 4.16.0-0 True True False 5m58s Progressing: … … ---- diff --git a/modules/virt-checking-storage-configuration.adoc b/modules/virt-checking-storage-configuration.adoc index 7da31be3b816..7df1c13db504 100644 --- a/modules/virt-checking-storage-configuration.adoc +++ b/modules/virt-checking-storage-configuration.adoc @@ -166,11 +166,11 @@ data: status.failureReason: "" # <2> status.startTimestamp: "2023-07-31T13:14:38Z" # <3> status.completionTimestamp: "2023-07-31T13:19:41Z" # <4> - status.result.cnvVersion: 4.15.2 + status.result.cnvVersion: 4.16.2 status.result.defaultStorageClass: trident-nfs <5> status.result.goldenImagesNoDataSource: # <6> status.result.goldenImagesNotUpToDate: # <7> - status.result.ocpVersion: 4.15.0 + status.result.ocpVersion: 4.16.0 status.result.storageMissingVolumeSnapshotClass: status.result.storageProfilesWithEmptyClaimPropertySets: # <8> status.result.storageProfilesWithSpecClaimPropertySets: diff --git a/storage/container_storage_interface/osd-persistent-storage-aws-efs-csi.adoc b/storage/container_storage_interface/osd-persistent-storage-aws-efs-csi.adoc index 4e68c0219b6d..acdccfad9fbf 100644 --- a/storage/container_storage_interface/osd-persistent-storage-aws-efs-csi.adoc +++ b/storage/container_storage_interface/osd-persistent-storage-aws-efs-csi.adoc @@ -16,7 +16,7 @@ This procedure is specific to the link:https://github.com/openshift/aws-efs-csi- {product-title} is capable of provisioning persistent volumes (PVs) using the link:https://github.com/openshift/aws-efs-csi-driver[AWS EFS CSI driver]. -Familiarity with link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-overview_understanding-persistent-storage[persistent storage] and link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-csi[configuring CSI volumes] is recommended when working with a CSI Operator and driver. +Familiarity with link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-overview_understanding-persistent-storage[persistent storage] and link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-csi[configuring CSI volumes] is recommended when working with a CSI Operator and driver. After installing the AWS EFS CSI Driver Operator, {product-title} installs the AWS EFS CSI Operator and the AWS EFS CSI driver by default in the `openshift-cluster-csi-drivers` namespace. This allows the AWS EFS CSI Driver Operator to create CSI-provisioned PVs that mount to AWS EFS assets. @@ -87,5 +87,5 @@ include::modules/persistent-storage-csi-olm-operator-uninstall.adoc[leveloffset= [role="_additional-resources"] == Additional resources -* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-csi[Configuring CSI volumes] +* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-csi[Configuring CSI volumes] diff --git a/storage/persistent_storage/rosa-persistent-storage-aws-efs-csi.adoc b/storage/persistent_storage/rosa-persistent-storage-aws-efs-csi.adoc index 1f25cab6ce69..a54a204a5af2 100644 --- a/storage/persistent_storage/rosa-persistent-storage-aws-efs-csi.adoc +++ b/storage/persistent_storage/rosa-persistent-storage-aws-efs-csi.adoc @@ -16,7 +16,7 @@ This procedure is specific to the Amazon Web Services Elastic File System (AWS E {product-title} is capable of provisioning persistent volumes (PVs) using the Container Storage Interface (CSI) driver for AWS Elastic File Service (EFS). -Familiarity with link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-overview_understanding-persistent-storage[persistent storage] and link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-csi[configuring CSI volumes] is recommended when working with a CSI Operator and driver. +Familiarity with link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-overview_understanding-persistent-storage[persistent storage] and link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-csi[configuring CSI volumes] is recommended when working with a CSI Operator and driver. After installing the AWS EFS CSI Driver Operator, {product-title} installs the AWS EFS CSI Operator and the AWS EFS CSI driver by default in the `openshift-cluster-csi-drivers` namespace. This allows the AWS EFS CSI Driver Operator to create CSI-provisioned PVs that mount to AWS EFS assets. @@ -51,7 +51,7 @@ include::modules/persistent-storage-csi-efs-sts.adoc[leveloffset=+1] * xref:../../storage/persistent_storage/rosa-persistent-storage-aws-efs-csi.adoc#persistent-storage-csi-olm-operator-install_rosa-persistent-storage-aws-efs-csi[Installing the AWS EFS CSI Driver Operator] -* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/authentication_and_authorization/index#cco-ccoctl-configuring_cco-mode-sts[Configuring the Cloud Credential Operator utility] +* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/authentication_and_authorization/index#cco-ccoctl-configuring_cco-mode-sts[Configuring the Cloud Credential Operator utility] :StorageClass: AWS EFS :Provisioner: efs.csi.aws.com @@ -80,5 +80,5 @@ include::modules/persistent-storage-csi-olm-operator-uninstall.adoc[leveloffset= [role="_additional-resources"] == Additional resources -* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.15/html-single/storage/index#persistent-storage-csi[Configuring CSI volumes] +* link:https://access.redhat.com/documentation/en-us/openshift_container_platform/4.16/html-single/storage/index#persistent-storage-csi[Configuring CSI volumes] diff --git a/telco_ref_design_specs/core/telco-core-ref-design-components.adoc b/telco_ref_design_specs/core/telco-core-ref-design-components.adoc index 63354160848d..7e0a011b1107 100644 --- a/telco_ref_design_specs/core/telco-core-ref-design-components.adoc +++ b/telco_ref_design_specs/core/telco-core-ref-design-components.adoc @@ -14,102 +14,102 @@ include::modules/telco-core-cpu-partitioning-performance-tune.adoc[leveloffset=+ [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-cpu-infra-container_cnf-master[Tuning nodes for low latency with the performance profile] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-cpu-infra-container_cnf-master[Tuning nodes for low latency with the performance profile] -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-reference-cluster-configuration-for-vdu.html#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] include::modules/telco-core-service-mesh.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/service_mesh/v2x/ossm-about.html[About OpenShift Service Mesh] +* link:https://docs.openshift.com/container-platform/4.16/service_mesh/v2x/ossm-about.html[About OpenShift Service Mesh] include::modules/telco-core-rds-networking.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/networking/understanding-networking.html[Understanding networking] +* link:https://docs.openshift.com/container-platform/4.16/networking/understanding-networking.html[Understanding networking] include::modules/telco-core-cluster-network-operator.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/networking/cluster-network-operator.html#nw-cluster-network-operator_cluster-network-operator[Cluster Network Operator] +* link:https://docs.openshift.com/container-platform/4.16/networking/cluster-network-operator.html#nw-cluster-network-operator_cluster-network-operator[Cluster Network Operator] include::modules/telco-core-load-balancer.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/networking/metallb/about-metallb.html[About MetalLB and the MetalLB Operator] +* link:https://docs.openshift.com/container-platform/4.16/networking/metallb/about-metallb.html[About MetalLB and the MetalLB Operator] include::modules/telco-core-sriov.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/networking/hardware_networks/about-sriov.html[About SR-IOV hardware networks] +* link:https://docs.openshift.com/container-platform/4.16/networking/hardware_networks/about-sriov.html[About SR-IOV hardware networks] include::modules/telco-nmstate-operator.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/networking/k8s_nmstate/k8s-nmstate-about-the-k8s-nmstate-operator.html[About the Kubernetes NMState Operator] +* link:https://docs.openshift.com/container-platform/4.16/networking/k8s_nmstate/k8s-nmstate-about-the-k8s-nmstate-operator.html[About the Kubernetes NMState Operator] include::modules/telco-core-logging.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/observability/logging/cluster-logging.html[About logging] +* link:https://docs.openshift.com/container-platform/4.16/observability/logging/cluster-logging.html[About logging] include::modules/telco-core-power-management.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes that run colocated high and low priority workloads] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.html#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes that run colocated high and low priority workloads] include::modules/telco-core-storage.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.15[Product Documentation for Red Hat OpenShift Data Foundation] +* link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.16[Product Documentation for Red Hat OpenShift Data Foundation] include::modules/telco-core-monitoring.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/observability/monitoring/monitoring-overview.html#about-openshift-monitoring[About {product-version} monitoring] +* link:https://docs.openshift.com/container-platform/4.16/observability/monitoring/monitoring-overview.html#about-openshift-monitoring[About {product-version} monitoring] include::modules/telco-core-scheduling.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/nodes/scheduling/nodes-scheduler-about.html[Controlling pod placement using the scheduler] +* link:https://docs.openshift.com/container-platform/4.16/nodes/scheduling/nodes-scheduler-about.html[Controlling pod placement using the scheduler] -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/cnf-numa-aware-scheduling.html[Scheduling NUMA-aware workloads] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/cnf-numa-aware-scheduling.html[Scheduling NUMA-aware workloads] include::modules/telco-core-installation.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/installing/installing_with_agent_based_installer/installing-with-agent-based-installer.html[Installing an {product-title} cluster with the Agent-based Installer] +* link:https://docs.openshift.com/container-platform/4.16/installing/installing_with_agent_based_installer/installing-with-agent-based-installer.html[Installing an {product-title} cluster with the Agent-based Installer] include::modules/telco-core-security.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/authentication/managing-security-context-constraints.html[Managing security context constraints] +* link:https://docs.openshift.com/container-platform/4.16/authentication/managing-security-context-constraints.html[Managing security context constraints] include::modules/telco-core-scalability.adoc[leveloffset=+1] @@ -121,7 +121,7 @@ include::modules/telco-core-rds-disconnected.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/updating/updating_a_cluster/updating_disconnected_cluster/index.html[About cluster updates in a disconnected environment] +* link:https://docs.openshift.com/container-platform/4.16/updating/updating_a_cluster/updating_disconnected_cluster/index.html[About cluster updates in a disconnected environment] include::modules/telco-core-kernel.adoc[leveloffset=+2] diff --git a/telco_ref_design_specs/ran/telco-ran-ref-du-components.adoc b/telco_ref_design_specs/ran/telco-ran-ref-du-components.adoc index e5e9c8197f7f..86d9afeed9a0 100644 --- a/telco_ref_design_specs/ran/telco-ran-ref-du-components.adoc +++ b/telco_ref_design_specs/ran/telco-ran-ref-du-components.adoc @@ -45,9 +45,9 @@ include::modules/telco-ran-gitops-operator-and-ztp-plugins.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-preparing-the-hub-cluster.html#ztp-preparing-the-ztp-git-repository-ver-ind_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository for version independence] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-preparing-the-hub-cluster.html#ztp-preparing-the-ztp-git-repository-ver-ind_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository for version independence] -* link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.html#ztp-adding-new-content-to-gitops-ztp_ztp-advanced-policy-config[Adding custom content to the {ztp} pipeline] +* link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.html#ztp-adding-new-content-to-gitops-ztp_ztp-advanced-policy-config[Adding custom content to the {ztp} pipeline] include::modules/telco-ran-agent-based-installer-abi.adoc[leveloffset=+2] diff --git a/telco_ref_design_specs/ran/telco-ran-ref-du-crs.adoc b/telco_ref_design_specs/ran/telco-ran-ref-du-crs.adoc index 1ca5d0e2cc22..5807fa4dcc11 100644 --- a/telco_ref_design_specs/ran/telco-ran-ref-du-crs.adoc +++ b/telco_ref_design_specs/ran/telco-ran-ref-du-crs.adoc @@ -14,7 +14,7 @@ CR fields you can change are annotated in the CR with YAML comments. [NOTE] ==== You can extract the complete set of RAN DU CRs from the `ztp-site-generate` container image. -See link:https://docs.openshift.com/container-platform/4.15/scalability_and_performance/ztp_far_edge/ztp-preparing-the-hub-cluster.html#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the GitOps ZTP site configuration repository] for more information. +See link:https://docs.openshift.com/container-platform/4.16/scalability_and_performance/ztp_far_edge/ztp-preparing-the-hub-cluster.html#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the GitOps ZTP site configuration repository] for more information. ==== include::modules/telco-ran-crs-day-2-operators.adoc[leveloffset=+1] diff --git a/virt/support/virt-collecting-virt-data.adoc b/virt/support/virt-collecting-virt-data.adoc index 7fa74d0be2b4..4bad7aa64753 100644 --- a/virt/support/virt-collecting-virt-data.adoc +++ b/virt/support/virt-collecting-virt-data.adoc @@ -39,7 +39,7 @@ Collecting data about your environment minimizes the time required to analyze an // must-gather not supported for ROSA/OSD, per Dustin Row ifndef::openshift-rosa,openshift-dedicated[] . xref:../../support/gathering-cluster-data.adoc#support_gathering_data_gathering-cluster-data[Collect must-gather data for the cluster]. -. link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.15/html-single/troubleshooting_openshift_data_foundation/index#downloading-log-files-and-diagnostic-information_rhodf[Collect must-gather data for {rh-storage-first}], if necessary. +. link:https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.16/html-single/troubleshooting_openshift_data_foundation/index#downloading-log-files-and-diagnostic-information_rhodf[Collect must-gather data for {rh-storage-first}], if necessary. . xref:../../virt/support/virt-collecting-virt-data.adoc#virt-using-virt-must-gather_virt-collecting-virt-data[Collect must-gather data for {VirtProductName}]. . xref:../../observability/monitoring/managing-metrics.adoc#querying-metrics-for-all-projects-as-an-administrator_managing-metrics[Collect Prometheus metrics for the cluster]. endif::openshift-rosa,openshift-dedicated[] From aaae169c513a14e3a642cf5a1d145a01b4711b33 Mon Sep 17 00:00:00 2001 From: EricPonvelle Date: Fri, 14 Jun 2024 08:36:25 -0400 Subject: [PATCH 181/339] SD Enhancement: Created a variable for the ROSA classic product --- _attributes/attributes-openshift-dedicated.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_attributes/attributes-openshift-dedicated.adoc b/_attributes/attributes-openshift-dedicated.adoc index 4cce2014c835..409b9f96fac4 100644 --- a/_attributes/attributes-openshift-dedicated.adoc +++ b/_attributes/attributes-openshift-dedicated.adoc @@ -50,4 +50,6 @@ :hcp: hosted control planes :hcp-title: ROSA with HCP :hcp-title-first: {product-title} (ROSA) with {hcp} (HCP) +:rosa-classic: ROSA (classic architecture) +:rosa-classic-first: {product-title} (ROSA) (classic architecture) //ROSA CLI variables From 2cae510cfbe1664117d8d04a4e20ab031f038729 Mon Sep 17 00:00:00 2001 From: Jesse Dohmann Date: Mon, 10 Jun 2024 15:08:44 -0700 Subject: [PATCH 182/339] OSDOCS-9735: add iscsi procedures --- ...ing-bare-metal-network-customizations.adoc | 5 ++ .../installing-bare-metal.adoc | 5 ++ ...alling-restricted-networks-bare-metal.adoc | 5 ++ modules/rhcos-install-iscsi-ibft.adoc | 63 +++++++++++++++++++ modules/rhcos-install-iscsi-manual.adoc | 55 ++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 modules/rhcos-install-iscsi-ibft.adoc create mode 100644 modules/rhcos-install-iscsi-manual.adoc diff --git a/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc b/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc index 6836b2e97d1f..5f521b46ccd2 100644 --- a/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc +++ b/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc @@ -160,6 +160,11 @@ include::modules/installation-user-infra-machines-static-network.adoc[leveloffse include::modules/rhcos-enabling-multipath.adoc[leveloffset=+2] +//iscsi using `coreos-installer install` +include::modules/rhcos-install-iscsi-manual.adoc[leveloffset=+2] + +include::modules/rhcos-install-iscsi-ibft.adoc[leveloffset=+2] + include::modules/installation-installing-bare-metal.adoc[leveloffset=+1] [role="_additional-resources"] diff --git a/installing/installing_bare_metal/installing-bare-metal.adoc b/installing/installing_bare_metal/installing-bare-metal.adoc index a7fb0ba2a3bf..00655ff80cab 100644 --- a/installing/installing_bare_metal/installing-bare-metal.adoc +++ b/installing/installing_bare_metal/installing-bare-metal.adoc @@ -188,6 +188,11 @@ include::modules/installation-user-infra-machines-static-network.adoc[leveloffse include::modules/rhcos-enabling-multipath.adoc[leveloffset=+2] +//iscsi using `coreos-installer install` +include::modules/rhcos-install-iscsi-manual.adoc[leveloffset=+2] + +include::modules/rhcos-install-iscsi-ibft.adoc[leveloffset=+2] + [role="_additional-resources"] .Additional resources diff --git a/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc b/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc index 6d208664d674..c58904744eaa 100644 --- a/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc +++ b/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc @@ -181,6 +181,11 @@ include::modules/installation-user-infra-machines-static-network.adoc[leveloffse include::modules/rhcos-enabling-multipath.adoc[leveloffset=+2] +//iscsi using `coreos-installer install` +include::modules/rhcos-install-iscsi-manual.adoc[leveloffset=+2] + +include::modules/rhcos-install-iscsi-ibft.adoc[leveloffset=+2] + include::modules/installation-installing-bare-metal.adoc[leveloffset=+1] [role="_additional-resources"] diff --git a/modules/rhcos-install-iscsi-ibft.adoc b/modules/rhcos-install-iscsi-ibft.adoc new file mode 100644 index 000000000000..935b27c41e15 --- /dev/null +++ b/modules/rhcos-install-iscsi-ibft.adoc @@ -0,0 +1,63 @@ +// Module included in the following assemblies: +// +// * installing/installing_bare_metal/installing-bare-metal.adoc +// * installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc +// * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc + +:_mod-docs-content-type: PROCEDURE +[id="rhcos-install-iscsi-ibft_{context}"] += Installing {op-system} on an iSCSI boot device using iBFT + +On a completely diskless machine, the iSCSI target and initiator values can be passed through iBFT. iSCSI multipathing is also supported. + +.Prerequisites +. You are in the {op-system} live environment. +. You have an iSCSI target you want to install {op-system} on. +. Optional: you have multipathed your iSCSI target. + +.Procedure + +. Mount the iSCSI target from the live environment by running the following command: ++ +[source,text] +---- +$ iscsiadm \ + --mode discovery \ + --type sendtargets + --portal \ <1> + --login +---- +<1> The IP address of the target portal. + +. Optional: enable multipathing and start the daemon with the following command: ++ +[source,text] +---- +$ mpathconf --enable && systemctl start multipathd.service +---- + +. Install {op-system} onto the iSCSI target by running the following command and using the necessary kernel arguments, for example: ++ +[source,text] +---- +$ coreos-installer install \ + /dev/mapper/mpatha \ <1> + --append-karg rd.iscsi.firmware=1 \ <2> + --append-karg rd.multipath=default \ <3> + --console ttyS0 \ + --ignition-file +---- +<1> The path of a single multipathed device. If there are multiple multipath devices connected, or to be explicit, you can use the World Wide Name (WWN) symlink available in `/dev/disk/by-path`. +<2> The iSCSI parameter is read from the BIOS firmware. +<3> Optional: include this parameter if you are enabling multipathing. ++ +For more information about the iSCSI options supported by `dracut`, see the link:https://www.man7.org/linux/man-pages/man7/dracut.cmdline.7.html[`dracut.cmdline` manual page]. + +. Unmount the iSCSI disk: ++ +[source,text] +---- +$ iscsiadm --mode node --logout=all +---- + +This procedure can also be performed using the `coreos-installer iso customize` or `coreos-installer pxe customize` subcommands. diff --git a/modules/rhcos-install-iscsi-manual.adoc b/modules/rhcos-install-iscsi-manual.adoc new file mode 100644 index 000000000000..b446e66581f1 --- /dev/null +++ b/modules/rhcos-install-iscsi-manual.adoc @@ -0,0 +1,55 @@ +// Module included in the following assemblies: +// +// * installing/installing_bare_metal/installing-bare-metal.adoc +// * installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc +// * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc + +:_mod-docs-content-type: PROCEDURE +[id="rhcos-install-iscsi-manual_{context}"] += Installing {op-system} manually on an iSCSI boot device + +You can manually install {op-system} on an iSCSI target. + +.Prerequisites +. You are in the {op-system} live environment. +. You have an iSCSI target that you want to install {op-system} on. + +.Procedure + +. Mount the iSCSI target from the live environment by running the following command: ++ +[source,text] +---- +$ iscsiadm \ + --mode discovery \ + --type sendtargets + --portal \ <1> + --login +---- +<1> The IP address of the target portal. + +. Install {op-system} onto the iSCSI target by running the following command and using the necessary kernel arguments, for example: ++ +[source,text] +---- +$ coreos-installer install \ + /dev/disk/by-path/ip-:-iscsi--lun- \ <1> + --append-karg rd.iscsi.initiator= \ <2> + --append.karg netroot= \ <3> + --console ttyS0,115200n8 + --ignition-file +---- +<1> The location you are installing to. You must provide the IP address of the target portal, the associated port number, the target iSCSI node in IQN format, and the iSCSI logical unit number (LUN). +<2> The iSCSI initiator, or client, name in IQN format. The initiator forms a session to connect to the iSCSI target. +<3> The the iSCSI target, or server, name in IQN format. ++ +For more information about the iSCSI options supported by `dracut`, see the link:https://www.man7.org/linux/man-pages/man7/dracut.cmdline.7.html[`dracut.cmdline` manual page]. + +. Unmount the iSCSI disk with the following command: ++ +[source,text] +---- +$ iscsiadm --mode node --logoutall=all +---- + +This procedure can also be performed using the `coreos-installer iso customize` or `coreos-installer pxe customize` subcommands. From 5d9d3b9de2c2392181b55524eb445c7f0e261a0e Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 7 Jun 2024 11:12:13 +0100 Subject: [PATCH 183/339] OCPBUGS-31103 update SriovOperatorConfig for Telco DU profile --- snippets/ztp_SriovOperatorConfig.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/snippets/ztp_SriovOperatorConfig.yaml b/snippets/ztp_SriovOperatorConfig.yaml index fafae3ee7df6..270f7383e30b 100644 --- a/snippets/ztp_SriovOperatorConfig.yaml +++ b/snippets/ztp_SriovOperatorConfig.yaml @@ -3,7 +3,8 @@ kind: SriovOperatorConfig metadata: name: default namespace: openshift-sriov-network-operator - annotations: {} + annotations: + ran.openshift.io/ztp-deploy-wave: "10" spec: configDaemonNodeSelector: "node-role.kubernetes.io/$mcp": "" @@ -20,6 +21,8 @@ spec: # openshift.io/: "1" # requests: # openshift.io/: "1" - enableInjector: true - enableOperatorWebhook: true + enableInjector: false + enableOperatorWebhook: false + # Disable drain is needed for single-node OpenShift. + disableDrain: true logLevel: 0 From 516e221fe3c44de1dbc861d5471f9657c1565150 Mon Sep 17 00:00:00 2001 From: Alex Dellapenta Date: Fri, 14 Jun 2024 09:50:58 -0600 Subject: [PATCH 184/339] Revert "Merge pull request #76555 from subhtk/ocm-v1" This reverts commit 690b892098f88ab44979749e73d6620b31a0437a, reversing changes made to c136038fb4cdb24c9bfdf84707a5dde3ee1a0fcd. Conflicts: modules/oc-mirror-imageset-config-params.adoc Resolved conflicts by keeping the "4.16" version bump that happened via PR 76649, but set back the commas instead of colons to their pre-76555 state. --- .../installing-mirroring-disconnected.adoc | 114 ++++++++------- ...tallation-adding-registry-pull-secret.adoc | 13 +- modules/oc-mirror-about-image-set-config.adoc | 33 ----- modules/oc-mirror-about.adoc | 15 +- .../oc-mirror-creating-image-set-config.adoc | 41 +++--- modules/oc-mirror-disk-to-mirror.adoc | 17 +-- modules/oc-mirror-dry-run.adoc | 6 +- modules/oc-mirror-fully-disconnected.adoc | 11 -- .../oc-mirror-image-set-config-examples.adoc | 132 +++++++----------- modules/oc-mirror-imageset-config-params.adoc | 85 ++++++----- modules/oc-mirror-installing-plugin.adoc | 15 +- modules/oc-mirror-mirror-to-disk.adoc | 16 +-- modules/oc-mirror-mirror-to-mirror.adoc | 19 +-- modules/oc-mirror-mirroring-image-set.adoc | 15 -- modules/oc-mirror-oci-format.adoc | 11 +- ...-mirror-setting-incremental-mirroring.adoc | 53 ------- modules/oc-mirror-support.adoc | 4 +- .../oc-mirror-updating-cluster-manifests.adoc | 4 +- .../oc-mirror-updating-registry-about.adoc | 20 +-- modules/oc-mirror-updating-use-cases.adoc | 90 ++++-------- 20 files changed, 270 insertions(+), 444 deletions(-) delete mode 100644 modules/oc-mirror-about-image-set-config.adoc delete mode 100644 modules/oc-mirror-fully-disconnected.adoc delete mode 100644 modules/oc-mirror-mirroring-image-set.adoc delete mode 100644 modules/oc-mirror-setting-incremental-mirroring.adoc diff --git a/installing/disconnected_install/installing-mirroring-disconnected.adoc b/installing/disconnected_install/installing-mirroring-disconnected.adoc index 43698be0a2d1..bedd847aba29 100644 --- a/installing/disconnected_install/installing-mirroring-disconnected.adoc +++ b/installing/disconnected_install/installing-mirroring-disconnected.adoc @@ -1,12 +1,14 @@ :_mod-docs-content-type: ASSEMBLY -[id="installing-mirroring-disconnected_{context}"] -= Mirroring images for a disconnected installation using the oc-mirror plugin v1 +[id="installing-mirroring-disconnected"] += Mirroring images for a disconnected installation using the oc-mirror plugin include::_attributes/common-attributes.adoc[] :context: installing-mirroring-disconnected toc::[] -Running your cluster in a restricted network without direct internet connectivity is possible by installing the cluster from a mirrored set of {product-title} container images in a private registry. This registry must be running at all times as long as the cluster is running. See "Prerequisites" section for more information. +Running your cluster in a restricted network without direct internet connectivity is possible by installing the cluster from a mirrored set of {product-title} container images in a private registry. This registry must be running at all times as long as the cluster is running. See the xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#prerequisites_installing-mirroring-disconnected[Prerequisites] section for more information. + +You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror images to a mirror registry in your fully or partially disconnected environments. You must run oc-mirror from a system with internet connectivity in order to download the required images from the official Red Hat registries. // About the oc-mirror plugin include::modules/oc-mirror-about.adoc[leveloffset=+1] @@ -14,68 +16,76 @@ include::modules/oc-mirror-about.adoc[leveloffset=+1] // oc-mirror compatibility and support include::modules/oc-mirror-support.adoc[leveloffset=+1] -[id="prerequisites_installing-mirroring-disconnected_{context}"] +[role="_additional-resources"] +.Additional resources + +* For information on updating oc-mirror, see xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source]. + +// About the mirror registry +include::modules/installation-about-mirror-registry.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For information about viewing the CRI-O logs to view the image source, see xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source]. + +[id="prerequisites_installing-mirroring-disconnected"] == Prerequisites -* You must have a container image registry, which is referred as the mirror registry, that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2] in the location that hosts the {product-title} cluster, such as {quay}. +* You must have a container image registry that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2] in the location that will host the {product-title} cluster, such as Red Hat Quay. + [NOTE] ==== -If you use {quay}, you must use version 3.6 or later with the oc-mirror plugin. If you have an entitlement to {quay}, see the documentation on deploying {quay} link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploy_red_hat_quay_for_proof-of-concept_non-production_purposes/[for proof-of-concept purposes] or link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploying_the_red_hat_quay_operator_on_openshift_container_platform/index[by using the Red Hat Quay Operator]. If you need additional assistance selecting and installing a registry, contact your sales representative or Red Hat Support. +If you use Red Hat Quay, you must use version 3.6 or later with the oc-mirror plugin. If you have an entitlement to Red Hat Quay, see the documentation on deploying Red Hat Quay link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploy_red_hat_quay_for_proof-of-concept_non-production_purposes/[for proof-of-concept purposes] or link:https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/deploying_the_red_hat_quay_operator_on_openshift_container_platform/index[by using the Red Hat Quay Operator]. If you need additional assistance selecting and installing a registry, contact your sales representative or Red Hat Support. ==== + -If you do not already have an existing solution for a mirror registry, the subscribers of {product-title} are provided in "Creating a mirror registry with mirror registry for Red Hat OpenShift". +If you do not already have an existing solution for a container image registry, subscribers of {product-title} are provided a xref:../../installing/disconnected_install/installing-mirroring-creating-registry.adoc#installing-mirroring-creating-registry[mirror registry for Red Hat OpenShift]. The _mirror registry for Red Hat OpenShift_ is included with your subscription and is a small-scale container registry that can be used to mirror the required container images of {product-title} in disconnected installations. -* The mirror registry must be reachable by every machine in the clusters that you provision. If the registry is unreachable, installation, updating, or normal operations such as workload relocation might fail. For this reason, you must run mirror registries ensuring highly availability. The mirror registries must meet or exceed the production availability of your {product-title} clusters. +[id="mirroring-preparing-your-hosts"] +== Preparing your mirror hosts -* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. +Before you can use the oc-mirror plugin to mirror images, you must install the plugin and create a container image registry credentials file to allow the mirroring from Red Hat to your mirror. + +// Installing the oc-mirror OpenShift CLI plugin +include::modules/oc-mirror-installing-plugin.adoc[leveloffset=+2] [role="_additional-resources"] .Additional resources -* xref:../../installing/disconnected_install/installing-mirroring-creating-registry.adoc#installing-mirroring-creating-registry[Creating a mirror registry with mirror registry for Red Hat OpenShift] - -[id="mirroring-preparing-your-hosts_{context}"] -== Preparing your mirror hosts - -To use the oc-mirror plugin v1 to mirror images, you need to install the plugin and create a container image registry credentials file to enable mirroring from Red Hat to your mirror. - -// Installing the oc-mirror OpenShift CLI plugin v1 -include::modules/oc-mirror-installing-plugin.adoc[leveloffset=+2] +* xref:../../cli_reference/openshift_cli/extending-cli-plugins.adoc#cli-installing-plugins_cli-extend-plugins[Installing and using CLI plugins] // Configuring credentials that allow images to be mirrored include::modules/installation-adding-registry-pull-secret.adoc[leveloffset=+2] -// About Image set configuration -include::modules/oc-mirror-about-image-set-config.adoc[leveloffset=+1] - // Creating the image set configuration -include::modules/oc-mirror-creating-image-set-config.adoc[leveloffset=+2] +include::modules/oc-mirror-creating-image-set-config.adoc[leveloffset=+1] -// Image set configuration parameters -include::modules/oc-mirror-imageset-config-params.adoc[leveloffset=+2] +[role="_additional-resources"] +.Additional resources -// Image set configuration examples -include::modules/oc-mirror-image-set-config-examples.adoc[leveloffset=+2] +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-imageset-config-params_installing-mirroring-disconnected[Image set configuration parameters] +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-image-set-examples_installing-mirroring-disconnected[Image set configuration examples] +* xref:../../updating/updating_a_cluster/updating_disconnected_cluster/disconnected-update-osus.adoc#update-service-overview_updating-restricted-network-cluster-osus[Using the OpenShift Update Service in a disconnected environment] -// Setting up for incremental mirroring -include::modules/oc-mirror-setting-incremental-mirroring.adoc[leveloffset=+1] +[id="mirroring-image-set"] +== Mirroring an image set to a mirror registry -[role="_additional-resources"] -.Additional resources +You can use the oc-mirror CLI plugin to mirror images to a mirror registry in a xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-partial[partially disconnected environment] or in a xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-full[fully disconnected environment]. + +These procedures assume that you already have your mirror registry set up. -* xref:../../updating/updating_a_cluster/updating_disconnected_cluster/disconnected-update-osus.adoc#update-service-overview_updating-restricted-network-cluster-osus[Updating a cluster in a disconnected environment using the OpenShift Update Service] +[id="mirroring-image-set-partial"] +=== Mirroring an image set in a partially disconnected environment -* xref:../../cli_reference/openshift_cli/extending-cli-plugins.adoc#cli-installing-plugins_cli-extend-plugins[Extending the OpenShift CLI with plugins] +In a partially disconnected environment, you can mirror an image set directly to the target mirror registry. -// Mirroring an image set to a mirror registry -include::modules/oc-mirror-mirroring-image-set.adoc[leveloffset=+1] +// Mirroring from mirror to mirror +include::modules/oc-mirror-mirror-to-mirror.adoc[leveloffset=+3] -// Mirroring from partially disconnected environment:mirror to mirror -include::modules/oc-mirror-mirror-to-mirror.adoc[leveloffset=+2] +[id="mirroring-image-set-full"] +=== Mirroring an image set in a fully disconnected environment -// Mirroring from fully disconnected environment -include::modules/oc-mirror-fully-disconnected.adoc[leveloffset=+2] +To mirror an image set in a fully disconnected environment, you must first xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-mirror-to-disk_installing-mirroring-disconnected[mirror the image set to disk], then xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-disk-to-mirror_installing-mirroring-disconnected[mirror the image set file on disk to a mirror]. // Mirroring from mirror to disk include::modules/oc-mirror-mirror-to-disk.adoc[leveloffset=+3] @@ -86,34 +96,42 @@ include::modules/oc-mirror-disk-to-mirror.adoc[leveloffset=+3] // Configuring your cluster to use the resources generated by oc-mirror include::modules/oc-mirror-updating-cluster-manifests.adoc[leveloffset=+1] -[role="_additional-resources"] -.Additional resources - -* xref:../../updating/understanding_updates/intro-to-updates.adoc#update-service-about_understanding-openshift-updates[About the OpenShift Update Service] - // About updating your mirror registry content include::modules/oc-mirror-updating-registry-about.adoc[leveloffset=+1] -// Use-cases include::modules/oc-mirror-updating-use-cases.adoc[leveloffset=+2] +[role="_additional-resources"] +.Additional resources + +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-image-set-examples_installing-mirroring-disconnected[Image set configuration examples] +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-partial[Mirroring an image set in a partially disconnected environment] +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#mirroring-image-set-full[Mirroring an image set in a fully disconnected environment] +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-updating-cluster-manifests_installing-mirroring-disconnected[Configuring your cluster to use the resources generated by oc-mirror] + // Performing a dry run include::modules/oc-mirror-dry-run.adoc[leveloffset=+1] // Including local OCI Operator catalogs include::modules/oc-mirror-oci-format.adoc[leveloffset=+1] -// Additional resources +[role="_additional-resources"] +.Additional resources // TODO: This title might need to update per sebastian's PR -// Configuring your cluster to use the resources generated by oc-mirror +* xref:../../installing/disconnected_install/installing-mirroring-disconnected.adoc#oc-mirror-updating-cluster-manifests_installing-mirroring-disconnected[Configuring your cluster to use the resources generated by oc-mirror] + +// Image set configuration parameters +include::modules/oc-mirror-imageset-config-params.adoc[leveloffset=+1] + +// Image set configuration examples +include::modules/oc-mirror-image-set-config-examples.adoc[leveloffset=+1] // Command reference for oc-mirror include::modules/oc-mirror-command-reference.adoc[leveloffset=+1] [role="_additional-resources"] +[id="additional-resources_installing-mirroring-disconnected"] == Additional resources * xref:../../updating/updating_a_cluster/updating_disconnected_cluster/index.adoc#about-restricted-network-updates[About cluster updates in a disconnected environment] - -* xref:../../installing/validating-an-installation.adoc#viewing-the-image-pull-source_validating-an-installation[Viewing the image pull source] diff --git a/modules/installation-adding-registry-pull-secret.adoc b/modules/installation-adding-registry-pull-secret.adoc index 802ccab21bea..a3918c0cb846 100644 --- a/modules/installation-adding-registry-pull-secret.adoc +++ b/modules/installation-adding-registry-pull-secret.adoc @@ -22,18 +22,23 @@ endif::[] :_mod-docs-content-type: PROCEDURE [id="installation-adding-registry-pull-secret_{context}"] -= Configuring credentials to enable mirroring images += Configuring credentials that allow images to be mirrored -Follow the procedure to create a container image registry credentials file for mirroring images from Red Hat to your mirror registry. +Create a container image registry credentials file that allows mirroring +images from Red Hat to your mirror. ifdef::restricted[] [WARNING] ==== -Do not use this image registry credentials file as the pull secret when installing a cluster. Using this file will grant write access to your mirror registry for all machines in the cluster. +Do not use this image registry credentials file as the pull secret when you install a cluster. If you provide this file when you install cluster, all of the machines in the cluster will have write access to your mirror registry. ==== endif::restricted[] ifdef::restricted[] +[WARNING] +==== +This process requires that you have write access to a container image registry on the mirror registry and adds the credentials to a registry pull secret. +==== endif::restricted[] @@ -47,8 +52,6 @@ endif::openshift-rosa,openshift-dedicated[] ifdef::restricted[] * You identified an image repository location on your mirror registry to mirror images into. * You provisioned a mirror registry account that allows images to be uploaded to that image repository. -* You have write access to the mirror registry. -* You included the credentials in the registry pull secret. endif::restricted[] .Procedure diff --git a/modules/oc-mirror-about-image-set-config.adoc b/modules/oc-mirror-about-image-set-config.adoc deleted file mode 100644 index e3897f8ecf4e..000000000000 --- a/modules/oc-mirror-about-image-set-config.adoc +++ /dev/null @@ -1,33 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/disconnected_install/installing-mirroring-disconnected.adoc -// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc - -:_mod-docs-content-type: CONCEPT -[id="oc-mirror-about-image-set-config_{context}"] -= About the Image Set Configuration - -An `ImageSetConfiguration` (ISC) file is a collection of container images for mirroring. The ISC specifies the images, their versions, and any additional configuration needed for mirroring. ISCs provide a structured way to manage image mirroring tasks, allowing users to easily define, organize, and execute mirroring operations within their {product-title} environment. - -[id="oc-mirror-possibile-deployment-scenarios_{context}"] -== Possible deployment scenarios - -[id="oc-mirror-getting-image-set-config-specific-release_{context}"] -=== Scenario 1: Obtaining the `ImageSetConfiguration` file for a specific release - -To obtain the `ImageSetConfiguration` file for a specific release, follow one of these methods: - -* Set `minVersion` at the channel level to your target deployment version. -* Alternatively, set `minVersion` to the latest version in the default channel and keep it unchanged. -* Set the `maxVersion` to limit versions being mirrored. -* Use the same version for both `minVersion` and `maxVersion` to mirror only one version. - -When you run the `oc-mirror` plugin v1 with the `ImageSetConfiguration` file, it evaluates the latest release of the `stable-` channel. - -[id="oc-mirror-image-set-config-local-storage-shortest-path_{context}"] -=== Scenario 2: Using local storage and including all {product-title} versions with the shortest update path - -When using local storage and including all {product-title} versions with the shortest update path, consider the following options: - -* Set `maxVersion` to a valid version that exists in the channel you are setting it on, or include a different channel that has this version. -* If `minVersion` and `maxVersion` are not the same, the default behavior is to mirror the shortest valid upgrade path between them. \ No newline at end of file diff --git a/modules/oc-mirror-about.adoc b/modules/oc-mirror-about.adoc index 4bf152aaeb27..bffe8ae767f0 100644 --- a/modules/oc-mirror-about.adoc +++ b/modules/oc-mirror-about.adoc @@ -5,7 +5,7 @@ :_mod-docs-content-type: CONCEPT [id="installation-oc-mirror-about_{context}"] -= About the oc-mirror plugin v1 += About the oc-mirror plugin You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror all required {product-title} content and other images to your mirror registry by using a single tool. It provides the following features: @@ -21,28 +21,27 @@ You can use the oc-mirror OpenShift CLI (`oc`) plugin to mirror all required {pr * Optionally generates supporting artifacts for OpenShift Update Service (OSUS) usage. -When using the oc-mirror plugin v1, you specify the content to mirror in an image set configuration file. This YAML file allows you to configure which {product-title} releases and Operators your cluster requires, reducing the amount of data to download and transfer. The plugin can also mirror helm charts and additional container images to facilitate workload synchronization onto mirror registries. +When using the oc-mirror plugin, you specify which content to mirror in an image set configuration file. In this YAML file, you can fine-tune the configuration to only include the {product-title} releases and Operators that your cluster needs. This reduces the amount of data that you need to download and transfer. The oc-mirror plugin can also mirror arbitrary helm charts and additional container images to assist users in seamlessly synchronizing their workloads onto mirror registries. -The first time you run the oc-mirror plugin v1, it populates your mirror registry with the necessary content for your disconnected cluster installation or update. To continue receiving updates, it's essential to keep your mirror registry updated. Running the oc-mirror plugin v1 with the same configuration as the initial run allows for referencing metadata from the storage backend and downloading only the releases since the last run, providing update paths for {product-title} and Operators, and performing necessary dependency resolution. +The first time you run the oc-mirror plugin, it populates your mirror registry with the required content to perform your disconnected cluster installation or update. In order for your disconnected cluster to continue receiving updates, you must keep your mirror registry updated. To update your mirror registry, you run the oc-mirror plugin using the same configuration as the first time you ran it. The oc-mirror plugin references the metadata from the storage backend and only downloads what has been released since the last time you ran the tool. This provides update paths for {product-title} and Operators and performs dependency resolution as required. [id="installation-oc-mirror-workflow_{context}"] == High level workflow - -The following steps outline the high-level workflow on how to use the oc-mirror plugin v1 to mirror images to a mirror registry: +The following steps outline the high-level workflow on how to use the oc-mirror plugin to mirror images to a mirror registry: . Create an image set configuration file. -. Mirror the image set to the target mirror registry by using one of the following workflows: +. Mirror the image set to the target mirror registry by using one of the following methods: ** Mirror an image set directly to the target mirror registry. ** Mirror an image set to disk, transfer the image set to the target environment, then upload the image set to the target mirror registry. -. Configure your cluster to use the resources generated by the oc-mirror plugin v1. +. Configure your cluster to use the resources generated by the oc-mirror plugin. . Repeat these steps to update your target mirror registry as necessary. [IMPORTANT] ==== -When using the oc-mirror CLI plugin to populate a mirror registry, any further updates to the target mirror registry must be made by using the oc-mirror plugin v1. +When using the oc-mirror CLI plugin to populate a mirror registry, any further updates to the target mirror registry must be made by using the oc-mirror plugin. ==== diff --git a/modules/oc-mirror-creating-image-set-config.adoc b/modules/oc-mirror-creating-image-set-config.adoc index 72e39af106b7..fbc04b196dac 100644 --- a/modules/oc-mirror-creating-image-set-config.adoc +++ b/modules/oc-mirror-creating-image-set-config.adoc @@ -7,11 +7,18 @@ [id="oc-mirror-creating-image-set-config_{context}"] = Creating the image set configuration -In order to use the oc-mirror plugin v1 to mirror image sets, you must create an image set configuration file that specifies the {product-title} releases, Operators, and additional images for mirroring, along with various configuration parameters for the oc-mirror plugin v1. +Before you can use the oc-mirror plugin to mirror image sets, you must create an image set configuration file. This image set configuration file defines which {product-title} releases, Operators, and other images to mirror, along with other configuration settings for the oc-mirror plugin. + +You must specify a storage backend in the image set configuration file. This storage backend can be a local directory or a registry that supports link:https://docs.docker.com/registry/spec/manifest-v2-2[Docker v2-2]. The oc-mirror plugin stores metadata in this storage backend during image set creation. + +[IMPORTANT] +==== +Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. +==== .Prerequisites -* You have created a container image registry credentials file. For instructions, see "Configuring credentials that allow images to be mirrored". +* You have created a container image registry credentials file. For instructions, see _Configuring credentials that allow images to be mirrored_. .Procedure @@ -21,7 +28,7 @@ In order to use the oc-mirror plugin v1 to mirror image sets, you must create an ---- $ oc mirror init --registry example.com/mirror/oc-mirror-metadata > imageset-config.yaml <1> ---- -<1> Replace `example.com/mirror/oc-mirror-metadata` with the location you have created for the storage backend image of oc-mirror on your mirror registry. +<1> Replace `example.com/mirror/oc-mirror-metadata` with the location of your registry for the storage backend. . Edit the file and adjust the settings as necessary: + @@ -29,37 +36,35 @@ $ oc mirror init --registry example.com/mirror/oc-mirror-metadata > imageset-con ---- kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v1alpha2 -archiveSize: 4 #<1> +archiveSize: 4 <1> storageConfig: <2> registry: - imageURL: example.com/mirror/oc-mirror-metadata #<3> + imageURL: example.com/mirror/oc-mirror-metadata <3> skipTLS: false mirror: platform: channels: - - name: stable-{product-version} #<4> + - name: stable-{product-version} <4> type: ocp - graph: true #<5> + graph: true <5> operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} #<6> + - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} <6> packages: - - name: serverless-operator #<7> + - name: serverless-operator <7> channels: - - name: stable #<8> + - name: stable <8> additionalImages: - - name: registry.redhat.io/ubi9/ubi:latest #<9> + - name: registry.redhat.io/ubi9/ubi:latest <9> helm: {} ---- -<1> Add `archiveSize` to set the maximum size, in GiB, of each archive generated. This setup is only valid when mirroring to a fully disconnected environment. +<1> Add `archiveSize` to set the maximum size, in GiB, of each file within the image set. <2> Set the back-end location to save the image set metadata to. This location can be a registry or local directory. It is required to specify `storageConfig` values. <3> Set the registry URL for the storage backend. <4> Set the channel to retrieve the {product-title} images from. -<5> Add `graph: true` to build and push the graph-data image to the mirror registry. The graph-data image is required to create OpenShift Update Service (OSUS). The `graph: true` field also generates the `UpdateService` custom resource manifest. The `oc` command-line interface (CLI) can use the `UpdateService` custom resource manifest to create OSUS. For more information, see "About the OpenShift Update Service". -<6> Set the Operator catalog to retrieve the {product-title} images from; retrieves the latest version of all Operators of this catalog. +<5> Add `graph: true` to build and push the graph-data image to the mirror registry. The graph-data image is required to create OpenShift Update Service (OSUS). The `graph: true` field also generates the `UpdateService` custom resource manifest. The `oc` command-line interface (CLI) can use the `UpdateService` custom resource manifest to create OSUS. For more information, see _About the OpenShift Update Service_. +<6> Set the Operator catalog to retrieve the {product-title} images from. <7> Specify only certain Operator packages to include in the image set. Remove this field to retrieve all packages in the catalog. -<8> Specify only certain channels of the Operator packages to include in the image set. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. -You can find the default channel by running the following command: -`oc mirror list operators --catalog= --package=`. +<8> Specify only certain channels of the Operator packages to include in the image set. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. You can find the default channel by running the following command: `oc mirror list operators --catalog= --package=`. <9> Specify any additional images to include in image set. + [NOTE] @@ -67,7 +72,7 @@ You can find the default channel by running the following command: The `graph: true` field also mirrors the `ubi-micro` image along with other mirrored images. ==== + -See "Image set configuration parameters" for the full list of parameters and "Image set configuration examples" for various mirroring use cases. +See _Image set configuration parameters_ for the full list of parameters and _Image set configuration examples_ for various mirroring use cases. . Save the updated file. + diff --git a/modules/oc-mirror-disk-to-mirror.adoc b/modules/oc-mirror-disk-to-mirror.adoc index 808635963d35..7164bf5da7d5 100644 --- a/modules/oc-mirror-disk-to-mirror.adoc +++ b/modules/oc-mirror-disk-to-mirror.adoc @@ -5,18 +5,16 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-disk-to-mirror_{context}"] -= Mirroring from disk-to-mirror += Mirroring from disk to mirror -You can use the oc-mirror plugin v1 to mirror the contents of a generated image set to the target mirror registry. +You can use the oc-mirror plugin to mirror the contents of a generated image set to the target mirror registry. .Prerequisites * You have installed the OpenShift CLI (`oc`) in the disconnected environment. -* You have installed the `oc-mirror` CLI plugin v1 in the disconnected environment. +* You have installed the `oc-mirror` CLI plugin in the disconnected environment. * You have generated the image set file by using the `oc mirror` command. -* You have access to the target mirror registry. * You have transferred the image set file to the disconnected environment. -* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. // TODO: Confirm prereq about not needing a cluster, but need pull secret misc .Procedure @@ -28,14 +26,9 @@ You can use the oc-mirror plugin v1 to mirror the contents of a generated image $ oc mirror --from=./mirror_seq1_000000.tar \// <1> docker://registry.example:5000 <2> ---- -<1> Pass in the image set `.tar` file to mirror, named `mirror_seq1_000000.tar` in this example. If an `archiveSize` value was specified in the image set configuration file, the image set might be broken up into multiple `.tar` files. In this situation, you can pass in a directory that contains the image set `.tar` files. +<1> Pass in the image set .tar file to mirror, named `mirror_seq1_000000.tar` in this example. If an `archiveSize` value was specified in the image set configuration file, the image set might be broken up into multiple .tar files. In this situation, you can pass in a directory that contains the image set .tar files. <2> Specify the registry to mirror the image set file to. The registry must start with `docker://`. If you specify a top-level namespace for the mirror registry, you must also use this same namespace on subsequent executions. + -[NOTE] -==== -The generated image sets follow a sequential order and must be pushed to the target mirror registry accordingly. You can determine the sequence number from the file name of the generated image set archive file. -==== -+ This command updates the mirror registry with the image set and generates the `ImageContentSourcePolicy` and `CatalogSource` resources. .Verification @@ -52,5 +45,5 @@ This command updates the mirror registry with the image set and generates the `I .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] +* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. diff --git a/modules/oc-mirror-dry-run.adoc b/modules/oc-mirror-dry-run.adoc index f81565278dd9..aa2c7fa4d3e3 100644 --- a/modules/oc-mirror-dry-run.adoc +++ b/modules/oc-mirror-dry-run.adoc @@ -8,13 +8,13 @@ [id="oc-mirror-dry-run_{context}"] = Performing a dry run -You can use oc-mirror plugin v1 to perform a dry run, without actually mirroring any images. This allows you to review the list of images that would be mirrored, as well as any images that would be pruned from the mirror registry. A dry run also allows you to catch any errors with your image set configuration early or use the generated list of images with other tools to carry out the mirroring operation. +You can use oc-mirror to perform a dry run, without actually mirroring any images. This allows you to review the list of images that would be mirrored, as well as any images that would be pruned from the mirror registry. A dry run also allows you to catch any errors with your image set configuration early or use the generated list of images with other tools to carry out the mirroring operation. .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin v1. +* You have installed the `oc-mirror` CLI plugin. * You have created the image set configuration file. .Procedure @@ -66,5 +66,5 @@ This file contains a list of all images that would be pruned from the mirror reg + [NOTE] ==== -The `pruning-plan.json` file is only generated if your oc-mirror plugin v1 command points to your mirror registry and there are images to be pruned. +The `pruning-plan.json` file is only generated if your oc-mirror command points to your mirror registry and there are images to be pruned. ==== diff --git a/modules/oc-mirror-fully-disconnected.adoc b/modules/oc-mirror-fully-disconnected.adoc deleted file mode 100644 index a5c944b5fc61..000000000000 --- a/modules/oc-mirror-fully-disconnected.adoc +++ /dev/null @@ -1,11 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/disconnected_install/installing-mirroring-disconnected.adoc -// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc -// * microshift_running_apps/microshift_operators/microshift-operators-oc-mirror.adoc - -:_mod-docs-content-type: CONCEPT -[id="oc-mirror-fully-disconnected_{context}"] -= Mirroring an image set in a fully disconnected environment - -To mirror an image set in a fully disconnected environment, you must first mirror the image set to disk, then mirror the image set file on disk to a mirror. \ No newline at end of file diff --git a/modules/oc-mirror-image-set-config-examples.adoc b/modules/oc-mirror-image-set-config-examples.adoc index 0549d16b3364..769de6e520e9 100644 --- a/modules/oc-mirror-image-set-config-examples.adoc +++ b/modules/oc-mirror-image-set-config-examples.adoc @@ -5,21 +5,16 @@ :_mod-docs-content-type: REFERENCE [id="oc-mirror-image-set-examples_{context}"] -= Optimizing the image set configuration += Image set configuration examples The following `ImageSetConfiguration` file examples show the configuration for various mirroring use cases. -[id="oc-mirror-image-set-example-specific-ocp-release_{context}"] -== Use case: Preparing for installing a specific {product-title} release - -See "About ImageSetConfiguration" for further information. - -[NOTE] -==== -Regularly running oc-mirror plugin v1 facilitates the automatic retrieval of the latest {product-title} releases. -==== +// Moved to first; unchanged +[discrete] +[id="oc-mirror-image-set-examples-shortest-upgrade-path_{context}"] +== Use case: Including the shortest {product-title} update path -The following example `ImageSetConfiguration` file uses a local storage backend, including all {product-title} versions from the minimum version of 4.15.13: +The following `ImageSetConfiguration` file uses a local storage backend and includes all {product-title} versions along the shortest update path from the minimum version of `4.11.37` to the maximum version of `4.12.15`. .Example `ImageSetConfiguration` file [source,yaml] @@ -32,19 +27,20 @@ storageConfig: mirror: platform: channels: - - name: stable-4.15 - minVersion: 4.15.13 + - name: stable-4.12 + minVersion: 4.11.37 + maxVersion: 4.12.15 + shortestPath: true ---- -[id="oc-mirror-image-set-example-multi-architecture_{context}"] -== Use case: Preparing for installing for multiple architectures +// Moved to second; unchanged +[discrete] +[id="oc-mirror-image-set-examples-minimum-to-latest_{context}"] +== Use case: Including all versions of {product-title} from a minimum to the latest version for multi-architecture releases -If you set the architectures to `multi` in the `imageSetConfiguration` file, it implies that the images in the set support multiple architectures. +The following `ImageSetConfiguration` file uses a registry storage backend and includes all {product-title} versions starting at a minimum version of `4.13.4` to the latest version in the channel. On every invocation of oc-mirror with this image set configuration, the latest release of the `stable-4.13` channel is evaluated, so running oc-mirror at regular intervals ensures that you automatically receive the latest releases of {product-title} images. -[NOTE] -==== -The `multi` value only supports the {product-title} releases and not the Operators. -==== +By setting the value of `platform.architectures` to `multi`, you can ensure that the mirroring is supported for multi-architecture releases. .Example `ImageSetConfiguration` file [source,yaml] @@ -60,47 +56,25 @@ mirror: architectures: - "multi" channels: - - name: stable-4.15 - minVersion: 4.15.13 ----- - -[id="oc-mirror-image-set-examples-shortest-upgrade-path_{context}"] -== Use case: Preparing for an {product-title} upgrade including the shortest update path - -The following `ImageSetConfiguration` file uses a local storage backend and includes all {product-title} versions along with the shortest update path from the minimum version of 4.14.25 to the maximum version of 4.15.13: - -.Example `ImageSetConfiguration` file -[source,yaml] ----- -apiVersion: mirror.openshift.io/v1alpha2 -kind: ImageSetConfiguration -storageConfig: - local: - path: /home/user/metadata -mirror: - platform: - channels: - - name: stable-4.15 - minVersion: 4.14.25 - maxVersion: 4.15.13 - shortestPath: true + - name: stable-4.13 + minVersion: 4.13.4 + maxVersion: 4.13.6 ---- -[IMPORTANT] -==== -When using EUS channels and more than one channel is specified in the `imagesetconfig`, you might need to include non-EUS channels to make sure that all required intermediate versions are included in the `imageset`. See link:https://access.redhat.com/labs/ocpupgradegraph/update_path[Red Hat OpenShift Container Platform Update Graph] to check all versions forming the upgrade graph. -==== - +// Updated: +// - Added a note below about the maxVersion +// - Added a note about not necessarily getting all versions in the range +[discrete] [id="oc-mirror-image-set-examples-operator-versions_{context}"] == Use case: Including Operator versions from a minimum to the latest -The following `ImageSetConfiguration` file uses a local storage backend and includes only the Red Hat Advanced Cluster Security for Kubernetes Operator, versions starting at 4.0.1 and later regardless of the channel. +The following `ImageSetConfiguration` file uses a local storage backend and includes only the Red Hat Advanced Cluster Security for Kubernetes Operator, versions starting at 4.0.1 and later in the `stable` channel. [NOTE] ==== When you specify a minimum or maximum version range, you might not receive all Operator versions in that range. -By default, oc-mirror plugin v1 excludes any versions that are skipped or replaced by a newer version in the Operator Lifecycle Manager (OLM) specification. Operator versions that are skipped might be affected by a CVE or contain bugs. Use a newer version instead. For more information on skipped and replaced versions, see link:https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/[Creating an update graph with OLM]. +By default, oc-mirror excludes any versions that are skipped or replaced by a newer version in the Operator Lifecycle Manager (OLM) specification. Operator versions that are skipped might be affected by a CVE or contain bugs. Use a newer version instead. For more information on skipped and replaced versions, see link:https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/[Creating an update graph with OLM]. To receive all Operator versions in a specified range, you can set the `mirror.operators.full` field to `true`. ==== @@ -118,15 +92,11 @@ mirror: - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} packages: - name: rhacs-operator - - minVersion: 4.0.1 + channels: + - name: stable + minVersion: 4.0.1 ---- -In this example, if you set the `minVersion` to the latest possible version and omit the `maxVersion`, no additional versions are mirrored. - -The oc-mirror plugin v1 automatically evaluates the latest Operator version with each use. Running the oc-mirror plugin v1 regularly ensures automatic updates to receive the latest versions of the Red Hat Advanced Cluster Security for Kubernetes Operator. - -When selecting channels for your package, consider their suitability. Enabling all channels within `minVersion` and `maxVersion` or specifying only `minVersion` allows for gradual updates with minimal configuration changes. - [NOTE] ==== To specify a maximum version instead of the latest, set the `mirror.operators.packages.channels.maxVersion` field. @@ -135,7 +105,6 @@ To specify a maximum version instead of the latest, set the `mirror.operators.pa [discrete] [id="oc-mirror-image-set-examples-nutanix-operator_{context}"] == Use case: Including the Nutanix CSI Operator - The following `ImageSetConfiguration` file uses a local storage backend and includes the Nutanix CSI Operator, the OpenShift Update Service (OSUS) graph image, and an additional Red Hat Universal Base Image (UBI). .Example `ImageSetConfiguration` file @@ -163,12 +132,12 @@ mirror: - name: registry.redhat.io/ubi9/ubi:latest ---- +// New example; including the default channel +[discrete] [id="oc-mirror-image-set-examples-default-channel_{context}"] -== Use case: Including an Operator version that is not available in the default channel - -To include an Operator version not available in the default channel, consider installing `aws-load-balancer-operator`, specifically version 0.2.0. +== Use case: Including the default Operator channel -In the `ImageSetConfiguration` file, include the `stable-v0.2` and `stable-v1` channels for the AWS Load Balancer Operator. Even if only the packages from the `stable-v0.2` channel are needed, you must include the `stable-v1` channel in the `ImageSetConfiguration` file, as it is the default channel for the Operator. It's important to always include the default channel for the Operator package, even if you do not use the bundles in that channel. +The following `ImageSetConfiguration` file includes the `stable-5.7` and `stable` channels for the OpenShift Elasticsearch Operator. Even if only the packages from the `stable-5.7` channel are needed, the `stable` channel must also be included in the `ImageSetConfiguration` file, because it is the default channel for the Operator. You must always include the default channel for the Operator package even if you do not use the bundles in that channel. [TIP] ==== @@ -186,22 +155,23 @@ storageConfig: skipTLS: false mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:{product-version} + - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} packages: - - name: aws-load-balancer-operator + - name: elasticsearch-operator channels: - - name: stable-v0.2 - - name: stable-v1 + - name: stable-5.7 + - name: stable ---- -[id="oc-mirror-image-set-examples-default-channel-alternative_{context}"] -== Use case: Alternative example to include an Operator version that is not available in the default channel +// New example; Entire catalog; all versions +[discrete] +[id="oc-mirror-image-set-examples-entire-catalog-full_{context}"] +== Use case: Including an entire catalog (all versions) -Another possibility is to redefine the default channel as follows: +The following `ImageSetConfiguration` file sets the `mirror.operators.full` field to `true` to include all versions for an entire Operator catalog. .Example `ImageSetConfiguration` file - -[source,yaml] +[source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 kind: ImageSetConfiguration @@ -211,21 +181,19 @@ storageConfig: skipTLS: false mirror: operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:{product-version} - packages: - - name: aws-load-balancer-operator - defaultChannel: stable-v0.2 <1> - channels: - - name: stable-v0.2 + - catalog: registry.redhat.io/redhat/redhat-operator-index:v{product-version} + full: true ---- -<1> The value for `defaultChannel` must be specified in the `channels` list. -[id="oc-mirror-image-set-examples-entire-catalog-full_{context}"] +// New example; Entire catalog; heads only +// - Included 'targetCatalog' in example +[discrete] +[id="oc-mirror-image-set-examples-entire-catalog-heads_{context}"] == Use case: Including an entire catalog (channel heads only) The following `ImageSetConfiguration` file includes the channel heads for an entire Operator catalog. -By default, for each Operator in the catalog, oc-mirror plugin v1 includes the latest Operator version (channel head) from the default channel. If you want to mirror all Operator versions, and not just the channel heads, you must set the `mirror.operators.full` field to `true`. +By default, for each Operator in the catalog, oc-mirror includes the latest Operator version (channel head) from the default channel. If you want to mirror all Operator versions, and not just the channel heads, you must set the `mirror.operators.full` field to `true`. This example also uses the `targetCatalog` field to specify an alternative namespace and name to mirror the catalog as. @@ -244,6 +212,8 @@ mirror: targetCatalog: my-namespace/my-operator-catalog ---- +// Moved to last; unchanged +[discrete] [id="oc-mirror-image-set-examples-helm_{context}"] == Use case: Including arbitrary images and helm charts diff --git a/modules/oc-mirror-imageset-config-params.adoc b/modules/oc-mirror-imageset-config-params.adoc index 0808985dbd38..84cc2ae68f53 100644 --- a/modules/oc-mirror-imageset-config-params.adoc +++ b/modules/oc-mirror-imageset-config-params.adoc @@ -8,7 +8,7 @@ [id="oc-mirror-imageset-config-params_{context}"] = Image set configuration parameters -The oc-mirror plugin v1 requires an image set configuration file that defines what images to mirror. The following table lists the available parameters for the `ImageSetConfiguration` resource. +The oc-mirror plugin requires an image set configuration file that defines what images to mirror. The following table lists the available parameters for the `ImageSetConfiguration` resource. // TODO: Consider adding examples for the general "Object" params @@ -21,13 +21,13 @@ The oc-mirror plugin v1 requires an image set configuration file that defines wh |`apiVersion` |The API version for the `ImageSetConfiguration` content. -|String. For example, `mirror.openshift.io/v1alpha2`. +|String. For example: `mirror.openshift.io/v1alpha2`. ifndef::microshift[] |`archiveSize` |The maximum size, in GiB, of each archive file within the image set. -|Integer. For example, `4` +|Integer. For example: `4` endif::microshift[] @@ -37,7 +37,7 @@ endif::microshift[] |`mirror.additionalImages` |The additional images configuration of the image set. -|Array of objects. For example, +|Array of objects. For example: [source,yaml] ---- @@ -47,11 +47,11 @@ additionalImages: |`mirror.additionalImages.name` |The tag or digest of the image to mirror. -|String. For example, `registry.redhat.io/ubi8/ubi:latest` +|String. For example: `registry.redhat.io/ubi8/ubi:latest` |`mirror.blockedImages` |The full tag, digest, or pattern of images to block from mirroring. -|Array of strings. For example, `docker.io/library/alpine` +|Array of strings. For example: `docker.io/library/alpine` ifndef::microshift[] @@ -61,7 +61,7 @@ ifndef::microshift[] |`mirror.helm.local` |The local helm charts to mirror. -|Array of objects. For example, +|Array of objects. For example: [source,yaml] ---- @@ -72,15 +72,15 @@ local: |`mirror.helm.local.name` |The name of the local helm chart to mirror. -|String. For example, `podinfo`. +|String. For example: `podinfo`. |`mirror.helm.local.path` |The path of the local helm chart to mirror. -|String. For example, `/test/podinfo-5.0.0.tar.gz`. +|String. For example: `/test/podinfo-5.0.0.tar.gz`. |`mirror.helm.repositories` |The remote helm repositories to mirror from. -|Array of objects. For example, +|Array of objects. For example: [source,yaml] ---- @@ -94,11 +94,11 @@ repositories: |`mirror.helm.repositories.name` |The name of the helm repository to mirror from. -|String. For example, `podinfo`. +|String. For example: `podinfo`. |`mirror.helm.repositories.url` |The URL of the helm repository to mirror from. -|String. For example, [x-]`https://example.github.io/podinfo`. +|String. For example: [x-]`https://example.github.io/podinfo`. |`mirror.helm.repositories.charts` |The remote helm charts to mirror. @@ -106,17 +106,17 @@ repositories: |`mirror.helm.repositories.charts.name` |The name of the helm chart to mirror. -|String. For example, `podinfo`. +|String. For example: `podinfo`. |`mirror.helm.repositories.charts.version` |The version of the named helm chart to mirror. -|String. For example, `5.0.0`. +|String. For example: `5.0.0`. endif::microshift[] |`mirror.operators` |The Operators configuration of the image set. -|Array of objects. For example, +|Array of objects. For example: [source,yaml,subs="attributes+"] ---- @@ -129,7 +129,7 @@ operators: |`mirror.operators.catalog` |The Operator catalog to include in the image set. -|String. For example, `registry.redhat.io/redhat/redhat-operator-index:v4.16`. +|String. For example: `registry.redhat.io/redhat/redhat-operator-index:v4.16`. |`mirror.operators.full` |When `true`, downloads the full catalog, Operator package, or Operator channel. @@ -137,7 +137,7 @@ operators: |`mirror.operators.packages` |The Operator packages configuration. -|Array of objects. For example, +|Array of objects. For example: [source,yaml,subs="attributes+"] ---- @@ -150,7 +150,7 @@ operators: |`mirror.operators.packages.name` |The Operator package name to include in the image set -|String. For example, `elasticsearch-operator`. +|String. For example: `elasticsearch-operator`. |`mirror.operators.packages.channels` |The Operator package channel configuration. @@ -158,32 +158,27 @@ operators: |`mirror.operators.packages.channels.name` |The Operator channel name, unique within a package, to include in the image set. -|String. For example, `fast` or `stable-v4.16`. +|String. For example: `fast` or `stable-v4.16`. |`mirror.operators.packages.channels.maxVersion` -|The highest version of the Operator mirror across all channels in which it exists. See the note that follows the table for further information. -|String. For example, `5.2.3-31` +|The highest version of the Operator mirror across all channels in which it exists. See the following note for further information. +|String. For example: `5.2.3-31` |`mirror.operators.packages.channels.minBundle` |The name of the minimum bundle to include, plus all bundles in the update graph to the channel head. Set this field only if the named bundle has no semantic version metadata. -|String. For example, `bundleName` +|String. For example: `bundleName` |`mirror.operators.packages.channels.minVersion` -|The lowest version of the Operator to mirror across all channels in which it exists. See the note that follows the table for further information. -|String. For example, `5.2.3-31` - -|`mirrors.operators.packages.defaultChannel` -|The `defaultChannel` overrides the channel that is selected as default for this Operator in the catalog. -|String. For example, `stable-5.8`. -See "Use case: Including an operator version that is not available in the default channel" for an example. +|The lowest version of the Operator to mirror across all channels in which it exists. See the following note for further information. +|String. For example: `5.2.3-31` |`mirror.operators.packages.maxVersion` -|The highest version of the Operator to mirror in this channel. See the following note for further information. -|String. For example, `5.2.3-31`. +|The highest version of the Operator to mirror across all channels in which it exists. See the following note for further information. +|String. For example: `5.2.3-31`. |`mirror.operators.packages.minVersion` -|The lowest version of the Operator to mirror in this channel. See the note that follows the table for further information. -|String. For example, `5.2.3-31`. +|The lowest version of the Operator to mirror across all channels in which it exists. See the following note for further information. +|String. For example: `5.2.3-31`. |`mirror.operators.skipDependencies` |If `true`, dependencies of bundles are not included. @@ -191,18 +186,18 @@ See "Use case: Including an operator version that is not available in the defaul |`mirror.operators.targetCatalog` |An alternative name and optional namespace hierarchy to mirror the referenced catalog as. -|String. For example, `my-namespace/my-operator-catalog` +|String. For example: `my-namespace/my-operator-catalog` |`mirror.operators.targetName` |An alternative name to mirror the referenced catalog as. The `targetName` parameter is deprecated. Use the `targetCatalog` parameter instead. -|String. For example, `my-operator-catalog` +|String. For example: `my-operator-catalog` |`mirror.operators.targetTag` |An alternative tag to append to the `targetName` or `targetCatalog`. -|String. For example, `v1` +|String. For example: `v1` ifndef::microshift[] @@ -212,7 +207,7 @@ ifndef::microshift[] |`mirror.platform.architectures` |The architecture of the platform release payload to mirror. -|Array of strings. For example, +|Array of strings. For example: [source,yaml] ---- @@ -228,7 +223,7 @@ The default value is `amd64`. The value `multi` ensures that the mirroring is su |`mirror.platform.channels` |The platform channel configuration of the image set. -|Array of objects. For example, +|Array of objects. For example: [source,yaml,subs="attributes+"] ---- @@ -243,15 +238,15 @@ channels: |`mirror.platform.channels.name` |The name of the release channel. -|String. For example, `stable-4.16` +|String. For example: `stable-4.16` |`mirror.platform.channels.minVersion` |The minimum version of the referenced platform to be mirrored. -|String. For example, `4.12.6` +|String. For example: `4.12.6` |`mirror.platform.channels.maxVersion` |The highest version of the referenced platform to be mirrored. -|String. For example, `4.16.1` +|String. For example: `4.16.1` |`mirror.platform.channels.shortestPath` |Toggles shortest path mirroring or full range mirroring. @@ -259,7 +254,7 @@ channels: |`mirror.platform.channels.type` |The type of the platform to be mirrored. -|String. For example, `ocp` or `okd`. The default is `ocp`. +|String. For example: `ocp` or `okd`. The default is `ocp`. |`mirror.platform.graph` |Indicates whether the OSUS graph is added to the image set and subsequently published to the mirror. @@ -277,7 +272,7 @@ endif::microshift[] |`storageConfig.local.path` |The path of the directory to contain the image set metadata. -|String. For example, `./path/to/dir/`. +|String. For example: `./path/to/dir/`. |`storageConfig.registry` |The registry back-end configuration of the image set. @@ -285,7 +280,7 @@ endif::microshift[] |`storageConfig.registry.imageURL` |The back-end registry URI. Can optionally include a namespace reference in the URI. -|String. For example, `quay.io/myuser/imageset:metadata`. +|String. For example: `quay.io/myuser/imageset:metadata`. |`storageConfig.registry.skipTLS` |Optionally skip TLS verification of the referenced back-end registry. @@ -297,7 +292,7 @@ endif::microshift[] ==== Using the `minVersion` and `maxVersion` properties to filter for a specific Operator version range can result in a multiple channel heads error. The error message states that there are `multiple channel heads`. This is because when the filter is applied, the update graph of the Operator is truncated. -Operator Lifecycle Manager [OLM] requires that every Operator channel contains versions that form an update graph with exactly one end point, that is, the latest version of the Operator. When the filter range is applied, that graph can turn into two or more separate graphs or a graph that has more than one end point. +Operator Lifecycle Manager requires that every Operator channel contains versions that form an update graph with exactly one end point, that is, the latest version of the Operator. When the filter range is applied, that graph can turn into two or more separate graphs or a graph that has more than one end point. To avoid this error, do not filter out the latest version of an Operator. If you still run into the error, depending on the Operator, either the `maxVersion` property must be increased or the `minVersion` property must be decreased. Because every Operator graph can be different, you might need to adjust these values until the error resolves. ==== diff --git a/modules/oc-mirror-installing-plugin.adoc b/modules/oc-mirror-installing-plugin.adoc index 2058f7e42412..1139197e7875 100644 --- a/modules/oc-mirror-installing-plugin.adoc +++ b/modules/oc-mirror-installing-plugin.adoc @@ -11,23 +11,22 @@ * You have installed the OpenShift CLI (`oc`). If you are mirroring image sets in a fully disconnected environment, ensure the following: -** You have installed the oc-mirror plugin v1 on the host that has internet access. +** You have installed the oc-mirror plugin on the host that has internet access. ** The host in the disconnected environment has access to the target mirror registry. +* You have set the `umask` parameter to `0022` on the operating system that uses oc-mirror. + * You have installed the correct binary for the {op-system-base} version that you are using. .Procedure -. Download the oc-mirror CLI plugin v1: +. Download the oc-mirror CLI plugin. .. Navigate to the link:https://console.redhat.com/openshift/downloads[Downloads] page of the {cluster-manager-url}. -.. Under the *OpenShift disconnected installation tools* section, follow the steps to save the file: -* Select your operating system and architecture type: -** Choose *{op-system-base-full} 9* for FIPS compliance. -* Click *Download* to get the oc-mirror plugin v1 and save the file. +.. Under the *OpenShift disconnected installation tools* section, click *Download* for *OpenShift Client (oc) mirror plugin* and save the file. . Extract the archive: + @@ -36,7 +35,7 @@ $ tar xvzf oc-mirror.tar.gz ---- -. If necessary, update the oc-mirror plugin v1 file to be executable: +. If necessary, update the plugin file to be executable: + [source,terminal] ---- @@ -57,7 +56,7 @@ $ sudo mv oc-mirror /usr/local/bin/. .Verification -* Run the `oc mirror help` command to verify that the oc-mirror plugin v1 was successfully installed: +* Run `oc mirror help` to verify that the plugin was successfully installed: + [source,terminal] ---- diff --git a/modules/oc-mirror-mirror-to-disk.adoc b/modules/oc-mirror-mirror-to-disk.adoc index 3e515318f0b8..831b0937c974 100644 --- a/modules/oc-mirror-mirror-to-disk.adoc +++ b/modules/oc-mirror-mirror-to-disk.adoc @@ -5,31 +5,30 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-mirror-to-disk_{context}"] -= Mirroring from mirror-to-disk += Mirroring from mirror to disk -You can use the oc-mirror plugin v1 to generate an image set and save the contents to disk. The generated image set can then be transferred to the disconnected environment and mirrored to the target registry. +You can use the oc-mirror plugin to generate an image set and save the contents to disk. The generated image set can then be transferred to the disconnected environment and mirrored to the target registry. [IMPORTANT] ==== Depending on the configuration specified in the image set configuration file, using oc-mirror to mirror images might download several hundreds of gigabytes of data to disk. -When configuring the mirror registry, the initial image set tends to be the largest. Subsequent uses of the oc-mirror plugin v1 result in smaller downloads, as only the changed images are retrieved since the last execution. +The initial image set download when you populate the mirror registry is often the largest. Because you only download the images that changed since the last time you ran the command, when you run the oc-mirror plugin again, the generated image set is often smaller. ==== -You must specify a storage backend in the image set configuration file. See "Setting up incremental mirroring". +You are required to specify a storage backend in the image set configuration file. This storage backend can be a local directory or a docker v2 registry. The oc-mirror plugin stores metadata in this storage backend during image set creation. [IMPORTANT] ==== -Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. You must use the same storage backend every time you run the oc-mirror plugin v1 for the same mirror registry. +Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. ==== .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin v1. +* You have installed the `oc-mirror` CLI plugin. * You have created the image set configuration file. -* You have set the umask parameter to `0022` on the operating system that uses oc-mirror plugin v1. // TODO: Don't need a running cluster, but need some pull secrets. Sync w/ team on this .Procedure @@ -72,4 +71,5 @@ mirror_seq1_000000.tar .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] \ No newline at end of file +* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. + diff --git a/modules/oc-mirror-mirror-to-mirror.adoc b/modules/oc-mirror-mirror-to-mirror.adoc index 5f968e42c5ea..72e8683a37f5 100644 --- a/modules/oc-mirror-mirror-to-mirror.adoc +++ b/modules/oc-mirror-mirror-to-mirror.adoc @@ -6,28 +6,23 @@ :_mod-docs-content-type: PROCEDURE [id="oc-mirror-mirror-to-mirror_{context}"] -= Mirroring an image set in a partially disconnected environment: += Mirroring from mirror to mirror -You can use the oc-mirror plugin v1 to mirror an image set directly to a target mirror registry that is accessible during image set creation. +You can use the oc-mirror plugin to mirror an image set directly to a target mirror registry that is accessible during image set creation. -[NOTE] -==== -You must specify a storage backend in the image set configuration file. See "Setting up incremental mirroring". -==== +You are required to specify a storage backend in the image set configuration file. This storage backend can be a local directory or a Docker v2 registry. The oc-mirror plugin stores metadata in this storage backend during image set creation. [IMPORTANT] ==== -Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. You must use the same storage backend every time you run the oc-mirror plugin v1 for the same mirror registry. +Do not delete or modify the metadata that is generated by the oc-mirror plugin. You must use the same storage backend every time you run the oc-mirror plugin for the same mirror registry. ==== .Prerequisites * You have access to the internet to get the necessary container images. -* You have access to the target mirror registry. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin v1. +* You have installed the `oc-mirror` CLI plugin. * You have created the image set configuration file. -* You have set the umask parameter to `0022` on the underlying operating system that uses oc-mirror plugin v1. .Procedure @@ -75,8 +70,8 @@ ifdef::microshift[] * Convert the `ImageContentSourcePolicy` YAML content for use in manually configuring CRI-O. * If required, mirror the images from mirror to disk for disconnected or offline use. endif::microshift[] -* Configure your cluster to use the resources generated by the oc-mirror plugin. See "Configuring your cluster to use the resources generated by oc-mirror". +* Configure your cluster to use the resources generated by oc-mirror. .Troubleshooting -* link:https://access.redhat.com/solutions/7032017[What to do when encountering "manifest unknown error: unable to retrieve source image" while using oc-mirror?] \ No newline at end of file +* link:https://access.redhat.com/solutions/7032017[Unable to retrieve source image]. diff --git a/modules/oc-mirror-mirroring-image-set.adoc b/modules/oc-mirror-mirroring-image-set.adoc deleted file mode 100644 index 5adde9b94e0b..000000000000 --- a/modules/oc-mirror-mirroring-image-set.adoc +++ /dev/null @@ -1,15 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/disconnected_install/installing-mirroring-disconnected.adoc -// * updating/updating_a_cluster/updating_disconnected_cluster/mirroring-image-repository.adoc -// * microshift_running_apps/microshift_operators/microshift-operators-oc-mirror.adoc - -:_mod-docs-content-type: CONCEPT -[id="mirroring-image-set_{context}"] -= Mirroring an image set to a mirror registry - -To populate your mirror registry with {product-title} images, you can use one of the following scenarios: - -* *Partially disconnected environment*: The host can access both the internet and your mirror registry, but not your cluster nodes. This setup enables you to mirror content directly from the host machine. - -* *Fully disconnected environment*: The host cannot access the internet, your mirror registry, or the cluster nodes. In this setup, you must mirror the images to a file system and then bring that host or removable media into your restricted environment. \ No newline at end of file diff --git a/modules/oc-mirror-oci-format.adoc b/modules/oc-mirror-oci-format.adoc index 9f9e295bdc92..a716103c9c28 100644 --- a/modules/oc-mirror-oci-format.adoc +++ b/modules/oc-mirror-oci-format.adoc @@ -15,16 +15,21 @@ The local catalog and its contents are mirrored to your target mirror registry b ==== When mirroring local OCI catalogs, any {product-title} releases or additional images that you want to mirror along with the local OCI-formatted catalog must be pulled from a registry. -You cannot mirror OCI catalogs along with an oc-mirror plugin v1 image set file on disk. +You cannot mirror OCI catalogs along with an oc-mirror image set file on disk. ==== One example use case for using the OCI feature is if you have a CI/CD system building an OCI catalog to a location on disk, and you want to mirror that OCI catalog along with an {product-title} release to your mirror registry. +[NOTE] +==== +If you used the Technology Preview OCI local catalogs feature for the oc-mirror plugin for {product-title} 4.12, you can no longer use the OCI local catalogs feature of the oc-mirror plugin to copy a catalog locally and convert it to OCI format as a first step to mirroring to a fully disconnected cluster. +==== + .Prerequisites * You have access to the internet to obtain the necessary container images. * You have installed the OpenShift CLI (`oc`). -* You have installed the `oc-mirror` CLI plugin v1. +* You have installed the `oc-mirror` CLI plugin. .Procedure @@ -95,4 +100,4 @@ Optionally, you can specify other flags to adjust the behavior of the OCI featur .Next steps -* Configure your cluster to use the resources generated by oc-mirror plugin v1. +* Configure your cluster to use the resources generated by oc-mirror. diff --git a/modules/oc-mirror-setting-incremental-mirroring.adoc b/modules/oc-mirror-setting-incremental-mirroring.adoc deleted file mode 100644 index 3dde1d957b8c..000000000000 --- a/modules/oc-mirror-setting-incremental-mirroring.adoc +++ /dev/null @@ -1,53 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/disconnected_install/installing-mirroring-disconnected.adoc - -:_mod-docs-content-type: PROCEDURE -[id="setting-incremental-mirroring_{context}"] -= Setting up for incremental mirroring - -You mirror images to install, upgrade, and maintain {product-title} in a disconnected environment. Because the volume of the image set needed to install or upgrade {product-title} can be substantial, oc-mirror plugin v1 stores the metadata of the previously mirrored images in its storage backend thus reducing the volume of the image sets to the recent images only. - -You can specify the following storage backends: - -* A local directory -+ -[NOTE] -==== -Using a local directory is not recommended for enterprise scenarios because it does not scale effectively. This method is suitable only for small-scale environments or testing purposes. -==== -+ -.Example `ImageSetConfiguration` file -[source,terminal] ----- -kind: ImageSetConfiguration -apiVersion: mirror.openshift.io/v1alpha2 -storageConfig: - local: - path: <1> ----- -<1> Specify your target workspace path. - -* A registry that supports Docker v2-2 -+ -.Example `ImageSetConfiguration` file -[source,terminal] ----- -kind: ImageSetConfiguration -apiVersion: mirror.openshift.io/v1alpha2 -storageConfig: - registry: - imageURL: <1> - skipTLS: false ----- -<1> Specifies the location of your storage backend, such as `example.com/mirror/oc-mirror-metadata`. - -When mirroring content with the oc-mirror plugin v1, consider the following: - -* Ensure you always use the same storage backend and the same image set configuration for a given mirror registry location, so that the metadata remains consistent. - -* Do not attempt to push or prune images of that mirror registry location manually, without using oc-mirror plugin v1. - -* Do not delete or modify the metadata that is generated by the oc-mirror plugin v1. - -* Keep a backup of the storage backend when mirroring content to a given location on your mirror registry with the oc-mirror plugin v1. \ No newline at end of file diff --git a/modules/oc-mirror-support.adoc b/modules/oc-mirror-support.adoc index 21bb74a4af52..5db4fcdc9df4 100644 --- a/modules/oc-mirror-support.adoc +++ b/modules/oc-mirror-support.adoc @@ -7,11 +7,11 @@ [id="oc-mirror-support_{context}"] = oc-mirror compatibility and support -The oc-mirror plugin v1 supports mirroring {product-title} payload images and Operator catalogs for {product-title} versions 4.12 and later. +The oc-mirror plugin supports mirroring {product-title} payload images and Operator catalogs for {product-title} versions 4.10 and later. [NOTE] ==== -On `aarch64`, `ppc64le`, and `s390x` architectures the oc-mirror plugin v1 is only supported for {product-title} versions 4.14 and later. +On `aarch64`, `ppc64le`, and `s390x` architectures the oc-mirror plugin is only supported for {product-title} versions 4.14 and later. ==== Use the latest available version of the oc-mirror plugin regardless of which versions of {product-title} you need to mirror. \ No newline at end of file diff --git a/modules/oc-mirror-updating-cluster-manifests.adoc b/modules/oc-mirror-updating-cluster-manifests.adoc index 3b5b287187a8..56b673f2d8aa 100644 --- a/modules/oc-mirror-updating-cluster-manifests.adoc +++ b/modules/oc-mirror-updating-cluster-manifests.adoc @@ -9,9 +9,7 @@ After you have mirrored your image set to the mirror registry, you must apply the generated `ImageContentSourcePolicy`, `CatalogSource`, and release image signature resources into the cluster. -If you set `graph:true` in your `ImageSetConfiguration` file, the oc-mirror plugin v1 generates an `UpdateService.yaml` file. The `UpdateService` resource can be used to configure the OSUS service on the cluster side. See "About the OpenShift Update Service" for more information. - -The `ImageContentSourcePolicy` resource associates the mirror registry with the source registry and redirects image pull requests from the online registries to the mirror registry. The `CatalogSource` resource is used by OLM to retrieve information about the available Operators in the mirror registry. The release image signatures are used to verify the mirrored release images. +The `ImageContentSourcePolicy` resource associates the mirror registry with the source registry and redirects image pull requests from the online registries to the mirror registry. The `CatalogSource` resource is used by Operator Lifecycle Manager (OLM) to retrieve information about the available Operators in the mirror registry. The release image signatures are used to verify the mirrored release images. .Prerequisites diff --git a/modules/oc-mirror-updating-registry-about.adoc b/modules/oc-mirror-updating-registry-about.adoc index d85fe28a60ba..5a6fc76ce630 100644 --- a/modules/oc-mirror-updating-registry-about.adoc +++ b/modules/oc-mirror-updating-registry-about.adoc @@ -7,24 +7,24 @@ [id="oc-mirror-updating-registry-about_{context}"] = Updating your mirror registry content -In order to upgrade your disconnected {product-title} cluster, you must update your mirror registry content with updated content from the Red Hat registries. - -You can update your registry content by updating the image set configuration file and mirroring the image set to the mirror registry. Every time you run the oc-mirror plugin v1, an image set is generated that only contains new and updated images since the previous execution. +You can update your mirror registry content by updating the image set configuration file and mirroring the image set to the mirror registry. The next time that you run the oc-mirror plugin, an image set is generated that only contains new and updated images since the previous execution. While updating the mirror registry, you must take into account the following considerations: -* Images are pruned from the target mirror registry if they are no longer included in the latest image set that was generated and mirrored. Therefore, ensure that you are updating images for the same combination of the following key components: +* Images are pruned from the target mirror registry if they are no longer included in the latest image set that was generated and mirrored. Therefore, ensure that you are updating images for the same combination of the following key components so that only a differential image set is created and mirrored: -** Image set configuration: Modify your existing `ImageSetConfiguration` file to update channels and version selections to align with the desired content in your disconnected registry after completing the mirror operation. +** Image set configuration -** Target mirror registry: If you specified a top-level namespace for the mirror registry during the initial image set creation, use the same namespace every time you run the oc-mirror plugin v1 for that mirror registry. +** Destination registry -** Storage configuration: Retain the exact metadata, either container image or file directory, from your `storageConfig` across runs on the connected side. +** Storage configuration -* The images can be pruned during the disk-to-mirror or mirror-to-mirror workflow. +* The images can be pruned in case of disk to mirror or mirror to mirror workflow. * The generated image sets must be pushed to the target mirror registry in sequence. You can derive the sequence number from the file name of the generated image set archive file. -* Do not delete or modify the metadata image that is generated by the oc-mirror plugin v1. +* Do not delete or modify the metadata image that is generated by the oc-mirror plugin. + +* If you specified a top-level namespace for the mirror registry during the initial image set creation, then you must use this same namespace every time you run the oc-mirror plugin for the same mirror registry. -For more information about the workflow to update the mirror registry content, see "High level workflow" section. \ No newline at end of file +For more information about the workflow to update the mirror registry content, see the "High level workflow" section. \ No newline at end of file diff --git a/modules/oc-mirror-updating-use-cases.adoc b/modules/oc-mirror-updating-use-cases.adoc index 9fa9d4603146..8ef2f66c8d77 100644 --- a/modules/oc-mirror-updating-use-cases.adoc +++ b/modules/oc-mirror-updating-use-cases.adoc @@ -6,9 +6,10 @@ [id="oc-mirror-image-set-examples-add-images_{context}"] = Mirror registry update examples -This section covers the use cases for updating the mirror registry by using the disk-to-mirror workflows. +This section covers the use cases for updating the mirror registry from disk to mirror. + +.Example `ImageSetConfiguration` file that was previously used for mirroring: -.Example `ImageSetConfiguration` file that was previously used for mirroring [source, yaml] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -28,15 +29,13 @@ mirror: - name: rhacs-operator channels: - name: stable - minVersion: 1.0.1 ---- -[id="mirror-latest-version-upgrading_{context}"] -== Upgrading to the latest {product-title} version +[discrete] +== Mirroring a specific {product-title} version by pruning the existing images -You can upgrade to the latest {product-title} version by running the mirroring workflow without changing the `ImageSetConfiguration` file. +.Updated `ImageSetConfiguration` file: -.Updated `ImageSetConfiguration` file [source,yaml] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -47,60 +46,21 @@ storageConfig: mirror: platform: channels: - - name: stable-4.12 - minVersion: 4.12.1 - maxVersion: 4.12.1 - - name: stable-4.14 + - name: stable-4.13 #<1> operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 packages: - name: rhacs-operator channels: - name: stable - minVersion: 1.0.1 ---- +<1> Replacing by `stable-4.13` prunes all the images of `stable-4.12`. -This image set configuration mirrors all the necessary {product-title} releases for upgrading the cluster from version 4.12.1 to the latest version in the `stable-4.14` channel. - -When adding `stable-4.14` alongside 4.12.1 while you are still using 4.12.1, note that a cluster reboot may occur after a mirror refresh, but before an upgrade, due to routine operations. It is crucial to ensure that you have the images you are currently using. +[discrete] +== Updating to the latest version of an Operator by pruning the existing images -[id="mirror-specific-version-prune-existing_{context}"] -== Mirroring a specific {product-title} version and pruning the existing images +.Updated `ImageSetConfiguration` file: -You can mirror a specific {product-title} version while pruning images from an older version. In this scenario, you remove the images of {product-title} 4.12.1, as the cluster was previously upgraded to 4.14.25 during the prior mirroring process. - -.Updated `ImageSetConfiguration` file -[source,yaml] ----- -apiVersion: mirror.openshift.io/v1alpha2 -kind: ImageSetConfiguration -storageConfig: - local: - path: /home/user/metadata -mirror: - platform: - channels: - - name: stable-4.14 <1> - minVersion: 4.14.25 - - name: stable-4.15 - operators: - - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 - packages: - - name: rhacs-operator - channels: - - name: stable - minVersion: 1.0.1 ----- -<1> Replacing `stable-4.12` with `stable-4.14` prunes all the images of `stable-4.12`. - -[id="mirror-latest-version-prune-existing_{context}"] -== Updating to the latest version of an Operator and pruning the existing images - -You can update to the latest version of an Operator while pruning existing images using an updated `ImageSetConfiguration` file. By following this method, you ensure that only the necessary images for the specific upgrade path are retained. - -If the initial `ImageSetConfiguration` file contains only a specified `minVersion`, oc-mirror plugin v1 includes these versions and valid upgrade paths in its processing. To ensure only the latest versions are mirrored, and oc-mirror plugin v1 retains only the images necessary for the specific upgrade path, avoid specifying any `minVersion`. - -.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -119,15 +79,17 @@ mirror: packages: - name: rhacs-operator channels: - - name: stable + - name: stable #<1> ---- +<1> Using the same channel without specifying a version prunes the existing images and updates with the latest version of images. + +[discrete] [id="oc-mirror-image-set-examples-operator-pruning-versions_{context}"] -== Mirroring a new Operator and pruning the existing Operator +== Mirroring a new Operator by pruning the existing Operator -You can mirror a new Operator and prune an existing one using an `ImageSetConfiguration` file. +.Updated `ImageSetConfiguration` file: -.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -148,15 +110,13 @@ mirror: channels: - name: stable ---- -<1> Replacing `rhacs-operator` with `` prunes the Red Hat Advanced Cluster Security for Kubernetes Operator. +<1> Replacing `rhacs-operator` with `new_operator_name` prunes the Red Hat Advanced Cluster Security for Kubernetes Operator. +[discrete] +== Pruning all the {product-title} images -[id="mirror-non-ideal-practice-pruning_{context}"] -== Pruning All {product-title} Images +.Updated `ImageSetConfiguration` file: -You can prune all {product-title} images by running the mirroring workflow without altering the `ImageSetConfiguration` file. - -.Updated `ImageSetConfiguration` file [source,yaml,subs=attributes+] ---- apiVersion: mirror.openshift.io/v1alpha2 @@ -165,11 +125,9 @@ storageConfig: local: path: /home/user/metadata mirror: + platform: + channels: operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.14 packages: ----- - -If you remove the platform section from your `ImageSetConfiguration` file, the `oc-mirror` plugin v1 removes all {product-title} images from the mirror registry. This action may disrupt the cluster's functionality, especially during a cluster reboot due to a `MachineConfiguration` change or other routine tasks. - -To avoid unintended disruptions, use the `--dry-run` flag with the mirror-to-mirror or disk-to-mirror workflows. Running `--dry-run` allows you to verify the intended actions and ensure they do not negatively impact any disconnected clusters, even if you choose to skip pruning during the actual workflow. \ No newline at end of file +---- \ No newline at end of file From 7043dc9f355516595687efe5195bfe5193e8543a Mon Sep 17 00:00:00 2001 From: John Wilkins Date: Fri, 14 Jun 2024 11:26:37 -0700 Subject: [PATCH 185/339] HCIDOCS-72: Added a module for attaching a non-bootable ISO after provisioning a node.. --- ...non-bootable-iso-to-a-bare-metal-node.adoc | 98 +++++++++++++++++++ .../bare-metal-configuration.adoc | 2 + 2 files changed, 100 insertions(+) create mode 100644 modules/bmo-attaching-a-non-bootable-iso-to-a-bare-metal-node.adoc diff --git a/modules/bmo-attaching-a-non-bootable-iso-to-a-bare-metal-node.adoc b/modules/bmo-attaching-a-non-bootable-iso-to-a-bare-metal-node.adoc new file mode 100644 index 000000000000..3c69a3771ddb --- /dev/null +++ b/modules/bmo-attaching-a-non-bootable-iso-to-a-bare-metal-node.adoc @@ -0,0 +1,98 @@ +// This module is included in the following assemblies: +// +// * post_installation_configuration/bare-metal-configuration.adoc + +:_mod-docs-content-type: PROCEDURE +[id="attaching-a-non-bootable-iso-to-a-bare-metal-node_{context}"] += Attaching a non-bootable ISO to a bare-metal node + +You can attach a generic, non-bootable ISO virtual media image to a provisioned node by using the `DataImage` resource. After you apply the resource, the ISO image becomes accessible to the operating system after it has booted. This is useful for configuring a node after provisioning the operating system and before the node boots for the first time. + +.Prerequisites + +* The node must use Redfish or drivers derived from it to support this feature. +* The node must be in the `Provisioned` or `ExternallyProvisioned` state. +* The `name` must be the same as the name of the node defined in its `BareMetalHost` resource. +* You have a valid `url` to the ISO image. + +.Procedure + +. Create a `DataImage` resource: ++ +[source,yaml] +---- +apiVersion: metal3.io/v1alpha1 +kind: DataImage +metadata: + name: # <1> +spec: + url: "http://dataimage.example.com/non-bootable.iso" # <2> +---- +<1> Specify the name of the node as defined in its `BareMetalHost` resource. +<2> Specify the URL and path to the ISO image. + +. Save the `DataImage` resource to a file by running the following command: ++ +[source,terminal] +---- +$ vim -dataimage.yaml +---- + +. Apply the `DataImage` resource by running the following command: ++ +[source,terminal] +---- +$ oc apply -f -dataimage.yaml -n <1> +---- +<1> Replace `` so that the namespace matches the namespace for the `BareMetalHost` resource. For example, `openshift-machine-api`. + +. Reboot the node. ++ +[NOTE] +==== +You can physically reboot the node. You can also attach the `reboot.metal3.io` annotation or reset set the `online` status in the `BareMetalHost` resource. A forced reboot of the bare-metal node will change the state of the node to `NotReady` for awhile. For example, 5 minutes or more. +==== + +. View the `DataImage` resource by running the following command: ++ +[source,terminal] +---- +$ oc get dataimage -n openshift-machine-api -o yaml +---- ++ +.Example output +[source,yaml] +---- +apiVersion: v1 +items: +- apiVersion: metal3.io/v1alpha1 + kind: DataImage + metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"metal3.io/v1alpha1","kind":"DataImage","metadata":{"annotations":{},"name":"bmh-node-1","namespace":"openshift-machine-api"},"spec":{"url":"http://dataimage.example.com/non-bootable.iso"}} + creationTimestamp: "2024-06-10T12:00:00Z" + finalizers: + - dataimage.metal3.io + generation: 1 + name: bmh-node-1 + namespace: openshift-machine-api + ownerReferences: + - apiVersion: metal3.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: BareMetalHost + name: bmh-node-1 + uid: 046cdf8e-0e97-485a-8866-e62d20e0f0b3 + resourceVersion: "21695581" + uid: c5718f50-44b6-4a22-a6b7-71197e4b7b69 + spec: + url: http://dataimage.example.com/non-bootable.iso + status: + attachedImage: + url: http://dataimage.example.com/non-bootable.iso + error: + count: 0 + message: "" + lastReconciled: "2024-06-10T12:05:00Z" +---- diff --git a/post_installation_configuration/bare-metal-configuration.adoc b/post_installation_configuration/bare-metal-configuration.adoc index d59a9da6844d..cca6bc9b672e 100644 --- a/post_installation_configuration/bare-metal-configuration.adoc +++ b/post_installation_configuration/bare-metal-configuration.adoc @@ -14,6 +14,8 @@ include::modules/bmo-about-the-baremetalhost-resource.adoc[leveloffset=+1] include::modules/bmo-getting-the-baremetalhost-resource.adoc[leveloffset=+1] include::modules/bmo-editing-a-baremetalhost-resource.adoc[leveloffset=+1] +include::modules/bmo-attaching-a-non-bootable-iso-to-a-bare-metal-node.adoc[leveloffset=+1] + include::modules/bmo-about-the-hostfirmwaresettings-resource.adoc[leveloffset=+1] include::modules/bmo-getting-the-hostfirmwaresettings-resource.adoc[leveloffset=+1] include::modules/bmo-editing-the-hostfirmwaresettings-resource.adoc[leveloffset=+1] From 854e0fac2d5b47095186ff09843a9b214fc080c2 Mon Sep 17 00:00:00 2001 From: Aidan Reilly <74046732+aireilly@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:58:30 +0100 Subject: [PATCH 186/339] Removing out of date TP note --- ...nfiguring-linuxptp-services-as-boundary-clock-dual-nic.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/ptp-configuring-linuxptp-services-as-boundary-clock-dual-nic.adoc b/modules/ptp-configuring-linuxptp-services-as-boundary-clock-dual-nic.adoc index ad1e3b4015f0..a2904177b24d 100644 --- a/modules/ptp-configuring-linuxptp-services-as-boundary-clock-dual-nic.adoc +++ b/modules/ptp-configuring-linuxptp-services-as-boundary-clock-dual-nic.adoc @@ -6,9 +6,6 @@ [id="ptp-configuring-linuxptp-services-as-bc-for-dual-nic_{context}"] = Configuring linuxptp services as boundary clocks for dual-NIC hardware -:FeatureName: Precision Time Protocol (PTP) hardware with dual-NIC configured as boundary clocks -include::snippets/technology-preview.adoc[leveloffset=+1] - You can configure the `linuxptp` services (`ptp4l`, `phc2sys`) as boundary clocks for dual-NIC hardware by creating a `PtpConfig` custom resource (CR) object for each NIC. Dual NIC hardware allows you to connect each NIC to the same upstream leader clock with separate `ptp4l` instances for each NIC feeding the downstream clocks. From 9eb5569d46c18bcbcb53856c5b4b5965f2b5673e Mon Sep 17 00:00:00 2001 From: Max Leonov Date: Mon, 10 Jun 2024 16:09:03 +0200 Subject: [PATCH 187/339] OBSDOCS-1132: Release notes for the Distributed Tracing 3.2.1 patch --- _topic_maps/_topic_map.yml | 8 +- .../distr-tracing-rn-3-2-1.adoc | 145 ++++++++ .../distr-tracing-rn-3-2.adoc | 129 ------- .../distr-tracing-rn-past-releases.adoc | 325 ++++++++++++------ observability/otel/otel_rn/otel-rn-3-2-1.adoc | 74 ++++ observability/otel/otel_rn/otel-rn-3-2.adoc | 78 ----- .../otel/otel_rn/otel-rn-past-releases.adoc | 168 ++++++--- 7 files changed, 562 insertions(+), 365 deletions(-) create mode 100644 observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc delete mode 100644 observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2.adoc create mode 100644 observability/otel/otel_rn/otel-rn-3-2-1.adoc delete mode 100644 observability/otel/otel_rn/otel-rn-3-2.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index b52dc17752f0..430469dca6f1 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2825,8 +2825,8 @@ Topics: - Name: Release notes Dir: distr_tracing_rn Topics: - - Name: Distributed tracing 3.2 - File: distr-tracing-rn-3-2 + - Name: Distributed tracing 3.2.1 + File: distr-tracing-rn-3-2-1 - Name: Past releases File: distr-tracing-rn-past-releases - Name: Distributed tracing architecture @@ -2863,8 +2863,8 @@ Topics: - Name: Release notes Dir: otel_rn Topics: - - Name: Red Hat build of OpenTelemetry 3.2 - File: otel-rn-3-2 + - Name: Red Hat build of OpenTelemetry 3.2.1 + File: otel-rn-3-2-1 - Name: Past releases File: otel-rn-past-releases - Name: Installing diff --git a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc new file mode 100644 index 000000000000..470344e1f6ef --- /dev/null +++ b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc @@ -0,0 +1,145 @@ +:_mod-docs-content-type: ASSEMBLY +include::_attributes/common-attributes.adoc[] +[id="distributed-tracing-rn-3-2-1"] += Release notes for {DTProductName} 3.2.1 +:context: distributed-tracing-rn-3-2-1 + +toc::[] + +include::modules/distr-tracing-product-overview.adoc[leveloffset=+1] + +You can use the {DTShortName} xref:../../otel/otel-forwarding.adoc#otel-forwarding-traces[in combination with] the xref:../../otel/otel-installing.adoc#install-otel[{OTELName}]. + +This release of the {DTProductName} includes the {TempoName} and the deprecated {JaegerName}. + +[id="distributed-tracing-rn_3-2-1_cves_{context}"] +== CVEs + +This release fixes link:https://access.redhat.com/security/cve/CVE-2024-25062/[CVE-2024-25062]. + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_{context}"] +== {TempoName} + +The {TempoName} is provided through the {TempoOperator}. +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_technology-preview-features_{context}"] +=== Technology Preview features + +This update introduces the following Technology Preview feature: + +* Support for the Tempo monolithic deployment. + +:FeatureName: The Tempo monolithic deployment +include::snippets/technology-preview.adoc[leveloffset=+1] +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_new-features-and-enhancements_{context}"] +=== New features and enhancements + +This update introduces the following enhancements: + +* {TempoName} 3.2.1 is based on the open source link:https://grafana.com/oss/tempo/[Grafana Tempo] 2.4.1. +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_deprecated-functionality_{context}"] +=== Deprecated functionality + +In the {TempoName} 3.2.1, ??? +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_removal-notice_{context}"] +=== Removal notice + +In {TempoName} 3.2.1, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_bug-fixes_{context}"] +=== Bug fixes + +This update introduces the following bug fixes: + +* Before this update, ... . (link:https://issues.redhat.com/browse/TRACING-????[TRACING-????]) +//// + +//// +[id="distributed-tracing-rn_3-2-1_tempo-release-notes_known-issues_{context}"] +=== Known issues + +There is currently a known issue: + +* Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_{context}"] +== {JaegerName} + +The {JaegerName} is provided through the {JaegerOperator} Operator. + +[IMPORTANT] +==== +Jaeger does not use FIPS validated cryptographic modules. +==== +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_support-for-elasticsearch-operator_{context}"] +=== Support for {es-op} + +{JaegerName} 3.2.1 is supported for use with the {es-op} 5.6, 5.7, and 5.8. +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_deprecated-functionality_{context}"] +=== Deprecated functionality + +In the {DTProductName} 3.2.1, Jaeger and support for Elasticsearch remain deprecated, and both are planned to be removed in a future release. +Red Hat will provide support for these components and fixes for CVEs and bugs with critical and higher severity during the current release lifecycle, but these components will no longer receive feature enhancements. +The {TempoOperator} and the {OTELName} are the preferred Operators for distributed tracing collection and storage. +Users must adopt the OpenTelemetry and Tempo distributed tracing stack because it is the stack to be enhanced going forward. + +In the {DTProductName} 3.2.1, the Jaeger agent is deprecated and planned to be removed in the following release. +Red Hat will provide bug fixes and support for the Jaeger agent during the current release lifecycle, but the Jaeger agent will no longer receive enhancements and will be removed. +The OpenTelemetry Collector provided by the {OTELName} is the preferred Operator for injecting the trace collector agent. +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_removal-notice_{context}"] +=== Removal notice + +In {DTProductName} 3.2.1, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_new-features-and-enhancements_{context}"] +=== New features and enhancements + +This update introduces the following enhancements for the {JaegerShortName}: + +* {JaegerName} 3.2.1 is based on the open source link:https://www.jaegertracing.io/[Jaeger] release 1.57.0. +//// + +//// +[id="distributed-tracing-rn_3-2-1_jaeger-release-notes_known-issues_{context}"] +=== Known issues + +There is currently a known issue: + +* Currently, Apache Spark is not supported. + +ifndef::openshift-rosa[] + +* Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. +endif::openshift-rosa[] +//// + +include::modules/support.adoc[leveloffset=+1] + +include::modules/making-open-source-more-inclusive.adoc[leveloffset=+1] diff --git a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2.adoc b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2.adoc deleted file mode 100644 index 59e16af53822..000000000000 --- a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2.adoc +++ /dev/null @@ -1,129 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -include::_attributes/common-attributes.adoc[] -[id="distributed-tracing-rn-3-2"] -= Release notes for {DTProductName} 3.2 -:context: distributed-tracing-rn-3-2 - -toc::[] - -include::modules/distr-tracing-product-overview.adoc[leveloffset=+1] - -You can use the {DTShortName} xref:../../otel/otel-forwarding.adoc#otel-forwarding-traces[in combination with] the xref:../../otel/otel-installing.adoc#install-otel[{OTELName}]. - -This release of the {DTProductName} includes the {TempoName} and the deprecated {JaegerName}. - -//// -[id="distributed-tracing-rn_3-2_cves"] -== CVEs - -This release fixes link:https://access.redhat.com/security/cve/cve-202?-?????[CVE-202?-?????]. -//// - -[id="distributed-tracing-rn_3-2_tempo-release-notes"] -== {TempoName} - -The {TempoName} is provided through the {TempoOperator}. - -[id="distributed-tracing-rn_3-2_tempo-release-notes_technology-preview-features"] -=== Technology Preview features - -This update introduces the following Technology Preview feature: - -* Support for the Tempo monolithic deployment. - -:FeatureName: The Tempo monolithic deployment -include::snippets/technology-preview.adoc[leveloffset=+1] - -[id="distributed-tracing-rn_3-2_tempo-release-notes_new-features-and-enhancements"] -=== New features and enhancements - -This update introduces the following enhancements: - -* {TempoName} 3.2 is based on the open source link:https://grafana.com/oss/tempo/[Grafana Tempo] 2.4.1. -* Allowing the overriding of resources per component. - -//// -[id="distributed-tracing-rn_3-2_tempo-release-notes_deprecated-functionality"] -=== Deprecated functionality - -In the {TempoName} 3.2, ??? -//// - -//// -[id="distributed-tracing-rn_3-2_tempo-release-notes_removal-notice"] -=== Removal notice - -In {TempoName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. -//// - -[id="distributed-tracing-rn_3-2_tempo-release-notes_bug-fixes"] -=== Bug fixes - -This update introduces the following bug fixes: - -* Before this update, the Jaeger UI only displayed services that sent traces in the previous 15 minutes. With this update, the availability of the service and operation names can be configured by using the following field: `spec.template.queryFrontend.jaegerQuery.servicesQueryDuration`. (link:https://issues.redhat.com/browse/TRACING-3139[TRACING-3139]) -* Before this update, the `query-frontend` pod might get stopped when out-of-memory (OOM) as a result of searching a large trace. With this update, resource limits can be set to prevent this issue. (link:https://issues.redhat.com/browse/TRACING-4009[TRACING-4009]) - -[id="distributed-tracing-rn_3-2_tempo-release-notes_known-issues"] -=== Known issues - -There is currently a known issue: - -* Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) - -[id="distributed-tracing-rn_3-2_jaeger-release-notes"] -== {JaegerName} - -The {JaegerName} is provided through the {JaegerOperator} Operator. - -[IMPORTANT] -==== -Jaeger does not use FIPS validated cryptographic modules. -==== - -[id="distributed-tracing-rn_3-2_jaeger-release-notes_support-for-elasticsearch-operator"] -=== Support for {es-op} - -{JaegerName} 3.2 is supported for use with the {es-op} 5.6, 5.7, and 5.8. - -[id="distributed-tracing-rn_3-2_jaeger-release-notes_deprecated-functionality"] -=== Deprecated functionality - -In the {DTProductName} 3.2, Jaeger and support for Elasticsearch remain deprecated, and both are planned to be removed in a future release. -Red Hat will provide support for these components and fixes for CVEs and bugs with critical and higher severity during the current release lifecycle, but these components will no longer receive feature enhancements. -The {TempoOperator} and the {OTELName} are the preferred Operators for distributed tracing collection and storage. -Users must adopt the OpenTelemetry and Tempo distributed tracing stack because it is the stack to be enhanced going forward. - -In the {DTProductName} 3.2, the Jaeger agent is deprecated and planned to be removed in the following release. -Red Hat will provide bug fixes and support for the Jaeger agent during the current release lifecycle, but the Jaeger agent will no longer receive enhancements and will be removed. -The OpenTelemetry Collector provided by the {OTELName} is the preferred Operator for injecting the trace collector agent. - -//// -[id="distributed-tracing-rn_3-2_jaeger-release-notes_removal-notice"] -=== Removal notice - -In {DTProductName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. -//// - -[id="distributed-tracing-rn_3-2_jaeger-release-notes_new-features-and-enhancements"] -=== New features and enhancements - -This update introduces the following enhancements for the {JaegerShortName}: - -* {JaegerName} 3.2 is based on the open source link:https://www.jaegertracing.io/[Jaeger] release 1.57.0. - -[id="distributed-tracing-rn_3-2_jaeger-release-notes_known-issues"] -=== Known issues - -There is currently a known issue: - -* Currently, Apache Spark is not supported. - -ifndef::openshift-rosa[] - -* Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. -endif::openshift-rosa[] - -include::modules/support.adoc[leveloffset=+1] - -include::modules/making-open-source-more-inclusive.adoc[leveloffset=+1] diff --git a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-past-releases.adoc b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-past-releases.adoc index 9dd1543c705d..42e86f6b3cf0 100644 --- a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-past-releases.adoc +++ b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-past-releases.adoc @@ -10,23 +10,140 @@ include::modules/distr-tracing-product-overview.adoc[leveloffset=+1] You can use the {DTShortName} xref:../../otel/otel-forwarding.adoc#otel-forwarding-traces[in combination with] the xref:../../otel/otel-installing.adoc#install-otel[{OTELName}]. -[id="distributed-tracing-rn-3-1-1"] +[id="distributed-tracing-rn-3-2_{context}"] +== Release notes for {DTProductName} 3.2 + +This release of the {DTProductName} includes the {TempoName} and the deprecated {JaegerName}. + +//// +[id="distributed-tracing-rn_3-2_cves_{context}"] +=== CVEs + +This release fixes link:https://access.redhat.com/security/cve/cve-202?-?????[CVE-202?-?????]. +//// + +[id="distributed-tracing-rn_3-2_tempo-release-notes_{context}"] +=== {TempoName} + +The {TempoName} is provided through the {TempoOperator}. + +[id="distributed-tracing-rn_3-2_tempo-release-notes_technology-preview-features_{context}"] +==== Technology Preview features + +This update introduces the following Technology Preview feature: + +* Support for the Tempo monolithic deployment. + +:FeatureName: The Tempo monolithic deployment +include::snippets/technology-preview.adoc[leveloffset=+1] + +[id="distributed-tracing-rn_3-2_tempo-release-notes_new-features-and-enhancements_{context}"] +==== New features and enhancements + +This update introduces the following enhancements: + +* {TempoName} 3.2 is based on the open source link:https://grafana.com/oss/tempo/[Grafana Tempo] 2.4.1. +* Allowing the overriding of resources per component. + +//// +[id="distributed-tracing-rn_3-2_tempo-release-notes_deprecated-functionality_{context}"] +==== Deprecated functionality + +In the {TempoName} 3.2, ??? +//// + +//// +[id="distributed-tracing-rn_3-2_tempo-release-notes_removal-notice_{context}"] +==== Removal notice + +In {TempoName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +[id="distributed-tracing-rn_3-2_tempo-release-notes_bug-fixes_{context}"] +==== Bug fixes + +This update introduces the following bug fixes: + +* Before this update, the Jaeger UI only displayed services that sent traces in the previous 15 minutes. With this update, the availability of the service and operation names can be configured by using the following field: `spec.template.queryFrontend.jaegerQuery.servicesQueryDuration`. (link:https://issues.redhat.com/browse/TRACING-3139[TRACING-3139]) +* Before this update, the `query-frontend` pod might get stopped when out-of-memory (OOM) as a result of searching a large trace. With this update, resource limits can be set to prevent this issue. (link:https://issues.redhat.com/browse/TRACING-4009[TRACING-4009]) + +[id="distributed-tracing-rn_3-2_tempo-release-notes_known-issues_{context}"] +==== Known issues + +There is currently a known issue: + +* Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) + +[id="distributed-tracing-rn_3-2_jaeger-release-notes_{context}"] +=== {JaegerName} + +The {JaegerName} is provided through the {JaegerOperator} Operator. + +[IMPORTANT] +==== +Jaeger does not use FIPS validated cryptographic modules. +==== + +[id="distributed-tracing-rn_3-2_jaeger-release-notes_support-for-elasticsearch-operator_{context}"] +==== Support for {es-op} + +{JaegerName} 3.2 is supported for use with the {es-op} 5.6, 5.7, and 5.8. + +[id="distributed-tracing-rn_3-2_jaeger-release-notes_deprecated-functionality_{context}"] +==== Deprecated functionality + +In the {DTProductName} 3.2, Jaeger and support for Elasticsearch remain deprecated, and both are planned to be removed in a future release. +Red Hat will provide support for these components and fixes for CVEs and bugs with critical and higher severity during the current release lifecycle, but these components will no longer receive feature enhancements. +The {TempoOperator} and the {OTELName} are the preferred Operators for distributed tracing collection and storage. +Users must adopt the OpenTelemetry and Tempo distributed tracing stack because it is the stack to be enhanced going forward. + +In the {DTProductName} 3.2, the Jaeger agent is deprecated and planned to be removed in the following release. +Red Hat will provide bug fixes and support for the Jaeger agent during the current release lifecycle, but the Jaeger agent will no longer receive enhancements and will be removed. +The OpenTelemetry Collector provided by the {OTELName} is the preferred Operator for injecting the trace collector agent. + +//// +[id="distributed-tracing-rn_3-2_jaeger-release-notes_removal-notice_{context}"] +==== Removal notice + +In {DTProductName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +[id="distributed-tracing-rn_3-2_jaeger-release-notes_new-features-and-enhancements_{context}"] +==== New features and enhancements + +This update introduces the following enhancements for the {JaegerShortName}: + +* {JaegerName} 3.2 is based on the open source link:https://www.jaegertracing.io/[Jaeger] release 1.57.0. + +[id="distributed-tracing-rn_3-2_jaeger-release-notes_known-issues_{context}"] +==== Known issues + +There is currently a known issue: + +* Currently, Apache Spark is not supported. + +ifndef::openshift-rosa[] + +* Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. +endif::openshift-rosa[] + +[id="distributed-tracing-rn-3-1-1_{context}"] == Release notes for {DTProductName} 3.1.1 This release of the {DTProductName} includes the {TempoName} and the deprecated {JaegerName}. -[id="distributed-tracing-rn_3-1-1_cves"] +[id="distributed-tracing-rn_3-1-1_cves_{context}"] === CVEs This release fixes link:https://access.redhat.com/security/cve/cve-2023-39326[CVE-2023-39326]. // Tempo section -[id="distributed-tracing-rn_3-1-1_tempo-release-notes"] +[id="distributed-tracing-rn_3-1-1_tempo-release-notes_{context}"] === {TempoName} The {TempoName} is provided through the {TempoOperator}. -[id="distributed-tracing-rn_3-1-1_tempo-release-notes_known-issues"] +[id="distributed-tracing-rn_3-1-1_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -36,7 +153,7 @@ There are currently known issues: * Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) // Jaeger section -[id="distributed-tracing-rn_3-1-1_jaeger-release-notes"] +[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_{context}"] === {JaegerName} The {JaegerName} is provided through the {JaegerOperator} Operator. @@ -46,19 +163,19 @@ The {JaegerName} is provided through the {JaegerOperator} Operator. Jaeger does not use FIPS validated cryptographic modules. ==== -[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_support-for-elasticsearch-operator"] +[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_support-for-elasticsearch-operator_{context}"] ==== Support for {es-op} {JaegerName} 3.1.1 is supported for use with the {es-op} 5.6, 5.7, and 5.8. -[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_deprecated-functionality"] +[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_deprecated-functionality_{context}"] ==== Deprecated functionality In the {DTProductName} 3.1.1, Jaeger and support for Elasticsearch remain deprecated, and both are planned to be removed in a future release. Red Hat will provide critical and above CVE bug fixes and support for these components during the current release lifecycle, but these components will no longer receive feature enhancements. In the {DTProductName} 3.1.1, Tempo provided by the {TempoOperator} and the OpenTelemetry Collector provided by the {OTELName} are the preferred Operators for distributed tracing collection and storage. The OpenTelemetry and Tempo distributed tracing stack is to be adopted by all users because this will be the stack that will be enhanced going forward. -[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_known-issues"] +[id="distributed-tracing-rn_3-1-1_jaeger-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -71,19 +188,19 @@ ifndef::openshift-rosa[] * Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -[id="distributed-tracing-rn-3-1"] +[id="distributed-tracing-rn-3-1_{context}"] == Release notes for {DTProductName} 3.1 This release of the {DTProductName} includes the {TempoName} and the deprecated {JaegerName}. // Tempo section -[id="distributed-tracing-rn_3-1_tempo-release-notes"] +[id="distributed-tracing-rn_3-1_tempo-release-notes_{context}"] === {TempoName} The {TempoName} is provided through the {TempoOperator}. //// -[id="technology-preview-features_jaeger-release-notes_distributed-tracing-rn-3-1"] +[id="technology-preview-features_jaeger-release-notes_distributed-tracing-rn-3-1_{context}"] ==== Technology Preview features This update introduces the following Technology Preview feature for the {TempoShortName}: @@ -94,7 +211,7 @@ This update introduces the following Technology Preview feature for the {TempoSh include::snippets/technology-preview.adoc[leveloffset=+1] //// -[id="distributed-tracing-rn_3-1_tempo-release-notes_new-features-and-enhancements"] +[id="distributed-tracing-rn_3-1_tempo-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements This update introduces the following enhancements for the {TempoShortName}: @@ -103,7 +220,7 @@ This update introduces the following enhancements for the {TempoShortName}: * Support for cluster-wide proxy environments. * Support for TraceQL to Gateway component. -[id="distributed-tracing-rn_3-1_tempo-release-notes_bug-fixes"] +[id="distributed-tracing-rn_3-1_tempo-release-notes_bug-fixes_{context}"] ==== Bug fixes This update introduces the following bug fixes for the {TempoShortName}: @@ -111,7 +228,7 @@ This update introduces the following bug fixes for the {TempoShortName}: * Before this update, when a TempoStack instance was created with the `monitorTab` enabled in {product-title} 4.15, the required `tempo-redmetrics-cluster-monitoring-view` ClusterRoleBinding was not created. This update resolves the issue by fixing the Operator RBAC for the monitor tab when the Operator is deployed in an arbitrary namespace. (link:https://issues.redhat.com/browse/TRACING-3786[TRACING-3786]) * Before this update, when a TempoStack instance was created on an {product-title} cluster with only an IPv6 networking stack, the compactor and ingestor pods ran in the `CrashLoopBackOff` state, resulting in multiple errors. This update provides support for IPv6 clusters.(link:https://issues.redhat.com/browse/TRACING-3226[TRACING-3226]) -[id="distributed-tracing-rn_3-1_tempo-release-notes_known-issues"] +[id="distributed-tracing-rn_3-1_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -121,7 +238,7 @@ There are currently known issues: * Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) // Jaeger section -[id="distributed-tracing-rn_3-1_jaeger-release-notes"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_{context}"] === {JaegerName} The {JaegerName} is provided through the {JaegerOperator} Operator. @@ -131,33 +248,33 @@ The {JaegerName} is provided through the {JaegerOperator} Operator. Jaeger does not use FIPS validated cryptographic modules. ==== -[id="distributed-tracing-rn_3-1_jaeger-release-notes_support-for-elasticsearch-operator"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_support-for-elasticsearch-operator_{context}"] ==== Support for {es-op} {JaegerName} 3.1 is supported for use with the {es-op} 5.6, 5.7, and 5.8. -[id="distributed-tracing-rn_3-1_jaeger-release-notes_deprecated-functionality"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_deprecated-functionality_{context}"] ==== Deprecated functionality In the {DTProductName} 3.1, Jaeger and support for Elasticsearch remain deprecated, and both are planned to be removed in a future release. Red Hat will provide critical and above CVE bug fixes and support for these components during the current release lifecycle, but these components will no longer receive feature enhancements. In the {DTProductName} 3.1, Tempo provided by the {TempoOperator} and the OpenTelemetry Collector provided by the {OTELName} are the preferred Operators for distributed tracing collection and storage. The OpenTelemetry and Tempo distributed tracing stack is to be adopted by all users because this will be the stack that will be enhanced going forward. -[id="distributed-tracing-rn_3-1_jaeger-release-notes_new-features-and-enhancements"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements This update introduces the following enhancements for the {JaegerShortName}: * {JaegerName} 3.1 is based on the open source link:https://www.jaegertracing.io/[Jaeger] release 1.53.0. -[id="distributed-tracing-rn_3-1_jaeger-release-notes_bug-fixes"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_bug-fixes_{context}"] ==== Bug fixes This update introduces the following bug fix for the {JaegerShortName}: * Before this update, the connection target URL for the `jaeger-agent` container in the `jager-query` pod was overwritten with another namespace URL in {product-title} 4.13. This was caused by a bug in the sidecar injection code in the `jaeger-operator`, causing nondeterministic `jaeger-agent` injection. With this update, the Operator prioritizes the Jaeger instance from the same namespace as the target deployment. (link:https://issues.redhat.com/browse/TRACING-3722[TRACING-3722]) -[id="distributed-tracing-rn_3-1_jaeger-release-notes_known-issues"] +[id="distributed-tracing-rn_3-1_jaeger-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -170,13 +287,13 @@ ifndef::openshift-rosa[] * Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -[id="distr-tracing-rn_3.0"] +[id="distr-tracing-rn_3.0_{context}"] == Release notes for {DTProductName} 3.0 -[id="distributed-tracing-rn_3-0_component-versions"] +[id="distributed-tracing-rn_3-0_component-versions_{context}"] === Component versions in the {DTProductName} 3.0 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -189,17 +306,17 @@ endif::openshift-rosa[] |=== // Jaeger section -[id="distributed-tracing-rn_3-0_jaeger-release-notes"] +[id="distributed-tracing-rn_3-0_jaeger-release-notes_{context}"] === {JaegerName} -[id="distributed-tracing-rn_3-0_jaeger-release-notes_deprecated-functionality"] +[id="distributed-tracing-rn_3-0_jaeger-release-notes_deprecated-functionality_{context}"] ==== Deprecated functionality In the {DTProductName} 3.0, Jaeger and support for Elasticsearch are deprecated, and both are planned to be removed in a future release. Red Hat will provide critical and above CVE bug fixes and support for these components during the current release lifecycle, but these components will no longer receive feature enhancements. In the {DTProductName} 3.0, Tempo provided by the {TempoOperator} and the OpenTelemetry Collector provided by the {OTELName} are the preferred Operators for distributed tracing collection and storage. The OpenTelemetry and Tempo distributed tracing stack is to be adopted by all users because this will be the stack that will be enhanced going forward. -[id="distributed-tracing-rn_3-0_jaeger-release-notes_new-features-and-enhancements"] +[id="distributed-tracing-rn_3-0_jaeger-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements This update introduces the following enhancements for the {JaegerShortName}: @@ -207,14 +324,14 @@ This update introduces the following enhancements for the {JaegerShortName}: * Support for the ARM architecture. * Support for cluster-wide proxy environments. -[id="distributed-tracing-rn_3-0_jaeger-release-notes_bug-fixes"] +[id="distributed-tracing-rn_3-0_jaeger-release-notes_bug-fixes_{context}"] ==== Bug fixes This update introduces the following bug fix for the {JaegerShortName}: * Before this update, the {JaegerName} Operator used other images than `relatedImages`. This caused the *ImagePullBackOff* error in disconnected network environments when launching the `jaeger` pod because the `oc adm catalog mirror` command mirrors images specified in `relatedImages`. This update provides support for disconnected environments when using the `oc adm catalog mirror` CLI command. (link:https://issues.redhat.com/browse/TRACING-3546[TRACING-3546]) -[id="distributed-tracing-rn_3-0_jaeger-release-notes_known-issues"] +[id="distributed-tracing-rn_3-0_jaeger-release-notes_known-issues_{context}"] ==== Known issues There is currently a known issue: @@ -228,10 +345,10 @@ ifndef::openshift-rosa[] endif::openshift-rosa[] // Tempo section -[id="distributed-tracing-rn_3-0_tempo-release-notes"] +[id="distributed-tracing-rn_3-0_tempo-release-notes_{context}"] === {TempoName} -[id="distributed-tracing-rn_3-0_tempo-release-notes_new-features-and-enhancements"] +[id="distributed-tracing-rn_3-0_tempo-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements This update introduces the following enhancements for the {TempoShortName}: @@ -239,7 +356,7 @@ This update introduces the following enhancements for the {TempoShortName}: * Support for the ARM architecture. * Support for span request count, duration, and error count (RED) metrics. The metrics can be visualized in the Jaeger console deployed as part of Tempo or in the web console in the *Observe* menu. -[id="distributed-tracing-rn_3-0_tempo-release-notes_bug-fixes"] +[id="distributed-tracing-rn_3-0_tempo-release-notes_bug-fixes_{context}"] ==== Bug fixes This update introduces the following bug fixes for the {TempoShortName}: @@ -248,7 +365,7 @@ This update introduces the following bug fixes for the {TempoShortName}: * Before this update, when mirroring the {DTProductName} Operator images to a mirror registry for use in a disconnected cluster, the related Operator images for `tempo`, `tempo-gateway`, `opa-openshift`, and `tempo-query` were not mirrored. This update fixes support for disconnected environments when using the `oc adm catalog mirror` CLI command. (link:https://issues.redhat.com/browse/TRACING-3523[TRACING-3523]) * Before this update, the query frontend service of the {DTProductName} was using internal mTLS when gateway was not deployed. This caused endpoint failure errors. This update fixes mTLS when Gateway is not deployed. (link:https://issues.redhat.com/browse/TRACING-3510[TRACING-3510]) -[id="distributed-tracing-rn_3-0_tempo-release-notes_known-issues"] +[id="distributed-tracing-rn_3-0_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -257,13 +374,13 @@ There are currently known issues: * Currently, when used with the {TempoOperator}, the Jaeger UI only displays services that have sent traces in the last 15 minutes. For services that did not send traces in the last 15 minutes, traces are still stored but not displayed in the Jaeger UI. (link:https://issues.redhat.com/browse/TRACING-3139[TRACING-3139]) * Currently, the {TempoShortName} fails on the {ibm-z-title} (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) -[id="distr-tracing-rn_2-9-2"] +[id="distr-tracing-rn_2-9-2_{context}"] == Release notes for {DTProductName} 2.9.2 -[id="distr-tracing-rn_2-9-2_component-versions"] +[id="distr-tracing-rn_2-9-2_component-versions_{context}"] === Component versions in the {DTProductName} 2.9.2 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -279,10 +396,10 @@ There are currently known issues: This release fixes link:https://bugzilla.redhat.com/show_bug.cgi?id=2246470[CVE-2023-46234]. -[id="distr-tracing-rn_2-9-2_jaeger-release-notes"] +[id="distr-tracing-rn_2-9-2_jaeger-release-notes_{context}"] === {JaegerName} -[id="distr-tracing-rn_2-9-2_jaeger-release-notes_known-issues"] +[id="distr-tracing-rn_2-9-2_jaeger-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -294,13 +411,13 @@ ifndef::openshift-rosa[] * The streaming deployment via AMQ/Kafka is unsupported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -[id="distr-tracing-rn_2-9-2_tempo-release-notes"] +[id="distr-tracing-rn_2-9-2_tempo-release-notes_{context}"] === {TempoName} :FeatureName: The {TempoName} include::snippets/technology-preview.adoc[leveloffset=+1] -[id="distr-tracing-rn_2-9-2_tempo-release-notes_known-issues"] +[id="distr-tracing-rn_2-9-2_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -375,13 +492,13 @@ mirror: - name: registry.redhat.io/rhosdt/tempo-query-rhel8@sha256:0da43034f440b8258a48a0697ba643b5643d48b615cdb882ac7f4f1f80aad08e ---- -[id="distr-tracing-rn_2-9-1"] +[id="distr-tracing-rn_2-9-1_{context}"] == Release notes for {DTProductName} 2.9.1 -[id="distr-tracing-rn_2-9-1_component-versions"] +[id="distr-tracing-rn_2-9-1_component-versions_{context}"] === Component versions in the {DTProductName} 2.9.1 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -397,10 +514,10 @@ mirror: This release fixes link:https://access.redhat.com/security/cve/cve-2023-44487[CVE-2023-44487]. -[id="distr-tracing-rn_2-9-1_jaeger-release-notes"] +[id="distr-tracing-rn_2-9-1_jaeger-release-notes_{context}"] === {JaegerName} -[id="distr-tracing-rn_2-9-1_jaeger-release-notes_known-issues"] +[id="distr-tracing-rn_2-9-1_jaeger-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -412,13 +529,13 @@ ifndef::openshift-rosa[] * The streaming deployment via AMQ/Kafka is unsupported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -[id="distr-tracing-rn_2-9-1_tempo-release-notes"] +[id="distr-tracing-rn_2-9-1_tempo-release-notes_{context}"] === {TempoName} :FeatureName: The {TempoName} include::snippets/technology-preview.adoc[leveloffset=+1] -[id="distr-tracing-rn_2-9-1_tempo-release-notes_known-issues"] +[id="distr-tracing-rn_2-9-1_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -492,13 +609,13 @@ mirror: - name: registry.redhat.io/rhosdt/tempo-query-rhel8@sha256:0da43034f440b8258a48a0697ba643b5643d48b615cdb882ac7f4f1f80aad08e ---- -[id="distr-tracing-rn_2-9"] +[id="distr-tracing-rn_2-9_{context}"] == Release notes for {DTProductName} 2.9 -[id="distr-tracing-rn_2-9_component-versions"] +[id="distr-tracing-rn_2-9_component-versions_{context}"] === Component versions in the {DTProductName} 2.9 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -510,22 +627,22 @@ mirror: |2.1.1 |=== -[id="distr-tracing-rn_2-9_jaeger-release-notes"] +[id="distr-tracing-rn_2-9_jaeger-release-notes_{context}"] === {JaegerName} //// -[id="distr-tracing-rn_2-9_jaeger-release-notes_new-features-and-enhancements"] +[id="distr-tracing-rn_2-9_jaeger-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements * None. //// //// -[id="technology-preview-features_jaeger-release-notes_distributed-tracing-rn-2-9"] +[id="technology-preview-features_jaeger-release-notes_distributed-tracing-rn-2-9_{context}"] ==== Technology Preview features None. //// -[id="distr-tracing-rn_2-9_jaeger-release-notes_bug-fixes"] +[id="distr-tracing-rn_2-9_jaeger-release-notes_bug-fixes_{context}"] ==== Bug fixes * Before this update, connection was refused due to a missing gRPC port on the `jaeger-query` deployment. This issue resulted in `transport: Error while dialing: dial tcp :16685: connect: connection refused` error message. With this update, the Jaeger Query gRPC port (16685) is successfully exposed on the Jaeger Query service. (link:https://issues.redhat.com/browse/TRACING-3322[TRACING-3322]) @@ -536,7 +653,7 @@ None. * Before this update, the Jaeger Operator pod restarted with the default memory value due to the `reason: OOMKilled` error message. With this update, this issue is fixed by removing the resource limits. (link:https://issues.redhat.com/browse/TRACING-3173[TRACING-3173]) -[id="distr-tracing-rn_2-9_jaeger-release-notes_known-issues"] +[id="distr-tracing-rn_2-9_jaeger-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -548,13 +665,13 @@ ifndef::openshift-rosa[] * The streaming deployment via AMQ/Kafka is unsupported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -[id="distr-tracing-rn_2-9_tempo-release-notes"] +[id="distr-tracing-rn_2-9_tempo-release-notes_{context}"] === {TempoName} :FeatureName: The {TempoName} include::snippets/technology-preview.adoc[leveloffset=+1] -[id="distr-tracing-rn_2-9_tempo-release-notes_new-features-and-enhancements"] +[id="distr-tracing-rn_2-9_tempo-release-notes_new-features-and-enhancements_{context}"] ==== New features and enhancements This release introduces the following enhancements for the {TempoShortName}: @@ -572,12 +689,12 @@ This release introduces the following enhancements for the {TempoShortName}: * Support multitenancy without Gateway authentication and authorization. //// -[id="distributed-tracing-rn_2-9_tempo-release-notes_technology-preview-features"] +[id="distributed-tracing-rn_2-9_tempo-release-notes_technology-preview-features_{context}"] === Technology Preview features None. //// -[id="distr-tracing-rn_2-9_tempo-release-notes_bug-fixes"] +[id="distr-tracing-rn_2-9_tempo-release-notes_bug-fixes_{context}"] ==== Bug fixes * Before this update, the {TempoOperator} was not compatible with disconnected environments. With this update, the {TempoOperator} supports disconnected environments. (link:https://issues.redhat.com/browse/TRACING-3145[TRACING-3145]) @@ -586,7 +703,7 @@ None. * Before this update, the resource limits from the {TempoOperator} caused error messages such as `reason: OOMKilled`. With this update, the resource limits for the {TempoOperator} are removed to avoid such errors. (link:https://issues.redhat.com/browse/TRACING-3204[TRACING-3204]) -[id="distr-tracing-rn_2-9_tempo-release-notes_known-issues"] +[id="distr-tracing-rn_2-9_tempo-release-notes_known-issues_{context}"] ==== Known issues //There is currently a known issue: @@ -661,13 +778,13 @@ mirror: - name: registry.redhat.io/rhosdt/tempo-query-rhel8@sha256:0da43034f440b8258a48a0697ba643b5643d48b615cdb882ac7f4f1f80aad08e ---- -[id="distr-tracing-rn_2-8"] +[id="distr-tracing-rn_2-8_{context}"] == Release notes for {DTProductName} 2.8 -[id="distr-tracing-rn_2-8_component-versions"] +[id="distr-tracing-rn_2-8_component-versions_{context}"] === Component versions in the {DTProductName} 2.8 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -679,7 +796,7 @@ mirror: |0.1.0 |=== -[id="distr-tracing-rn_2-8_technology-preview-features"] +[id="distr-tracing-rn_2-8_technology-preview-features_{context}"] === Technology Preview features This release introduces support for the {TempoName} as a link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview] feature for {DTProductName}. @@ -702,18 +819,18 @@ Expanded support for the {TempoOperator} is planned for future releases of the { Possible additional features might include support for TLS authentication, multitenancy, and multiple clusters. For more information about the {TempoOperator}, see the link:https://tempo-operator.netlify.app[Tempo community documentation]. -[id="distr-tracing-rn_2-8_bug-fixes"] +[id="distr-tracing-rn_2-8_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-7"] +[id="distr-tracing-rn_2-7_{context}"] == Release notes for {DTProductName} 2.7 -[id="distr-tracing-rn_2-7_component-versions"] +[id="distr-tracing-rn_2-7_component-versions_{context}"] === Component versions in the {DTProductName} 2.7 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -721,18 +838,18 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.39 |=== -[id="distr-tracing-rn_2-7_bug-fixes"] +[id="distr-tracing-rn_2-7_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-6"] +[id="distr-tracing-rn_2-6_{context}"] == Release notes for {DTProductName} 2.6 -[id="distr-tracing-rn_2-6_component-versions"] +[id="distr-tracing-rn_2-6_component-versions_{context}"] === Component versions in the {DTProductName} 2.6 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -740,18 +857,18 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.38 |=== -[id="distr-tracing-rn_2-6_bug-fixes"] +[id="distr-tracing-rn_2-6_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-5"] +[id="distr-tracing-rn_2-5_{context}"] == Release notes for {DTProductName} 2.5 -[id="distr-tracing-rn_2-5_component-versions"] +[id="distr-tracing-rn_2-5_component-versions_{context}"] === Component versions in the {DTProductName} 2.5 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -759,7 +876,7 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.36 |=== -[id="distr-tracing-rn_2-5_new-features-and-enhancements"] +[id="distr-tracing-rn_2-5_new-features-and-enhancements_{context}"] === New features and enhancements This release introduces support for ingesting OpenTelemetry protocol (OTLP) to the {JaegerName} Operator. @@ -770,18 +887,18 @@ The Operator now automatically enables the OTLP ports: This release also adds support for collecting Kubernetes resource attributes to the {OTELName} Operator. -[id="distr-tracing-rn_2-5_bug-fixes"] +[id="distr-tracing-rn_2-5_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-4"] +[id="distr-tracing-rn_2-4_{context}"] == Release notes for {DTProductName} 2.4 -[id="distr-tracing-rn_2-4_component-versions"] +[id="distr-tracing-rn_2-4_component-versions_{context}"] === Component versions in the {DTProductName} 2.4 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -789,7 +906,7 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.34.1 |=== -[id="distr-tracing-rn_2-4_new-features-and-enhancements"] +[id="distr-tracing-rn_2-4_new-features-and-enhancements_{context}"] === New features and enhancements This release adds support for auto-provisioning certificates using the {es-op}. @@ -801,23 +918,23 @@ Self-provisioning by using the {JaegerName} Operator to call the {es-op} during When upgrading to the {DTProductName} 2.4, the Operator recreates the Elasticsearch instance, which might take five to ten minutes. Distributed tracing will be down and unavailable for that period. ==== -[id="distr-tracing-rn_2-4_technology-preview-features"] +[id="distr-tracing-rn_2-4_technology-preview-features_{context}"] === Technology Preview features Creating the Elasticsearch instance and certificates first and then configuring the {JaegerShortName} to use the certificate is a link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview] for this release. -[id="distr-tracing-rn_2-4_bug-fixes"] +[id="distr-tracing-rn_2-4_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-3"] +[id="distr-tracing-rn_2-3_{context}"] == Release notes for {DTProductName} 2.3 -[id="distr-tracing-rn_2-3_component-versions_2-3-1"] +[id="distr-tracing-rn_2-3_component-versions_2-3-1_{context}"] === Component versions in the {DTProductName} 2.3.1 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -825,10 +942,10 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.30.2 |=== -[id="distr-tracing-rn_2-3_component-versions_2-3-0"] +[id="distr-tracing-rn_2-3_component-versions_2-3-0_{context}"] === Component versions in the {DTProductName} 2.3.0 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -836,36 +953,36 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.30.1 |=== -[id="distr-tracing-rn_2-3_new-features-and-enhancements"] +[id="distr-tracing-rn_2-3_new-features-and-enhancements_{context}"] === New features and enhancements With this release, the {JaegerName} Operator is now installed to the `openshift-distributed-tracing` namespace by default. Before this update, the default installation had been in the `openshift-operators` namespace. -[id="distr-tracing-rn_2-3_bug-fixes"] +[id="distr-tracing-rn_2-3_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-2"] +[id="distr-tracing-rn_2-2_{context}"] == Release notes for {DTProductName} 2.2 -[id="distr-tracing-rn_2-2_technology-preview-features"] +[id="distr-tracing-rn_2-2_technology-preview-features_{context}"] === Technology Preview features The unsupported OpenTelemetry Collector components included in the 2.1 release are removed. -[id="distr-tracing-rn_2-2_bug-fixes"] +[id="distr-tracing-rn_2-2_bug-fixes_{context}"] === Bug fixes This release of the {DTProductName} addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-1"] +[id="distr-tracing-rn_2-1_{context}"] == Release notes for {DTProductName} 2.1 -[id="distr-tracing-rn_2-1_component-versions"] +[id="distr-tracing-rn_2-1_component-versions_{context}"] === Component versions in the {DTProductName} 2.1 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -873,7 +990,7 @@ This release of the {DTProductName} addresses Common Vulnerabilities and Exposur |1.29.1 |=== -[id="distr-tracing-rn_2-1_technology-preview-features"] +[id="distr-tracing-rn_2-1_technology-preview-features_{context}"] === Technology Preview features * This release introduces a breaking change to how to configure certificates in the OpenTelemetry custom resource file. With this update, the `ca_file` moves under `tls` in the custom resource, as shown in the following examples. @@ -905,18 +1022,18 @@ spec: ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt" ---- -[id="distr-tracing-rn_2-1_bug-fixes"] +[id="distr-tracing-rn_2-1_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="distr-tracing-rn_2-0"] +[id="distr-tracing-rn_2-0_{context}"] == Release notes for {DTProductName} 2.0 -[id="distr-tracing-rn_2-0_component-versions"] +[id="distr-tracing-rn_2-0_component-versions_{context}"] === Component versions in the {DTProductName} 2.0 -[options="header"] +[options="header_{context}"] |=== |Operator |Component |Version |{JaegerName} @@ -924,7 +1041,7 @@ This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes |1.28.0 |=== -[id="distr-tracing-rn_2-0_new-features-and-enhancements"] +[id="distr-tracing-rn_2-0_new-features-and-enhancements_{context}"] === New features and enhancements This release introduces the following new features and enhancements: @@ -940,12 +1057,12 @@ Channels for individual releases are no longer supported. * Includes rolling updates to the documentation to support the name change and new features. -[id="distr-tracing-rn_2-0_technology-preview-features"] +[id="distr-tracing-rn_2-0_technology-preview-features_{context}"] === Technology Preview features This release adds the {OTELName} as a link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview], which you install using the {OTELName} Operator. {OTELName} is based on the link:https://opentelemetry.io/[OpenTelemetry] APIs and instrumentation. The {OTELName} includes the OpenTelemetry Operator and Collector. You can use the Collector to receive traces in the OpenTelemetry or Jaeger protocol and send the trace data to the {DTProductName}. Other capabilities of the Collector are not supported at this time. The OpenTelemetry Collector allows developers to instrument their code with vendor agnostic APIs, avoiding vendor lock-in and enabling a growing ecosystem of observability tooling. -[id="distr-tracing-rn_2-0_bug-fixes"] +[id="distr-tracing-rn_2-0_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. diff --git a/observability/otel/otel_rn/otel-rn-3-2-1.adoc b/observability/otel/otel_rn/otel-rn-3-2-1.adoc new file mode 100644 index 000000000000..b48d4ce6ef80 --- /dev/null +++ b/observability/otel/otel_rn/otel-rn-3-2-1.adoc @@ -0,0 +1,74 @@ +:_mod-docs-content-type: ASSEMBLY +include::_attributes/common-attributes.adoc[] +[id="otel-rn-3-2-1"] += Release notes for {OTELName} 3.2.1 +:context: otel-rn-3-2-1 + +toc::[] + +include::modules/otel-product-overview.adoc[leveloffset=+1] + +The {OTELName} is provided through the {OTELOperator}. + +[id="otel-rn_3-2-1_cves_{context}"] +== CVEs + +This release fixes the following CVEs: + +* link:https://access.redhat.com/security/cve/CVE-2024-25062/[CVE-2024-25062] +* link:https://opentelemetry.io/blog/2024/cve-2024-36129/[Upstream CVE-2024-36129] + +//// +[id="otel-rn_3-2-1_technology-preview-features_{context}"] +== Technology Preview features + +This update introduces the following Technology Preview features: + +* + +:FeatureName: Each of these features +include::snippets/technology-preview.adoc[leveloffset=+1] +//// + +[id="otel-rn_3-2-1_new-features-and-enhancements_{context}"] +== New features and enhancements + +This update introduces the following enhancement: + +* {OTELName} 3.2.1 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.102.1. + +//// +[id="otel-rn_3-2-1_jaeger-release-notes_deprecated-functionality_{context}"] +== Deprecated functionality + +In the {OTELName} 3.2.1, ... +//// + +//// +[id="otel-rn_3-2-1_removal-notice_{context}"] +== Removal notice + +In the {OTELName} 3.2.1, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +//// +[id="otel-rn_3-2-1_bug-fixes_{context}"] +== Bug fixes + +This update introduces the following bug fix: + +* Before this update, the checkbox to enable Operator monitoring was not available in the web console when installing the {OTELOperator}. As a result, a *ServiceMonitor* resource was not created in the `openshift-opentelemetry-operator` namespace. With this update, the checkbox appears for the {OTELOperator} in the web console so that Operator monitoring can be enabled during installation. (link:https://issues.redhat.com/browse/TRACING-3761[TRACING-3761]) +//// + +//// +[id="otel-rn_3-2-1_known-issues_{context}"] +== Known issues + +There are currently known issues: + +* ??? +//// + +include::modules/support.adoc[leveloffset=+1] + +include::modules/making-open-source-more-inclusive.adoc[leveloffset=+1] diff --git a/observability/otel/otel_rn/otel-rn-3-2.adoc b/observability/otel/otel_rn/otel-rn-3-2.adoc deleted file mode 100644 index b6ebaeee5bcf..000000000000 --- a/observability/otel/otel_rn/otel-rn-3-2.adoc +++ /dev/null @@ -1,78 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -include::_attributes/common-attributes.adoc[] -[id="otel-rn-3-2"] -= Release notes for {OTELName} 3.2 -:context: otel-rn-3-2 - -toc::[] - -include::modules/otel-product-overview.adoc[leveloffset=+1] - -The {OTELName} is provided through the {OTELOperator}. - -//// -[id="otel-rn_3-2_cves"] -== CVEs - -This release fixes link:https://access.redhat.com/security/cve/cve-202?-?????[CVE-202?-?????]. -//// - -[id="otel-rn_3-2_technology-preview-features"] -== Technology Preview features - -This update introduces the following Technology Preview features: - -* Host Metrics Receiver -* OIDC Auth Extension -* Kubernetes Cluster Receiver -* Kubernetes Events Receiver -* Kubernetes Objects Receiver -* Load-Balancing Exporter -* Kubelet Stats Receiver -* Cumulative to Delta Processor -* Forward Connector -* Journald Receiver -* Filelog Receiver -* File Storage Extension - -:FeatureName: Each of these features -include::snippets/technology-preview.adoc[leveloffset=+1] - -[id="otel-rn_3-2_new-features-and-enhancements"] -== New features and enhancements - -This update introduces the following enhancement: - -* {OTELName} 3.2 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.100.0. - -[id="otel-rn_3-2_jaeger-release-notes_deprecated-functionality"] -== Deprecated functionality - -In {OTELName} 3.2, use of empty values and `null` keywords in the OpenTelemetry Collector custom resource is deprecated and planned to be unsupported in a future release. Red Hat will provide bug fixes and support for this syntax during the current release lifecycle, but this syntax will become unsupported. As an alternative to empty values and `null` keywords, you can update the OpenTelemetry Collector custom resource to contain empty JSON objects as open-closed braces `{}` instead. - -//// -[id="otel-rn_3-2_removal-notice"] -== Removal notice - -In the {OTELName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. -//// - -[id="otel-rn_3-2_bug-fixes"] -== Bug fixes - -This update introduces the following bug fix: - -* Before this update, the checkbox to enable Operator monitoring was not available in the web console when installing the {OTELOperator}. As a result, a *ServiceMonitor* resource was not created in the `openshift-opentelemetry-operator` namespace. With this update, the checkbox appears for the {OTELOperator} in the web console so that Operator monitoring can be enabled during installation. (link:https://issues.redhat.com/browse/TRACING-3761[TRACING-3761]) - -//// -[id="otel-rn_3-2_known-issues"] -== Known issues - -There are currently known issues: - -* ??? -//// - -include::modules/support.adoc[leveloffset=+1] - -include::modules/making-open-source-more-inclusive.adoc[leveloffset=+1] diff --git a/observability/otel/otel_rn/otel-rn-past-releases.adoc b/observability/otel/otel_rn/otel-rn-past-releases.adoc index 08425b89791d..a357fd9d028c 100644 --- a/observability/otel/otel_rn/otel-rn-past-releases.adoc +++ b/observability/otel/otel_rn/otel-rn-past-releases.adoc @@ -8,22 +8,90 @@ toc::[] include::modules/otel-product-overview.adoc[leveloffset=+1] -[id="otel-rn-3-1-1"] +[id="otel-rn-3-2_{context}"] +== Release notes for {OTELName} 3.2 + +The {OTELName} is provided through the {OTELOperator}. + +//// +[id="otel-rn_3-2_cves_{context}"] +=== CVEs + +This release fixes link:https://access.redhat.com/security/cve/cve-202?-?????[CVE-202?-?????]. +//// + +[id="otel-rn_3-2_technology-preview-features_{context}"] +=== Technology Preview features + +This update introduces the following Technology Preview features: + +* Host Metrics Receiver +* OIDC Auth Extension +* Kubernetes Cluster Receiver +* Kubernetes Events Receiver +* Kubernetes Objects Receiver +* Load-Balancing Exporter +* Kubelet Stats Receiver +* Cumulative to Delta Processor +* Forward Connector +* Journald Receiver +* Filelog Receiver +* File Storage Extension + +:FeatureName: Each of these features +include::snippets/technology-preview.adoc[leveloffset=+1] + +[id="otel-rn_3-2_new-features-and-enhancements_{context}"] +=== New features and enhancements + +This update introduces the following enhancement: + +* {OTELName} 3.2 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.100.0. + +[id="otel-rn_3-2_jaeger-release-notes_deprecated-functionality_{context}"] +=== Deprecated functionality + +In {OTELName} 3.2, use of empty values and `null` keywords in the OpenTelemetry Collector custom resource is deprecated and planned to be unsupported in a future release. Red Hat will provide bug fixes and support for this syntax during the current release lifecycle, but this syntax will become unsupported. As an alternative to empty values and `null` keywords, you can update the OpenTelemetry Collector custom resource to contain empty JSON objects as open-closed braces `{}` instead. + +//// +[id="otel-rn_3-2_removal-notice_{context}"] +=== Removal notice + +In the {OTELName} 3.2, the FEATURE has been removed. Bug fixes and support are provided only through the end of the 3.? lifecycle. As an alternative to the FEATURE for USE CASE, you can use the ALTERNATIVE instead. +//// + +[id="otel-rn_3-2_bug-fixes_{context}"] +=== Bug fixes + +This update introduces the following bug fix: + +* Before this update, the checkbox to enable Operator monitoring was not available in the web console when installing the {OTELOperator}. As a result, a *ServiceMonitor* resource was not created in the `openshift-opentelemetry-operator` namespace. With this update, the checkbox appears for the {OTELOperator} in the web console so that Operator monitoring can be enabled during installation. (link:https://issues.redhat.com/browse/TRACING-3761[TRACING-3761]) + +//// +[id="otel-rn_3-2_known-issues_{context}"] +=== Known issues + +There are currently known issues: + +* ??? +//// + +[id="otel-rn-3-1-1_{context}"] == Release notes for {OTELName} 3.1.1 The {OTELName} is provided through the {OTELOperator}. -[id="otel-rn_3-1-1_cves"] +[id="otel-rn_3-1-1_cves_{context}"] === CVEs This release fixes link:https://access.redhat.com/security/cve/cve-2023-39326[CVE-2023-39326]. -[id="otel-rn-3-1"] +[id="otel-rn-3-1_{context}"] == Release notes for {OTELName} 3.1 The {OTELName} is provided through the {OTELOperator}. -[id="otel-rn_3-1_technology-preview-features"] +[id="otel-rn_3-1_technology-preview-features_{context}"] === Technology Preview features This update introduces the following Technology Preview feature: @@ -37,7 +105,7 @@ This update introduces the following Technology Preview feature: :FeatureName: The target allocator include::snippets/technology-preview.adoc[leveloffset=+1] -[id="otel-rn_3-1_new-features-and-enhancements"] +[id="otel-rn_3-1_new-features-and-enhancements_{context}"] === New features and enhancements //plural: `enhancements:` @@ -46,29 +114,29 @@ This update introduces the following enhancement: * {OTELName} 3.1 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.93.0. //// -[id="otel-rn_3-1_removal-notice"] +[id="otel-rn_3-1_removal-notice_{context}"] ==== Removal notice * //// //// -[id="otel-rn_3-1_bug-fixes"] +[id="otel-rn_3-1_bug-fixes_{context}"] ==== Bug fixes This update introduces the following bug fixes: * Fixed support for ... //// //// -[id="otel-rn_3-1_known-issues"] +[id="otel-rn_3-1_known-issues_{context}"] ==== Known issues //There is currently a known issue: //There are currently known issues: //// -[id="otel-rn_3-0"] +[id="otel-rn_3-0_{context}"] == Release notes for {OTELName} 3.0 -[id="otel-rn_3-0_new-features-and-enhancements"] +[id="otel-rn_3-0_new-features-and-enhancements_{context}"] === New features and enhancements This update introduces the following enhancements: @@ -82,19 +150,19 @@ This update introduces the following enhancements: * The {OTELOperator} creates the Prometheus `ServiceMonitor` custom resource if the Prometheus exporter is enabled. * The Operator enables the `Instrumentation` custom resource that allows injecting upstream OpenTelemetry auto-instrumentation libraries. -[id="otel-rn_3-0_removal-notice"] +[id="otel-rn_3-0_removal-notice_{context}"] === Removal notice In {OTELName} 3.0, the Jaeger exporter has been removed. Bug fixes and support are provided only through the end of the 2.9 lifecycle. As an alternative to the Jaeger exporter for sending data to the Jaeger collector, you can use the OTLP exporter instead. -[id="otel-rn_3-0_bug-fixes"] +[id="otel-rn_3-0_bug-fixes_{context}"] === Bug fixes This update introduces the following bug fixes: * Fixed support for disconnected environments when using the `oc adm catalog mirror` CLI command. -[id="otel-rn_3-0_known-issues"] +[id="otel-rn_3-0_known-issues_{context}"] === Known issues There is currently a known issue: @@ -168,7 +236,7 @@ subjects: namespace: openshift-monitoring ---- -[id="otel-rn_2-9-2"] +[id="otel-rn_2-9-2_{context}"] == Release notes for {OTELName} 2.9.2 :FeatureName: The {OTELName} @@ -176,12 +244,12 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.9.2 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.81.0. -[id="otel-rn_2-9-2_cves"] +[id="otel-rn_2-9-2_cves_{context}"] === CVEs * This release fixes link:https://bugzilla.redhat.com/show_bug.cgi?id=2246470[CVE-2023-46234]. -[id="otel-rn_2-9-2_known-issues"] +[id="otel-rn_2-9-2_known-issues_{context}"] === Known issues There is currently a known issue: @@ -189,7 +257,7 @@ There is currently a known issue: * Currently, you must manually set link:https://operatorframework.io/operator-capabilities/[Operator maturity] to Level IV, Deep Insights. (link:https://issues.redhat.com/browse/TRACING-3431[TRACING-3431]) -[id="otel-rn_2-9-1"] +[id="otel-rn_2-9-1_{context}"] == Release notes for {OTELName} 2.9.1 :FeatureName: The {OTELName} @@ -197,12 +265,12 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.9.1 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.81.0. -[id="otel-rn_2-9-1_cves"] +[id="otel-rn_2-9-1_cves_{context}"] === CVEs * This release fixes link:https://access.redhat.com/security/cve/cve-2023-44487[CVE-2023-44487]. -[id="otel-rn_2-9-1_known-issues"] +[id="otel-rn_2-9-1_known-issues_{context}"] === Known issues There is currently a known issue: @@ -210,7 +278,7 @@ There is currently a known issue: * Currently, you must manually set link:https://operatorframework.io/operator-capabilities/[Operator maturity] to Level IV, Deep Insights. (link:https://issues.redhat.com/browse/TRACING-3431[TRACING-3431]) -[id="otel-rn_2-9"] +[id="otel-rn_2-9_{context}"] == Release notes for {OTELName} 2.9 :FeatureName: The {OTELName} @@ -218,7 +286,7 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.9 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.81.0. -[id="otel-rn_2-9_new-features-and-enhancements"] +[id="otel-rn_2-9_new-features-and-enhancements_{context}"] === New features and enhancements This release introduces the following enhancements for the {OTELShortName}: @@ -234,18 +302,18 @@ This release introduces the following enhancements for the {OTELShortName}: * Support the `managed` and `unmanaged` states in the `OpenTelemetryCollector` custom resouce. //// -[id="otel-rn_2-9_technology-preview-features"] +[id="otel-rn_2-9_technology-preview-features_{context}"] ==== Technology Preview features None. //// //// -[id="otel-rn_2-9_bug-fixes"] +[id="otel-rn_2-9_bug-fixes_{context}"] ==== Bug fixes None. //// -[id="otel-rn_2-9_known-issues"] +[id="otel-rn_2-9_known-issues_{context}"] === Known issues There is currently a known issue: @@ -253,7 +321,7 @@ There is currently a known issue: * Currently, you must manually set link:https://operatorframework.io/operator-capabilities/[Operator maturity] to Level IV, Deep Insights. (link:https://issues.redhat.com/browse/TRACING-3431[TRACING-3431]) -[id="otel-rn_2-8"] +[id="otel-rn_2-8_{context}"] == Release notes for {OTELName} 2.8 :FeatureName: The {OTELName} @@ -261,18 +329,18 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.8 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.74.0. -[id="otel-rn_2-8_bug-fixes"] +[id="otel-rn_2-8_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. //// -[id="otel-rn_2-8_known-issues"] +[id="otel-rn_2-8_known-issues_{context}"] == Known issues None. //// -[id="otel-rn_2-7"] +[id="otel-rn_2-7_{context}"] == Release notes for {OTELName} 2.7 :FeatureName: The {OTELName} @@ -280,12 +348,12 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.7 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.63.1. -[id="otel-rn_2-7_bug-fixes"] +[id="otel-rn_2-7_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="otel-rn_2-6"] +[id="otel-rn_2-6_{context}"] == Release notes for {OTELName} 2.6 :FeatureName: The {OTELName} @@ -293,12 +361,12 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.6 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.60. -[id="otel-rn_2-6_bug-fixes"] +[id="otel-rn_2-6_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="otel-rn_2-5"] +[id="otel-rn_2-5_{context}"] == Release notes for {OTELName} 2.5 :FeatureName: The {OTELName} @@ -306,19 +374,19 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.5 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.56. -[id="otel-rn_2-5_new-features-and-enhancements"] +[id="otel-rn_2-5_new-features-and-enhancements_{context}"] === New features and enhancements This update introduces the following enhancement: * Support for collecting Kubernetes resource attributes to the {OTELName} Operator. -[id="otel-rn_2-5_bug-fixes"] +[id="otel-rn_2-5_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. -[id="otel-rn_2-4"] +[id="otel-rn_2-4_{context}"] == Release notes for {OTELName} 2.4 :FeatureName: The {OTELName} @@ -326,18 +394,18 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.4 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.49. -[id="otel-rn_2-4_bug-fixes"] +[id="otel-rn_2-4_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. //// -[id="otel-rn_2-4_known-issues"] +[id="otel-rn_2-4_known-issues_{context}"] === Known issues None. //// -[id="otel-rn_2-3"] +[id="otel-rn_2-3_{context}"] == Release notes for {OTELName} 2.3 :FeatureName: The {OTELName} @@ -347,18 +415,18 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.3.0 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.44.0. -[id="otel-rn_2-3_bug-fixes"] +[id="otel-rn_2-3_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. //// -[id="otel-rn_2-3_known-issues"] +[id="otel-rn_2-3_known-issues_{context}"] === Known issues None. //// -[id="otel-rn_2-2"] +[id="otel-rn_2-2_{context}"] == Release notes for {OTELName} 2.2 :FeatureName: The {OTELName} @@ -366,23 +434,23 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.2 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.42.0. -[id="otel-rn_2-2_technology-preview-features"] +[id="otel-rn_2-2_technology-preview-features_{context}"] === Technology Preview features The unsupported OpenTelemetry Collector components included in the 2.1 release are removed. -[id="otel-rn_2-2_bug-fixes"] +[id="otel-rn_2-2_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. //// -[id="otel-rn_2-2_known-issues"] +[id="otel-rn_2-2_known-issues_{context}"] === Known issues None. //// -[id="otel-rn_2-1"] +[id="otel-rn_2-1_{context}"] == Release notes for {OTELName} 2.1 :FeatureName: The {OTELName} @@ -390,7 +458,7 @@ include::snippets/technology-preview.adoc[leveloffset=+1] {OTELName} 2.1 is based on the open source link:https://opentelemetry.io/[OpenTelemetry] release 0.41.1. -[id="otel-rn_2-1_technology-preview-features"] +[id="otel-rn_2-1_technology-preview-features_{context}"] === Technology Preview features This release introduces a breaking change to how to configure certificates in the OpenTelemetry custom resource file. With this update, the `ca_file` moves under `tls` in the custom resource, as shown in the following examples. @@ -422,18 +490,18 @@ spec: ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt" ---- -[id="otel-rn_2-1_bug-fixes"] +[id="otel-rn_2-1_bug-fixes_{context}"] === Bug fixes This release addresses Common Vulnerabilities and Exposures (CVEs) and bug fixes. //// -[id="otel-rn_2-1_known-issues"] +[id="otel-rn_2-1_known-issues_{context}"] === Known issues None. //// -[id="otel-rn_2-0"] +[id="otel-rn_2-0_{context}"] == Release notes for {OTELName} 2.0 :FeatureName: The {OTELName} @@ -444,7 +512,7 @@ include::snippets/technology-preview.adoc[leveloffset=+1] This release adds the {OTELName} as a link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview], which you install using the {OTELName} Operator. {OTELName} is based on the link:https://opentelemetry.io/[OpenTelemetry] APIs and instrumentation. The {OTELName} includes the OpenTelemetry Operator and Collector. You can use the Collector to receive traces in the OpenTelemetry or Jaeger protocol and send the trace data to the {OTELName}. Other capabilities of the Collector are not supported at this time. The OpenTelemetry Collector allows developers to instrument their code with vendor agnostic APIs, avoiding vendor lock-in and enabling a growing ecosystem of observability tooling. //// -[id="otel-rn_2-0_known-issues"] +[id="otel-rn_2-0_known-issues_{context}"] === Known issues None. //// From cc8e8200112ca7fb69d6af73e0513c3c35647b85 Mon Sep 17 00:00:00 2001 From: Sara Thomas Date: Tue, 9 Apr 2024 16:46:57 -0400 Subject: [PATCH 188/339] OSDOCS-10171: Deduper merge mode Integrate NetObserv 1.6 feature branch with OCP docs main branch OSDOCS-10211: eBPF flow rule filtering OSDOCS-9959: NetObserv Health dashboard updates Fixes xref error Flow format reference regeneration Update DNS example to include sampling>1 note OSDOCS-9553: Netobserv Lokiless enhancements OSDOCS-10790: Update NetObserv Operator Install prereqs OSDOCS-10747: Adding FlowMetric API Reference Changing FlowMetrics to FlowMetric Netobserv API doc regeneration OSDOCS-9969: netobserv cli Network Observability 1.6 release notes --- _topic_maps/_topic_map.yml | 17 +- .../network-observability-RTT-overview.adoc | 16 +- modules/network-observability-RTT.adoc | 1 - ...ork-observability-cli-capturing-flows.adoc | 88 ++ ...k-observability-cli-capturing-packets.adoc | 29 + ...ervability-configuring-custom-metrics.adoc | 85 ++ .../network-observability-custom-metrics.adoc | 8 + .../network-observability-dns-tracking.adoc | 3 +- ...etwork-observability-ebpf-agent-alert.adoc | 38 + ...k-observability-ebpf-rule-flow-filter.adoc | 18 + ...ork-observability-filtering-ebpf-rule.adoc | 74 + ...-observability-flow-filter-parameters.adoc | 59 + ...lity-flowcollector-api-specifications.adoc | 1224 ++++++++++++++--- ...ability-flowmetric-api-specifications.adoc | 298 ++++ ...work-observability-flowmetrics-charts.adoc | 112 ++ .../network-observability-flows-format.adoc | 84 +- ...-observability-health-alerts-overview.adoc | 13 + ...servability-health-dashboard-overview.adoc | 19 + ... network-observability-metrics-names.adoc} | 12 +- ...ork-observability-netobserv-cli-about.adoc | 14 + ...-observability-netobserv-cli-cleaning.adoc | 19 + ...k-observability-netobserv-cli-install.adoc | 54 + ...observability-netobserv-cli-reference.adoc | 195 +++ ...bservability-nodes-taints-tolerations.adoc | 44 + ...etwork-observability-operator-install.adoc | 2 +- .../network-observability-packet-drops.adoc | 1 - ...work-observability-predefined-metrics.adoc | 9 + .../network-observability-quickfilter.adoc | 2 +- .../network-observability-viewing-alerts.adoc | 19 +- .../network-observability-without-loki.adoc | 23 +- ...work-observability-working-with-zones.adoc | 2 +- .../network_observability/flowmetric-api.adoc | 11 + .../metrics-alerts-dashboards.adoc | 14 +- .../netobserv_cli/_attributes | 1 + .../netobserv_cli/images | 1 + .../netobserv_cli/modules | 1 + .../netobserv_cli/netobserv-cli-install.adoc | 20 + .../netobserv-cli-reference.adoc | 11 + .../netobserv_cli/netobserv-cli-using.adoc | 17 + .../netobserv_cli/snippets | 1 + ...ork-observability-operator-monitoring.adoc | 4 +- ...-observability-operator-release-notes.adoc | 71 +- .../network-observability-overview.adoc | 17 +- ...rk-observability-scheduling-resources.adoc | 19 + .../observing-network-traffic.adoc | 10 + 45 files changed, 2505 insertions(+), 275 deletions(-) create mode 100644 modules/network-observability-cli-capturing-flows.adoc create mode 100644 modules/network-observability-cli-capturing-packets.adoc create mode 100644 modules/network-observability-configuring-custom-metrics.adoc create mode 100644 modules/network-observability-custom-metrics.adoc create mode 100644 modules/network-observability-ebpf-agent-alert.adoc create mode 100644 modules/network-observability-ebpf-rule-flow-filter.adoc create mode 100644 modules/network-observability-filtering-ebpf-rule.adoc create mode 100644 modules/network-observability-flow-filter-parameters.adoc create mode 100644 modules/network-observability-flowmetric-api-specifications.adoc create mode 100644 modules/network-observability-flowmetrics-charts.adoc create mode 100644 modules/network-observability-health-alerts-overview.adoc create mode 100644 modules/network-observability-health-dashboard-overview.adoc rename modules/{network-observability-metrics.adoc => network-observability-metrics-names.adoc} (77%) create mode 100644 modules/network-observability-netobserv-cli-about.adoc create mode 100644 modules/network-observability-netobserv-cli-cleaning.adoc create mode 100644 modules/network-observability-netobserv-cli-install.adoc create mode 100644 modules/network-observability-netobserv-cli-reference.adoc create mode 100644 modules/network-observability-nodes-taints-tolerations.adoc create mode 100644 modules/network-observability-predefined-metrics.adoc create mode 100644 observability/network_observability/flowmetric-api.adoc create mode 120000 observability/network_observability/netobserv_cli/_attributes create mode 120000 observability/network_observability/netobserv_cli/images create mode 120000 observability/network_observability/netobserv_cli/modules create mode 100644 observability/network_observability/netobserv_cli/netobserv-cli-install.adoc create mode 100644 observability/network_observability/netobserv_cli/netobserv-cli-reference.adoc create mode 100644 observability/network_observability/netobserv_cli/netobserv-cli-using.adoc create mode 120000 observability/network_observability/netobserv_cli/snippets create mode 100644 observability/network_observability/network-observability-scheduling-resources.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 430469dca6f1..6e2f3a619c86 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -2913,9 +2913,22 @@ Topics: File: metrics-alerts-dashboards - Name: Monitoring the Network Observability Operator File: network-observability-operator-monitoring - - Name: API reference + - Name: Scheduling resources + File: network-observability-scheduling-resources + - Name: Network Observability CLI + Dir: netobserv_cli + Topics: + - Name: Installing the Network Observability CLI + File: netobserv-cli-install + - Name: Using the Network Observability CLI + File: netobserv-cli-using + - Name: Network Observability CLI reference + File: netobserv-cli-reference + - Name: FlowCollector API reference File: flowcollector-api - - Name: JSON flows format reference + - Name: FlowMetric API reference + File: flowmetric-api + - Name: Flows format reference File: json-flows-format-reference - Name: Troubleshooting Network Observability File: troubleshooting-network-observability diff --git a/modules/network-observability-RTT-overview.adoc b/modules/network-observability-RTT-overview.adoc index 6c42599c3117..881084351716 100644 --- a/modules/network-observability-RTT-overview.adoc +++ b/modules/network-observability-RTT-overview.adoc @@ -5,24 +5,24 @@ :_mod-docs-content-type: CONCEPT [id="network-observability-RTT-overview_{context}"] = Round-Trip Time -You can use TCP handshake Round-Trip Time (RTT) to analyze network flows. You can use RTT captured from the `fentry/tcp_rcv_established` eBPF hookpoint to read SRTT from the TCP socket to help with the following: +You can use TCP smoothed Round-Trip Time (sRTT) to analyze network flow latencies. You can use RTT captured from the `fentry/tcp_rcv_established` eBPF hookpoint to read sRTT from the TCP socket to help with the following: -* Network Monitoring: Gain insights into TCP handshakes, helping +* Network Monitoring: Gain insights into TCP latencies, helping network administrators identify unusual patterns, potential bottlenecks, or performance issues. * Troubleshooting: Debug TCP-related issues by tracking latency and identifying misconfigurations. -By default, when RTT is enabled, you can see the following TCP handshake RTT metrics represented in the *Overview*: +By default, when RTT is enabled, you can see the following TCP RTT metrics represented in the *Overview*: -* Top X 90th percentile TCP handshake Round Trip Time with overall -* Top X average TCP handshake Round Trip Time with overall -* Bottom X minimum TCP handshake Round Trip Time with overall +* Top X 90th percentile TCP Round Trip Time with overall +* Top X average TCP Round Trip Time with overall +* Bottom X minimum TCP Round Trip Time with overall Other RTT panels can be added in *Manage panels*: -* Top X maximum TCP handshake Round Trip Time with overall -* Top X 99th percentile TCP handshake Round Trip Time with overall +* Top X maximum TCP Round Trip Time with overall +* Top X 99th percentile TCP Round Trip Time with overall See the _Additional Resources_ in this section for more information about enabling and working with this view. \ No newline at end of file diff --git a/modules/network-observability-RTT.adoc b/modules/network-observability-RTT.adoc index f56205ba0e7f..a7d1c98bdad8 100644 --- a/modules/network-observability-RTT.adoc +++ b/modules/network-observability-RTT.adoc @@ -23,7 +23,6 @@ metadata: name: cluster spec: namespace: netobserv - deploymentModel: Direct agent: type: eBPF ebpf: diff --git a/modules/network-observability-cli-capturing-flows.adoc b/modules/network-observability-cli-capturing-flows.adoc new file mode 100644 index 000000000000..6f101c610676 --- /dev/null +++ b/modules/network-observability-cli-capturing-flows.adoc @@ -0,0 +1,88 @@ +//Module included in the following assemblies: +// +// observability/network_observability/netobserv_cli/netobserv-cli-using.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-cli-capturing-flows_{context}"] += Capturing flows + +You can capture flows and filter on any resource or zone in the data to solve use cases, such as displaying Round-Trip Time (RTT) between two zones. Table visualization in the CLI provides viewing and flow search capabilities. + +.Prerequisites +* Install the {oc-first}. +* Install the Network Observability CLI (`oc netobserv`) plugin. + +.Procedure +. Capture flows with filters enabled by running the following command: ++ +[source,terminal] +---- +$ oc netobserv flows --enable_filter=true --action=Accept --cidr=0.0.0.0/0 --protocol=TCP --port=49051 +---- +. Add filters to the `live table filter` prompt in the terminal to further refine the incoming flows. For example: ++ +[source,terminal] +---- +live table filter: [SrcK8S_Zone:us-west-1b] press enter to match multiple regular expressions at once +---- +. To stop capturing, press kbd:[Ctrl+C]. The data that was captured is written to two separate files in an `./output` directory located in the same path used to install the CLI. +. View the captured data in the `./output/flow/.json` JSON file, which contains JSON arrays of the captured data. ++ +.Example JSON file +[source,json] +---- +{ + "AgentIP": "10.0.1.76", + "Bytes": 561, + "DnsErrno": 0, + "Dscp": 20, + "DstAddr": "f904:ece9:ba63:6ac7:8018:1e5:7130:0", + "DstMac": "0A:58:0A:80:00:37", + "DstPort": 9999, + "Duplicate": false, + "Etype": 2048, + "Flags": 16, + "FlowDirection": 0, + "IfDirection": 0, + "Interface": "ens5", + "K8S_FlowLayer": "infra", + "Packets": 1, + "Proto": 6, + "SrcAddr": "3e06:6c10:6440:2:a80:37:b756:270f", + "SrcMac": "0A:58:0A:80:00:01", + "SrcPort": 46934, + "TimeFlowEndMs": 1709741962111, + "TimeFlowRttNs": 121000, + "TimeFlowStartMs": 1709741962111, + "TimeReceived": 1709741964 +} +---- +. You can use SQLite to inspect the `./output/flow/.db` database file. For example: +.. Open the file by running the following command: ++ +[source,terminal] +---- +$ sqlite3 ./output/flow/.db +---- + +.. Query the data by running a SQLite `SELECT` statement, for example: ++ +[source,terminal] +---- +sqlite> SELECT DnsLatencyMs, DnsFlagsResponseCode, DnsId, DstAddr, DstPort, Interface, Proto, SrcAddr, SrcPort, Bytes, Packets FROM flow WHERE DnsLatencyMs >10 LIMIT 10; +---- ++ +.Example output +[source,terminal] +---- +12|NoError|58747|10.128.0.63|57856||17|172.30.0.10|53|284|1 +11|NoError|20486|10.128.0.52|56575||17|169.254.169.254|53|225|1 +11|NoError|59544|10.128.0.103|51089||17|172.30.0.10|53|307|1 +13|NoError|32519|10.128.0.52|55241||17|169.254.169.254|53|254|1 +12|NoError|32519|10.0.0.3|55241||17|169.254.169.254|53|254|1 +15|NoError|57673|10.128.0.19|59051||17|172.30.0.10|53|313|1 +13|NoError|35652|10.0.0.3|46532||17|169.254.169.254|53|183|1 +32|NoError|37326|10.0.0.3|52718||17|169.254.169.254|53|169|1 +14|NoError|14530|10.0.0.3|58203||17|169.254.169.254|53|246|1 +15|NoError|40548|10.0.0.3|45933||17|169.254.169.254|53|174|1 +---- diff --git a/modules/network-observability-cli-capturing-packets.adoc b/modules/network-observability-cli-capturing-packets.adoc new file mode 100644 index 000000000000..748c96417212 --- /dev/null +++ b/modules/network-observability-cli-capturing-packets.adoc @@ -0,0 +1,29 @@ +//Module included in the following assemblies: +// +// observability/network_observability/netobserv_cli/netobserv-cli-using.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-cli-capturing-packets_{context}"] += Capturing packets +You can capture packets using the Network Observability CLI. + +.Prerequisites +* Install the {oc-first}. +* Install the Network Observability CLI (`oc netobserv`) plugin. + +.Procedure +. Run the packet capture with filters enabled: ++ +[source,terminal] +---- +$ oc netobserv packets --filter=tcp,80 +---- +. Add filters to the `live table filter` prompt in the terminal to refine the incoming packets. An example filter is as follows: ++ +[source,terminal] +---- +live table filter: [SrcK8S_Zone:us-west-1b] press enter to match multiple regular expressions at once +---- +. To stop capturing, press kbd:[Ctrl+C]. +. View the captured data, which is written to a single file in an `./output/pcap` directory located in the same path that was used to install the CLI: +.. The `./output/pcap/.pcap` file can be opened with Wireshark. \ No newline at end of file diff --git a/modules/network-observability-configuring-custom-metrics.adoc b/modules/network-observability-configuring-custom-metrics.adoc new file mode 100644 index 000000000000..c73bb1054903 --- /dev/null +++ b/modules/network-observability-configuring-custom-metrics.adoc @@ -0,0 +1,85 @@ +// Module included in the following assemblies: +// +// network_observability/metrics-alerts-dashboards.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-configuring-custom-metrics_{context}"] += Configuring custom metrics by using FlowMetric API +You can configure the `FlowMetric` API to create custom metrics by using flowlogs data fields as Prometheus labels. You can add multiple `FlowMetric` resources to a project to see multiple dashboard views. + +.Procedure + +. In the web console, navigate to *Operators* -> *Installed Operators*. +. In the *Provided APIs* heading for the *NetObserv Operator*, select *FlowMetric*. +. In the *Project:* dropdown list, select the project of the Network Observability Operator instance. +. Click *Create FlowMetric*. +. Configure the `FlowMetric` resource, similar to the following sample configurations: ++ +.Generate a metric that tracks ingress bytes received from cluster external sources +[%collapsible] +==== +[source,yaml] +---- +apiVersion: flows.netobserv.io/v1alpha1 +kind: FlowMetric +metadata: + name: flowmetric-cluster-external-ingress-traffic + namespace: netobserv <1> +spec: + metricName: cluster_external_ingress_bytes_total <2> + type: Counter <3> + valueField: Bytes + direction: Ingress <4> + labels: [DstK8S_HostName,DstK8S_Namespace,DstK8S_OwnerName,DstK8S_OwnerType] <5> + filters: <6> + - field: SrcSubnetLabel + matchType: Absence +---- +<1> The `FlowMetric` resources need to be created in the namespace defined in the `FlowCollector` `spec.namespace`, which is `netobserv` by default. +<2> The name of the Prometheus metric, which in the web console appears with the prefix `netobserv-`. +<3> The `type` specifies the type of metric. The `Counter` `type` is useful for counting bytes or packets. +<4> The direction of traffic to capture. If not specified, both ingress and egress are captured, which can lead to duplicated counts. +<5> Labels define what the metrics look like and the relationship between the different entities and also define the metrics cardinality. For example, `SrcK8S_Name` is a high cardinality metric. +<6> Refines results based on the listed criteria. In this example, selecting only the cluster external traffic is done by matching only flows where `SrcSubnetLabel` is absent. This assumes the subnet labels feature is enabled (via `spec.processor.subnetLabels`), which is done by default. + +.Verification +. Once the pods refresh, navigate to *Observe* -> *Metrics*. +. In the *Expression* field, type the metric name to view the corresponding result. You can also enter an expression, such as `topk(5, sum(rate(netobserv_cluster_external_ingress_bytes_total{DstK8S_Namespace="my-namespace"}[2m])) by (DstK8S_HostName, DstK8S_OwnerName, DstK8S_OwnerType))` +==== ++ +.Show RTT latency for cluster external ingress traffic +[%collapsible] +==== +[source,yaml] +---- +apiVersion: flows.netobserv.io/v1alpha1 +kind: FlowMetric +metadata: + name: flowmetric-cluster-external-ingress-rtt + namespace: netobserv <1> +spec: + metricName: cluster_external_ingress_rtt_seconds + type: Histogram <2> + valueField: TimeFlowRttNs + direction: Ingress + labels: [DstK8S_HostName,DstK8S_Namespace,DstK8S_OwnerName,DstK8S_OwnerType] + filters: + - field: SrcSubnetLabel + matchType: Absence + - field: TimeFlowRttNs + matchType: Presence + divider: "1000000000" <3> + buckets: [".001", ".005", ".01", ".02", ".03", ".04", ".05", ".075", ".1", ".25", "1"] <4> +---- +<1> The `FlowMetric` resources need to be created in the namespace defined in the `FlowCollector` `spec.namespace`, which is `netobserv` by default. +<2> The `type` specifies the type of metric. The `Histogram` `type` is useful for a latency value (`TimeFlowRttNs`). +<3> Since the Round-trip time (RTT) is provided as nanos in flows, use a divider of 1 billion to convert into seconds, which is standard in Prometheus guidelines. +<4> The custom buckets specify precision on RTT, with optimal precision ranging between 5ms and 250ms. + +.Verification +. Once the pods refresh, navigate to *Observe* -> *Metrics*. +. In the *Expression* field, you can type the metric name to view the corresponding result. +==== + + + diff --git a/modules/network-observability-custom-metrics.adoc b/modules/network-observability-custom-metrics.adoc new file mode 100644 index 000000000000..eeb505747c12 --- /dev/null +++ b/modules/network-observability-custom-metrics.adoc @@ -0,0 +1,8 @@ +// Module included in the following assemblies: +// +// network_observability/metrics-alerts-dashboards.adoc + +:_mod-docs-content-type: CONCEPT +[id="network-observability-custom-metrics_{context}"] += Custom metrics +You can create custom metrics out of the flowlogs data using the `FlowMetric` API. In every flowlogs data that is collected, there are a number of fields labeled per log, such as source name and destination name. These fields can be leveraged as Prometheus labels to enable the customization of cluster information on your dashboard. \ No newline at end of file diff --git a/modules/network-observability-dns-tracking.adoc b/modules/network-observability-dns-tracking.adoc index 134cb6c09b31..1bebed820f97 100644 --- a/modules/network-observability-dns-tracking.adoc +++ b/modules/network-observability-dns-tracking.adoc @@ -27,7 +27,6 @@ metadata: name: cluster spec: namespace: netobserv - deploymentModel: Direct agent: type: eBPF ebpf: @@ -36,7 +35,7 @@ spec: sampling: 1 <2> ---- <1> You can set the `spec.agent.ebpf.features` parameter list to enable DNS tracking of each network flow in the web console. -<2> You can set `sampling` to a value of `1` for more accurate metrics. +<2> You can set `sampling` to a value of `1` for more accurate metrics and to capture *DNS latency*. For a `sampling` value greater than 1, you can observe flows with *DNS Response Code* and *DNS Id*, and it is unlikely that *DNS Latency* can be observed. . When you refresh the *Network Traffic* page, there are new DNS representations you can choose to view in the *Overview* and *Traffic Flow* views and new filters you can apply. .. Select new DNS choices in *Manage panels* to display graphical visualizations and DNS metrics in the *Overview*. diff --git a/modules/network-observability-ebpf-agent-alert.adoc b/modules/network-observability-ebpf-agent-alert.adoc new file mode 100644 index 000000000000..f9201d46aa88 --- /dev/null +++ b/modules/network-observability-ebpf-agent-alert.adoc @@ -0,0 +1,38 @@ +// Module included in the following assemblies: +// * network_observability/network-observability-operator-monitoring.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-netobserv-dashboard-ebpf-agent-alerts_{context}"] += Using the eBPF agent alert + +An alert, `NetObservAgentFlowsDropped`, is triggered when the Network Observability eBPF agent hashmap table is full or when the capacity limiter is triggered. If you see this alert, consider increasing the `cacheMaxFlows` in the `FlowCollector`, as shown in the following example. + +[NOTE] +==== +Increasing the `cacheMaxFlows` might increase the memory usage of the eBPF agent. +==== + +.Procedure + +. In the web console, navigate to *Operators* -> *Installed Operators*. + +. Under the *Provided APIs* heading for the *Network Observability Operator*, select *Flow Collector*. + +. Select *cluster*, and then select the *YAML* tab. + +. Increase the `spec.agent.ebpf.cacheMaxFlows` value, as shown in the following YAML sample: +[source,yaml] +---- +apiVersion: flows.netobserv.io/v1beta2 +kind: FlowCollector +metadata: + name: cluster +spec: + namespace: netobserv + deploymentModel: Direct + agent: + type: eBPF + ebpf: + cacheMaxFlows: 200000 <1> +---- +<1> Increase the `cacheMaxFlows` value from its value at the time of the `NetObservAgentFlowsDropped` alert. diff --git a/modules/network-observability-ebpf-rule-flow-filter.adoc b/modules/network-observability-ebpf-rule-flow-filter.adoc new file mode 100644 index 000000000000..b20c6a803514 --- /dev/null +++ b/modules/network-observability-ebpf-rule-flow-filter.adoc @@ -0,0 +1,18 @@ +// Module included in the following assemblies: +// +// network_observability/observing-network-traffic.adoc + +:_mod-docs-content-type: CONCEPT +[id="network-observability-ebpf-flow-rule-filter_{context}"] += eBPF flow rule filter +You can use rule-based filtering to control the volume of packets cached in the eBPF flow table. For example, a filter can specify that only packets coming from port 100 should be recorded. Then only the packets that match the filter are cached and the rest are not cached. + +[id="ingress-and-egress-traffic-filtering_{context}"] +== Ingress and egress traffic filtering +CIDR notation efficiently represents IP address ranges by combining the base IP address with a prefix length. For both ingress and egress traffic, the source IP address is first used to match filter rules configured with CIDR notation. If there is a match, then the filtering proceeds. If there is no match, then the destination IP is used to match filter rules configured with CIDR notation. + +After matching either the source IP or the destination IP CIDR, you can pinpoint specific endpoints using the `peerIP` to differentiate the destination IP address of the packet. Based on the provisioned action, the flow data is either cached in the eBPF flow table or not cached. + +[id="dashboard-and-metrics-integrations_{context}"] +== Dashboard and metrics integrations +When this option is enabled, the *Netobserv/Health* dashboard for *eBPF agent statistics* now has the *Filtered flows rate* view. Additionally, in *Observe* -> *Metrics* you can query `netobserv_agent_filtered_flows_total` to observe metrics with the reason in *FlowFilterAcceptCounter*, *FlowFilterNoMatchCounter* or *FlowFilterRecjectCounter*. \ No newline at end of file diff --git a/modules/network-observability-filtering-ebpf-rule.adoc b/modules/network-observability-filtering-ebpf-rule.adoc new file mode 100644 index 000000000000..85e41e34b28e --- /dev/null +++ b/modules/network-observability-filtering-ebpf-rule.adoc @@ -0,0 +1,74 @@ +// Module included in the following assemblies: +// +// network_observability/observing-network-traffic.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-filtering-ebpf-rule_{context}"] += Filtering eBPF flow data using a global rule +You can configure the `FlowCollector` to filter eBPF flows using a global rule to control the flow of packets cached in the eBPF flow table. + +.Procedure +. In the web console, navigate to *Operators* -> *Installed Operators*. +. Under the *Provided APIs* heading for *Network Observability*, select *Flow Collector*. +. Select *cluster*, then select the *YAML* tab. +. Configure the `FlowCollector` custom resource, similar to the following sample configurations: ++ + +[%collapsible] +.Filter Kubernetes service traffic to a specific Pod IP endpoint +==== +[source, yaml] +---- +apiVersion: flows.netobserv.io/v1beta2 +kind: FlowCollector +metadata: + name: cluster +spec: + namespace: netobserv + deploymentModel: Direct + agent: + type: eBPF + ebpf: + flowFilter: + action: Accept <1> + cidr: 172.210.150.1/24 <2> + protocol: SCTP + direction: Ingress + destPortRange: 80-100 + peerIP: 10.10.10.10 + enable: true <3> +---- +<1> The required `action` parameter describes the action that is taken for the flow filter rule. Possible values are `Accept` or `Reject`. +<2> The required `cidr` parameter provides the IP address and CIDR mask for the flow filter rule and supports IPv4 and IPv6 address formats. If you want to match against any IP address, you can use `0.0.0.0/0` for IPv4 or `::/0` for IPv6. +<3> You must set `spec.agent.ebpf.flowFilter.enable` to `true` to enable this feature. +==== ++ +[%collapsible] +.See flows to any addresses outside the cluster +==== +[source, yaml] +---- +apiVersion: flows.netobserv.io/v1beta2 +kind: FlowCollector +metadata: + name: cluster +spec: + namespace: netobserv + deploymentModel: Direct + agent: + type: eBPF + ebpf: + flowFilter: + action: Accept <1> + cidr: 0.0.0.0/0 <2> + protocol: TCP + direction: Egress + sourcePort: 100 + peerIP: 192.168.127.12 <3> + enable: true <4> +---- +<1> You can `Accept` flows based on the criteria in the `flowFilter` specification. +<2> The `cidr` value of `0.0.0.0/0` matches against any IP address. +<3> See flows after `peerIP` is configured with `192.168.127.12`. +<4> You must set `spec.agent.ebpf.flowFilter.enable` to `true` to enable the feature. +==== \ No newline at end of file diff --git a/modules/network-observability-flow-filter-parameters.adoc b/modules/network-observability-flow-filter-parameters.adoc new file mode 100644 index 000000000000..51e10d254cff --- /dev/null +++ b/modules/network-observability-flow-filter-parameters.adoc @@ -0,0 +1,59 @@ +:_mod-docs-content-type: REFERENCE +// Module included in the following assemblies: +// +// network_observability/observing-network-traffic.adoc + +[id="network-observability-flowcollector-flowfilter-parameters_{context}"] += Flow filter configuration parameters +The flow filter rules consist of required and optional parameters. + +.Required configuration parameters +[cols="3a,8a",options="header"] +|=== +|Parameter |Description + +|`enable` +| Set `enable` to `true` to enable the eBPF flow filtering feature. + +|`cidr` +| Provides the IP address and CIDR mask for the flow filter rule. Supports both IPv4 and IPv6 address format. If you want to match against any IP, you can use `0.0.0.0/0` for IPv4 or `::/0` for IPv6. + +|`action` +| Describes the action that is taken for the flow filter rule. The possible values are `Accept` or `Reject`. + +* For the `Accept` action matching rule, the flow data is cached in the eBPF table and updated with the global metric, `FlowFilterAcceptCounter`. +* For the `Reject` action matching rule, the flow data is dropped and not cached in the eBPF table. The flow data is updated with the global metric, `FlowFilterRejectCounter`. +* If the rule is not matched, the flow is cached in the eBPF table and updated with the global metric, `FlowFilterNoMatchCounter`. +|=== + + +.Optional configuration parameters +[cols="3a,8a",options="header"] +|=== +|Parameter |Description + +|`direction` +| Defines the direction of the flow filter rule. Possible values are `Ingress` or `Egress`. + +|`protocol` +| Defines the protocol of the flow filter rule. Possible values are `TCP`, `UDP`, `SCTP`, `ICMP`, and `ICMPv6`. + +| `ports` +| Defines the ports to use for filtering flows. It can be used for either source or destination ports. To filter a single port, set a single port as an integer value. For example `ports: 80`. To filter a range of ports, use a "start-end" range in string format. For example `ports: "80-100"` + +|`sourcePorts` +| Defines the source port to use for filtering flows. To filter a single port, set a single port as an integer value, for example `sourcePorts: 80`. To filter a range of ports, use a "start-end" range, string format, for example `sourcePorts: "80-100"`. + + +| `destPorts` +| DestPorts defines the destination ports to use for filtering flows. To filter a single port, set a single port as an integer value, for example `destPorts: 80`. To filter a range of ports, use a "start-end" range in string format, for example `destPorts: "80-100"`. + +| `icmpType` +| Defines the ICMP type to use for filtering flows. + +| `icmpCode` +| Defines the ICMP code to use for filtering flows. + +| `peerIP` +| Defines the IP address to use for filtering flows, for example: `10.10.10.10`. +|=== \ No newline at end of file diff --git a/modules/network-observability-flowcollector-api-specifications.adoc b/modules/network-observability-flowcollector-api-specifications.adoc index 3f60dc67b5de..b1f5bde9a9b4 100644 --- a/modules/network-observability-flowcollector-api-specifications.adoc +++ b/modules/network-observability-flowcollector-api-specifications.adoc @@ -35,9 +35,14 @@ Type:: | `spec` | `object` -| Defines the desired state of the FlowCollector resource. + +| Defines the desired state of the FlowCollector resource. + - *: the mention of "unsupported", or "deprecated" for a feature throughout this document means that this feature is not officially supported by Red Hat. It might have been, for example, contributed by the community and accepted without a formal agreement for maintenance. The product maintainers might provide some support for these features as a best effort only. + + + +*: the mention of "unsupported" or "deprecated" for a feature throughout this document means that this feature +is not officially supported by Red Hat. It might have been, for example, contributed by the community +and accepted without a formal agreement for maintenance. The product maintainers might provide some support +for these features as a best effort only. |=== == .metadata @@ -57,9 +62,14 @@ Type:: Description:: + -- -Defines the desired state of the FlowCollector resource. + +Defines the desired state of the FlowCollector resource. + - *: the mention of "unsupported", or "deprecated" for a feature throughout this document means that this feature is not officially supported by Red Hat. It might have been, for example, contributed by the community and accepted without a formal agreement for maintenance. The product maintainers might provide some support for these features as a best effort only. + + + +*: the mention of "unsupported" or "deprecated" for a feature throughout this document means that this feature +is not officially supported by Red Hat. It might have been, for example, contributed by the community +and accepted without a formal agreement for maintenance. The product maintainers might provide some support +for these features as a best effort only. -- Type:: @@ -83,9 +93,12 @@ Type:: | `deploymentModel` | `string` | `deploymentModel` defines the desired type of deployment for flow processing. Possible values are: + - - `Direct` (default) to make the flow processor listening directly from the agents. + - - `Kafka` to make flows sent to a Kafka pipeline before consumption by the processor. + - Kafka can provide better scalability, resiliency, and high availability (for more details, see https://www.redhat.com/en/topics/integration/what-is-apache-kafka). + +- `Direct` (default) to make the flow processor listen directly from the agents. + + +- `Kafka` to make flows sent to a Kafka pipeline before consumption by the processor. + + +Kafka can provide better scalability, resiliency, and high availability (for more details, see https://www.redhat.com/en/topics/integration/what-is-apache-kafka). | `exporters` | `array` @@ -105,7 +118,12 @@ Type:: | `processor` | `object` -| `processor` defines the settings of the component that receives the flows from the agent, enriches them, generates metrics, and forwards them to the Loki persistence layer and/or any available exporter. +| `processor` defines the settings of the component that receives the flows from the agent, +enriches them, generates metrics, and forwards them to the Loki persistence layer and/or any available exporter. + +| `prometheus` +| `object` +| `prometheus` defines Prometheus settings, such as querier configuration used to fetch metrics from the Console plugin. |=== == .spec.agent @@ -127,25 +145,21 @@ Type:: | `ebpf` | `object` -| `ebpf` describes the settings related to the eBPF-based flow reporter when `spec.agent.type` is set to `eBPF`. - -| `ipfix` -| `object` -| `ipfix` [deprecated (*)] - describes the settings related to the IPFIX-based flow reporter when `spec.agent.type` is set to `IPFIX`. +| `ebpf` describes the settings related to the eBPF-based flow reporter when `spec.agent.type` +is set to `eBPF`. | `type` | `string` -| `type` selects the flows tracing agent. Possible values are: + - - `eBPF` (default) to use Network Observability eBPF agent. + - - `IPFIX` [deprecated (*)] - to use the legacy IPFIX collector. + - `eBPF` is recommended as it offers better performances and should work regardless of the CNI installed on the cluster. `IPFIX` works with OVN-Kubernetes CNI (other CNIs could work if they support exporting IPFIX, but they would require manual configuration). +| `type` [deprecated (*)] selects the flows tracing agent. Previously, this field allowed to select between `eBPF` or `IPFIX`. +Only `eBPF` is allowed now, so this field is deprecated and is planned for removal in a future version of the API. |=== == .spec.agent.ebpf Description:: + -- -`ebpf` describes the settings related to the eBPF-based flow reporter when `spec.agent.type` is set to `eBPF`. +`ebpf` describes the settings related to the eBPF-based flow reporter when `spec.agent.type` +is set to `eBPF`. -- Type:: @@ -160,27 +174,44 @@ Type:: | `advanced` | `object` -| `advanced` allows setting some aspects of the internal configuration of the eBPF agent. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +| `advanced` allows setting some aspects of the internal configuration of the eBPF agent. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. | `cacheActiveTimeout` | `string` -| `cacheActiveTimeout` is the max period during which the reporter aggregates flows before sending. Increasing `cacheMaxFlows` and `cacheActiveTimeout` can decrease the network traffic overhead and the CPU load, however you can expect higher memory consumption and an increased latency in the flow collection. +| `cacheActiveTimeout` is the max period during which the reporter aggregates flows before sending. +Increasing `cacheMaxFlows` and `cacheActiveTimeout` can decrease the network traffic overhead and the CPU load, +however you can expect higher memory consumption and an increased latency in the flow collection. | `cacheMaxFlows` | `integer` -| `cacheMaxFlows` is the max number of flows in an aggregate; when reached, the reporter sends the flows. Increasing `cacheMaxFlows` and `cacheActiveTimeout` can decrease the network traffic overhead and the CPU load, however you can expect higher memory consumption and an increased latency in the flow collection. +| `cacheMaxFlows` is the max number of flows in an aggregate; when reached, the reporter sends the flows. +Increasing `cacheMaxFlows` and `cacheActiveTimeout` can decrease the network traffic overhead and the CPU load, +however you can expect higher memory consumption and an increased latency in the flow collection. | `excludeInterfaces` | `array (string)` -| `excludeInterfaces` contains the interface names that are excluded from flow tracing. An entry enclosed by slashes, such as `/br-/`, is matched as a regular expression. Otherwise it is matched as a case-sensitive string. +| `excludeInterfaces` contains the interface names that are excluded from flow tracing. +An entry enclosed by slashes, such as `/br-/`, is matched as a regular expression. +Otherwise it is matched as a case-sensitive string. | `features` | `array (string)` | List of additional features to enable. They are all disabled by default. Enabling additional features might have performance impacts. Possible values are: + - - `PacketDrop`: enable the packets drop flows logging feature. This feature requires mounting the kernel debug filesystem, so the eBPF pod has to run as privileged. If the `spec.agent.ebpf.privileged` parameter is not set, an error is reported. + - - `DNSTracking`: enable the DNS tracking feature. + - - `FlowRTT`: enable flow latency (RTT) calculations in the eBPF agent during TCP handshakes. This feature better works with `sampling` set to 1. + +- `PacketDrop`: enable the packets drop flows logging feature. This feature requires mounting +the kernel debug filesystem, so the eBPF pod has to run as privileged. +If the `spec.agent.ebpf.privileged` parameter is not set, an error is reported. + + +- `DNSTracking`: enable the DNS tracking feature. + + +- `FlowRTT`: enable flow latency (sRTT) extraction in the eBPF agent from TCP traffic. + + + +| `flowFilter` +| `object` +| `flowFilter` defines the eBPF agent configuration regarding flow filtering. | `imagePullPolicy` | `string` @@ -188,23 +219,35 @@ Type:: | `interfaces` | `array (string)` -| `interfaces` contains the interface names from where flows are collected. If empty, the agent fetches all the interfaces in the system, excepting the ones listed in ExcludeInterfaces. An entry enclosed by slashes, such as `/br-/`, is matched as a regular expression. Otherwise it is matched as a case-sensitive string. +| `interfaces` contains the interface names from where flows are collected. If empty, the agent +fetches all the interfaces in the system, excepting the ones listed in `excludeInterfaces`. +An entry enclosed by slashes, such as `/br-/`, is matched as a regular expression. +Otherwise it is matched as a case-sensitive string. | `kafkaBatchSize` | `integer` -| `kafkaBatchSize` limits the maximum size of a request in bytes before being sent to a partition. Ignored when not using Kafka. Default: 10MB. +| `kafkaBatchSize` limits the maximum size of a request in bytes before being sent to a partition. Ignored when not using Kafka. Default: 1MB. | `logLevel` | `string` | `logLevel` defines the log level for the Network Observability eBPF Agent +| `metrics` +| `object` +| `metrics` defines the eBPF agent configuration regarding metrics. + | `privileged` | `boolean` -| Privileged mode for the eBPF Agent container. When ignored or set to `false`, the operator sets granular capabilities (BPF, PERFMON, NET_ADMIN, SYS_RESOURCE) to the container. If for some reason these capabilities cannot be set, such as if an old kernel version not knowing CAP_BPF is in use, then you can turn on this mode for more global privileges. Some agent features require the privileged mode, such as packet drops tracking (see `features`) and SR-IOV support. +| Privileged mode for the eBPF Agent container. When ignored or set to `false`, the operator sets +granular capabilities (BPF, PERFMON, NET_ADMIN, SYS_RESOURCE) to the container. +If for some reason these capabilities cannot be set, such as if an old kernel version not knowing CAP_BPF +is in use, then you can turn on this mode for more global privileges. +Some agent features require the privileged mode, such as packet drops tracking (see `features`) and SR-IOV support. | `resources` | `object` -| `resources` are the compute resources required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| `resources` are the compute resources required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `sampling` | `integer` @@ -215,7 +258,9 @@ Type:: Description:: + -- -`advanced` allows setting some aspects of the internal configuration of the eBPF agent. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +`advanced` allows setting some aspects of the internal configuration of the eBPF agent. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. -- Type:: @@ -230,14 +275,21 @@ Type:: | `env` | `object (string)` -| `env` allows passing custom environment variables to underlying components. Useful for passing some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be publicly exposed as part of the FlowCollector descriptor, as they are only useful in edge debug or support scenarios. +| `env` allows passing custom environment variables to underlying components. Useful for passing +some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be +publicly exposed as part of the FlowCollector descriptor, as they are only useful +in edge debug or support scenarios. + +| `scheduling` +| `object` +| scheduling controls how the pods are scheduled on nodes. |=== -== .spec.agent.ebpf.resources +== .spec.agent.ebpf.advanced.scheduling Description:: + -- -`resources` are the compute resources required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +scheduling controls how the pods are scheduled on nodes. -- Type:: @@ -250,20 +302,128 @@ Type:: |=== | Property | Type | Description -| `limits` +| `affinity` +| `object` +| If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. + +| `nodeSelector` +| `object (string)` +| `nodeSelector` allows scheduling of pods only onto nodes that have each of the specified labels. +For documentation, refer to https://kubernetes.io/docs/concepts/configuration/assign-pod-node/. + +| `priorityClassName` +| `string` +| If specified, indicates the pod's priority. For documentation, refer to https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#how-to-use-priority-and-preemption. +If not specified, default priority is used, or zero if there is no default. + +| `tolerations` +| `array` +| `tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. + +|=== +== .spec.agent.ebpf.advanced.scheduling.affinity +Description:: ++ +-- +If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `object` + + + + +== .spec.agent.ebpf.advanced.scheduling.tolerations +Description:: ++ +-- +`tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `array` + + + + +== .spec.agent.ebpf.flowFilter +Description:: ++ +-- +`flowFilter` defines the eBPF agent configuration regarding flow filtering. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `action` +| `string` +| `action` defines the action to perform on the flows that match the filter. + +| `cidr` +| `string` +| `cidr` defines the IP CIDR to filter flows by. +Examples: `10.10.10.0/24` or `100:100:100:100::/64` + +| `destPorts` | `integer-or-string` -| Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| `destPorts` defines the destination ports to filter flows by. +To filter a single port, set a single port as an integer value. For example: `destPorts: 80`. +To filter a range of ports, use a "start-end" range in string format. For example: `destPorts: "80-100"`. -| `requests` +| `direction` +| `string` +| `direction` defines the direction to filter flows by. + +| `enable` +| `boolean` +| Set `enable` to `true` to enable the eBPF flow filtering feature. + +| `icmpCode` +| `integer` +| `icmpCode`, for Internet Control Message Protocol (ICMP) traffic, defines the ICMP code to filter flows by. + +| `icmpType` +| `integer` +| `icmpType`, for ICMP traffic, defines the ICMP type to filter flows by. + +| `peerIP` +| `string` +| `peerIP` defines the IP address to filter flows by. +Example: `10.10.10.10`. + +| `ports` | `integer-or-string` -| Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| `ports` defines the ports to filter flows by. It is used both for source and destination ports. +To filter a single port, set a single port as an integer value. For example: `ports: 80`. +To filter a range of ports, use a "start-end" range in string format. For example: `ports: "80-100"`. + +| `protocol` +| `string` +| `protocol` defines the protocol to filter flows by. + +| `sourcePorts` +| `integer-or-string` +| `sourcePorts` defines the source ports to filter flows by. +To filter a single port, set a single port as an integer value. For example: `sourcePorts: 80`. +To filter a range of ports, use a "start-end" range in string format. For example: `sourcePorts: "80-100"`. |=== -== .spec.agent.ipfix +== .spec.agent.ebpf.metrics Description:: + -- -`ipfix` [deprecated (*)] - describes the settings related to the IPFIX-based flow reporter when `spec.agent.type` is set to `IPFIX`. +`metrics` defines the eBPF agent configuration regarding metrics. -- Type:: @@ -276,36 +436,93 @@ Type:: |=== | Property | Type | Description -| `cacheActiveTimeout` -| `string` -| `cacheActiveTimeout` is the max period during which the reporter aggregates flows before sending. +| `disableAlerts` +| `array (string)` +| `disableAlerts` is a list of alerts that should be disabled. +Possible values are: + -| `cacheMaxFlows` +`NetObservDroppedFlows`, which is triggered when the eBPF agent is dropping flows, such as when the BPF hashmap is full or the capacity limiter is being triggered. + + + +| `enable` +| `boolean` +| Set `enable` to `false` to disable eBPF agent metrics collection. It is enabled by default. + +| `server` +| `object` +| Metrics server endpoint configuration for the Prometheus scraper. + +|=== +== .spec.agent.ebpf.metrics.server +Description:: ++ +-- +Metrics server endpoint configuration for the Prometheus scraper. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `port` | `integer` -| `cacheMaxFlows` is the max number of flows in an aggregate; when reached, the reporter sends the flows. +| The metrics server HTTP port. -| `clusterNetworkOperator` +| `tls` | `object` -| `clusterNetworkOperator` defines the settings related to the {product-title} Cluster Network Operator, when available. +| TLS configuration. + +|=== +== .spec.agent.ebpf.metrics.server.tls +Description:: ++ +-- +TLS configuration. +-- + +Type:: + `object` -| `forceSampleAll` + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `insecureSkipVerify` | `boolean` -| `forceSampleAll` allows disabling sampling in the IPFIX-based flow reporter. It is not recommended to sample all the traffic with IPFIX, as it might generate cluster instability. If you REALLY want to do that, set this flag to `true`. Use at your own risk. When it is set to `true`, the value of `sampling` is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the provided certificate. +If set to `true`, the `providedCaFile` field is ignored. -| `ovnKubernetes` +| `provided` | `object` -| `ovnKubernetes` defines the settings of the OVN-Kubernetes CNI, when available. This configuration is used when using OVN's IPFIX exports, without {product-title}. When using {product-title}, refer to the `clusterNetworkOperator` property instead. +| TLS configuration when `type` is set to `Provided`. -| `sampling` -| `integer` -| `sampling` is the sampling rate on the reporter. 100 means one flow on 100 is sent. To ensure cluster stability, it is not possible to set a value below 2. If you really want to sample every packet, which might impact the cluster stability, refer to `forceSampleAll`. Alternatively, you can use the eBPF Agent instead of IPFIX. +| `providedCaFile` +| `object` +| Reference to the CA file when `type` is set to `Provided`. + +| `type` +| `string` +| Select the type of TLS configuration: + + +- `Disabled` (default) to not configure TLS for the endpoint. +- `Provided` to manually provide cert file and a key file. [Unsupported (*)]. +- `Auto` to use {product-title} auto generated certificate using annotations. |=== -== .spec.agent.ipfix.clusterNetworkOperator +== .spec.agent.ebpf.metrics.server.tls.provided Description:: + -- -`clusterNetworkOperator` defines the settings related to the {product-title} Cluster Network Operator, when available. +TLS configuration when `type` is set to `Provided`. -- Type:: @@ -318,16 +535,33 @@ Type:: |=== | Property | Type | Description +| `certFile` +| `string` +| `certFile` defines the path to the certificate file name within the config map or secret. + +| `certKey` +| `string` +| `certKey` defines the path to the certificate private key file name within the config map or secret. Omit when the key is not necessary. + +| `name` +| `string` +| Name of the config map or secret containing certificates. + | `namespace` | `string` -| Namespace where the config map is going to be deployed. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. + +| `type` +| `string` +| Type for the certificate reference: `configmap` or `secret`. |=== -== .spec.agent.ipfix.ovnKubernetes +== .spec.agent.ebpf.metrics.server.tls.providedCaFile Description:: + -- -`ovnKubernetes` defines the settings of the OVN-Kubernetes CNI, when available. This configuration is used when using OVN's IPFIX exports, without {product-title}. When using {product-title}, refer to the `clusterNetworkOperator` property instead. +Reference to the CA file when `type` is set to `Provided`. -- Type:: @@ -340,17 +574,53 @@ Type:: |=== | Property | Type | Description -| `containerName` +| `file` | `string` -| `containerName` defines the name of the container to configure for IPFIX. +| File name within the config map or secret. -| `daemonSetName` +| `name` | `string` -| `daemonSetName` defines the name of the DaemonSet controlling the OVN-Kubernetes pods. +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace where OVN-Kubernetes pods are deployed. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. + +| `type` +| `string` +| Type for the file reference: "configmap" or "secret". + +|=== +== .spec.agent.ebpf.resources +Description:: ++ +-- +`resources` are the compute resources required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `limits` +| `integer-or-string` +| Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + +| `requests` +| `integer-or-string` +| Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |=== == .spec.consolePlugin @@ -372,7 +642,9 @@ Type:: | `advanced` | `object` -| `advanced` allows setting some aspects of the internal configuration of the console plugin. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +| `advanced` allows setting some aspects of the internal configuration of the console plugin. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. | `autoscaler` | `object` @@ -380,7 +652,7 @@ Type:: | `enable` | `boolean` -| Enables the console plugin deployment. `spec.loki.enable` must also be `true` +| Enables the console plugin deployment. | `imagePullPolicy` | `string` @@ -404,14 +676,17 @@ Type:: | `resources` | `object` -| `resources`, in terms of compute resources, required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| `resources`, in terms of compute resources, required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |=== == .spec.consolePlugin.advanced Description:: + -- -`advanced` allows setting some aspects of the internal configuration of the console plugin. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +`advanced` allows setting some aspects of the internal configuration of the console plugin. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. -- Type:: @@ -426,11 +701,17 @@ Type:: | `args` | `array (string)` -| `args` allows passing custom arguments to underlying components. Useful for overriding some parameters, such as an url or a configuration path, that should not be publicly exposed as part of the FlowCollector descriptor, as they are only useful in edge debug or support scenarios. +| `args` allows passing custom arguments to underlying components. Useful for overriding +some parameters, such as a URL or a configuration path, that should not be +publicly exposed as part of the FlowCollector descriptor, as they are only useful +in edge debug or support scenarios. | `env` | `object (string)` -| `env` allows passing custom environment variables to underlying components. Useful for passing some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be publicly exposed as part of the FlowCollector descriptor, as they are only useful in edge debug or support scenarios. +| `env` allows passing custom environment variables to underlying components. Useful for passing +some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be +publicly exposed as part of the FlowCollector descriptor, as they are only useful +in edge debug or support scenarios. | `port` | `integer` @@ -438,9 +719,79 @@ Type:: | `register` | `boolean` -| `register` allows, when set to `true`, to automatically register the provided console plugin with the {product-title} Console operator. When set to `false`, you can still register it manually by editing console.operator.openshift.io/cluster with the following command: `oc patch console.operator.openshift.io cluster --type='json' -p '[{"op": "add", "path": "/spec/plugins/-", "value": "netobserv-plugin"}]'` +| `register` allows, when set to `true`, to automatically register the provided console plugin with the {product-title} Console operator. +When set to `false`, you can still register it manually by editing console.operator.openshift.io/cluster with the following command: +`oc patch console.operator.openshift.io cluster --type='json' -p '[{"op": "add", "path": "/spec/plugins/-", "value": "netobserv-plugin"}]'` + +| `scheduling` +| `object` +| `scheduling` controls how the pods are scheduled on nodes. + +|=== +== .spec.consolePlugin.advanced.scheduling +Description:: ++ +-- +`scheduling` controls how the pods are scheduled on nodes. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `affinity` +| `object` +| If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. + +| `nodeSelector` +| `object (string)` +| `nodeSelector` allows scheduling of pods only onto nodes that have each of the specified labels. +For documentation, refer to https://kubernetes.io/docs/concepts/configuration/assign-pod-node/. + +| `priorityClassName` +| `string` +| If specified, indicates the pod's priority. For documentation, refer to https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#how-to-use-priority-and-preemption. +If not specified, default priority is used, or zero if there is no default. + +| `tolerations` +| `array` +| `tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. |=== +== .spec.consolePlugin.advanced.scheduling.affinity +Description:: ++ +-- +If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `object` + + + + +== .spec.consolePlugin.advanced.scheduling.tolerations +Description:: ++ +-- +`tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `array` + + + + == .spec.consolePlugin.autoscaler Description:: + @@ -477,7 +828,8 @@ Type:: | `portNames` | `object (string)` -| `portNames` defines additional port names to use in the console, for example, `portNames: {"3100": "loki"}`. +| `portNames` defines additional port names to use in the console, +for example, `portNames: {"3100": "loki"}`. |=== == .spec.consolePlugin.quickFilters @@ -519,7 +871,8 @@ Required:: | `filter` | `object (string)` -| `filter` is a set of keys and values to be set when this filter is selected. Each key can relate to a list of values using a coma-separated string, for example, `filter: {"src_namespace": "namespace1,namespace2"}`. +| `filter` is a set of keys and values to be set when this filter is selected. Each key can relate to a list of values using a coma-separated string, +for example, `filter: {"src_namespace": "namespace1,namespace2"}`. | `name` | `string` @@ -530,7 +883,8 @@ Required:: Description:: + -- -`resources`, in terms of compute resources, required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +`resources`, in terms of compute resources, required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ -- Type:: @@ -545,11 +899,15 @@ Type:: | `limits` | `integer-or-string` -| Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `requests` | `integer-or-string` -| Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |=== == .spec.exporters @@ -716,19 +1074,20 @@ Type:: | `file` | `string` -| File name within the config map or secret +| File name within the config map or secret. | `name` | `string` -| Name of the config map or secret containing the file +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the file reference: "configmap" or "secret" +| Type for the file reference: "configmap" or "secret". |=== == .spec.exporters[].kafka.sasl.clientSecretReference @@ -750,19 +1109,20 @@ Type:: | `file` | `string` -| File name within the config map or secret +| File name within the config map or secret. | `name` | `string` -| Name of the config map or secret containing the file +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the file reference: "configmap" or "secret" +| Type for the file reference: "configmap" or "secret". |=== == .spec.exporters[].kafka.tls @@ -792,7 +1152,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -818,7 +1179,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -826,15 +1187,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.exporters[].kafka.tls.userCert @@ -856,7 +1218,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -864,15 +1226,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.kafka @@ -961,19 +1324,20 @@ Type:: | `file` | `string` -| File name within the config map or secret +| File name within the config map or secret. | `name` | `string` -| Name of the config map or secret containing the file +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the file reference: "configmap" or "secret" +| Type for the file reference: "configmap" or "secret". |=== == .spec.kafka.sasl.clientSecretReference @@ -995,19 +1359,20 @@ Type:: | `file` | `string` -| File name within the config map or secret +| File name within the config map or secret. | `name` | `string` -| Name of the config map or secret containing the file +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the file reference: "configmap" or "secret" +| Type for the file reference: "configmap" or "secret". |=== == .spec.kafka.tls @@ -1037,7 +1402,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -1063,7 +1429,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1071,15 +1437,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.kafka.tls.userCert @@ -1101,7 +1468,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1109,15 +1476,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki @@ -1139,40 +1507,57 @@ Type:: | `advanced` | `object` -| `advanced` allows setting some aspects of the internal configuration of the Loki clients. This section is aimed mostly for debugging and fine-grained performance optimizations. +| `advanced` allows setting some aspects of the internal configuration of the Loki clients. +This section is aimed mostly for debugging and fine-grained performance optimizations. | `enable` | `boolean` -| Set `enable` to `true` to store flows in Loki. It is required for the {product-title} Console plugin installation. +| Set `enable` to `true` to store flows in Loki. +The Console plugin can use either Loki or Prometheus as a data source for metrics (see also `spec.prometheus.querier`), or both. +Not all queries are transposable from Loki to Prometheus. Hence, if Loki is disabled, some features of the plugin are disabled as well, +such as getting per-pod information or viewing raw flows. +If both Prometheus and Loki are enabled, Prometheus takes precedence and Loki is used as a fallback for queries that Prometheus cannot handle. +If they are both disabled, the Console plugin is not deployed. | `lokiStack` | `object` -| Loki configuration for `LokiStack` mode. This is useful for an easy loki-operator configuration. It is ignored for other modes. +| Loki configuration for `LokiStack` mode. This is useful for an easy Loki Operator configuration. +It is ignored for other modes. | `manual` | `object` -| Loki configuration for `Manual` mode. This is the most flexible configuration. It is ignored for other modes. +| Loki configuration for `Manual` mode. This is the most flexible configuration. +It is ignored for other modes. | `microservices` | `object` -| Loki configuration for `Microservices` mode. Use this option when Loki is installed using the microservices deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#microservices-mode). It is ignored for other modes. +| Loki configuration for `Microservices` mode. +Use this option when Loki is installed using the microservices deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#microservices-mode). +It is ignored for other modes. | `mode` | `string` | `mode` must be set according to the installation mode of Loki: + - - Use `LokiStack` when Loki is managed using the Loki Operator + - - Use `Monolithic` when Loki is installed as a monolithic workload + - - Use `Microservices` when Loki is installed as microservices, but without Loki Operator + - - Use `Manual` if none of the options above match your setup + + +- Use `LokiStack` when Loki is managed using the Loki Operator + + +- Use `Monolithic` when Loki is installed as a monolithic workload + + +- Use `Microservices` when Loki is installed as microservices, but without Loki Operator + + +- Use `Manual` if none of the options above match your setup + | `monolithic` | `object` -| Loki configuration for `Monolithic` mode. Use this option when Loki is installed using the monolithic deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#monolithic-mode). It is ignored for other modes. +| Loki configuration for `Monolithic` mode. +Use this option when Loki is installed using the monolithic deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#monolithic-mode). +It is ignored for other modes. | `readTimeout` | `string` -| `readTimeout` is the maximum console plugin loki query total time limit. A timeout of zero means no timeout. +| `readTimeout` is the maximum console plugin loki query total time limit. +A timeout of zero means no timeout. | `writeBatchSize` | `integer` @@ -1184,14 +1569,16 @@ Type:: | `writeTimeout` | `string` -| `writeTimeout` is the maximum Loki time connection / request limit. A timeout of zero means no timeout. +| `writeTimeout` is the maximum Loki time connection / request limit. +A timeout of zero means no timeout. |=== == .spec.loki.advanced Description:: + -- -`advanced` allows setting some aspects of the internal configuration of the Loki clients. This section is aimed mostly for debugging and fine-grained performance optimizations. +`advanced` allows setting some aspects of the internal configuration of the Loki clients. +This section is aimed mostly for debugging and fine-grained performance optimizations. -- Type:: @@ -1225,7 +1612,8 @@ Type:: Description:: + -- -Loki configuration for `LokiStack` mode. This is useful for an easy loki-operator configuration. It is ignored for other modes. +Loki configuration for `LokiStack` mode. This is useful for an easy Loki Operator configuration. +It is ignored for other modes. -- Type:: @@ -1251,7 +1639,8 @@ Type:: Description:: + -- -Loki configuration for `Manual` mode. This is the most flexible configuration. It is ignored for other modes. +Loki configuration for `Manual` mode. This is the most flexible configuration. +It is ignored for other modes. -- Type:: @@ -1267,18 +1656,26 @@ Type:: | `authToken` | `string` | `authToken` describes the way to get a token to authenticate to Loki. + - - `Disabled` does not send any token with the request. + - - `Forward` forwards the user token for authorization. + - - `Host` [deprecated (*)] - uses the local pod service account to authenticate to Loki. + - When using the Loki Operator, this must be set to `Forward`. + +- `Disabled` does not send any token with the request. + + +- `Forward` forwards the user token for authorization. + + +- `Host` [deprecated (*)] - uses the local pod service account to authenticate to Loki. + + +When using the Loki Operator, this must be set to `Forward`. | `ingesterUrl` | `string` -| `ingesterUrl` is the address of an existing Loki ingester service to push the flows to. When using the Loki Operator, set it to the Loki gateway service with the `network` tenant set in path, for example https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network. +| `ingesterUrl` is the address of an existing Loki ingester service to push the flows to. When using the Loki Operator, +set it to the Loki gateway service with the `network` tenant set in path, for example +https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network. | `querierUrl` | `string` -| `querierUrl` specifies the address of the Loki querier service. When using the Loki Operator, set it to the Loki gateway service with the `network` tenant set in path, for example https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network. +| `querierUrl` specifies the address of the Loki querier service. +When using the Loki Operator, set it to the Loki gateway service with the `network` tenant set in path, for example +https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network. | `statusTls` | `object` @@ -1286,11 +1683,17 @@ Type:: | `statusUrl` | `string` -| `statusUrl` specifies the address of the Loki `/ready`, `/metrics` and `/config` endpoints, in case it is different from the Loki querier URL. If empty, the `querierUrl` value is used. This is useful to show error messages and some context in the frontend. When using the Loki Operator, set it to the Loki HTTP query frontend service, for example https://loki-query-frontend-http.netobserv.svc:3100/. `statusTLS` configuration is used when `statusUrl` is set. +| `statusUrl` specifies the address of the Loki `/ready`, `/metrics` and `/config` endpoints, in case it is different from the +Loki querier URL. If empty, the `querierUrl` value is used. +This is useful to show error messages and some context in the frontend. +When using the Loki Operator, set it to the Loki HTTP query frontend service, for example +https://loki-query-frontend-http.netobserv.svc:3100/. +`statusTLS` configuration is used when `statusUrl` is set. | `tenantID` | `string` -| `tenantID` is the Loki `X-Scope-OrgID` that identifies the tenant for each request. When using the Loki Operator, set it to `network`, which corresponds to a special tenant mode. +| `tenantID` is the Loki `X-Scope-OrgID` that identifies the tenant for each request. +When using the Loki Operator, set it to `network`, which corresponds to a special tenant mode. | `tls` | `object` @@ -1324,7 +1727,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -1350,7 +1754,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1358,15 +1762,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.manual.statusTls.userCert @@ -1388,7 +1793,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1396,15 +1801,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.manual.tls @@ -1434,7 +1840,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -1460,7 +1867,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1468,15 +1875,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.manual.tls.userCert @@ -1498,7 +1906,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1506,22 +1914,25 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.microservices Description:: + -- -Loki configuration for `Microservices` mode. Use this option when Loki is installed using the microservices deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#microservices-mode). It is ignored for other modes. +Loki configuration for `Microservices` mode. +Use this option when Loki is installed using the microservices deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#microservices-mode). +It is ignored for other modes. -- Type:: @@ -1578,7 +1989,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -1604,7 +2016,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1612,15 +2024,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.microservices.tls.userCert @@ -1642,7 +2055,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1650,22 +2063,25 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.monolithic Description:: + -- -Loki configuration for `Monolithic` mode. Use this option when Loki is installed using the monolithic deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#monolithic-mode). It is ignored for other modes. +Loki configuration for `Monolithic` mode. +Use this option when Loki is installed using the monolithic deployment mode (https://grafana.com/docs/loki/latest/fundamentals/architecture/deployment-modes/#monolithic-mode). +It is ignored for other modes. -- Type:: @@ -1718,7 +2134,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the server certificate. If set to `true`, the `caCert` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. | `userCert` | `object` @@ -1744,7 +2161,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1752,15 +2169,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.loki.monolithic.tls.userCert @@ -1782,7 +2200,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -1790,22 +2208,24 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.processor Description:: + -- -`processor` defines the settings of the component that receives the flows from the agent, enriches them, generates metrics, and forwards them to the Loki persistence layer and/or any available exporter. +`processor` defines the settings of the component that receives the flows from the agent, +enriches them, generates metrics, and forwards them to the Loki persistence layer and/or any available exporter. -- Type:: @@ -1820,11 +2240,14 @@ Type:: | `addZone` | `boolean` -| `addZone` allows availability zone awareness by labelling flows with their source and destination zones. This feature requires the "topology.kubernetes.io/zone" label to be set on nodes. +| `addZone` allows availability zone awareness by labelling flows with their source and destination zones. +This feature requires the "topology.kubernetes.io/zone" label to be set on nodes. | `advanced` | `object` -| `advanced` allows setting some aspects of the internal configuration of the flow processor. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +| `advanced` allows setting some aspects of the internal configuration of the flow processor. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. | `clusterName` | `string` @@ -1836,7 +2259,8 @@ Type:: | `kafkaConsumerAutoscaler` | `object` -| `kafkaConsumerAutoscaler` is the spec of a horizontal pod autoscaler to set up for `flowlogs-pipeline-transformer`, which consumes Kafka messages. This setting is ignored when Kafka is disabled. Refer to HorizontalPodAutoscaler documentation (autoscaling/v2). +| `kafkaConsumerAutoscaler` is the spec of a horizontal pod autoscaler to set up for `flowlogs-pipeline-transformer`, which consumes Kafka messages. +This setting is ignored when Kafka is disabled. Refer to HorizontalPodAutoscaler documentation (autoscaling/v2). | `kafkaConsumerBatchSize` | `integer` @@ -1848,7 +2272,8 @@ Type:: | `kafkaConsumerReplicas` | `integer` -| `kafkaConsumerReplicas` defines the number of replicas (pods) to start for `flowlogs-pipeline-transformer`, which consumes Kafka messages. This setting is ignored when Kafka is disabled. +| `kafkaConsumerReplicas` defines the number of replicas (pods) to start for `flowlogs-pipeline-transformer`, which consumes Kafka messages. +This setting is ignored when Kafka is disabled. | `logLevel` | `string` @@ -1857,13 +2282,17 @@ Type:: | `logTypes` | `string` | `logTypes` defines the desired record types to generate. Possible values are: + - - `Flows` (default) to export regular network flows + - - `Conversations` to generate events for started conversations, ended conversations as well as periodic "tick" updates + - - `EndedConversations` to generate only ended conversations events + - - `All` to generate both network flows and all conversations events + +- `Flows` (default) to export regular network flows + -| `metrics` +- `Conversations` to generate events for started conversations, ended conversations as well as periodic "tick" updates + + +- `EndedConversations` to generate only ended conversations events + + +- `All` to generate both network flows and all conversations events + + + +| `metrics` | `object` | `Metrics` define the processor configuration regarding metrics @@ -1873,14 +2302,22 @@ Type:: | `resources` | `object` -| `resources` are the compute resources required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| `resources` are the compute resources required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + +| `subnetLabels` +| `object` +| `subnetLabels` allows to define custom labels on subnets and IPs or to enable automatic labelling of recognized subnets in {product-title}, which is used to identify cluster external traffic. +When a subnet matches the source or destination IP of a flow, a corresponding field is added: `SrcSubnetLabel` or `DstSubnetLabel`. |=== == .spec.processor.advanced Description:: + -- -`advanced` allows setting some aspects of the internal configuration of the flow processor. This section is aimed mostly for debugging and fine-grained performance optimizations, such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. +`advanced` allows setting some aspects of the internal configuration of the flow processor. +This section is aimed mostly for debugging and fine-grained performance optimizations, +such as `GOGC` and `GOMAXPROCS` env vars. Set these values at your own risk. -- Type:: @@ -1895,7 +2332,8 @@ Type:: | `conversationEndTimeout` | `string` -| `conversationEndTimeout` is the time to wait after a network flow is received, to consider the conversation ended. This delay is ignored when a FIN packet is collected for TCP flows (see `conversationTerminatingTimeout` instead). +| `conversationEndTimeout` is the time to wait after a network flow is received, to consider the conversation ended. +This delay is ignored when a FIN packet is collected for TCP flows (see `conversationTerminatingTimeout` instead). | `conversationHeartbeatInterval` | `string` @@ -1907,7 +2345,7 @@ Type:: | `dropUnusedFields` | `boolean` -| `dropUnusedFields` allows, when set to `true`, to drop fields that are known to be unused by OVS, to save storage space. +| `dropUnusedFields` [deprecated (*)] this setting is not used anymore. | `enableKubeProbes` | `boolean` @@ -1915,7 +2353,10 @@ Type:: | `env` | `object (string)` -| `env` allows passing custom environment variables to underlying components. Useful for passing some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be publicly exposed as part of the FlowCollector descriptor, as they are only useful in edge debug or support scenarios. +| `env` allows passing custom environment variables to underlying components. Useful for passing +some very concrete performance-tuning options, such as `GOGC` and `GOMAXPROCS`, that should not be +publicly exposed as part of the FlowCollector descriptor, as they are only useful +in edge debug or support scenarios. | `healthPort` | `integer` @@ -1923,18 +2364,89 @@ Type:: | `port` | `integer` -| Port of the flow collector (host port). By convention, some values are forbidden. It must be greater than 1024 and different from 4500, 4789 and 6081. +| Port of the flow collector (host port). +By convention, some values are forbidden. It must be greater than 1024 and different from +4500, 4789 and 6081. | `profilePort` | `integer` | `profilePort` allows setting up a Go pprof profiler listening to this port +| `scheduling` +| `object` +| scheduling controls how the pods are scheduled on nodes. + |=== +== .spec.processor.advanced.scheduling +Description:: ++ +-- +scheduling controls how the pods are scheduled on nodes. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `affinity` +| `object` +| If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. + +| `nodeSelector` +| `object (string)` +| `nodeSelector` allows scheduling of pods only onto nodes that have each of the specified labels. +For documentation, refer to https://kubernetes.io/docs/concepts/configuration/assign-pod-node/. + +| `priorityClassName` +| `string` +| If specified, indicates the pod's priority. For documentation, refer to https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#how-to-use-priority-and-preemption. +If not specified, default priority is used, or zero if there is no default. + +| `tolerations` +| `array` +| `tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. + +|=== +== .spec.processor.advanced.scheduling.affinity +Description:: ++ +-- +If specified, the pod's scheduling constraints. For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `object` + + + + +== .spec.processor.advanced.scheduling.tolerations +Description:: ++ +-- +`tolerations` is a list of tolerations that allow the pod to schedule onto nodes with matching taints. +For documentation, refer to https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling. +-- + +Type:: + `array` + + + + == .spec.processor.kafkaConsumerAutoscaler Description:: + -- -`kafkaConsumerAutoscaler` is the spec of a horizontal pod autoscaler to set up for `flowlogs-pipeline-transformer`, which consumes Kafka messages. This setting is ignored when Kafka is disabled. Refer to HorizontalPodAutoscaler documentation (autoscaling/v2). +`kafkaConsumerAutoscaler` is the spec of a horizontal pod autoscaler to set up for `flowlogs-pipeline-transformer`, which consumes Kafka messages. +This setting is ignored when Kafka is disabled. Refer to HorizontalPodAutoscaler documentation (autoscaling/v2). -- Type:: @@ -1962,14 +2474,24 @@ Type:: | `disableAlerts` | `array (string)` -| `disableAlerts` is a list of alerts that should be disabled. Possible values are: + - `NetObservNoFlows`, which is triggered when no flows are being observed for a certain period. + - `NetObservLokiError`, which is triggered when flows are being dropped due to Loki errors. + +| `disableAlerts` is a list of alerts that should be disabled. +Possible values are: + + +`NetObservNoFlows`, which is triggered when no flows are being observed for a certain period. + + +`NetObservLokiError`, which is triggered when flows are being dropped due to Loki errors. + | `includeList` | `array (string)` -| `includeList` is a list of metric names to specify which ones to generate. The names correspond to the names in Prometheus without the prefix. For example, `namespace_egress_packets_total` shows up as `netobserv_namespace_egress_packets_total` in Prometheus. Note that the more metrics you add, the bigger is the impact on Prometheus workload resources. Metrics enabled by default are: `namespace_flows_total`, `node_ingress_bytes_total`, `workload_ingress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled), `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled). More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md +| `includeList` is a list of metric names to specify which ones to generate. +The names correspond to the names in Prometheus without the prefix. For example, +`namespace_egress_packets_total` shows up as `netobserv_namespace_egress_packets_total` in Prometheus. +Note that the more metrics you add, the bigger is the impact on Prometheus workload resources. +Metrics enabled by default are: +`namespace_flows_total`, `node_ingress_bytes_total`, `workload_ingress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled), +`namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled). +More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md | `server` | `object` @@ -1995,7 +2517,7 @@ Type:: | `port` | `integer` -| The prometheus HTTP port +| The metrics server HTTP port. | `tls` | `object` @@ -2021,7 +2543,8 @@ Type:: | `insecureSkipVerify` | `boolean` -| `insecureSkipVerify` allows skipping client-side verification of the provided certificate. If set to `true`, the `providedCaFile` field is ignored. +| `insecureSkipVerify` allows skipping client-side verification of the provided certificate. +If set to `true`, the `providedCaFile` field is ignored. | `provided` | `object` @@ -2034,7 +2557,10 @@ Type:: | `type` | `string` | Select the type of TLS configuration: + - - `Disabled` (default) to not configure TLS for the endpoint. - `Provided` to manually provide cert file and a key file. - `Auto` to use {product-title} auto generated certificate using annotations. + +- `Disabled` (default) to not configure TLS for the endpoint. +- `Provided` to manually provide cert file and a key file. [Unsupported (*)]. +- `Auto` to use {product-title} auto generated certificate using annotations. |=== == .spec.processor.metrics.server.tls.provided @@ -2056,7 +2582,7 @@ Type:: | `certFile` | `string` -| `certFile` defines the path to the certificate file name within the config map or secret +| `certFile` defines the path to the certificate file name within the config map or secret. | `certKey` | `string` @@ -2064,15 +2590,16 @@ Type:: | `name` | `string` -| Name of the config map or secret containing certificates +| Name of the config map or secret containing certificates. | `namespace` | `string` -| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the certificate reference: `configmap` or `secret` +| Type for the certificate reference: `configmap` or `secret`. |=== == .spec.processor.metrics.server.tls.providedCaFile @@ -2094,26 +2621,28 @@ Type:: | `file` | `string` -| File name within the config map or secret +| File name within the config map or secret. | `name` | `string` -| Name of the config map or secret containing the file +| Name of the config map or secret containing the file. | `namespace` | `string` -| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. If the namespace is different, the config map or the secret is copied so that it can be mounted as required. +| Namespace of the config map or secret containing the file. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. | `type` | `string` -| Type for the file reference: "configmap" or "secret" +| Type for the file reference: "configmap" or "secret". |=== == .spec.processor.resources Description:: + -- -`resources` are the compute resources required by this container. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +`resources` are the compute resources required by this container. +For more information, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ -- Type:: @@ -2128,10 +2657,295 @@ Type:: | `limits` | `integer-or-string` -| Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `requests` | `integer-or-string` -| Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +| Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + +|=== +== .spec.processor.subnetLabels +Description:: ++ +-- +`subnetLabels` allows to define custom labels on subnets and IPs or to enable automatic labelling of recognized subnets in {product-title}, which is used to identify cluster external traffic. +When a subnet matches the source or destination IP of a flow, a corresponding field is added: `SrcSubnetLabel` or `DstSubnetLabel`. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `customLabels` +| `array` +| `customLabels` allows to customize subnets and IPs labelling, such as to identify cluster-external workloads or web services. +If you enable `openShiftAutoDetect`, `customLabels` can override the detected subnets in case they overlap. + +| `openShiftAutoDetect` +| `boolean` +| `openShiftAutoDetect` allows, when set to `true`, to detect automatically the machines, pods and services subnets based on the +{product-title} install configuration and the Cluster Network Operator configuration. Indirectly, this is a way to accurately detect +external traffic: flows that are not labeled for those subnets are external to the cluster. Enabled by default on {product-title}. + +|=== +== .spec.processor.subnetLabels.customLabels +Description:: ++ +-- +`customLabels` allows to customize subnets and IPs labelling, such as to identify cluster-external workloads or web services. +If you enable `openShiftAutoDetect`, `customLabels` can override the detected subnets in case they overlap. +-- + +Type:: + `array` + + + + +== .spec.processor.subnetLabels.customLabels[] +Description:: ++ +-- +SubnetLabel allows to label subnets and IPs, such as to identify cluster-external workloads or web services. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `cidrs` +| `array (string)` +| List of CIDRs, such as `["1.2.3.4/32"]`. + +| `name` +| `string` +| Label name, used to flag matching flows. + +|=== +== .spec.prometheus +Description:: ++ +-- +`prometheus` defines Prometheus settings, such as querier configuration used to fetch metrics from the Console plugin. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `querier` +| `object` +| Prometheus querying configuration, such as client settings, used in the Console plugin. + +|=== +== .spec.prometheus.querier +Description:: ++ +-- +Prometheus querying configuration, such as client settings, used in the Console plugin. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `enable` +| `boolean` +| When `enable` is `true`, the Console plugin queries flow metrics from Prometheus instead of Loki whenever possible. +It is enbaled by default: set it to `false` to disable this feature. +The Console plugin can use either Loki or Prometheus as a data source for metrics (see also `spec.loki`), or both. +Not all queries are transposable from Loki to Prometheus. Hence, if Loki is disabled, some features of the plugin are disabled as well, +such as getting per-pod information or viewing raw flows. +If both Prometheus and Loki are enabled, Prometheus takes precedence and Loki is used as a fallback for queries that Prometheus cannot handle. +If they are both disabled, the Console plugin is not deployed. + +| `manual` +| `object` +| Prometheus configuration for `Manual` mode. + +| `mode` +| `string` +| `mode` must be set according to the type of Prometheus installation that stores Network Observability metrics: + + +- Use `Auto` to try configuring automatically. In {product-title}, it uses the Thanos querier from {product-title} Cluster Monitoring + + +- Use `Manual` for a manual setup + + + +| `timeout` +| `string` +| `timeout` is the read timeout for console plugin queries to Prometheus. +A timeout of zero means no timeout. + +|=== +== .spec.prometheus.querier.manual +Description:: ++ +-- +Prometheus configuration for `Manual` mode. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `forwardUserToken` +| `boolean` +| Set `true` to forward logged in user token in queries to Prometheus + +| `tls` +| `object` +| TLS client configuration for Prometheus URL. + +| `url` +| `string` +| `url` is the address of an existing Prometheus service to use for querying metrics. + +|=== +== .spec.prometheus.querier.manual.tls +Description:: ++ +-- +TLS client configuration for Prometheus URL. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `caCert` +| `object` +| `caCert` defines the reference of the certificate for the Certificate Authority + +| `enable` +| `boolean` +| Enable TLS + +| `insecureSkipVerify` +| `boolean` +| `insecureSkipVerify` allows skipping client-side verification of the server certificate. +If set to `true`, the `caCert` field is ignored. + +| `userCert` +| `object` +| `userCert` defines the user certificate reference and is used for mTLS (you can ignore it when using one-way TLS) + +|=== +== .spec.prometheus.querier.manual.tls.caCert +Description:: ++ +-- +`caCert` defines the reference of the certificate for the Certificate Authority +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `certFile` +| `string` +| `certFile` defines the path to the certificate file name within the config map or secret. + +| `certKey` +| `string` +| `certKey` defines the path to the certificate private key file name within the config map or secret. Omit when the key is not necessary. + +| `name` +| `string` +| Name of the config map or secret containing certificates. + +| `namespace` +| `string` +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. + +| `type` +| `string` +| Type for the certificate reference: `configmap` or `secret`. + +|=== +== .spec.prometheus.querier.manual.tls.userCert +Description:: ++ +-- +`userCert` defines the user certificate reference and is used for mTLS (you can ignore it when using one-way TLS) +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `certFile` +| `string` +| `certFile` defines the path to the certificate file name within the config map or secret. + +| `certKey` +| `string` +| `certKey` defines the path to the certificate private key file name within the config map or secret. Omit when the key is not necessary. + +| `name` +| `string` +| Name of the config map or secret containing certificates. + +| `namespace` +| `string` +| Namespace of the config map or secret containing certificates. If omitted, the default is to use the same namespace as where Network Observability is deployed. +If the namespace is different, the config map or the secret is copied so that it can be mounted as required. + +| `type` +| `string` +| Type for the certificate reference: `configmap` or `secret`. |=== \ No newline at end of file diff --git a/modules/network-observability-flowmetric-api-specifications.adoc b/modules/network-observability-flowmetric-api-specifications.adoc new file mode 100644 index 000000000000..3bcc0f41dbfd --- /dev/null +++ b/modules/network-observability-flowmetric-api-specifications.adoc @@ -0,0 +1,298 @@ +// Automatically generated by 'openshift-apidocs-gen'. Do not edit. +:_mod-docs-content-type: REFERENCE +[id="flowmetric-flows-netobserv-io-v1alpha1"] += FlowMetric [flows.netobserv.io/v1alpha1] + + + +Description:: ++ +-- +FlowMetric is the API allowing to create custom metrics from the collected flow logs. +-- + +Type:: + `object` + + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `apiVersion` +| `string` +| APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and might reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + +| `kind` +| `string` +| Kind is a string value representing the REST resource this object represents. Servers might infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + +| `metadata` +| `object` +| Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + +| `spec` +| `object` +| FlowMetricSpec defines the desired state of FlowMetric +The provided API allows you to customize these metrics according to your needs. + + +When adding new metrics or modifying existing labels, you must carefully monitor the memory +usage of Prometheus workloads as this could potentially have a high impact. Cf https://rhobs-handbook.netlify.app/products/openshiftmonitoring/telemetry.md/#what-is-the-cardinality-of-a-metric + + +To check the cardinality of all Network Observability metrics, run as `promql`: `count({__name__=~"netobserv.*"}) by (__name__)`. + +|=== +== .metadata +Description:: ++ +-- +Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata +-- + +Type:: + `object` + + + + +== .spec +Description:: ++ +-- +FlowMetricSpec defines the desired state of FlowMetric +The provided API allows you to customize these metrics according to your needs. + + +When adding new metrics or modifying existing labels, you must carefully monitor the memory +usage of Prometheus workloads as this could potentially have a high impact. Cf https://rhobs-handbook.netlify.app/products/openshiftmonitoring/telemetry.md/#what-is-the-cardinality-of-a-metric + + +To check the cardinality of all Network Observability metrics, run as `promql`: `count({__name__=~"netobserv.*"}) by (__name__)`. +-- + +Type:: + `object` + +Required:: + - `metricName` + - `type` + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `buckets` +| `array (string)` +| A list of buckets to use when `type` is "Histogram". The list must be parsable as floats. When not set, Prometheus default buckets are used. + +| `charts` +| `array` +| Charts configuration, for the {product-title} Console in the administrator view, Dashboards menu. + +| `direction` +| `string` +| Filter for ingress, egress or any direction flows. +When set to `Ingress`, it is equivalent to adding the regular expression filter on `FlowDirection`: `0\|2`. +When set to `Egress`, it is equivalent to adding the regular expression filter on `FlowDirection`: `1\|2`. + +| `divider` +| `string` +| When nonzero, scale factor (divider) of the value. Metric value = Flow value / Divider. + +| `filters` +| `array` +| `filters` is a list of fields and values used to restrict which flows are taken into account. Oftentimes, these filters must +be used to eliminate duplicates: `Duplicate != "true"` and `FlowDirection = "0"`. +Refer to the documentation for the list of available fields: https://docs.openshift.com/container-platform/latest/observability/network_observability/json-flows-format-reference.html. + +| `labels` +| `array (string)` +| `labels` is a list of fields that should be used as Prometheus labels, also known as dimensions. +From choosing labels results the level of granularity of this metric, and the available aggregations at query time. +It must be done carefully as it impacts the metric cardinality (cf https://rhobs-handbook.netlify.app/products/openshiftmonitoring/telemetry.md/#what-is-the-cardinality-of-a-metric). +In general, avoid setting very high cardinality labels such as IP or MAC addresses. +"SrcK8S_OwnerName" or "DstK8S_OwnerName" should be preferred over "SrcK8S_Name" or "DstK8S_Name" as much as possible. +Refer to the documentation for the list of available fields: https://docs.openshift.com/container-platform/latest/observability/network_observability/json-flows-format-reference.html. + +| `metricName` +| `string` +| Name of the metric. In Prometheus, it is automatically prefixed with "netobserv_". + +| `type` +| `string` +| Metric type: "Counter" or "Histogram". +Use "Counter" for any value that increases over time and on which you can compute a rate, such as Bytes or Packets. +Use "Histogram" for any value that must be sampled independently, such as latencies. + +| `valueField` +| `string` +| `valueField` is the flow field that must be used as a value for this metric. This field must hold numeric values. +Leave empty to count flows rather than a specific value per flow. +Refer to the documentation for the list of available fields: https://docs.openshift.com/container-platform/latest/observability/network_observability/json-flows-format-reference.html. + +|=== +== .spec.charts +Description:: ++ +-- +Charts configuration, for the {product-title} Console in the administrator view, Dashboards menu. +-- + +Type:: + `array` + + + + +== .spec.charts[] +Description:: ++ +-- +Configures charts / dashboard generation associated to a metric +-- + +Type:: + `object` + +Required:: + - `dashboardName` + - `queries` + - `title` + - `type` + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `dashboardName` +| `string` +| Name of the containing dashboard. If this name does not refer to an existing dashboard, a new dashboard is created. + +| `queries` +| `array` +| List of queries to be displayed on this chart. If `type` is `SingleStat` and multiple queries are provided, +this chart is automatically expanded in several panels (one per query). + +| `sectionName` +| `string` +| Name of the containing dashboard section. If this name does not refer to an existing section, a new section is created. +If `sectionName` is omitted or empty, the chart is placed in the global top section. + +| `title` +| `string` +| Title of the chart. + +| `type` +| `string` +| Type of the chart. + +| `unit` +| `string` +| Unit of this chart. Only a few units are currently supported. Leave empty to use generic number. + +|=== +== .spec.charts[].queries +Description:: ++ +-- +List of queries to be displayed on this chart. If `type` is `SingleStat` and multiple queries are provided, +this chart is automatically expanded in several panels (one per query). +-- + +Type:: + `array` + + + + +== .spec.charts[].queries[] +Description:: ++ +-- +Configures PromQL queries +-- + +Type:: + `object` + +Required:: + - `legend` + - `promQL` + - `top` + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `legend` +| `string` +| The query legend that applies to each timeseries represented in this chart. When multiple timeseries are displayed, you should set a legend +that distinguishes each of them. It can be done with the following format: `{{ Label }}`. For example, if the `promQL` groups timeseries per +label such as: `sum(rate($METRIC[2m])) by (Label1, Label2)`, you might write as the legend: `Label1={{ Label1 }}, Label2={{ Label2 }}`. + +| `promQL` +| `string` +| The `promQL` query to be run against Prometheus. If the chart `type` is `SingleStat`, this query should only return +a single timeseries. For other types, a top 7 is displayed. +You can use `$METRIC` to refer to the metric defined in this resource. For example: `sum(rate($METRIC[2m]))`. +To learn more about `promQL`, refer to the Prometheus documentation: https://prometheus.io/docs/prometheus/latest/querying/basics/ + +| `top` +| `integer` +| Top N series to display per timestamp. Does not apply to `SingleStat` chart type. + +|=== +== .spec.filters +Description:: ++ +-- +`filters` is a list of fields and values used to restrict which flows are taken into account. Oftentimes, these filters must +be used to eliminate duplicates: `Duplicate != "true"` and `FlowDirection = "0"`. +Refer to the documentation for the list of available fields: https://docs.openshift.com/container-platform/latest/observability/network_observability/json-flows-format-reference.html. +-- + +Type:: + `array` + + + + +== .spec.filters[] +Description:: ++ +-- + +-- + +Type:: + `object` + +Required:: + - `field` + - `matchType` + + + +[cols="1,1,1",options="header"] +|=== +| Property | Type | Description + +| `field` +| `string` +| Name of the field to filter on + +| `matchType` +| `string` +| Type of matching to apply + +| `value` +| `string` +| Value to filter on. When `matchType` is `Equal` or `NotEqual`, you can use field injection with `$(SomeField)` to refer to any other field of the flow. + +|=== \ No newline at end of file diff --git a/modules/network-observability-flowmetrics-charts.adoc b/modules/network-observability-flowmetrics-charts.adoc new file mode 100644 index 000000000000..ff0aef792c57 --- /dev/null +++ b/modules/network-observability-flowmetrics-charts.adoc @@ -0,0 +1,112 @@ +// Module included in the following assemblies: +// +// network_observability/metrics-alerts-dashboards.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-custom-charts-flowmetrics_{context}"] += Configuring custom charts using FlowMetric API +You can generate charts for dashboards in the {product-title} web console, which you can view as an administrator in the *Dashboard* menu by defining the `charts` section of the `FlowMetric` resource. + +.Procedure +. In the web console, navigate to *Operators* -> *Installed Operators*. +. In the *Provided APIs* heading for the *NetObserv Operator*, select *FlowMetric*. +. In the *Project:* dropdown list, select the project of the Network Observability Operator instance. +. Click *Create FlowMetric*. +. Configure the `FlowMetric` resource, similar to the following sample configurations: + +.Chart for tracking ingress bytes received from cluster external sources +[%collapsible] +==== +[source,yaml] +---- +apiVersion: flows.netobserv.io/v1alpha1 +kind: FlowMetric +metadata: + name: flowmetric-cluster-external-ingress-traffic + namespace: netobserv <1> +# ... + charts: + - dashboardName: Main <2> + title: External ingress traffic + unit: Bps + type: SingleStat + queries: + - promQL: "sum(rate($METRIC[2m]))" + legend: "" + - dashboardName: Main <2> + sectionName: External + title: Top external ingress traffic per workload + unit: Bps + type: StackArea + queries: + - promQL: "sum(rate($METRIC{DstK8S_Namespace!=\"\"}[2m])) by (DstK8S_Namespace, DstK8S_OwnerName)" + legend: "{{DstK8S_Namespace}} / {{DstK8S_OwnerName}}" +# ... +---- +<1> The `FlowMetric` resources need to be created in the namespace defined in the `FlowCollector` `spec.namespace`, which is `netobserv` by default. + +.Verification +. Once the pods refresh, navigate to *Observe* -> *Dashboards*. +. Search for the *NetObserv / Main* dashboard. View two panels under the *NetObserv / Main* dashboard, or optionally a dashboard name that you create: + +* A textual single statistic showing the global external ingress rate summed across all dimensions +* A timeseries graph showing the same metric per destination workload + +For more information about the query language, refer to the link:https://prometheus.io/docs/prometheus/latest/querying/basics/[Prometheus documentation]. +==== + +.Chart for RTT latency for cluster external ingress traffic +[%collapsible] +==== +[source,yaml] +---- +apiVersion: flows.netobserv.io/v1alpha1 +kind: FlowMetric +metadata: + name: flowmetric-cluster-external-ingress-traffic + namespace: netobserv <1> +# ... + charts: + - dashboardName: Main <2> + title: External ingress TCP latency + unit: seconds + type: SingleStat + queries: + - promQL: "histogram_quantile(0.99, sum(rate($METRIC_bucket[2m])) by (le)) > 0" + legend: "p99" + - dashboardName: Main <2> + sectionName: External + title: "Top external ingress sRTT per workload, p50 (ms)" + unit: seconds + type: Line + queries: + - promQL: "histogram_quantile(0.5, sum(rate($METRIC_bucket{DstK8S_Namespace!=\"\"}[2m])) by (le,DstK8S_Namespace,DstK8S_OwnerName))*1000 > 0" + legend: "{{DstK8S_Namespace}} / {{DstK8S_OwnerName}}" + - dashboardName: Main <2> + sectionName: External + title: "Top external ingress sRTT per workload, p99 (ms)" + unit: seconds + type: Line + queries: + - promQL: "histogram_quantile(0.99, sum(rate($METRIC_bucket{DstK8S_Namespace!=\"\"}[2m])) by (le,DstK8S_Namespace,DstK8S_OwnerName))*1000 > 0" + legend: "{{DstK8S_Namespace}} / {{DstK8S_OwnerName}}" +# ... +---- +<1> The `FlowMetric` resources need to be created in the namespace defined in the `FlowCollector` `spec.namespace`, which is `netobserv` by default. +<2> Using a different `dashboardName` creates a new dashboard that is prefixed with `Netobserv`. For example, *Netobserv / *. + +This example uses the `histogram_quantile` function to show `p50` and `p99`. + +You can show averages of histograms by dividing the metric, `$METRIC_sum`, by the metric ,`$METRIC_count`, which are automatically generated when you create a histogram. With the preceding example, the Prometheus query to do this is as follows: + +[source,yaml] +---- +promQL: "(sum(rate($METRIC_sum{DstK8S_Namespace!=\"\"}[2m])) by (DstK8S_Namespace,DstK8S_OwnerName) / sum(rate($METRIC_count{DstK8S_Namespace!=\"\"}[2m])) by (DstK8S_Namespace,DstK8S_OwnerName))*1000" +---- + +.Verification +. Once the pods refresh, navigate to *Observe* -> *Dashboards*. +. Search for the *NetObserv / Main* dashboard. View the new panel under the *NetObserv / Main* dashboard, or optionally a dashboard name that you create. + +For more information about the query language, refer to the link:https://prometheus.io/docs/prometheus/latest/querying/basics/[Prometheus documentation]. +==== diff --git a/modules/network-observability-flows-format.adoc b/modules/network-observability-flows-format.adoc index 47367884eaeb..72241cf6ab19 100644 --- a/modules/network-observability-flows-format.adoc +++ b/modules/network-observability-flows-format.adoc @@ -9,105 +9,131 @@ The "Filter ID" column shows which related name to use when defining Quick Filte The "Loki label" column is useful when querying Loki directly: label fields need to be selected using link:https://grafana.com/docs/loki/latest/logql/log_queries/#log-stream-selector[stream selectors]. +The "Cardinality" column gives information about the implied metric cardinality if this field was to be used as a Prometheus label with the `FlowMetric` API. For more information, see the "FlowMetric API reference". -[cols="1,1,3,1,1",options="header"] +[cols="1,1,3,1,1,1",options="header"] |=== -| Name | Type | Description | Filter ID | Loki label +| Name | Type | Description | Filter ID | Loki label | Cardinality | `Bytes` | number | Number of bytes | n/a | no +| avoid | `DnsErrno` | number | Error number returned from DNS tracker ebpf hook function | `dns_errno` | no +| fine | `DnsFlags` | number | DNS flags for DNS record | n/a | no +| fine | `DnsFlagsResponseCode` | string | Parsed DNS header RCODEs name | `dns_flag_response_code` | no +| fine | `DnsId` | number | DNS record id | `dns_id` | no +| avoid | `DnsLatencyMs` | number | Time between a DNS request and response, in milliseconds | `dns_latency` | no +| avoid | `Dscp` | number | Differentiated Services Code Point (DSCP) value | `dscp` | no +| fine | `DstAddr` | string | Destination IP address (ipv4 or ipv6) | `dst_address` | no +| avoid | `DstK8S_HostIP` | string | Destination node IP | `dst_host_address` | no +| fine | `DstK8S_HostName` | string | Destination node name | `dst_host_name` | no +| fine | `DstK8S_Name` | string | Name of the destination Kubernetes object, such as Pod name, Service name or Node name. | `dst_name` | no +| careful | `DstK8S_Namespace` | string | Destination namespace | `dst_namespace` | yes +| fine | `DstK8S_OwnerName` | string | Name of the destination owner, such as Deployment name, StatefulSet name, etc. | `dst_owner_name` | yes +| fine | `DstK8S_OwnerType` | string | Kind of the destination owner, such as Deployment, StatefulSet, etc. | `dst_kind` | no +| fine | `DstK8S_Type` | string | Kind of the destination Kubernetes object, such as Pod, Service or Node. | `dst_kind` | yes +| fine | `DstK8S_Zone` | string | Destination availability zone | `dst_zone` | yes +| fine | `DstMac` | string | Destination MAC address | `dst_mac` | no +| avoid | `DstPort` | number | Destination port | `dst_port` | no +| careful +| `DstSubnetLabel` +| string +| Destination subnet label +| `dst_subnet_label` +| no +| fine | `Duplicate` | boolean | Indicates if this flow was also captured from another interface on the same host | n/a | yes +| fine | `Flags` | number | Logical OR combination of unique TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: + @@ -116,164 +142,202 @@ The "Loki label" column is useful when querying Loki directly: label fields need - RST+ACK (0x400) | n/a | no +| fine | `FlowDirection` | number -| Flow direction from the node observation point. Can be one of: + +| Flow interpreted direction from the node observation point. Can be one of: + - 0: Ingress (incoming traffic, from the node observation point) + - 1: Egress (outgoing traffic, from the node observation point) + - 2: Inner (with the same source and destination node) -| `direction` +| `node_direction` | yes +| fine | `IcmpCode` | number | ICMP code | `icmp_code` | no +| fine | `IcmpType` | number | ICMP type | `icmp_type` | no -| `IfDirection` +| fine +| `IfDirections` | number -| Flow direction from the network interface observation point. Can be one of: + +| Flow directions from the network interface observation point. Can be one of: + - 0: Ingress (interface incoming traffic) + - 1: Egress (interface outgoing traffic) -| n/a +| `ifdirections` | no -| `Interface` +| fine +| `Interfaces` | string -| Network interface -| `interface` +| Network interfaces +| `interfaces` | no +| careful | `K8S_ClusterName` | string | Cluster name or identifier | `cluster_name` | yes +| fine | `K8S_FlowLayer` | string | Flow layer: 'app' or 'infra' | `flow_layer` | no +| fine | `Packets` | number | Number of packets | n/a | no +| avoid | `PktDropBytes` | number | Number of bytes dropped by the kernel | n/a | no +| avoid | `PktDropLatestDropCause` | string | Latest drop cause | `pkt_drop_cause` | no +| fine | `PktDropLatestFlags` | number | TCP flags on last dropped packet | n/a | no +| fine | `PktDropLatestState` | string | TCP state on last dropped packet | `pkt_drop_state` | no +| fine | `PktDropPackets` | number | Number of packets dropped by the kernel | n/a | no +| avoid | `Proto` | number | L4 protocol | `protocol` | no +| fine | `SrcAddr` | string | Source IP address (ipv4 or ipv6) | `src_address` | no +| avoid | `SrcK8S_HostIP` | string | Source node IP | `src_host_address` | no +| fine | `SrcK8S_HostName` | string | Source node name | `src_host_name` | no +| fine | `SrcK8S_Name` | string | Name of the source Kubernetes object, such as Pod name, Service name or Node name. | `src_name` | no +| careful | `SrcK8S_Namespace` | string | Source namespace | `src_namespace` | yes +| fine | `SrcK8S_OwnerName` | string | Name of the source owner, such as Deployment name, StatefulSet name, etc. | `src_owner_name` | yes +| fine | `SrcK8S_OwnerType` | string | Kind of the source owner, such as Deployment, StatefulSet, etc. | `src_kind` | no +| fine | `SrcK8S_Type` | string | Kind of the source Kubernetes object, such as Pod, Service or Node. | `src_kind` | yes +| fine | `SrcK8S_Zone` | string | Source availability zone | `src_zone` | yes +| fine | `SrcMac` | string | Source MAC address | `src_mac` | no +| avoid | `SrcPort` | number | Source port | `src_port` | no +| careful +| `SrcSubnetLabel` +| string +| Source subnet label +| `src_subnet_label` +| no +| fine | `TimeFlowEndMs` | number | End timestamp of this flow, in milliseconds | n/a | no +| avoid | `TimeFlowRttNs` | number | TCP Smoothed Round Trip Time (SRTT), in nanoseconds | `time_flow_rtt` | no +| avoid | `TimeFlowStartMs` | number | Start timestamp of this flow, in milliseconds | n/a | no +| avoid | `TimeReceived` | number | Timestamp when this flow was received and processed by the flow collector, in seconds | n/a | no +| avoid | `_HashId` | string | In conversation tracking, the conversation identifier | `id` | no +| avoid | `_RecordType` | string | Type of record: 'flowLog' for regular flow logs, or 'newConnection', 'heartbeat', 'endConnection' for conversation tracking | `type` | yes +| fine |=== \ No newline at end of file diff --git a/modules/network-observability-health-alerts-overview.adoc b/modules/network-observability-health-alerts-overview.adoc new file mode 100644 index 000000000000..ee06e061fdbe --- /dev/null +++ b/modules/network-observability-health-alerts-overview.adoc @@ -0,0 +1,13 @@ +// Module included in the following assemblies: +// +// * network_observability/network-observability-operator-monitoring.adoc + +:_mod-docs-content-type: CONCEPT +[id="network-observability-health-alert-overview_{context}"] += Health alerts + +A health alert banner that directs you to the dashboard can appear on the *Network Traffic* and *Home* pages if an alert is triggered. Alerts are generated in the following cases: + +* The `NetObservLokiError` alert occurs if the `flowlogs-pipeline` workload is dropping flows because of Loki errors, such as if the Loki ingestion rate limit has been reached. +* The `NetObservNoFlows` alert occurs if no flows are ingested for a certain amount of time. +* The `NetObservFlowsDropped` alert occurs if the Network Observability eBPF agent hashmap table is full, and the eBPF agent processes flows with degraded performance, or when the capacity limiter is triggered. \ No newline at end of file diff --git a/modules/network-observability-health-dashboard-overview.adoc b/modules/network-observability-health-dashboard-overview.adoc new file mode 100644 index 000000000000..78729968d437 --- /dev/null +++ b/modules/network-observability-health-dashboard-overview.adoc @@ -0,0 +1,19 @@ +// Module included in the following assemblies: +// +// * network_observability/network-observability-operator-monitoring.adoc + +:_mod-docs-content-type: CONCEPT +[id="network-observability-health-dashboard-overview_{context}"] += Health dashboards + +Metrics about health and resource usage of the Network Observability Operator are located in the *Observe* -> *Dashboards* page in the web console. You can view metrics about the health of the Operator in the following categories: + +* *Flows per second* +* *Sampling* +* *Errors last minute* +* *Dropped flows per second* +* *Flowlogs-pipeline statistics* +* *Flowlogs-pipleine statistics views* +* *eBPF agent statistics views* +* *Operator statistics* +* *Resource usage* \ No newline at end of file diff --git a/modules/network-observability-metrics.adoc b/modules/network-observability-metrics-names.adoc similarity index 77% rename from modules/network-observability-metrics.adoc rename to modules/network-observability-metrics-names.adoc index 9ecab20728af..c2555fe71632 100644 --- a/modules/network-observability-metrics.adoc +++ b/modules/network-observability-metrics-names.adoc @@ -5,13 +5,11 @@ :_mod-docs-content-type: REFERENCE [id="network-observability-metrics_{context}"] = Network Observability metrics -Metrics generated by the `flowlogs-pipeline` are configurable in the `spec.processor.metrics.includeList` of the `FlowCollector` custom resource to add or remove metrics. - You can also create alerts by using the `includeList` metrics in Prometheus rules, as shown in the example "Creating alerts". -When looking for these metrics in Prometheus, such as in the Console through Observe -> Metrics, or when defining alerts, all the metrics names are prefixed with `netobserv_. For example, `netobserv_namespace_flows_total. Available metrics names are as follows. +When looking for these metrics in Prometheus, such as in the Console through *Observe* -> *Metrics*, or when defining alerts, all the metrics names are prefixed with `netobserv_`. For example, `netobserv_namespace_flows_total`. Available metrics names are as follows: -== includeList metrics names +includeList metrics names:: Names followed by an asterisk `*` are enabled by default. * `namespace_egress_bytes_total` @@ -30,7 +28,7 @@ Names followed by an asterisk `*` are enabled by default. * `workload_ingress_packets_total` * `workload_flows_total` -=== PacketDrop metrics names +PacketDrop metrics names:: When the `PacketDrop` feature is enabled in `spec.agent.ebpf.features` (with `privileged` mode), the following additional metrics are available: * `namespace_drop_bytes_total` @@ -40,14 +38,14 @@ When the `PacketDrop` feature is enabled in `spec.agent.ebpf.features` (with `pr * `workload_drop_bytes_total` * `workload_drop_packets_total` -=== DNS metrics names +DNS metrics names:: When the `DNSTracking` feature is enabled in `spec.agent.ebpf.features`, the following additional metrics are available: * `namespace_dns_latency_seconds` * * `node_dns_latency_seconds` * `workload_dns_latency_seconds` -=== FlowRTT metrics names +FlowRTT metrics names:: When the `FlowRTT` feature is enabled in `spec.agent.ebpf.features`, the following additional metrics are available: * `namespace_rtt_seconds` * diff --git a/modules/network-observability-netobserv-cli-about.adoc b/modules/network-observability-netobserv-cli-about.adoc new file mode 100644 index 000000000000..e0005e75dc9b --- /dev/null +++ b/modules/network-observability-netobserv-cli-about.adoc @@ -0,0 +1,14 @@ +//Module included in the following assemblies: +// +// observability/network_observability/network-observability-cli/netobserv-cli-overview.adoc + +:_mod-docs-content-type: CONCEPT +[id="network-observability-netoberv-cli-about_{context}"] += About the Network Observability CLI + +You can quickly debug and troubleshoot networking issues by using the Network Observability CLI (`oc netobserv`). The Network Observability CLI is a flow and packet visualization tool that relies on eBPF agents to stream collected data to an ephemeral collector pod. It requires no persistent storage during the capture. After the run, the output is transferred to your local machine. This enables quick, live insight into packets and flow data without installing the Network Observability Operator. + +[IMPORTANT] +==== +CLI capture is meant to run only for short durations, such as 8-10 minutes. If it runs for too long, it can be difficult to delete the running process. +==== \ No newline at end of file diff --git a/modules/network-observability-netobserv-cli-cleaning.adoc b/modules/network-observability-netobserv-cli-cleaning.adoc new file mode 100644 index 000000000000..600d0375715c --- /dev/null +++ b/modules/network-observability-netobserv-cli-cleaning.adoc @@ -0,0 +1,19 @@ +// Module included in the following assemblies: + +// * observability/network_observability/netobserv_cli/netobserv-cli-install.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-cli-uninstall_{context}"] += Cleaning the Network Observability CLI + +You can manually clean the CLI workload by running `oc netobserv cleanup`. This command removes all the CLI components from your cluster. + +When you end a capture, this command is run automatically by the client. You might be required to manually run it if you experience connectivity issues. + +.Procedure +* Run the following command: ++ +[source,terminal] +---- +$ oc netobserv cleanup +---- \ No newline at end of file diff --git a/modules/network-observability-netobserv-cli-install.adoc b/modules/network-observability-netobserv-cli-install.adoc new file mode 100644 index 000000000000..f7e720fdf8aa --- /dev/null +++ b/modules/network-observability-netobserv-cli-install.adoc @@ -0,0 +1,54 @@ +// Module included in the following assemblies: + +// * observability/network_observability/netobserv_cli/netobserv-cli-install.adoc + +:_mod-docs-content-type: PROCEDURE +[id="network-observability-cli-install_{context}"] += Installing the Network Observability CLI +Installing the Network Observability CLI (`oc netobserv`) is a separate procedure from the Network Observability Operator installation. This means that, even if you have the Operator installed from OperatorHub, you need to install the CLI separately. + +[NOTE] +==== +You can optionally use Krew to install the `netobserv` CLI plugin. For more information, see "Installing a CLI plugin with Krew". +==== + +.Prerequisites +* You must install the {oc-first}. +* You must have a macOS or Linux operating system. + +.Procedure + +. Download the link:https://mirror.openshift.com/pub/openshift-v4/clients/netobserv/latest/[`oc netobserv` CLI tar file]. +. Unpack the archive: ++ +[source,terminal] +---- +$ tar xvf netobserv-cli.tar.gz +---- +. Make the file executable: ++ +[source,terminal] +---- +$ chmod +x ./build/oc-netobserv +---- +. Move the extracted `netobserv-cli` binary to a directory that is on your `PATH`, such as `/usr/local/bin/`: ++ +[source,terminal] +---- +$ sudo mv ./build/oc-netobserv /usr/local/bin/ +---- + +.Verification + +* Verify that `oc netobserv` is available: ++ +[source,terminal] +---- +$ oc netobserv version +---- ++ +.Example output +[source,terminal] +---- +Netobserv CLI version +---- diff --git a/modules/network-observability-netobserv-cli-reference.adoc b/modules/network-observability-netobserv-cli-reference.adoc new file mode 100644 index 000000000000..abb2d7f606a8 --- /dev/null +++ b/modules/network-observability-netobserv-cli-reference.adoc @@ -0,0 +1,195 @@ +// Module included in the following assemblies: +// * observability/network_observability/netobserv-cli-reference.adoc + +:_mod-docs-content-type: REFERENCE +[id="network-observability-netobserv-cli-reference_{context}"] += oc netobserv CLI reference +The Network Observability CLI (`oc netobserv`) is a CLI tool for capturing flow data and packet data for further analysis. + +.`oc netobserv` syntax +[source,terminal] +---- +$ oc netobserv [] [] [] <1> +---- +<1> Feature options can only be used with the `oc netobserv flows` command. They cannot be used with the `oc netobserv packets` command. + +[cols="3a,8a",options="header"] +.Basic commands +|=== +|Command| Description + +| `flows` +| Capture flows information. For subcommands, see the "Flow capture subcommands" table. + +| `packets` +| Capture packets from a specific protocol or port pair, such as `netobserv packets --filter=tcp,80`. For more information about packet capture, see the "Packet capture subcommand" table. + +| `cleanup` +| Remove the Network Observability CLI components. + +| `version` +| Print the software version. + +| `help` +| Show help. +|=== + +[id="network-observability-cli-enrichment_{context}"] +== Network Observability enrichment +The Network Observability enrichment to display zone, node, owner and resource names including optional features about packet drops, DNS latencies and Round-trip time can only be enabled when capturing flows. These do not appear in packet capture pcap output file. + +.Network Observability enrichment syntax +[source,terminal] +---- +$ oc netobserv flows [] [] +---- + +.Network Observability enrichment options +|=== +|Option| Description| Possible values| Default + +| `--enable_pktdrop` +| Enable packet drop. +| `true`, `false` +| `false` + +| `--enable_rtt` +| Enable round trip time. +| `true`, `false` +| `false` + +| `--enable_dns` +| Enable DNS tracking. +| `true`, `false` +| `false` + +| `--help` +| Show help. +| - +| - + +| `--interfaces` +| Interfaces to match on the flow. For example, `"eth0,eth1"`. +| `""` +| - +|=== + +[id="cli-reference-flow-capture-options_{context}"] +== Flow capture options +Flow capture has mandatory commands as well as additional options, such as enabling extra features about packet drops, DNS latencies, Round-trip time, and filtering. + +.`oc netobserv flows` syntax +[source,terminal] +---- +$ oc netobserv flows [] [] +---- + +.Flow capture filter options +|=== +|Option| Description| Possible values| Mandatory| Default + +| `--enable_filter` +| Enable flow filter. +| `true`, `false` +| Yes +| `false` + +| `--action` +| Action to apply on the flow. +| `Accept`, `Reject` +| Yes +| `Accept` + +| `--cidr` +| CIDR to match on the flow. +| `1.1.1.0/24`, `1::100/64`, or `0.0.0.0/0` +| Yes +| `0.0.0.0/0` + +| `--protocol` +| Protocol to match on the flow +| `TCP`, `UDP`, `SCTP`, `ICMP`, or `ICMPv6` +| No +| - + +| `--direction` +| Direction to match on the flow +| `Ingress`, `Egress` +| No +| - + +| `--dport` +| Destination port to match on the flow. +| `80`, `443`, or `49051` +| no +| - + +| `--sport` +| Source port to match on the flow. +| `80`, `443`, or `49051` +| No +| - + +| `--port` +| Port to match on the flow. +| `80`, `443`, or `49051` +| No +| - + +| `--sport_range` +| Source port range to match on the flow. +| `80-100` or `443-445` +| No +| - + +| `--dport_range` +| Destination port range to match on the flow. +| `80-100` +| No +| - + +| `--port_range` +| Port range to match on the flow. +| `80-100` or `443-445` +| No +| - + +| `--icmp_type` +| ICMP type to match on the flow. +| `8` or `13` +| No +| - + +| `--icmp_code` +| ICMP code to match on the flow. +| `0` or `1` +| No +| - + +| `--peer_ip` +| Peer IP to match on the flow. +| `1.1.1.1` or `1::1` +| No +| - +|=== + +[id="cli-reference-packet-capture-options_{context}"] +== Packet capture options +You can filter on port and protocol for packet capture data. + +.`oc netobserv packets` syntax +[source,terminal] +---- +$ oc netobserv packets [

  • 0j3xjZfNNFUrUtM|}zDBCB8t;d*3XUtk!~Cp# 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 literal 0 HcmV?d00001 diff --git a/images/696_OpenShift_Lifecycle_Agent_0624_3.png b/images/696_OpenShift_Lifecycle_Agent_0624_3.png new file mode 100644 index 0000000000000000000000000000000000000000..52db05e6726ec0c022f39c45ce1f4ebfb29b6ebb GIT binary patch literal 39398 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%0D48X@lWzT=C=-6v1Mt+1c5<*HT*zH~057JdW(= zfXC9WcLF>3>uLcd1qEX>kH!afhKi{e^v(O3jC!agI9wd(3}?-R&Tl3(Je_=+#+(;3k&CS5Br(x1Egw9aLrG%Us7E=296{c zec5W)<&40_skyni!^6rjznXaWx@CMpwe;j{z23`l1xdwSO#7NvSi1SX`7oW(>J5f5 z%<8ySpE*}{P#0gbzMdYEX?su2wCKGX>;A^flse0sk-XI^t^Bj_Q)xAOZ2QXHLjgDQ zf&L+Fd5+M?0`W5@b{ENN4lanvq3gVv*%UcP+?_X%#IE#7n&}{%~ z&=LEOk9pcNB<$d?-e> Wk=VqHW`q|*NQ%lm&l7&}_J0CmU=-AG8MbV%=W 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

    JxKNq&hE>6Hcnt$ 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 label and adds the `labelSelector.matchLabels.lca.openshift.io/backup: ` label selector to the specified resources when creating the `Backup` CRs. + +To use the `lca.openshift.io/apply-label` annotation for backing up specific resources, the resources listed in the annotation must also be included in the `spec` section. +If the `lca.openshift.io/apply-label` annotation is used in the `Backup` CR, only the resources listed in the annotation are backed up, even if other resource types are specified in the `spec` section or not. + +.Example CR +[source,yaml] +---- +apiVersion: velero.io/v1 +kind: Backup +metadata: + name: acm-klusterlet + namespace: openshift-adp + annotations: + lca.openshift.io/apply-label: rbac.authorization.k8s.io/v1/clusterroles/klusterlet,apps/v1/deployments/open-cluster-management-agent/klusterlet <1> + labels: + velero.io/storage-location: default +spec: + includedNamespaces: + - open-cluster-management-agent + includedClusterScopedResources: + - clusterroles + includedNamespaceScopedResources: + - deployments +---- +<1> The value must be a list of comma-separated objects in `group/version/resource/name` format for cluster-scoped resources or `group/version/resource/namespace/name` format for namespace-scoped resources, and it must be attached to the related `Backup` CR. \ No newline at end of file diff --git a/modules/ztp-image-based-upgrade-cluster-validated-software.adoc b/modules/ztp-image-based-upgrade-cluster-validated-software.adoc new file mode 100644 index 000000000000..da6782fb915d --- /dev/null +++ b/modules/ztp-image-based-upgrade-cluster-validated-software.adoc @@ -0,0 +1,56 @@ +// Module included in the following assemblies: +// * edge_computing/image-based-upgrade/cnf-understanding-image-based-upgrade.adoc + +[id="ztp-image-based-upgrade-cluster-validated-software_{context}"] += Minimum software version of components + +Depending on your deployment method, the image-based upgrade requires the following minimum software versions. + +.Minimum software version of components +[cols=3*, width="80%", options="header"] +|==== +|Component +|Software version +|Required + +|{lcao} +|4.16 +|Yes + +|OADP Operator +|1.3.1 +|Yes + +|Managed cluster version +|4.14.13 +|Yes + +|Hub cluster version +|4.16 +|Yes, if using {rh-rhacm} + +|{rh-rhacm} +|2.10.2 +|Yes, if using {rh-rhacm} + +|{ztp} plugin +|4.16 +|Only for {ztp} deployment method + +|{gitops-title} +|1.12 +|Only for {ztp} deployment method + +|{cgu-operator-first} +|4.16 +|Only for {ztp} deployment method + +|Local Storage Operator ^[1]^ +|4.14 +|Yes + +|{lvms-first} ^[1]^ +|4.14.2 +|Yes +|==== +. The persistent storage must be provided by either the {lvms} or the Local Storage Operator, not both. diff --git a/modules/ztp-image-based-upgrade-extra-manifests-guide.adoc b/modules/ztp-image-based-upgrade-extra-manifests-guide.adoc new file mode 100644 index 000000000000..4b65963981b5 --- /dev/null +++ b/modules/ztp-image-based-upgrade-extra-manifests-guide.adoc @@ -0,0 +1,36 @@ +// Module included in the following assemblies: +// * edge_computing/image-based-upgrade/cnf-understanding-image-based-upgrade.adoc + +[id="ztp-image-based-upgrade-extra-manifests-guide_{context}"] += Extra manifest guidelines + +The {lcao} uses extra manifests to restore your target clusters after rebooting with the new default stateroot deployment and before restoring application artifacts. + +Different deployment methods require a different way to apply the extra manifests: + +{ztp}:: You use the `lca.openshift.io/target-ocp-version: ` label to mark the extra manifests that the {lcao} must extract and apply after the pivot. +You can specify the the number of manifests labeled with `lca.openshift.io/target-ocp-version` by using the `lca.openshift.io/target-ocp-version-manifest-count` annotation in the `ImageBasedUpgrade` CR. +If specified, the {lcao} verifies that the number of manifests extracted from policies matches the number provided in the annotation during the prep and upgrade stages. ++ +.Example for the lca.openshift.io/target-ocp-version-manifest-count annotation +[source,yaml] +---- +apiVersion: lca.openshift.io/v1 +kind: ImageBasedUpgrade +metadata: + annotations: + lca.openshift.io/target-ocp-version-manifest-count: "5" + name: upgrade +---- + +Non-Gitops:: You mark your extra manifests with the `lca.openshift.io/apply-wave` annotation to determine the apply order. The labeled extra manifests are wrapped in `ConfigMap` objects and referenced in the `ImageBasedUpgrade` CR that the {lcao} uses after the pivot. + +If the target cluster uses custom catalog sources, you must include them as extra manifests that point to the correct release version. + +[IMPORTANT] +==== +You cannot apply the following items as extra manifests: + +* `MachineConfig` objects +* OLM Operator subscriptions +==== \ No newline at end of file diff --git a/modules/ztp-image-based-upgrade-hub-cluster-guide.adoc b/modules/ztp-image-based-upgrade-hub-cluster-guide.adoc new file mode 100644 index 000000000000..5a2b9447fc1f --- /dev/null +++ b/modules/ztp-image-based-upgrade-hub-cluster-guide.adoc @@ -0,0 +1,10 @@ +// Module included in the following assemblies: +// * edge_computing/image-based-upgrade/cnf-understanding-image-based-upgrade.adoc + +[id="ztp-image-based-upgrade-hub-cluster-guide_{context}"] += Hub cluster guidelines + +If you are using {rh-rhacm-first}, your hub cluster needs to meet the following conditions: + +* To avoid including any {rh-rhacm} resources in your seed image, you need to disable all optional {rh-rhacm} add-ons before generating the seed image. +* Your hub cluster must be upgraded at least to the target version before performing an image-based upgrade a target {sno} cluster. \ No newline at end of file diff --git a/modules/ztp-image-based-upgrade-seed-image-guide.adoc b/modules/ztp-image-based-upgrade-seed-image-guide.adoc new file mode 100644 index 000000000000..71c6131744c1 --- /dev/null +++ b/modules/ztp-image-based-upgrade-seed-image-guide.adoc @@ -0,0 +1,30 @@ +// Module included in the following assemblies: +// * edge_computing/image-based-upgrade/cnf-understanding-image-based-upgrade.adoc + +[id="ztp-image-based-upgrade-seed-image-guide_{context}"] += Seed image guidelines + +The seed image targets a set of {sno} clusters with similar configuration. +This means that the seed cluster needs to have the same configuration as the target clusters for the following items: + +* Performance profile +* `MachineConfig` resources for the target cluster +* IP version ++ +[NOTE] +==== +Dual-stack networking is not supported in this release. +==== + +* Set of Day 2 Operators, including the {lcao} and the OADP Operator +* Disconnected registry +* FIPS configuration +* If the target cluster has multiple IPs and one of them belongs to the subnet that was used for creating the seed image, the upgrade fails if the target cluster's node IP does not belong to that subnet. + +The following configurations only have to partially match on the participating clusters: + +* If the target cluster has a proxy configuration, the seed cluster must have a proxy configuration too but the configuration does not have to be the same. +* A dedicated partition on the primary disk for container storage is required on all participating clusters. However, the size and start of the partition does not have to be the same. Only the `spec.config.storage.disks.partitions.label: varlibcontainers` label in the `MachineConfig` CR must match on both the seed and target clusters. +For more information about how to create the disk partition, see "Configuring a shared container directory between ostree stateroots" or "Configuring a shared container directory between ostree stateroots when using GitOps ZTP". + +For more information about what to include in the seed image, see "Seed image configuration" and "Seed image configuration using the RAN DU profile". \ No newline at end of file From b63934f961afce5f74f4588fbcb6a219d52eaba9 Mon Sep 17 00:00:00 2001 From: srir Date: Fri, 14 Jun 2024 13:26:03 +0530 Subject: [PATCH 194/339] TELCODOCS#1908: Adding xrefs for additional info on Encrypted devices --- .../persistent-storage-using-lvms.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc index e14c3e3f826d..f9c08fd1beb9 100644 --- a/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc +++ b/storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc @@ -71,6 +71,10 @@ include::modules/lvms-about-adding-devices-to-a-vg.adoc[leveloffset=+2] * xref:../../../installing/install_config/installing-customizing.adoc#installation-special-config-raid_installing-customizing[Configuring a RAID-enabled data volume] +* xref:../../../installing/install_config/installing-customizing.adoc#installation-special-config-encrypt-disk_installing-customizing[About disk encryption] + +* xref:../../../installing/install_config/installing-customizing.adoc#installation-special-config-storage-procedure_installing-customizing[Configuring disk encryption and mirroring] + * xref:../../../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#lvms-unsupported-devices_logical-volume-manager-storage[Devices not supported by {lvms}] // Devices not supported by LVMS From 245ecfbb5f89af868300e3f6e582c8107eb47dda Mon Sep 17 00:00:00 2001 From: GroceryBoyJr Date: Fri, 14 Jun 2024 15:51:30 -0400 Subject: [PATCH 195/339] CMP-2582: Update CO install documentation to include ROSA support --- modules/compliance-operator-hcp-install.adoc | 2 +- ...compliance-operator-rosa-installation.adoc | 106 ++++++++++++++++++ .../compliance-operator-installation.adoc | 4 +- 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 modules/compliance-operator-rosa-installation.adoc diff --git a/modules/compliance-operator-hcp-install.adoc b/modules/compliance-operator-hcp-install.adoc index d45b440248a0..a04177485ef5 100644 --- a/modules/compliance-operator-hcp-install.adoc +++ b/modules/compliance-operator-hcp-install.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="installing-compliance-operator-hcp_{context}"] -= Installing the Compliance Operator on {hcp} += Installing the Compliance Operator on Hypershift {hcp} The Compliance Operator can be installed in {hcp} using the OperatorHub by creating a `Subscription` file. diff --git a/modules/compliance-operator-rosa-installation.adoc b/modules/compliance-operator-rosa-installation.adoc new file mode 100644 index 000000000000..f4c289cc6251 --- /dev/null +++ b/modules/compliance-operator-rosa-installation.adoc @@ -0,0 +1,106 @@ +// Module included in the following assemblies: +// +// * security/compliance_operator/co-management/compliance-operator-installation.adoc + +:_mod-docs-content-type: PROCEDURE +[id="installing-compliance-operator-rosa_{context}"] += Installing the Compliance Operator on ROSA hosted control planes (HCP) + +As of the Compliance Operator 1.5.0 release, the Operator is tested against {product-rosa} using {hcp-capital}. + +{product-rosa} {hcp-capital} clusters have restricted access to the control plane, which is managed by Red{nbsp}Hat. By default, the Compliance Operator will schedule to nodes within the `master` node pool, which is not available in {product-rosa} {hcp-capital} installations. This requires you to configure the `Subscription` object in a way that allows the Operator to schedule on available node pools. This step is necessary for a successful installation on {product-rosa} {hcp-capital} clusters. + +.Prerequisites + +* You must have `admin` privileges. + +.Procedure + +. Define a `Namespace` object: ++ +.Example `namespace-object.yaml` file +[source,yaml] +---- +apiVersion: v1 +kind: Namespace +metadata: + labels: + openshift.io/cluster-monitoring: "true" + pod-security.kubernetes.io/enforce: privileged <1> + name: openshift-compliance +---- +<1> In {product-title} {product-version}, the pod security label must be set to `privileged` at the namespace level. + +. Create the `Namespace` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f namespace-object.yaml +---- + +. Define an `OperatorGroup` object: ++ +.Example `operator-group-object.yaml` file +[source,yaml] +---- +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: compliance-operator + namespace: openshift-compliance +spec: + targetNamespaces: + - openshift-compliance +---- + +. Create the `OperatorGroup` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f operator-group-object.yaml +---- + +. Define a `Subscription` object: ++ +.Example `subscription-object.yaml` file +[source,yaml] +---- +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: compliance-operator-sub + namespace: openshift-compliance +spec: + channel: "stable" + installPlanApproval: Automatic + name: compliance-operator + source: redhat-operators + sourceNamespace: openshift-marketplace + config: + nodeSelector: + node-role.kubernetes.io/worker: "" <1> +---- +<1> Update the Operator deployment to deploy on `worker` nodes. + +. Create the `Subscription` object by running the following command: ++ +[source,terminal] +---- +$ oc create -f subscription-object.yaml +---- + +.Verification + +. Verify that the installation succeeded by running the following command to inspect the cluster service version (CSV) file: ++ +[source,terminal] +---- +$ oc get csv -n openshift-compliance +---- + +. Verify that the Compliance Operator is up and running by using the following command: ++ +[source,terminal] +---- +$ oc get deploy -n openshift-compliance +---- diff --git a/security/compliance_operator/co-management/compliance-operator-installation.adoc b/security/compliance_operator/co-management/compliance-operator-installation.adoc index 97c53b9e46ee..f3bb95957219 100644 --- a/security/compliance_operator/co-management/compliance-operator-installation.adoc +++ b/security/compliance_operator/co-management/compliance-operator-installation.adoc @@ -10,7 +10,7 @@ Before you can use the Compliance Operator, you must ensure it is deployed in th [IMPORTANT] ==== -The Compliance Operator might report incorrect results on managed platforms, such as OpenShift Dedicated, Red Hat OpenShift Service on AWS, and Microsoft Azure Red Hat OpenShift. For more information, see the link:https://access.redhat.com/solutions/6983418[Red Hat Knowledgebase Solution #6983418]. +The Compliance Operator might report incorrect results on managed platforms, such as OpenShift Dedicated, Red{nbsp}Hat OpenShift Service on AWS Classic, and Microsoft Azure Red{nbsp}Hat OpenShift. For more information, see the Knowledgebase article link:https://access.redhat.com/solutions/6983418[Compliance Operator reports incorrect results on Managed Services]. ==== include::modules/compliance-operator-console-installation.adoc[leveloffset=+1] @@ -24,6 +24,8 @@ You can create a custom SCC for the Compliance Operator scanner pod service acco include::modules/compliance-operator-cli-installation.adoc[leveloffset=+1] +include::modules/compliance-operator-rosa-installation.adoc[leveloffset=+1] + [IMPORTANT] ==== If the `restricted` Security Context Constraints (SCC) have been modified to contain the `system:authenticated` group or has added `requiredDropCapabilities`, the Compliance Operator may not function properly due to permissions issues. From 15dffdc2020597eac765fc7bd6a9b977a3871e49 Mon Sep 17 00:00:00 2001 From: Talia Shwartzberg Date: Sun, 16 Jun 2024 10:27:02 +0300 Subject: [PATCH 196/339] HCIDOCS-128-revert: vCPU mismatch request not relevant to OCP --- modules/lvms-about-lvm-storage-installation.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/lvms-about-lvm-storage-installation.adoc b/modules/lvms-about-lvm-storage-installation.adoc index 1c01f3fb3ec3..708badfd21f6 100644 --- a/modules/lvms-about-lvm-storage-installation.adoc +++ b/modules/lvms-about-lvm-storage-installation.adoc @@ -22,8 +22,6 @@ The prerequisites to install {lvms} are as follows: * Ensure that you have a minimum of 10 milliCPU and 100 MiB of RAM. -* Ensure that you have a minimum of 9 vCPU cores. - * Ensure that every managed cluster has dedicated disks that are used to provision storage. {lvms} uses only those disks that are empty and do not contain file system signatures. To ensure that the disks are empty and do not contain file system signatures, wipe the disks before using them. * Before installing {lvms} in a private CI environment where you can reuse the storage devices that you configured in the previous {lvms} installation, ensure that you have wiped the disks that are not in use. If you do not wipe the disks before installing {lvms}, you cannot reuse the disks without manual intervention. From 4f8c20793a780580c0b5070088354a747495b26c Mon Sep 17 00:00:00 2001 From: dfitzmau Date: Thu, 13 Jun 2024 15:17:53 +0100 Subject: [PATCH 197/339] OCPBUGS-35361: Updated the wait-ip note for bm only --- ...stall-modifying-install-config-for-dual-stack-network.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ipi-install-modifying-install-config-for-dual-stack-network.adoc b/modules/ipi-install-modifying-install-config-for-dual-stack-network.adoc index 4c7dd83fb007..4d5326a44d0b 100644 --- a/modules/ipi-install-modifying-install-config-for-dual-stack-network.adoc +++ b/modules/ipi-install-modifying-install-config-for-dual-stack-network.adoc @@ -28,9 +28,10 @@ serviceNetwork: - fd03::/112 ---- +ifndef::vsphere[] [IMPORTANT] ==== -If you specified an NMState configuration in the `networkConfig` section of your `install-config.yaml` file, ensure you add `interfaces.wait-ip: ipv4+ipv6` to the NMState YAML file to resolve an issue that prevents your cluster from deploying on a dual-stack network. +On a bare-metal platform, if you specified an NMState configuration in the `networkConfig` section of your `install-config.yaml` file, add `interfaces.wait-ip: ipv4+ipv6` to the NMState YAML file to resolve an issue that prevents your cluster from deploying on a dual-stack network. .Example NMState YAML configuration file that includes the `wait-ip` parameter [source,yaml] @@ -44,6 +45,7 @@ networkConfig: # ... ---- ==== +endif::vsphere[] To provide an interface to the cluster for applications that use IPv4 and IPv6 addresses, configure IPv4 and IPv6 virtual IP (VIP) address endpoints for the Ingress VIP and API VIP services. To configure IPv4 and IPv6 address endpoints, edit the `apiVIPs` and `ingressVIPs` configuration settings in the `install-config.yaml` file . The `apiVIPs` and `ingressVIPs` configuration settings use a list format. The order of the list indicates the primary and secondary VIP address for each service. From 3d8c41892d4917904fdfb411501316bb2173a8db Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Thu, 6 Jun 2024 11:43:59 +0100 Subject: [PATCH 198/339] TELCODOCS-1683-image adding images --- images/693_OpenShift_QinQ_SR-IOV_CNI_0624.png | Bin 0 -> 99653 bytes modules/nw-sriov-about-qinq.adoc | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 images/693_OpenShift_QinQ_SR-IOV_CNI_0624.png diff --git a/images/693_OpenShift_QinQ_SR-IOV_CNI_0624.png b/images/693_OpenShift_QinQ_SR-IOV_CNI_0624.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd62b6f38870725a6394f047526f4ad80260ee4 GIT binary patch literal 99653 zcmeFZbySt>*Dfq7A>Ae2jdX)F0@9tb014@Clx{&JM5I#$L_m;~Sb_=&2!cpSNGJ`` zc;<5N-}|0FzW4k4oG}h#j{&mRde-yY_q^x4u4`VCcpWWOJZx(0OP4O;-BMH1yL1VC z`_iQ=d03a>H$8r3H{ctUkFtr6zWZGte;Y6ROY(N^2z!QGt~L(#diFMUfu8T}rQsbM zP6j4ECbu;uZQWh@Y*4S^3vl&-cVD_BEf?TnV|&luhXG;l;N&L5wAI?l#NcEn!(=RS z`^Ie#MSDjlwIDBh{U9v^+n{^45_U{-vJBDzl5hc6dmkHy09O|`Z^-}|roY#fgr8Br z=4WE~`x2jfGED#6l*w%!21R!-dj<(U0bbi1Hv}2PB>3zQHbQnbLI@Ea2EiMGLi_@P z`~o7p0yiXu1to>V82DOM{r&m;h4|dP9QXw! zBqaE62=WUG^1>^4y#w8RYyx=QyqW)V1toiLTQ4UMA18M=2GkX85bnM{GE8u@|2&1O z$A4Yc&HLY#f;Hn0u<_s*;Jbl(s{g$3_U-@wm%6(C*Q>pK^z8rpe*Zr&>}?R}Vb8B; z@9pmEWeaVB*hdZ1Vx1u6$BKNL<9tsRV2ieMdXDPg#`ta zL=*+YMgH?%C3jn2S9>>~|Gd}kzu&9)KfV_g5Uw8Z$x8NKPJZ@wDqilc41b?m(&>M` z7m5GzdjG!H?ti`)`Ty~~{BSe;sJ;E)_WD1+f&fDO_+P;b|M;))w|9e>_k!Tw3UUd& zg!Z8RmXf?dz|^l9e+vWE0?|9ErH5scI=!=Gzo=X5lz+W@R8jZN?H77*@=PzE5sP24 zh^UhC3l72;_apABZ;gHr-WtmCKHR*_#P%+EYY($?`PZ)o?@S?~fhQvagM;G?O#glz z=q4H7RQl(u#7ewC@jpM`{eM5BmZIeUt;64l_&<9c>^wa^U!XHF6-h7u_>q&H-ESvo zgiaLt`c-{>`lCnNhY5!A`^qC@W5OaLNNpn|g+^vx-jEp_f)6B;YLK*FU^1Ny{Lw4C z^$Cr(i2rsS0=bP`xj&Sp`R=p!-zfMpS;D?Rk>7FCLNPY(pD(pRkDLGZ{oHSY{&zq3 z^9zfMi>s@jWn^UJS?~=C z3NkXvbf)Cx<&}|<*^y*sW)>3KtLN3abLY;@oA*;vw0?f6-s4G(2@z)JK%Zn@E;$x?Rh6cBYi0@K=nyjp>Oz`htW0m?|US4^O2mAXe zbTX262PoV8{QdbYTZA!v{`V&+t*$;lJKkefO^LI{!^4}XwXPL5DXyyexxU`wJ}0|V zRbB16HQO%NgGSr`{{5|6w}=9V1_uZEvjaxe6=h%Pzo48TV`XaWm9zT0eAYG7(-u#D zh5z{&4EMsWou{UK$LUN&rf+cYwq#LtwdGrr_nlfA8dW;9j46wRX*r9yw0|@1=#3jU z`iF*69zL9_v+c_fxmR*c99A~?a5MDuw<`o*Lt~>M`;YnNl#~?Vq(@JmCf zsw3p zW-_ZJ5msSo`1txhq>*^#`|}GX0UZZjt$z7X4Bqwi@hbMRCWgtM6SWk476E5Ro=zJ! zLPGU$>soozUq5_M_mq67$(ERuWYHE-7aNN?nvrsyii+`y_sYBetv#N1Kw++rI`3M;%?L8 zc4UDZ43}hUB+KLDD(?In3Ppbc&-!L(FTS~Vo-b!v|K6OD3fP{1W&bfIHg;>W?#dQE z<&A=%gLSOE@DpM|subyf?E-^JJrUH;jyo>hBKfg=le!iA_vSqT*$XSX!)L}=sJFC8XYT3VWki3#ggzv}vWq1kHd&M^4+JlW77SQFQ8 zuaSLy?o$od&>(WzG_$uiXIk-TC52rkZ-|H-{1|-NgnsZ`fWJ7x>{BlRl|ak za~ttUNd;e=9YcadeQOUs+~$j@Hm!fx*N3^K^-R+D>}UtpXk=t0PJ)BO5z>k}_Xq>V zl`D~Ow~Rsu>*GE5AnnS@bwZHEL`Bg^c-cXOqGH31z{r`nvU=x||l^PgHHH~RT=m0=Zxsa)H|M$_EI*`Btsv2oiw zA{t}Mba8g}zPE1+R3FljaTySHQd3hy#Ol1r-a9$C_e7JNnmXv$q`=u!p<*nYQs$75 zkhYGF3&{Io?z2hT&mU6T+u4arO1^gbjPbzR+q?eND{4`f$+kf6w&+i6EG(<*>!`(& z3!_nmKo)VIl~#&t@(AfqWrWIGJ~}%3;W1~u;|P4Y$u0Z`R{yb9QF#|f#0-(P4;kcpPweUG>C-1qzN_Wws{uA? zY;3HxZ1p?dwXZYrf|dW6!Oc#GByL48=B=(ewvEF@@s3#-Lb$lOHKZvsR(`KQaz5&h z#-VVVZF`cN>tbg&R;Y-%V?w?_8XprAqoS<*UF~pl#@owFsR0UU!c)C#9UUD^wh#f= zu3cNW1LZvIo5quzob|OeR#w*dUk~EY=#SUR^GihT`}p|e$%Us-Xy-}GYfZg&z31R? zxV!vutK)QNYN|!^i69xbQEwLn3MD0Ffv8!No8`?*o4(3Q%5TyBDRn1*N^VJhd+kb6 zH4wKZ@!Z_!Ucagp#Am~uu84sFO*o*CFzX#YF=066bGE5LHSzX%@!|z(7Wa@hhpJ*n zoxh36!I4z8}PF~&we!AWN>r&d%~ z{{RPzG`5J)CWFiH7bF4|b8~Ysu_nmhjG7)E9tH-ayWw!Q;IwW+f-B`Pf9=wRR#FIn zL}7v1_@8*~>}8>?%kxD0?A^O7tdYq>#Jx4$89w*<^B%+p;tdreH+NOQ&H@GoM!?3# zMs;;HZ#!%H`^TdASw)sjZZkcx1Ro!Bdc%4C25F=%a1ZtxRy<+E%-lTD@%-$Jw0L}U zRB!5a8-T7ODhPNYBF5;ku`$w5H_2k+(2hO*{Z+%<`U_u9)L6E{2mRjorkncs@nbl@ z&CSgg%^qDnJw1bi8?9R%B%iYY_arEkmX(py+^3);3g!5>$c_9VPWS0J|83s(?vu3f zr;$|c(rb9Aq7D4}iJ-kYtPc+l&vWD2*~WXuP613pLZ4@6J5-XX1KRz!tir>?;V>yG zD(dThe);kxJV>HEmGUUF)=Z1<&ynKT($do8d)(0@xoK>>j% zLbx39SVcue#cfn1B_$E+sj6a9acH`#30y@-KZo?upOle7=4IFx;0gCbs>HL;>^GzE z4$jr${QNMab2tPL{y6lc+PRF#2vq6*@25&jOA`p#z7rfAd^X^IrR>EE9@q_7NLF_C zt#3{Ie0*Bw=28p{cOdRZ_e>GvOKYFY?>RfiL`NU2eO}434to=JegfOS-D2M4R<50I z^sJoONCZG*XW$;&f+pxH{+qcADF#etb>I9UVjvelKDqDM)aqTq?mOfRz;dRy0r)VV`mI$>It%viKlp4-O6G3D~}SVOqaA*SWR0SRc6e19q~Q zp#qciJKPipeo?#MhFL&BfSOuA1QxPI!SK0(JSR53&bGd-l2YITwd6lwldn!mz^X0y zP>b3~Od>xWG`FO;o&ja|F~FpIPEK`najW$i>FLESjr!jq z2mPwHfGjQP_sj9l9R}WOF8A(nZ*ZpE0nGX-U#_X4;cUIC78Rs152hOLIk>pc(9=JZ zo>v2~zcTQIgo?_^*7oyj*KY}A+zSj$PE!p|iR8S!tJf}SroMhXSRJul{*bZpt;zU< zbaxiFG5#$U78a=fY;0_qe3sOVX)`m9Ans(pmx?p|$DcR3%AfB-6IpZSj;KjOAWidA7jAzLXA zk!5kH;F6P*YiVg=vE{8Oq^0E(F{?00aC39p6+jHD;ZrHjmz1#FzCFlg_&kYL%5QV} zjdaXf`1RwITvZ9Cc!fD+BXq=hdT`bO1 zR9+st*zfG+^$L5ZoW8acnHUTloT9IdntAvTzHJiRLWX}Y(PEu z`0%M-zJ9F|z_|+*^+cyRVcSs83_Z7l<1di?Kmo{Xb?XNp>gvr3g0y%TyA9hsq5J;DK zzwRTKHwr4JO|d*7vN&<_InN%K)4X|j4QP}a&G4}{(Vv}wtvhnvaqPS}dt3N_X%!RG z$+U;xmzA3BdlqXyf0mb&w1u7;v1K_>0>xES?8(i|C6!RB0U}yz@iQFHc0|?6>F@bg z+OIvOaaaY>!bvU-UiD|7r_{_#ugO$XY_Q&O%4?y~#Cx;-nX8OUJJ1I}vali@o{R6i ze+&qSi5chWaAn#+(wyB{>^na{C#tSkhwRb>2&Hp*b?lizdUGl<2?-KA@NA0Pig?tb z8eUrG^%u#;jUgR`3nGVDTC!G604)IX2If{+1u}ryE4y28-^j-Oar_U_qX3sxm6YN{ z_8J=+KtObLaj_GmQcoDY#Vi%TEiAkbSmua|knsLCoSs*&UmHy`-;4(}z{6uZSHgR? zEiiJTrlv+kMdf1_zbb_#cBG^a@SN8!rt0e0#AGu^OG`_ssi{WQW}F9mNE-UK{>SiM0VjB1!~Zw*xE&_p;iXFe48Bh!hI?>sZtneir{Mzmz|FOPh0J`* z{6nGlv6D*M`>+sN&w?(_0$p5QP!0=-ib8%20bt$&i5J8MSc%FBmuD#LV|^V`@Zsu6 zF)S`%@X`AzKuCcqJQa2th4cWaJ@FZ>$PzPuUka`HE4%my59IIOz5B*%8K?_(ULkY( z`-sR$D9g7sHMhBCkLJ6s2z*zVir9gx#*uVVL!Rkh!7PkH=13*z#^YUvCE43u*08po z1GdZ@>?~OZatv%JRV5qHms#_4>tQi#w#0;l9O=MaAi5w6cs9=KE&VGaFg31y3B`W` zAZYjZZ>!fXPqMO%{rp5*vKB^4rl+T2IfsXJ2nYx$D6-;7*nj_=AduO6XpwV~E`LZl z^P}rW!%2X@LJZ-RueMxyTXAi6OQduwlDcA=FuO z^KXw>HDD8&q$O7%=Z;QHXaj0POWg!1W4nrSP(GlI1H_t;5b16WTRSx|NR?k+m>wOU z9Q=e@44$6xj)Rp{7sMW6#4(o|P>o^3k@vQ&bZs8d>5 zS^1D&j+~o>@eQ!nKf53K0UxQ~x+PCnQtqPj9rTdd*;%M5{q==~-?QrN1pm3=H0t9l zOdni4yqTGq^4m`{)6yPHQ12p5KaY+!G&E>JEGQ(2JKnnoGSfme-gVLW2~PboHE-<; zJ_Jq)6E4|zeZ*+;C}!Gscw&GIx3#sk+0x_3pFwFfZt-!tni3z60&SX_N;ldP^FvSe z>t4Us($?m`!*nam32ps3NFB-7#XwEsx9*U3*32=Ad{{uO+q3Y1n#LV!4wNI<+x>$B z?nTK@h$Ej9Iyo!w(@F{jazt)zU(35I9F!VIhrXcn3mZpL%4b+ZE-irv!DJ4;yLz+Cq{Z)3hKT$QL`~x zigQxBkX8j4Z(#yXmMjP$G7dhRBTuGZ*(aL3B}3TSmTNwV7!nG4v+5o8=ll?aP-*|o zX=EZrPj~n5RyDw9U=H`byoj%PHOhjsA4SvyLMyvl5);3*`n!iY75-8`xN+z0eUL1Gi;GK1VPaw?KCAD=y1YBT zxe2+^Utnl=@u6JU`N0H}otj!4hSIAZBH3IA_;r+wT&Mq!Gz?0?;84m7XzTDjGtQGDRD8qfdy}2^M z-)SC)ke=(#D7(2IymPIP5x0jet#L6VA`W_sHjPojHvxkkpqDJ(2Z?$23$ zcJt%EVt|Z6K{nQ1N5{Bz1ubA?~80-{|SL?V{~DmJeh z)mS*Wxzz}_7&LsmMV-WL$IEHC!tt?GBMZ`Od^*CxVFHMU*YXFlm)Kt4J8Az#0qA(E z1r!Nx+n_R(uqO@M=1K>?N>3*V`Z3y%6I2i9O1Uo>w93`h1^v}4b3jP@`pR{SRS@d^ z@To{Gnbi*fvne_OKdPTnSwcde>j+)-C7_iw7%)#esfv$}hmDu;`$fr=mT99R_oq7= z2Q*C!U<8lIXPow36crR|tlGIUCjgcrK-_~w2nt>NS)zkoTYG!0#hX`v%>in1_&z6+ zXgNFzfFJ`!7#T&Ib_`Xl)~r$8cRlv%4ztrz{r!eiZ)DI-W#CAf(ksy|3hp%LAp*!- zkI|pVtF@{0)5!#>G3xpW+)_25RlvZ+EH2Sg8|SUtHidRNDK^@6(Dr;+kz0FP8w6?W zWNO{;@Gw9O6wgA7h=>4A+%Av+7m2M->Y zK^eKF0*9*0P{0rLCkXeDcpS~TsWdkbUbXUNlP~F+E&SrJFX+$uj5+?u=e)p6r-g)F zi=l~02-Za^>?|N(Hndl`Mq1Sy`_INd4c8*=E$eTkl;;C0pYn^Xc`S-(UH^}^|jm%DVoEBOvsK!Ma2~9ZYpv9^WJ@iry<>chfl%k6nlBq=i z3#yPYX2-_%^`|k@%Y`MaBWn?dJ|R~-nU-J!!jHbkf|Psfq35k~#aw?71z{_dxZjy# zPrkgyE(|1d<+5ovCQ-9OG&Xd5D$Set_!N5CRO~=!fa;oR@j5qP3ahc*XKfVfpt^Q4 zr%~&ZC#D7lV?g$hRH|C3$!B!;xVo1OqRhI@n~yx7Eov~4yQ86@aYK- zAn6pZ90RQ%8#8bsdII4t3_RDY(OHd@b_xnU$p1t$ccWCbXQ4EL09k9@*#SDkNzLj& zu~a(%PwVh=Ltis&gi1DCYZCHHWBEO9(*O?X(AVOOS z?9Yc8JA)3MuTrAU!!jz}gZe^5NA#TURPU(4pz3lZ!wU3|)X;aN!_LG3=Hb$Pot&Kf z_AL>!a+{i-f>GD~$&)8ooJQmF_d(Lj;?!5ct`y#8p<`8i2PhVqpcY``;6Oo5&86be z8?SN(Di(-k%tZ%#dnC3ranEn1vmqRrd3apjB~jJY)ghEH$P59?h9uTvtKjtyj zb9sC*+jti{JVCA@lMrJuQz8`6r;$<9Ak_%}h;iXWu9U8oo*lE3MA+Jfee7@*D61=%(D{ zCrvBxPMJXDMVkaVK)P6EXU3q(m-6ScnxBArQYbZ3Ab+KFpx^ElIu1E5owSMcr(F=+ z3)%Ve3>3uZ){2_=={R#Feb-Ucs6CjScbzBsHShrp%Y8U{%t$Dfl2THOmZbs_3S}AA zrG;alvk?>6_-@TwN(V>p7KMqrO~*x2@4nGRkXc2Ma(`rCL3|kP@AEj-WGOFz48<4MFkaPTLOZIutokGQ-%Tr6^6NA^-9$l z?I4vBJ~eqqX`10|jvfC2s>(669f+{qadoMTukVnWO-SomzV+qdvw!66hZgi1$?PTYZ-+!Jt>u&!!&hWcG zv=>;kzrPRi{zEFEGLW%Xlf_)8d;s+Lu8$Gj+bk*%f>5le;Mh;zntnq9iqr+KWIL-y zCXJ{IrPaKei;D{=f|5R~_bYlAwMOeL6C~gWtWCcW+D%VQy-z3A@@17Vk%#f6Fy|H8 znFm)eTbi5WSabFD^k(13-;PL?JQ-Mh05TSkt$RQM5g*r!N;Bwv`jv|k8e_XVP7_Uj z8AXvkrQ!^e7824IC~-bJa#?(rth^M!%Qhbn7#P3tq}N-r;<%uo04Q*A3?RPV%ylSn zpi_|)(?L6ptiB>O2xvGtkIDV?2xhksn)O67I)SiZe7}hf~vQwQK9gQrxmG1GX z7wd6tEkAbA{>w*`5@GN_K$(COs&c)4{aPG}E_Z5_t)G-jQJA?+USs9?EK%g?-GOWY z&xKwHnD5`d&(Gh0`U(e_qR1PaM?hk{?rc-O|!h2`4)bp{J*>YxUFA#62lp9hQa6S;G3GFo|By>ch2^-oCy> zE1A)Q!^2NPj4X_0IQDn%LNpgtaK=6$k;=JUsi}m$cK{)Z4N?83mPx`qGWsu4>tZS00Q6S$!>r4If^ln?`#q58I|9LrvPcN|$ zM6p7r*$eZt1!N*%8z?v20s^{q-#`=#figqWLK{NsS<&X`zOsJIcsQ(m6*Jxn?xrhp#i>=c$8*dM~nwbHi*eJ&}>|-_xQom8 zJLJ{75WX82c(G05Axr$qxWTNuk(c(Cx_b9lc|5hRUmok<-c;e(#Fp zDz}-5$^PodmG)2py~vAo=#q~_11v3=ELGb#fXKW%lpEhs5iop(f2zs-VV+%3P>b^% z-HgVSD_3?dC7RG59_=h5#4#*=G&D5!*VBYg)|tX~yg`n^qZTH_;Z0=3I8zEI+hV$5 zrFQx(oX{r^dIX96rw2d90D%MVU?2e0(qCditd_K>M(a|^e9o_z(^v@YH!f2!z4R|1 zr-3zN^IMblSYA_;m~3>tJ`h#_IK>DkEd0OUDyX%+r6LWsE#%S($@R?5%Fd?Tx$(HQ z^%SJ~UP-Bnn*z(Kn%9UlTA?Zw#;4;XOM^KDOkL?A1Ts7(=?U4&LDZgCr^9Zo>PIhuphxMgQ823S|}JZE#}vdUz1(8~6TD1SH(DUh&_KVaAK0dv03p$cLnFKBp+rO9#BP>A_(6 z{^Q4&CU-d3zT8A@(xQtz_6>G1YHFD$fyru+i4 zT!M}*WDJGSgb}nl4}NC?hcD3Ahad;>4MFcySpt|;+!Ueoc61aR5t)du%m!0{J|}>E zH-IPv$O61HN58%b)!C3ERwwIh)3Wds8YilZ35*|SKZ+bED1j=yx4*B1mKNyky+_V# z7AKUF3qFXe zTmX1CK!xYT{~R|$6QwHV1qlw~Hk2(p9fFNJe*BL%#SeXC^N3j91(hlF8Tqq z1l+(F|a@UTK<2D}OdX2lkp4o9-b%(0Fbi=bTIaklD(UrHp*%8W#Rq= zCOy5d<1oNCSg77S9T25JVRDHlW>r|~rP920%hSgPI)=;(q!WrnEbQ!u&{u^ZmGb)q zdUW?!ZFP0=y11v1jDuBwVb(=7yiFvHK8>^u1H&Y$>vyB0%Oh1l|X2EE1y1^*N3_m z3{6sScr2*i?Jb*-mzPHf+@T>Vmgs+!kueShV~0ff6uMD58ls}2&=JPM!XhMbP5spO zke>NlMIE?iubMMm3Mz*-19%H2KwI==>HH&CfN~m409J|j)!z2>@dRfs7!ZtV ztO z0yg>5?mhAT89XKb@A2;P-X8viH8Ld*Q4KH1!k(VGxo5lbPPY`vusCUrXAZ8hKAIhL z_ls9^1YZW6L^aUV4VlB1j6iQ!4#%eCkmoFMVP|2P{Q5P6*WBpW$rzBhHo|D6IYcRs zWlIAB-xFH!o8q)6bW5=yAe@V%%aPj!p$>KZ8?gHuh9znulwRP2dQ(Mn*V|Yb>C5=3$YucHfE{|FzqUnYK28w53#D6!M>VMubtF&Ndr zEtlBdzD+Gbq=A*#1WLH_tfc?uiy-2(VX?UoeV}HbLAA8Dg6tdT0>qQrFiI#6m$WQ_ zbeRHoh13)kOd#R*YAtb0d@k4a#2c%zyuJnIu`-Zj!N;ql1&5!IpnHDz9`qC+(#a5F zL=#tCCeztK=YaiD;JtMv5CVXYj}J0fd&sd@K!A9MK8FJM9Klg@0G72SC6PV){r?jD zwD&-q&DStmy1we@9DXph+50ZDaj@H{EQdH1ZE}#4P?3PN(UsS(% z(K}FlCR_Aa0Lg+Kpm7kz_rz@#V-4n!GjznL2{y;e>`b7SZEpv5`;r@^lSTa{_{@Rv6W_y-B_}Mif_2kJ8P$) zP-ZLoWPR7qO-Zjzh3{U(s)losqhr6YNaE8E4HxS;pD9-5cKgY+Sx}v}&?jDAB6_3V zUJ?b0`>b7JR;}4T{)FsE31G$^Z(%SsH3fX!W`=E~nNH#p*TM5$WTXyG2dHNm-7KuE=VyDLuuQ=r z3nDY;CnM6JBY-SHI}6e6?dOj<^`WyJSYxQ&3wUn}M5*uH=myQ8FvvYCYEA%84JICS z)JK)I8E_0*P&PAo9^ayP2R=}6B|5pdNQ0FL4oT_5UL+ElgHtmz=Kv@j4HubSShl`S zPuB+-Bp?jN4(hYy#%FOdeCFbWVbM0YO1-VDy6K#MiHHK!c_? z7zMu@xU}h|{BR{Gu1NO3HMS0ozODnDQnqQY`=7-xgEoO?uDAdX4{qo$C>2iqeU7l) zt)ZuWfMJDSqlA|j1u$QB`2I9%2nH)LkxByE#%su&qL5{`roMfnVAB;2#ix^|1k1&j zjM4i;VBn7VO*N~af9u01c#bBQuYx|SIt`O>J065`L_a`DfHnfO=xTI}W1P8Ac5`SD z>FJHaUQ6Ue>L;~;b@eL4QAsI3DLOj3 zs;Y`ov+FkdryCFelA$LJ5Xcwzp+Gg$hH<0ysH}4hPM@L9!A=DS1c2RP5wx9EV<1uIf0{7t1c9>B z(mn%J1Lc^>xPufk3|c7rfY0E;t^+5779B8_xu<-RvvJr&T!V)&L4h-M6OLfq)hAA0 zUOdUmn+5uYvQd+hL+zAo_zmXz#Jg08n_i9@U^LkTpL!tvYC%(eW~LE1QRE{rb}T^e zBJ)iw`>ic^&O!@*;F&kx?9^XSmg}pZy-TXF90;@U%xa)ClK1!#3-5R;?R39Y{yWc- zp@5o%5GW}xXYK}zEqGRXr>CWF+#odG+FSVqyZvix>tT_nW^CMQdRP7ez+`{|R&Tsm znV2qDqnBRdw`#lj^D;jy0{eL=xloAQ>XWbFL4)C(~_tHzCe}$4?qQM0uqsWMH12{ zP!YvOTpICh`nKcUQ5JxdTM{1gm!{0Y{3rp&f6%0mUEq+`%n`nJyADzczsbv+P6MpG zysqnGmGJMZ6gzwS!6!lva3#P#Ek0{{Fv*gbN!74@_fy_8aBqQiiDd>HhikkI>8Yha zaf-ub!!OQ&l*Ad?0@`hFZ};>77^qGV0=}kV%V-rVNEDzj^m;=Tt|%^!H0#DeE&?6N z1G@?PP*OG{c!r5`d%>MY!59M|b>6wF(HOQ3Uh;eGvuY4G8{1t-5-3^R!vjVLmMhtr zPVB$}f`Lc9w6;b?Mi$+=2NHb7Wg00z9!5raeSL4}aMGs_10=R;3jje@&}05B*l)mS zOrK0R&K}4L$sA@-ws&`-hj!5~h=Gm{K~9m*u5AS~4dRnv(*#RAG?OrzN+6P<8c+y| zPUDqU_WhX-{C*#wh-f5y7&afw-_MPzxsrdVp+xu=-+SYKObdzFzGz*{8AWJB(bDf>wQUbaUFbk|T^IKct zD?_wPMwLDEgoFiERf#oWjDPlGzOb7`9g!kbqQ{;aYIu%f>wy#O^{ZFUP3y~iZa~t* zlZt{dnv^5ed@Q53fE}<_En3pk=Ywep+7*oV5oXY-2AleuH*cVUsK5qX2L^KhJedN> zI-AOY<~#&+(!+q6#;LnTQj-a!2M#fQT7?yFg$lHuA#Ym{TQEO~TP5ik1i#ra zly+zpL3fj$)V=HIH2i4WrmX_%E5xiETL#eSdG<{ywV$Afso`%#oniQRR3Y(555GcU zDI#N}H4X{0=plFQ@!!%CbXlr!-gQOUo%PV2MVf_o?_u_yj%c`GycL6nS--pIMQ2syA zEk>z1lMue}pNgs~Jychxn=3%}9Ni1wPeQ15+s%Xj4%K!yRI{%I|LfsgxSZcF69JAJ zfHLGRj*4yjQlJr@B@08Fq5yjVKnDf|K{LWafYPi1j#Dt~CN?Yi2`Cti!pGAS6Ngo` z9SX}J(4YVMT8|ocf?-5(8A8ecyiqN@MZICLgeRfItv@EJmwUtJ@-AC65fRfj&^TtB z-18mR7S8ag1h3ZW`hrIS<{TYm@u`KeTyM7}#@GVq%J{&FjO2kbq1hW50=-^8NEH>~ z$fQEkBn9-VS5e6om#GrwSb#STQz}Or)LO}OqS1nr8bAkxB+cMY=!`XLV2s*efD(X&y15Gbb^G*Xn6Ii+uYHu$j6ZgKIzI=7)wlj^G4zW2l;&it}Idl#JfH) zmPdZPVz>kQ2cFzwrO_X>Ko|k_^_nV5BN7IotV&Budo0KKdSF+0l%&+Zfds>-7z1z; z5Q7h32?Pz^?XyGt)p=)m923t6>`*1IZco5i!&{iqm=ERMX$pnmvu62ujB4?MNH$gQ zes0P`@;lFVLFp%`DK4LlDYDK4n?&Fcs39At@$F_t5RnNF1*dO92u@Y#GVk!mc5e+; zRzTWqt}7Bjjj8eT*P?u9DMo;%{*)_0LP22+0I#7}#|hER zGm9L=KimY>ePJjusE779l;>vOqGzIBOKL>dsO2iIf)yl9K$v)V5-dg00mjrW3;$Fm z!jm4@S!j9{i3*GhcD&x(~&Cw1u$I-$O z+q-wmgo|0^95bV1W1E~ltDG@wG{bD-)C=W+yO`)*<)ZGh(*PO991sX5EATq)LVp(c zfsVyXj11J=hwxCZ+_jNmrEi-cjwMp?Lp$c#k=P=C=UD{xyPxpfiMn}!n1H%}=Xqh( zPVJj=x0IBTIs%NDN;^ob#3Khw_BW7ZtzmknzaJ}k>ad0+DJc|uZ;nI>GqvE9NZqKY zsDMRDM0*BaXs9rS@kuc}UL22t;q=3t9o&>&wt5fMukk91np~hPg}0|c>38oqRw?#) zXz|@y{ss)|T&^L9Ue-|{iqeArbGPU>1E!`Q>y{Z1`Q1j|29hjDS>MZ7#^h;aW^+i~*T zu`vfm>Y+F|@m$;J1fY6xypj(pm;&3#Q2GUHoZdrFV{>+swF_NWmX`KGQG<9YYAGr% zen=}7(*|Rg208V%&dx0$4Fc>cB#Kwy#9JN6m$T+-L==<1A@;4B?B>3s`5el@sMU{v z_Q1WnEQin+^1O=P^%E@G3y9R$lvO%~m(4~Ue^QiX_P!ki5gpZjd^M0GQU#bf+GQcJ zN?AW;4#8BU&A`F28cQFBIu33ETQlFUHxW#CqdHGZ?@7Ry(Lm@y=s)@L<&EhP!cTom zOAt_T`AcZp_BKBnd-aGz%WX8(9We|b0TJEA0sVM!5PvsVH?x(4#^Q)@?fXL=G`i2xxpT_c8mc}2vw!;IsXL7E zQPa_-h~_U4k8wOk+}JSzQ$K}Slw*E$Ow2+On8=xh61u?jmLu%MbRiJeP=YA(GB}Lm zrAB75a*_C^h*nVELUVWD0;hh1V}@u_U%9MfDsp-{1dcz{Ux0*9Av1zdV3eKlw0Haw zw27*s&9jM!&OdvkBYCgMb)KwO0Wy8eZ++2DFRyR&{t+waxd3C|&d~d(0`p%CfcD9V+18j8 zpFivT<&5E*s0n*$J8IpfC5GwPmjE9?%s{TVA3<7?$V7=S2WVKM9|?mn-9Fuof$OX znU3^FI)51TJUeN!R(s=xc&kQ3^p$(cG3ycNR8V%kL7fplsPG;iXWeTx(@6(R&KEEx z2LfUV{0#yCpVABr1;DYPWD%yD%;C6R6UOjR1=bq^{Rj&Sngy8uJU+_~R)um4fKPbo z559!YYO3>nkjnvp8ao|Jul{?$ViyUi#Pu?r>Bfuh7kS??cklQOklpy z1Ht!Shi=CD&!1I8!}2}F^Wu<)l79?BgzuQWh>QJTe3Bo#UrVvpX>t6Qho{TJ#T%Je%PuEL>cJoX^~2&^))iC!F2umXlD;gmnD~**hFMCD4ciy$f=dIgJa` zq5K==fRebFL?HKodrHxmk)8=~u*=KJifn}MyuE~M8jf{hU@qp3B^jXIM*)cO0Pv zGU>9Asge@?75^U47Zz(nf$(}}8J}+{poIZ}1d^nzq-4?RhgY4pv}6}@#+;=n>$6Je z_PBW>iAo5gNo~z2;@c)*$`l%jh$xV8BQhWAkthT~idq9Q9QOt_HD;JF2iB&EiKhFm zACa|CSetKG@jZ@YLyZ9wDh35fQft6CGw(8XV5HF*w2w-g2SM8yf`hq1licZ7-@T!S z9VvS0(M|KAZ{N&!@@*F6y^xa$J9^-!)MJJ{LovdU7gPd>UO;o;*fZ=Y@I`sdU}me@ zs@+U;!EouvkC+b0mM;k!4Hez33r+<<4GUy+mvD>mgadc&g!_q!i2+H1mz5Uj51r@X z0v~_>PcUx*3OC3z7urIlCIZ63BW=OZ5Jge21^Me5W}aoKsWmZYx@7=jfr+|7vI8)t zsv#gLY3A%y7)?q;lbfB*5y~YhY9zw7#15vSN!sQd;F1`&~N z9-Jak$Ke8CQt*-3{&fV@gCnW@%ItTKYRsFoq}`)2A{TP4$6FP*QEU~Ymut6E0?oh@DEmI1NcCTH{ zOJ8G41FVCL0@jU>*mCX0E%MxSA=~q4VUVOKu9?0cPuIt_g&GC6CA{N{Yak1zrWCIg z1*DJ9|D8M&fe`?|27}>hV7cqS7j~ZtKR7-A-V-~*ng^TM>49_)eP0;&Fm`&RMdSmfmE?M`VMv1-49fs>%8nyN=s89g7Z-7V z;I*KEf%!{5-k{tPQV4Q(R#sS;bWq%`72q+tv_dU*ay^vZ;s@d(N88wBTm??c%gfO& zFiBathEj_l!Wfp|=&@^p>8~o$0ySdgtI7_4x~Ks)j;WGF`M~cxfO3$_BPNHbpNe}H zEyxWL5~~8|j`(5b?7R;AZNy-(zn}8Po%@rQ=%})R6rtK5GcDuLlV(X4W!-%Zox{mV zlQ9)QIM}8t4LrK;Fl5jyje$=Coir1$Aa%R+q_GQs0QXSB&#Myhjf>NaRTcCWm!iKe zs5`}^#DsWV00{IX$CfC^81#g3D|qta->}oMRi)tY;IM@OaX17h*^+90_W~s<8S|k2 zVnH_^%<(zF7d)s%gQG4Z`yDPp@L+6UxF!J;PGAn)cy`Ot%$* zjx%i0%*uXoz#{n#G#ix5;OR~0ooxdp`3B%0*reFO=FX@AIo3C_DC{W=P zSC>%%>BMti8tj^dSdMY16asa_@k`ti0H~A0t%qe+c^|pV&CH4{4}R8mLM=;de~a_K z=z7bzD7&tGc+^WQ5CudfRT@ER=o0Df8cMoBy1@bjq`RdXq#IPEyQD$7yZgWJe%_BS zpXMhc4Ex-%)=|5-EdM`R(vp>$ni@bo0sE9W1D*_U2p~WnnlnE%INF+qs>BJ9TiE2T zau?`f9-0qk55gpr#cdqC6|7y-AoCe|CGmB3eEeA0i9pvO!=Ry10c00c<~@^wUJofu z@Fg2y5JZnH`_nrCd4xr27Do=w7l4u~D%f0me*V;k3ajs9fC#d?n1pZjJ4~^w91a$s z5`589YCupmbB$w}q3UdgFYkp*-*HH*UIh!V;oMwY?&1AGmi3-~d{!(K)K+~UJXRR; zZ&KygB{U>`mJREa*{J59<0N7z|^{8n8o)s&O{-0p`fskVS~AXbsFun z(eBqp2&RB7N8Q?b2O2_P7O5I@tDNJ36M-G?UH6-}#)(;P@SsKD2{;1FY+xHzo!=>= zg@l;eQyfIO3(hV7AkftLkqg6V`ha4?%E<2M^c4Q39u5=8EiqF5BIHRK_UzzEJos{; zcY*+)XZMw|6kg~~3>1nA2)JKW1n8pErZ6D&vm ze?rcKSj##qJG)x`u4-A3 zfGe(5z9D-iuCskz{f*eEDW#^M(E_N(=h^Lu74aZTK?DaI*q`=I5-{yGs)4u! zpya@2%d6_|r?OVhD^kHu#dif5RA^sY8pN>NR2+;gFL*eu!2gqa@^3eQ!xrhZmXI9 zMsHLw`w34#>FlvS%8Xo*aY;@q1WWyu@tEBPtz5A25(NiO7T~!ses}NQeN&84&Wj}N ziMx$~5x&tFqr(at@C!N5Q!?jz;u4nisrwoucd*IL#>z0xHOF_LX;S$t0;TtF#9fZL zME*wKvv22ztFEC3H<2WweBl-Ho_&A7AO>}oJhpRES(*0TP|HUh#85{8<{rY;? z#qzexW*=kQWbxW{&!RT!G&7@N7yjYmwW7mGCen^IZM6{nRnF$Wbg$p{$WcyTx;V;- z^2B!;Ds$BGOdM~F6fc_hcVFgA;r8K3buwvbQOGJ03He#xDZTa@&pcTsEGCJ`$(nlM zTpAHvYy|y~sM<$$64*%OFBLY2I^NQQ=sss~#lz7KS1?$;MI@HuSmDNj(ye24o=k0_ z(KHaFT`d`4Zd)@%lf3UE5I;OrVW42DDCMf~S)>|v#tcGQMtx*=y=~}ax!cLku!pvb zLkyKI>M}*1D~JUie7M*Is+#A{yjpt!oTDhoM57p!QS4&)QhF($@R1dgmEry zFBDAB!RfUGX)km{gG%#te5w~uD{r@ON-yjv8N(}%4h5V4{^?x@tf#TK! z5C`AnEAo}00uzBaJLLAbh$|rjoB|8%su0LfLRR+-gzmB6ZHILYZcK2LJ5B%cgu+!U zWDY#kN1mA12oZ?)m&s64LqT;0%Fj0N?OtI-I8+}wj%zgWb&t#^IlZ<$rl90^OyC8% zIJ6Cf_@EI6=&c7bwp_9QV(UKf8nX6%bBA2^r;R>>_yrPK0)^Q@*>B($)|s>$9`i-a z17{){Qu5qK*9AIuskRX|4{rc?eu4ml{L==H5XT-bTK$Qi05Fie^01&D}yObn$ zKqvIlUfa!6$yHjhxh2yw6gb|!Hdfo&+FGgJn4OAj^X^c+5fl+ixrxv3T|x$-Qf|Pd z!QmHN_M3v}0-eVfR&3~>zd(7+%+A7JY`xHNrRkju#eeqg1_H5l@TYI__R`go0>K9y zQRG8wa6+dYjWZ+OHwfQZqDN1eX7@_M!j?=H{oeUcvN?1>fO{8vAoDE$Is^NOFxxN2{;+PUIa5^DlP06{xA#ZP$jp` zeM;{BdvN9D5j;+>7oi7*gY+H-hWS8dFH|vre{EACepH|Dz7L3*?FcFHI4tAlEE}(~ zQlyW5;$^kF)uEMXbnL4r9$t{@(1(Zdi^5$C55r^kB)sa8Z%k*|({mu?UQokU=w+Sx&UeM)J0?8yxV6R(p~@)zTIMIZi=Ap`eWN zWUz&}?TeRS9lIj!fE9p}9}tuCl#V~W& zjD=3KoJ1|3;P%pw$3qcI01$#d8&G>79(>CLMw`A}g^FL?!+oVLGO7uUDZox~OosPS zZxLHm7HCFICZ+e+ht@ld0ve9{DR9pi$g;2z=h6ZC#4!~6G`N0#v16&c5lGXCLYsnX zDISS}MMugcV(9$5ZaYgqYdH^|-ES|#5z_XeYlG|}K!1oIKfZEYgTbVPtdDE&YK9-3 zfn9;!sOOnzh!>5k57N7npds`~^Q8Y*(>)rMnvi43Awg0fgA6Qxoc(z>cHeJ#al$m_8u~_TrnnsPp zv);`Sx4+S`JDSRzutwI7>y^Ze=U?mC8hp5KKt~kNpE*ExLnZZXa&%au=IGEQyz*YYs^Bl3&N{?#+=h|Y*Q8a}J0jpn@^;~x_<#EUiC(kBM4-!vSqt2_#4cj1mawU$$#olbHL@IBA zrf9sx&bx1(+Bcb2A$9s#(8f@c&F!Q1Qwoa6$xlK{`zO8p-ov}C2`{A&-9M4_;@%a- zD~X!8TzSH>8xlnFptEOePDdT?dh6F#D-Ds+VPQfr52AUQj5!Bp`$e=k}l2(=OBpmoxK&UDodtjO8Ui9rn~9ND~kvI zv1622I8h6o~8rB<4Pl z8kr(hhxG*KDFX2~?_!-VSYLGm3e|V-zWe#LL$v{OFOcKbd(3@lG{Ha1$BKTB@1G@o zaw`?AeiiSrv>4wt)i~&*mnk<=ReL*K**R><_RNbpM+kEn|LHc3laio#STxc_bb&^- zHM-M?ejrPRjb`uKh-R{cOk*~)$Ep5pReQU`VTTpxrSoe4oXEmW#agLP$2ly~Uq6ba z1^D>ps^-7e`)yNH3)|~U)=ghO$y`E(mIUb!FB;1)?b@P5M0($yT~D;aTDxM6f628W|y3Zi$N3p{2buqF5*vp0KXAFXmZc^#dY_RI#A~b*cM=gpZa*~(-mJqn-vAh$qJ#7vZ=vD`jy4fcIC+`EAQDSV@8akB^(!j>$uOWOUrJF4VZKd z(bb-(6=wwOuN=AQ=v;3fwP0|}>#94ym>BE#z(3z1Qh0b%-bap1{FY*oC7at>%O{sZ zwvUE^#N0-K3q8n*d{fJCUqzh8;J~~fU-MTsMQ8GfuPlXZzBJrAfWvEIP%+&1P2J8? zSh9@Nt5+rg@>zoc{(6cHrmY*)5rdpLXMKjY0yaplO_77Ylj~Yud#vJEl1v`$Xoya@cq_?Ti?Ng>J zHO5#hP}SpgF=T21t;LZvcSZ&)oJ=G1Tk)57_@|ay25{u!xzv7=?k^qoAMj_iYBe`$ zxyM$X7xe2L*4*?ZZBj$oFX1Xw3Uy!bE1Qj0J8iZ)y<`os9+gkvwVAn?;N!h$UNfkV>pCQm7O=D*D;nxa<0R*U)^lOtr*_VH8V?_G{8rZIH$7epUg^ z7O4NOqELVl1I>gF$F=v}0u15{*LVXDwsur&Z6_N}9mtl$3pI3-Uo3VVag%eH{Mutj zC2+dUtToygQo2yYys9ml?}(0io2z&kTTBs{r_L2=HdW~4R-Hc)BJCZ{Bz>WeZ_mkY zs>h_5Dj@ok6c0T@Y|tdF8)s`tn^N?<`Rr(!M%7fk%jMDZjROrl*Rklu~Bx^@AMvi+HZ_??lN=<|qnwFxN^w8hg>(eE0 z&kjF{qILQC%gG76l!W8C z?6+aXA54tdZm?UlAw%Ty(tX3J)e3aBGg}sqe*F|q8r;>!d~@nx?l!Zel}cL(jj2wf zZxX8R&Fv*Px?SZU7Y3pt8X!i-7nimQ>;dm($Hb`=9rh~q{rFP zbf>BE#$=t<{>(A#u_OJtYK57i?FZr6;Ur^^<{NLf%?hIv@LE4eqqOa#Y&r0kCibTI z{d7dnhOg4anVsDfYvz(y@2eoo>50qGWxDFtz#YB)zT@J*cstR67GdftCQ`P2Lomv$}7jJIrCY!T|mdg~PFhs+0?}k^sAvdzCnq$(8?lk!M zo1FLs1yun5osYC0;bQuQs6Vf?3JseVzATneR9-J$e4uszb1tRtTgDJpw{Cl*#)LZA zP~0L3*j`5uo;>a}M#6j(o}TN_;_#Tx(2Rc-$0-l=9(1|@I^G)Gv3v9S7Mu+I>;Q&9 z5-Ml`00b+6kpkd883t=N`Dv3`L;|n)p48&T!nEdhqhQoNJ|num2vX`ufB2(n=z8nM zc#Tq}LFL@`{h0K1{-2aeIYJGmCx+i}8apTYjgTvQ9Kwt_WS&01$b7QRJni9n})_-W?>&=$Oqj~QWD_07ctMv$^ z)8Mu>3o93y1(AHyz2~QrMe||A{CP-fMJwhFZ)W3O@>eVgX0kbhdMV}{@5YvXbuAor zw$l3OOkTe!7IEjq^fFP;ZsY3|t>|pmcbZf4T^1$NHkV+z%BsrL?kDdS7wo8w=VE$J zr=xE$iM$YG8c6Zh=5fE!b6L5&9P%b^SrHGT+bWgCF+66p+9rcLhM$GSd?HDq()VL) zg<*3G+*3721c;|CLF<_m6P>YX?yV|Hnve@?r#g#Jxh>!PLQ|u*I z6mk^nryXb+4LhZnI?k(EGrkh*OE(pnZPeV95Te#f`ZZ!RUu$>nn@oA{A}WN*q3&0s zSTvbce^oenN|NE_wUB5=aRX5&>8+1z`ARu;roCN6JysnE#c%JnvGm)0(#xAZ8F}Sv z)Nd!%R=4cHcGVhhp7@g_E-wB)@o@Q8U{>v|K%>DVev`XYQUA@mG1U_DR8WYQnaMs3 z{xDMP$z5SMwKThWxEm!}$AkAOi>>trM~KLLt5%P@Q4xp30%>EmLQel{`lpMR43BOs z{ov*6FPRiAcA6NK{p2DjDB#+kJNSKDo|}tXFDF^YXrNp9-oF9zm;eB{%3+fTAAbz` z5dfre6e=#R|L~Z>m2E8YGw60anG1GnPl#7*;SHEI@_Oib8R#s3Ikw>G`-t_40INfJ z-6vst(_Pw;qpgeD%~j<)9SPz%652_Jtr2Rh`S*|YlXI$FOaflrwmxnfWV~hI@@_Lg zSGOUZ))pnHle|?{EAUhOFgD#(nWl(0+3x5^Lc^`Ykn3Zo_2?%_B<-1__7=O7Z#b$e z>PGm5Wi#K?j1c57kq4+2n|&blS+ytVN;qwFGz|PjbkURK)LO(RP2{;gUiAEUgOryQ zvwXwt*5UGah?w&qv#zf`bHsJVTbK;!4ZGvMp7+SVJ^|zLRIX&k^lV1ffQjq_DsJzS zn!6E(9%X8AMDw=3jm@KUk1ZlOyhM1R$3AfLh{V&=Cy?29KB zO2NlMnl_r2hUk$~)Xt=}pQd#S9JIt2yjPTRk|B`&{^vA(q*A_ly*&L<&fuQ-rX}Nr z$4Vy7?n6Nao3~|Y`1S?rNQa?67zZ1Inv=`fe{#oC^-uSnGCe`R-q5r8N^j>wC}FPB zy=G(bZcWC^Kq_y{H6MSU1t%W2Cd6Y_R$nC;=_0+ZuM=aecgRT!1_w>H%sI5`OWPlh z9NHajkv0}Lw>a++s+0&sO9DS#=QJ_I>lW`d^@v9OEEZ3naPyuPm&p2hl~`l;aI3C& zXFN|Z4JHA5l3O_s?ubcYOD4gyC1`t-apA<46Ns4rWR~F2;e;u)+7r}<60t1)sxN0Z>axwpf`V5)G$Cb<_ zj536VA2F)Q+3E3R3{_Uh;J!>#p^En%tzC5N=XkWHzshTCoA{F#ALDvm)mGi*OZJ`k zr%WZAF=@MTaq4L3_(MhfkNJ>e6wV}<(%DZrLMgl%Z0ijEome%4Q}>si_&0$nrX!X$ za82sMeYcY}Qvz`m=^FMv;6{6P2$8T{uF|T@;s+ho2yGR?!n89QLTRHIgU|%s(w3dE zyIY5MTZiq%wdv&851evyEu;O!GZtC%G-@3;zMf3ECvsX|GkhGm<$ahT`NU>^M%5)) z*I~`{qMj3;DbWWnn@-$;z&+~X6N)5TPwC2O_uaI-FL|c34IOnmo-63evL7GnwEaE z!wl%U$S8nM=6{XIA85xib0xaIPR=e}38%p)z5C?+ze&%<ULpNa2)eQ`RH&Rn zPgA@P7F)s%JHq}l^6~lHS?aqnd{*?jobxU)c)OR2PbT7~m- zNMaK@DA)On$@uOBj)Z!d;5$r@aVXU(8;$N0RbF3VI_Qz5_z9KWrJHeqcYtqt*Jsg1 zi`zJPG8NYx3kJqXsmh24GKcTQq%;gKso~Zq`=kjs;a#^NbPBW9VU~;z&-98)zK(d7 zSBNr`*MCH(m@W{_SYT1!+3nek^OtZ>>a0>e1MR$L`eg7WS$o(ex1;Fmx43(q9~??o zc(rz)EHWbAciW;#t)%iZ3YGATMjW^S(M0UsKrO#mSe9yDo;YTin6r1fyTyx`+4!Mul&r&&EYOl9Nh zdM*)#fiZapllvONwRBxF?VXTDcw86Soon&+f$7Hanzc5&5gJU+;84vOFy^vYQMaVS z^ixfyT*Ptcwdn|Rqn5kO6w!NI_`Ua8B}^I9~F za#XGX69ALYL2Ba&_O8aOtB>pXNql?rtdv$x0g%KWx1dbL_2V+`=(*`3G0oQbetLG) z;gs(|hmzmTaOgY{9-ju$c<=r6=KI$T+;~SoAv)9Yq4p1L;^xW*!^{v=>#lTBqqKl-|uYGqhZaheYBD2>yK5eD%&P(dSpNcMx?= zgvZHIZ%>`Z!TKms5ZSx45~oMmN>X2%Npb$Y@9F>G19uen<=?J&Kpl9U*4}N@9FupU z6f#v9{tYbRuZ_0MO?dm}0yH$Wj!7=Dn^Hua>NN@@(f5V`3g`&>Vg#QHhLGid`=?(h zlgHfOB+d0$jcVKHnR0_!yGnZ9q0L6Gk+3*m>!RSYh94Nj7?W3y(z!gi*; zUxh)@p}w@RVDSdt*te4vsQm;b8#W*@*-TF(IhL;GemJ~UMzB1vaNKJZCzO`1uNo}y zFp&rAK1)LRG>?j<)nSH$)FYT<~0-83$g)_R9M2QVjBytS3xFR#)uil%XV)sdLA8h1deAoV((%5S6BSw(A;`ydujMh7>dJQVm#Xpu1 z(#&}&S7Qr*^zP$VAv$p)X>!{r*mQ%d%PqK^)?~^EDqZ$2MX@d~d?LdX=%bw-ES%s3 zsG36N$>l`EeSyi9O8CDg=q~*8yTn$QPd~-i5)~Q^7t9S#y)eNtSWXDzaHR~@dXwYt z*SN8;XIiN{>3s*CXIIiXpTDd=JU9N)qt#*1NaUfd8bO18S-4nq?7?PVZ?k&hLvo8X zPmNvoXWRQ9X35Vo71p4zPX9_=XguLNcdN>JTfHTlEXCt;b__R9qDk3#DkzSGBq2|u z&Zx8K<}@a85baH0oK0@W%)M@+&>~bGIsc3Bfy*y)Te3G^$9&`qh83q-nevTNzi%m# z!vEo0C@T@Tisa z|D;-RmVMqrNy?#O`ZF^wIQob>v*d~`wnFUMSuaLXrldJ)FZz!AC&rk4`~&2225}_) zk1H?J?Ow7;^+Unw^pYiSw8~O$E171*`U$!Z|EWW*^D-8@#g5JvY99(<3V%Y}i>(h{ zi{@&M>%w<_(wAX#B3|QtCc2t0bol4!x`i#X-scrM+TV+F#(Ee+V@k|k-tIGe+K7$# zi#>svxdh#(giuO>)=Bg|WyAJ|&u;6HC}tY@Sei!E+g@~3&HJsgTD*}naom_0Dc&`Z zByXo3b0Fkpj?$*G{+O#-jk4j%1Sf1eE|BS+6{MNwzL zBqSa+w34)VO8!2+XV6U_-^CS~JZ;jEjf>OB9?YLgnfhDEi^=6S(-NCu6fpZl_?=La zK(AS$il(?we~H%+y(q6*=qEgkqtDl#ttb4Dz1leJY1(<*&c2KfS5&!tO~6sV9J9pm znW@gOxP}n9k-+UHabeIF!fbl*zCvXzROVxHg_F_lBWma6v*?Nn6&J?R7|l|>1XAB+ zCW952hBRtqDeI~Vp~3l=>#UsR?&VGsz8EG_T9sQFx7UG%t|L~iesu2_1+=eu$*@cbZm(q2= z|C2DfiO}+t(|?(-QTA-_V!|}ia_(i6IK3=2^CNuo8ruz|Q>n5cI6 zr?ZMBZE?}Xb_%5|l!|a+v!Y{KVRWLg`VYOZhVXV}PHAN?0vY5%F|*5TSP zR#EosA;!slqF@q-$wlczH0k(v^D~v>$9L^lM!IQGD&Z@wv%(L%6GJq1a4FA5Q=|-v z;X%f25NYq3`0ma_M6fBbycF`BVNy0{6D)qH-3Bws`NPU(V8{E_{tr zbf(cJ!|l9(u}h6UKJgM7A8BG<3E!a%oAy%9`;`?=^vLtQ*4g`=t5Y@h(Q8;ywB7~v zmyib!NNhX-ej+0xRrKG^b(Wa?EbInC>#?8UA0uQjZrGoOaW8)Zm>jeYJ1f<6woT8K2Evu*3 z8SyZ(xJT}i+xS=c*VOa_&Ozzcw1>{GN;^>TkpE-GSJ>j3fRoG_$`cOhOgI>WO7dyM z`u^;9DehBe$Ex3rcuI5{Z0^5b%l_~oMD#u5lDVQf5nKB@s((yMJK~VqfXnMKOJ95> zYYU@ONoC9EjpKH*-Km)FP81v^&lhvQx7{UcoExFcF*=;gE)^5*7b)>%A6s=D8l8S6 zbIB&mDE~Md>5Tp%a|H^Uw`U@Spjdfj%zOhXO+vxxHA_PKyiHUazQ>PUYx znyqQM&h%PER8*EtL`WDaUMXi#G}(w);P?^JJfh#Jkj;nEum~%~CKB)p-J^`mcsJu=58; zt{~5(3gwDMB>Ky`gg>@^erOA&@xPS^*y+nOr5s{UZWN;fx$4H`VFo#Ey`Mh=#qWDa z$y+3c zS#|YeNmKr{-njb{rx#oY4x)@|Q&Fa86G%LZ$=p_Kp$k10agzYJ`{>fWxl-uS>h zHkQKP&@9auOB#10jl^DGz^tC~y{o_=5&av-X#xZK-^;@A4O zISu3de7sanf9QNpWEX`8&)2y?Tcuu zH8!+2HxByKY>rfVCQ;=@lw(-tPTM)J6r5L+iN2saJ~8}`qViKb-Z(8oZ{VtMpm1EV ztce(0bqblB_%v0j-yC80Qnbx7ru1O{Fj&8M(r2pL#^JC`5({fa&2EWB`$Vra=8usA z2X|}qVrkiQsOqEG2gDxlx)YW%MZ$e03qMmcpHr@Vc+1FMU2(9)i*)IF?SNUJ?o>38 zJEoG-JKP`DsSuGnV!hZY9TC}eIeQWwYq3$5!d96%JF9~|GrPqH^Eix!xDvAF;f@YD z(88Jibk7;g9$NK-#3nFlC@T*I+Esvt1ybo>P*YR$d!d883nDCqXCT87@)x|--Ejni z^((=?04m$Y#}5&GSTX6$H4B8rzr{k#g6H-8?U*wRrh54j=19K~j|&nb5R>g@EQWVm z6v|~o({>HaRZ0~y23bw}d;9yF^~A>OsPvkC_mWCxSwDi(jQXxYjt;E`Po|>xhWJ9~ znQq%rhBT4eSdD*ZaeMG57XwKmy4&e%?7JoF$B)m1|5MQ4jwUE=GC)3YUlw40c||5-`TF{;$vcB)5N5j z*V8lgQnBrT*-?_k2hAtCAJaa6Zqcx!kFP{Wc1dvjpFuaf+r`~Y+hqwMzRlls2}~qB zED>h)Zo8;hOVe6=8M;K<@a#b`2@y8CncJ$|9w!14wj~9L^|askPdSr+ibOO1*VqPV6as7=6_;%ou)L5ynv2T-oxAZx3fF0*LU4PTv0hp?Ppa zzYS|?WBMsJA(_t$!P$Pa_ee5xG+U#XKg+hxwVEltLGm?QjE>S|7-w)Zk}Y^#Ky14X z!NJd-{Y@FK%~Z%f^s@c}qAa*T^9S7FbJ zHJqB*-IcZLQ|XrfwiVP{|Cm-)i2hElZ>8IL+X~t4TJQ$WQ~#za|Coi2SnoGnw-A4I zN%HgoiyCQv!ve*&+icaTgC*JTW*|%!Ta_UiP^fd%_MP4CyFJgs7DnS{skqATW}ehA ztoLd?n$1{ToHBA`%e9OD#JirKNeDfsie?s0a3xDXt6l&0l<}rYp06~=roD#yaGAE` zgk?sk>IX@kjUj8;N#%i@4j@%IT3llXF3Cz%0=)Fp!* zz|&j1-EXB0BIW=-U!;;T+7CGfl5d7BUuO_CRcgd(x^n~{da*4wk+h*117R$RmpCtm z(`YtQRBACXs#8dhj*X3dbO4&F$r{H=C7-cZfoQKVWsajk`+MopcL~6sH$EW9VLKxwvf?)ijl_zUNjgzW+d2b;$4pi(P7VCYz!avcTCBZyI^5O+Jx5Qs@!5t)5phw>l;m0T{n?FL5YOSK> zcklRYyEvG+@6ju4&Jo}`TkiKc@i$9|@Kn->PE|OKNkrceJsH|S_8GRBvFM@`0w;3M zI1CS?Y{@65y1LpsOA0Lozo~O>AyyeWPj+1uSC~c-I7Sq}F z$|ArhApY5HOPoN0UvK)qhMFr`&v!PkGnU*6|0l;NbGU}sN)v~%u#R>zH~0-=F~hbn z`26Ark+(}x=14q9pDKYUC0U&HUA&NcKS0Tc$7;a^oXq3LkDE8Z9SOoU^gDN+-&tc1 zs)gKPr-bqv%aSh8L?*J^c%_nhul8qjgE;`M^-Lc$Y5fI?>SDdtj|C)%RE8qeo$d!) z4S{Z7g~qal_!aXt%Uxodno=`Qj{BRjXED0+Pv(|aSug5b=j9IeE_tIVFnnoJ1n(oZ zHj7)VsT&qWjcZkvz5-y>Jqpij_^{qjoVuvebm>AzP1hK0x;~osto>) z%HxRds_OxPI;h~n#pa&~MAL*SgLic>P5iO2j8?=vNXbL|4+z&=MJ!Kv`IPwIiZ8 ztikVrUs;M1e5v@2o?-MxNMZ3^=uP{bp<$hLdWIeLhm8|il@_~ z$0COrq{o`tlFBwm9v=KnKy`{H|1hpy_&FS9Y%w-hK)!OH*?e>3i>BP*PfATn7W$ih~=3hHUpd0vhIcKUm`G?0$?93P4k z`>R~z$8<$B)u8T&x~vab3-*`PgtVf9f=%B?FTt20Bo{#??`1~7?OdWulYp~6QGE!b ziH1un>lS|tK`3-cwS2I8$Ez(Wn^+2Mvp5w))lsBzbN z2{`kVPB%WG^8Ub3^dj>p?}~D1|N0C@tk88*wIZ>ydmkUb?bla86hp2U;r3Z8oLQPY zN`f|c7{}7C>SoK<;W4Efly?oJQiKGrA%3_7voJN#m#KE-5gQ&@dFd~wdO7cGM_p>S zd1S$~q7s8O%=chtp%VmmTB>FKr9x7XU`2or(*}lj694s#zp2j&H1Tf-- zUWB|_KECFCnD7xyCeCnycfz8mg+cK#D6J1PR3b`w4Fm&9;V}O4<+i1zr7IPn9C8A( z?;H-zw#@zV-OxDMt3^TtWG^w7RP<~-vr7Rmrx7Kw77K}@H6-#g6KuSOICBxf57(Yb zl)&jI%Bv>pG-Xa*2W2Q}T~wp*(2j%{iA@M@3FVhdE>x0I&N_A`1?lgxMVj&!s*ca$ zV(9HVH8Ekd&tD~s-v(0i3aX^ByuTH95@t`6)3-$}Y*%aE7KYi0i}-8a=lB{kQv8RNI$Uf3?soBfY_KamFUJk|V0N%M)lL5u02&@1xQP!b$tgz!+HMfO2W)U{ zV&r&#{tUwX>WYdW`7))PQeHzL=FZ_47FM(vj4 zaViQWZC2M7BA8wBf2^@T%F&rRLY*9FoN^dcCYv)jh~eBEAVvJB|J?tMiNe3yZ5Hpe zi;4#%przeEYL0ig-F95Zx3+tOAEvb{oBT=tWEMdt8@Dw^C;h7->QY)z2mdwgGx0wm z`k(GTehGY!;PhrGD1AbM^^_ASmWBdPEl8e9Q05TW0jJ@*h9g|} zQV52ITFt9#=76Vz%l5kA&N&Dp0Db?o(}j5?c1Q!b$6Ki;dBS$UiMBp_H0OACqWjM(<5fnewt(C9Il^EL~8l(pT@E{YsETA2T%cCD~%b! zDmqyxZQqmx`rg3P@6j{EWq;F%=0>5=e#iEJc$%WT!dhlMMU|ybII%O~*+Un`bD!0Z zcR){n)TLJP&%J`5KZKD|G-?iCV+Qr#lYZJRl-%`5UD$R z&RO1-z*Pmv^wWFF^H6r_9q~~SBDsp)8vi_p{0J<#X?r152E+kJUeaC2 z6qbST7?9{!RaU}HTpm!u&MDv%5q0glf&m=91vzA<(j(9=fGv=S*L@t!*r2BebvQ(o zUHL7R_nm7g(_MGSsK92KHfSPhF{c8%o7ja3D7N9o@vCbRt=U3$!2k}s>KDwLh(6y- zX|;eV5DZ{4#^&wgvsTBKzpwQU5Np(|bi7ze+eL3z%93rKXlTEf%@m9{H$Rs&+ifzj ztEw0_8jCWbyFpd+hlSvS1IJX`peY4+MC0$qCiP0k4XdLDsQR_ITue^R6oF7-Aax%u zec%7i!E$0{u&}Yec{)LJa=m*0l|rt<+^%8!4N~fPF+?PZ-e;~uvN;*xB*9EK6yq{w% zJWv}a$L=)UZoTT_b@q$nz&hd>TJR90b-oWsrW8u)eM{d`bT-*+%8b_u0ReCWuH)8U zzEadV#CDt#EJAStn%a0)%LJ&IxYHmE6Lcl;EI|7Rony=VI(Q<%M124DZ8qz<+p1)@ z+}0_s%e@B|Cftq?ax-AoWH5W*;2KoO{P!ih_Vo^-tNzC#ArOgPq+;Bsm{wntQikMb zg#+rHm${4|Vd60)y$x0mNH3v`BHPyJX4P*G=5%bm{^@5~N6$cUM)zW83>Me?P-e>) zklyA`xIfc<{q0;^t*=ihYXE28pc@aBgyTm;QJQJ&m6UPG(uCW&eV|%nFYHq!NEWQ4 znk_WpMHtJnk`$vy}NhYf=Rq-+QC)pVtE2mzN`B( z!5ajF>vDF)P}$_@;sVCIS}?@H8PqDj&=zibl~{yJ3l5`amCxo|Lo*;fhL+p=G%{0VauLxKcNU;pC!XbN3(ut%@ukRu|@U*!|Es8 zy^3K_92fKOonG-s)Se9Pv0ow?^dg1I9v5?+bhp^BTb#yUlM!DmOpx3NT6iV8xkNX+ zG0kk&;pp!L()^Z;zy`xJ9t*jxH)2JCHl(7i7khU)do0y?&14B!9WeXy$^BQ}vmy-*7>8$^7E~EJ$?RT{9bSH9;RO-78O}Zs;`*1ri0T%Wue*;K_!oXJ` zuSwu_aXxKQv<`2LA#sQ>`v3w|uipYYawB)cI}O^xkZ=9pY zEd(y=DS``1kITY9+;SeuRt8Ro6u1V7iu_=IUjyPwsxjdv(E}*>W~*<*{+djg`baZZ zVFb7-Tvc+6Rfj+oQO(W=L6xp)CU}}J?~?c7UaIW&UPt^eBoz&5OkNqe%z&e&-gaYe zBM;ws4<9RtEJ%@IQHpSNvdqUVs7*Ql8P0rYm*sR!UY+~0>La&>-w#us_cjjZK}-E{ z`EtTZLWsd5>CH{QFgB;X9<9^MwKIN8f3H{utBw)*=9ZgAod^7lV&Pb3HrB0f9OYbA zbKf!|yI0mv^KeZUe&nhaEmXMA|N6kq`BEt_w|`ry@edUUDY28E1>Lx**J{F|)*1kl zm@cph*QLsNuZO2dy;w6Pu97JtPes4|MDf(#;-1Tsgs!1(o{)eM8aJ7%eHzR_nuh^0 zK<3s&3PxzCPk6+ZenAdsNyzVa32O=RWlv-pgE;D?Xg}&sa~jK_Txokjv(ue`KjL;)QklnD=I7_O?e}IyzK8}NpRnG17OzM>+qIEqq==lfg-k5+ z-t7)N=gls!!S=e-I$C}vrN$G!5qKtO1}$h;ZPj~^Za*IO%mGD>HjODGkItTRWo4uqv?h z+YHfLbVMXnxD1;X_G8&P{d(!;6XhCm0ttEEZ5~K^X~&eVWI7}xo9DFZ#oQ7bH(1nj>HyMwK)?*VB%b;UJ!jwp!0idw%8*W4 zTQr&R^qMh^cm@wy#x$tq-RAykQX6;75(4(GR!FZm7{c6+OT@F4ab8hfX5n}+SJ}q$ z$=Rg15js)1JKR_1K442obXCJc{Y(x9mJOu{$a3bXl{zDsyeY+yg7YsGY}+sTH>1kb zBlNwr{lclcO-mVigHP=(*Z*W3wl5D*#Vgrd-InvXi(FsLU$OScXS7wd*!AZxMRCmz zJD2UXEG=O$@>s<*>d1z8>D0OH;vKKft}f2Ucj>tX$5Y<6AR7H)#@-djwzKt<`zPtr zo~wym%-4^hO!cPXBI;&e#nLQ#^Zgt+w3`2R5@gf?9ot3wJg|Y7=+x9BCB0MRp`0qh zOPhWgz!9{6lqEa}=|Y;Eq0q}6g}zWFpY5h)>~tvtCI#7CP_4S51r~7=1mUPov-x{? zNdy$yg(N)^1MpImOjKvX)#($pGH^Hx$4nH;xhU{t#C?37r4ZKpObU;)BPixu}%DkrB?iF3PwWOk;zI8>7*`t6_p8{6W3dZQ?)9?-}t z*KM<`qDCz2yi~552sbPur-K289XSqO56yP9yezThxsK*WyfUv`@|?<@1>*fNBy%&{ z3_V^#mGklefc{uBvmlRQo(Vv+U(VcRJl zYrScF;d0=rG>Rb2lj1dydsp}In2^7L(pQH?d;v$KXvAz&Qa5(nR|#wbqn!=AvPTU{ z{-#}tk6c0Vp)pogYKijb4(KG647}iH)Nd8Am(Nnzwz9h6V*kb8rz`kn_YZAdmvgpU zm8>GtSRni>tl?)hw;PxOc^Dt30iX87)}+w>c!eVH7clrcLv^3xQOGKnRkYUcs;dFM z;UV)1X$m=6OcVhli%JEur^yv!fQhVUQbUM; z#%oY~_wfmL_{|?f4`4Z7Dcs@fdtuuj5RQw5-I-yN+MGK>NeIj01oVg9&&DBq8vN4I zJ!JS#pqI99}X{YtzY6h>yn}WG|sFc8agug3Bkt@Sp(%h@}%dDtcl#o|sqN)<#zA zB_4WwYp6U!)YJ7<&;Rdyd(*eXVp;E9!fn0pJU%@YAP_~?N;8tobg|4t<*WGMGmcoe z+*5()p8g?}V#(&W4YhbZe3SE(+Q&E^)UwXIOjQh;xH0VxJcdns;;J%%ulJW6IgM{F z+)BnnT*t#M<=`JD(TdgoeGk6vs{McOgV#sD{;w5-*IS_I} zzj+8hnhyQ{c2xM5)|3DKcU-{hI{N>^{owWg|1XeDg6-)qNnfT>L=s`n#}N}nO&S}T zJe}pCzII%}q8bst{xGHZUvwDBxhk3qAv)xrTg?>19P~qCZm=^RQ=~~IkT*)$67csQ zrC)utAG{%GH#i{4#h^G^NcZVq(_~6uas9+RpY0o_%QE28{m$ihYVK!G=^HDxZ=<2* zq1(54|atHDy$wp7o)yOtOJ~)diJsHKVh^{zoZImHNb9TC~Oo@{9 z8rtn%Zw^(KZ}}V){_$FsrlM;_YR~^8?5(4!+@p726h%c)L8L>F?vj%3?gl~W5ReX$ zP(kVLmXel~MkN>BT}pR%-HH2m?>Xa)d&lLEJ=}XQ7i+!m`>i>j=krKO$7TE#M6edq z4$d%a(3wxGkN0yY{*}X)E*no*72)9L@nG||Yx0$(q&3mxYbeo5S|>mYcicauqOzf& zWU@jK$~UeauTpG#cJJ_Mtxfu|S&|xb#7k4HKU?PX_CWs%6V&l*?f>i+|!r2GmRw-;slk*>0@@)W%-U6fq)x9K&~`N5)@1l_*E; zae1mVC6Pa!_-)v!!`RGs|G6Tqgu}8jA@d=AQg=XTI`jR)Zv9t;QlxM3ZC|6zms&mk+=)9r*OCFr#%m*iN3;&p!-o$y zjoJ3+{Qdmkv75F0SlWK4&)y-3yC>u&2jf~))Z`)LabVvcuhAg#C?&UsQjsO}=M* z-_vMk_?C;^R@?l=9k*u@4I1Mk{TZ6$ozwB1hzAZAIotHZ=h~DMrORrF2m4Q@-L@^v z^*iRZYTYmV{0K9*#<%Z}%smWjgE8@QL?klmbKloFKgg0Y6db_UYvj5)Ws*lOg?Rj( zKJSlJn*A>$N>A4UD=kdpn<+PcW?Nq<|HnE(5TI?B|C+l8BaLOuw==8&exLLmp1MQK zj^1EBDx1f%2#S#0+Ld&pUBrXPcv-u%-T9fC0i(lt)`mU76 zy^ol~Fk!Muae8^?u=PT*qE|gYEPbJnkay&;W_&*LB(Ea>WyNd{Q39f*6pRbWbqk`` zGXwwg>wnIsV;CE|5H(;pUZ9!|rg88GXw8_O=5VZ%An|)?7kGfy==0)%jb4qcdO!^A zQVL6B)j;-d;>iRqH%SBG$yuej+rOk~DkKWmYv>dC4kmLRN9BzaYtkp{td}>gu?)f+Wp5`7kxyv+Sq^AdigfHHW+i(`WRJWgO(>E=9Gb7bFppYW^ zaAm@=HOp~6(|^b!hE|9FgfZ=Ct6<6_)eM1IB8!KK{y|Co%nj@{VCCy7iWH!q7nOc zPmjEM#*?^_Lx7Qckq0ibvR@VrlzxTq>ZWO2-}=(8I#jrxlKYWkEE^r6V|SWEHHgIP zS}E>cOMvXpv)7A@ZBZNI_1koJWTR>O4$7baQbxE~7RcDl9oqRX6Or=|nNa^VW zr&X2P%KG5F2=FF6P3Y1pU9ye&YgNH~Y z(n_MgCJT;2PEfJ5%8jPW>2L!5{Pg%&+BI^gb47lj#j(c8R^S!nmkdocmWswbEs@1; zqqTSde%ybmGk!`=h7Jo&Q*`2$3trv>T9oVelvK*6j8H68j@pgN6O|B82t;|vWK;K; z$q)M-`{zfuXl%THlh!;8Gge}bP#Yvb`nlxu?~1a2(8AN|(I0wxam{M_P8|%arWy!A zjG9(bEPi#H;4rmiItVj}q4-GCV2kfC9IE2QBh(e2M)|=!sY+k$_2J9ceY*?mhN>5J zj|9a&e%QX^fY>PsA1dc>Q<$r6fvLo8=B(FF1OudpcPVrZkc|gTrojaR8)CT zkY163f{L-UpgL_o%h(enK@aci&oz&a+*31tSBBe95zDoCNL%tUjSy+}gS5L6l43? z86MrmMe)1~{|$b&xrJU}qtc`)Qb!0+E5{OX+Zh2pkoxmg_fHip zg&mi_cNQKZaoa9_Azr(MvkEfOwy9UkxP?G4MH zJb+#A-hu`iL`38(rK3pMFyktE`9MZ)6GWp+8J|LUD@5Jckh+f0GAQJrpN90hKSDM0 zU*hKQ9T~TT*6FJ#% zTS88V!vPhW`++>S@};l4#wF4=_B;>7)&aiY+#ZU~0JjqLhD#`)P)B`}+AI5cM|gD~ zD7Z)<0|1Da0CG2n{%)Rf4m%f@3*=nAe*HQ_it^E2mt-pRD&X}3<2af9uq5b)kauKk zY$bHx;T?g+8OeS?fhk4mI%h#7P+FiP{H(e*K{F{YeQ6c#ycb1Yu3bxwj_9D>gov3iGBJp5l8qDQfGYmqLX7%68eVC56}-c^7?4~Q0IIAmD&p*UHy5J2Yj;qzQ2I25l_Yk`Xh zsZS2ReL@HsNOb{HG3XgQAV)&duybUDlabN-KgJMQf~Jm+^Gd&1nqn&MeU9WM2zIIi zvM4~zi#28WkM{S4*}F=oe`@T6uHvPMTlNyzv8AT>?UdIVy|f%%`tf6ZX=wx~ru}+6 z&}@QUePU7)8->etao;-BL=AokA1`kwoz!C)a?B`tt?)MqG~Je)X>-fVu`|==N#S<8 z4?X9QQgDNdN2VF1M zxO{S^uv;0`>B>2m+zaPC~VE)XIErMuRN3 z;9<%h6s%!^hRNs|)F*ywG34I3YZgkA?IpWs5+ARmv3>YSi z5Um8yC#uf}_ht4)r%PPVHu|KQuiPdOUq!1|dki-O;t8((=YazgD+i~@cOHb&i9^UY z!kB7KeV)AdQxtSnZlobVa{^xVX$V0E$lvkl=~qo8q^ES9cDGM_H0dD-hnV@5ATUjV zaV>e^Q&tIGVmk=3>)+0j{gVt52!OrU1CR`cpAm(5$cjTXa4X9!M}jjn@`hOB-oOZf z2E`RTAyPMk#P=W$H9}wNW{ICJGnW%_s>OL+` z)hwj@U9DuNTxT)BW46t!Apbm$G zW2=XFkaB=!dJ75`3M>+P;=R|)Zui+PixcYEeSLxqf(uFVc{>LnokH*th(P@Y_4vmM z&ErW&8UvNKew0%Ln%~~4m1pgIH-D1cO7jz{(LUHWc|w`)`uqmf1Um3?VaP$0iqUK6 z$UuV|{lNpuj`{2ppr4rSBy$uo1hwla0`da7zG9xa-Fb9m?mu| zD~qfAh5#fATp{?E9e5Eucrea^|E-*0#vVU7s9L9IV-;>bZ5hm~q=oPopE}Z?!o&S+wtq>a`S+NJ#@a1&=IduJR3C7^uux>+r{- z2c=7g{q}h1#L2LgwdhuPGnLI3?H!M-Zd z$}_R5htPRx1&u#}H<4gZ&HqQMtppf(kSaiaA5sV*qx-dm1#MMp44sBG>|Zj3JOCyM z4dt+CO>J#$;4^=Q8xL4y0NutnsM>(~8X|KTdK6%TvA^%2yvO{*1>x3z+P)uzZM7Ti z%a_H#g!H?y@fzP^mrM>g%=sI1{nl4|JpxiSbue_Joz6fN1uXD3=D>x>r`hW8>ku@i z#JhgywZO80m<5EN>B_Ol@O_`(z!iW{rH>g@Ylt2oKZdh$&&~0=#zv{9Q?8Zc4?$73 zP`{3R{?hzBB8FC@Xvlf_At4oq^>5n|M*U-}1x#iAY<<&a0JYX)hq}5;(ebe z$Vnx$nU6=bhKSy5d>`WxnW1{=F72ml1PZ3Nm*=i_Qjq>qsNcY^CB?`OlS53$!nIg6 z%THt=0~dhT43_#;1sxo43`uZg^Re!_~=#<#p-&h^;t4_rwV82XSD zu9PVqrOS)rr&?y(I!u%PIU_SmF^ie6YVhj)*`oK)jgJ!YxP0bW>Swu5qJ<|$uUBK! zbcQbs#?Jp-)WmcrjW@hI+nuSv*`v)=&(TzWbiie>GHDLN<&Mg9Ad}qQ9A&rcW4bZr zM*SpLHZ89*rntdo>bqr!O`lQ-0zW0!11uo@wS`T7&407|6igKG4@SJF@Hoj^UDtbm zIX2KIu$n5RFETv&vVw#Jr_vNOb0e54Bg9{zW2?FDG}_sG?`$6{bRV&0k+A1fi(J^Dt4Hp(c-)qox?eXptp zkn6yTe~gI~IP;SiYzz-|zXMi{_8^I_HZK^Oxd@6#HH=n#el&-3!cR7No*@;j(u zF6)1kf|5Bs*=LpqXxYYk!^JrtTizjPSCuLNDsbn^qLdZcibGVbk(UUSCe%Z^l!E&;j0xeAN*+- z<=&zGEd!zG`B>(Y#O34xG&8XQPT9$nv{m~qPh-)bJH_rbyTwGmIP9g_FHGI!9&fO;FOgLFA?Io3N6!$pEnSAyPGi%GoRe zCJURJ)~-nY?3o$LIi;ng+&9egUT|^EpN~<86PRNPcwX`{G8V$-84w=S1MHk2-6cPX zIDnlS-e+0g9wpF-OTI{CpK@Lw72=nRlRZ4#NA)3l`t%i?H=>`E_T{I=DFLD!ZSnKObb)d2qoqObxD*%lnt@o`4T zEPq@Ht+w90kw8lKQmNvt zvP<=Ibn6XV)o_T!4C$G@dc00ncHguHAllA#tw6&AkZFB5qD;Pd_+Gav$*a%KO;BVXs0l$dbj0mA5&m(Yo15y zxz$*P^1|xO(T3fb__D9QMqm=FTzVGD1CoTuSZ0IC!P6jugiRu>s`ltS%}kxM7QY=^ zXzCU$ucafl-zVzzbQI(#l)ZT||9QurGNjIKC2@hmE^2sf|FQT3b_sj!vJEcBP1c^j zVu(UKUu9Z$o#BF0+i^`hf%yH#r(1BTRCmQdOb#`;V=PIXK?DNv>lY~phZDq}!{jL^ zB~^UO;qG2K*&+d(xmMWlItZ0J50YWVWP}WLm@LU7^7XBZ-OBtka?}g($8gNiQUJT_ zd371>6|72I2PZbzG;2l|sANA77iGk)t*r&V^EHtfG^en)i+9f-s~Bb2a02W-kn&}N zJbx3uElZTa`<%w|FdII>hHR1-Ymk`;2MuiE;fTk&!CqAIRo~{X(qu=TYEGahcN|LV zA6MiKyXO`o9lV3x4XtCOuF*xBapzN#+|rnCDay@j=qE>2Vs>FL87ROh9rT6}vSnys z0P;N0m>)&k&$01r4DsxandPY-2>{)X_n;@M{9tGl6c04Et}}!PxpyHW;1XA5 ztC>H9RDe$g;x(!@?ZS&S=j4#WMU@}|)0;u8~%fD8JPU-|G$M#!C?l{>@)EEvpU!VX;AD$G$i$a0?0;_)gqZm>I+!2~hHCh&a#skOX zE7APOcuIzeA6tV{EiGJB>Mb!%nATTYFM0?Cgrf=AtuObgtq7^4W!^_IR5d)r=T3a= zmlcecE2*HvVKW}j@J^EE&pkIJ>TTws`}2Itax`%D0U0T2Wdf%S$fp1fxs#I<99>xB z0?TBi2qw;dR)~^SfpiM?&9Q*$2LUH69cu@tApC`@29wIweS73UBS{W;I?+VN=V4<| z088%Jv$0hO`Jm(uXf~+Qm0y*D^VT~!vc$w_z@OL-C%t=;Ae+k@`3}JQ#rSpYoa!?B z&$D8%uA*1=pPFVV=X6H;<|9-?$aQE++V=9xTJlxf(XQHx#yhp}BHKMPSuRy_>H88j zY;Tp@PB{2vNh^g(*lOKtJ%8aQ15-NeizN$*!DliC0d-ZnaLS>!3|zP8`yfgb-=p!<<=`6|a#foCK>GxyFWhP%1yBBRR5 zX@qR|#-Ehb=jt=qPm;6nb07aUFPW?q)8TYp3e+cGK2SX?stIp=cS^oHoivg7g~D0Q zPc*(b8?E(T3S^;5h=m&;eNEO1{y=pGTSwH}Q9IURyMt@{4K@>kcqBX#!SU=m^ccpS z(Yie>7@@X&PkWDP<=J#{Y7Q&0XtJP*I|dA-T*J zQoVqNk1%50`!+!x9U_$Z9PO(AWS`5X$Q?4amjt0Gf>86(#e=iDvuwcUbQ6|J0JqbbFw z8QNtlW^OOqzprWBc6o3E2~~vcju_I3w{p%K5MRO}X{js0`EQdSlustc$FnjrsIgFU zRL3D<6vhW&?m<8c=Zo>NG1rzrJQz>&i*ne&KYR;eBXBOX8vX7K+o1>G)&Mar>?g

    gU|(oqQFvP;db*6X(nLHpj(1 z{4YY(sZ&C<2Yy)EGU*$+g=LvnJ^5jW`0Gd)6RzJX zdr@r05<)01(Tw{JrJ0I~B7EVmUM5%A(+Q?&7vu%C>Oj{M*G`p0F(gG?Xk4Fs+w2G5 z8JzI}tUp!%{sjX=S7T$kun#H>%H6%aXF-f5yI>Z{u!F-)0vKK58X2KXl)~dkJNAja zx;sT+rtswpd%@P`W@FIZLYllAWEi>TNQRLO4-YRE`L+2%QFjK!_>lMoLq{qgSk<6C zn&GUAb0(B0VwjzQia+>fp!+c7nejTUkAm+DPB(CC*}AXLeMI4meFqH}3@XBx(@+y@ zJ0MM=@w_=nTJ&Ug|5n$4}?B>jU=mVo$7~2St_R zW}ixq;?ntD*UO=d6|{&hs8{p)9#*5o?5(guW6tvKvY^Ln;@xyeDH(!rZ3wfGlcSKM zx923>J5q%cKa{d!Y~zvZrg`Na8m|UH=+guwQu?!YUA~H|)lKh%vsq(L&(?{(Ve6~# zhdKG0^*y9&nQ*#;R4OWjC_VNI9-i=V!Im`Bv{#n>8GbNxLnK!;lRhy925FS^eVuz> zd;&vXvulfN2J6Yv4p}geM17+PYalrx)d+`Gwt+85k@_6UQT#Ou>Um50Su4F#cV_ML z?`CFZhM^)r<`0fKQEdJxBB9?5`s_Bp0`FnwI4taMc7(Ikya=6bJ+ex7HL`#}s(hu@`@T+iN)5e%XiLN z{rn?wwdTXGOZYXMZly3my8`sZP{Fi&1XC339nSoY7$4o$;|=i(VGDLs$7KOK>1e@e+t!*@|uB$IG#~vpk_vNYVou^TLGrMo`5Gv%@PRr*ETJkcGt7FC? zry?9Y=PFH({gTI%^7wqkr<5uPpZyDcD7!~_!#1P7P-6XdlhxAx*~?Y5`{|3=39`FMJg1EZWa?1L#m^(Aq1IoQURrMc zCDHKngYbaQqGTKoZ0Ip%j0eGU&}ko0Q;qW+m%7gTs@hV)_cgHuuWtDpZ%wjLL=$;k zQr+?PuZ9Pk)AGtr$BQ}|&ZbH7bP)kp&dY7H$w|s8DsEsVzFMLXCS|}ZR>nhU(MRKc zR>1z=qQ{XPOa$^RL#pG6s1w;#mZOIsq&wbL~*GtLBkxw#Kbd)+#+6&v2+~gY!uqm@Tb!;Ac z+!|kDp;2qJGT(GuHmEAo9`@LD@bas?g+J=j6C^B@>uw|bVCjLrVX#T7PbrKl_`J$> zN_w|vteJs=0>LX%rSPP|Rp5d)TC(#Yi#dBWkO4EYD7U7njGm(>0tu?Lf*Ko|iVJZ%ir4Rd zwBa^6D1NRSPbTr+x05drf%5$s_(Ii(hx2~i+Pr#i*;_vq@_Q>gi+o~qJgP{uN^7mC z{-iJ@sG#ojAQH`a&F}>3;6}ig`mkJXH{{ahYIq27myXC$uW8B5}J< zEP0PS2jm0Xu-R~3OmVXHkn6APw+e@e0Fzr4{*06f&%u{=$kM+#-0sQywi4sVKEi5Q zy3GeQm%L8Pv%mOWkP)9J#fSe!)jA?eHrlJi>4{;Ae_Uy(vS9JNeobK19Ty4dHi1?0 z;K}1TSBPLuo~sNAbA>EU?Sd?GG!i7mFSEJ3dPam(Z@L2RzxHQnl;)r|%

    XABn{b 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 z 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

    KXr9cgyQw)RgA@xmTB9qr+k6 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

    cmqw-pibrVrCQ?mQ5eB#+o%5~ZP7 zk*8T|R^M}8sKx@dP!`mu9PvMX!AF1$*mE0IHf+R}ES;(#O-cO7Ea2i;o=*t*oD$i-5J#=#LS z@i{3TsL&jBowpJN2rNx#>=vNUsBfrO<1^PE8~N&-$S~Keq-*GNl3~2}y~BU8KahR2 zv>2y0z#J)q)Q_*)Pu(d7x$P21i49JVx&z0VYV$>-9 zPR!bWc#Bx)D~&yx9Tt}>_X9$hNGdw#ZM;AVb(C3&&816I8O~FsIhze4MaGS#1(B>d zg+F-4`7>xYAAg`d`la_{`!d>?5b;~Hsw7tES1=ljO1mkW5nZ?PIDMb7$QKtmF6+ZS zHaM?Uv*mV;e%2jLuOk?usYlU^o$^K{awi1koB=DH)N=6#`d+&MGfSj*gnyA@R!%yG zCOb6YWH-rrq?(vYK7Z@aJidQh(=lU}asflkgTg_mJI6@EoE^mWQV|J^d$r3xepZAL>2713uXlHe4%gr9j zPI5o~b3d}+uT0m~5OuYLdLoc*3r$eVRU(&-ELK$%7z*m70ZDKK zA~_(%d9ra#)3T70JBv5ypRt*R`F>trZN?MYs8l_XG&0BM*DkkO41L*=?*iuJf28+S4lz8behxK7wso|F-y4!*$X@OFH!&h+)k7#9w@;0+NE zWl~?HQMU0F>RA^iIXu~JtL}vc32J10n_Bh%sn{7;ZmIBCcL^y$WwlmfR12zqdSOA6 zB&b}Sevq%#VOAxGTavnk)oY*h@wD*5l!43sTLn|*<*)l+3cAJ*Dsl*vV>F+rkLfkU zQhEAg4R>@aO4fcd!=mJ(ro8sL)apE3NJ&y(ndd3k^rZ*f zCl#Co&uYyuFWzD}+p66@cRH4w-9_`)t-@*76ajm=++RgQ#x8&D!}0zSE;G{Kbp2FHTphRkCEH-_E^G zB$P+rtgXeAg$t9C-bO^7(9o-Y>p{WF!^gPYP;AcO1e<|8B5!>!~PdpxP`gPWq`Gohru(U>OH|d#0@sb)sBXueK|Iz24@l zIO66KjPyR;--WHRIm>;^(8&b!B?nPa6PeO;9NL*8+!DGtM8AWSlhr_Wcn{=Z=Z9Tr`~p}f@_R(GfZf)g+TEqCr!uC1U7l;!UJoa z!6~7dh)J7u2{^IF@ejq>Tc<~`jN_GKTCmW%9^ zK@|5ef56_+_sI50|8VT*>T`DwqfY-Mq0Oj%Pnvvx_b}#6_(C5VcRUvC&-41AXsOj^ z%}0W_9U98%!Xpd$X_-VI;VU~wl{j>Kx+r7UEFw1;1Q(1t=+yFF7RXx|7|2mPB8lB4 z$v(X$XS=(pscWzOJO)2sQp5QCd70UTGKBPxzztXM1~lG`cq(2&87#hk!2?kSUo6Te zhS0+6L7Yx6?d%*qgzdTqI9}fYyyv`-bS-;@Q|h@7EQudw9@&OZ27z5@Oy0;t=4bMh zx`{PIDssN*LOW+ja&3nT*`Q&8JLkqa%Gr^+5&cSKbg+^^Nu1<^&@c2S(%gg0^0)-O z2y4(i2$dpKxi$Qm`RR9vLXY?1SlhC0o^nPYp1M*>tbP3nb((r!s}hmWqD&vcBVQeH z*zl`kf~`T$uh8d)k_8gPvYGtuN%>fJvd`q9X}Ua}J;M1% zyjk3MH$Cq|wzU~rync@_oM&_Lba+d=GP$vmD@i;~Mmf>~>eB(dE^F>R$^r~n!k8JN zh)%0XQ@Nky)XihaoqC54MeX|T z{_m0aC>$#`lnv~m=xPWljx(nL?6feTLde3F-oeqK^cw;s<6$aAb2Zk875|?zx(dDF zJa=Y4Z?8TkKAb9VvC7APsKdaW2Bz3}&gBXPbm31(zTywc=P1uo$3;|q?IEN@v0BRn z#6v~BRuw{?=Z9?CP%qS4oS>paO{j>%D?E?3HUrec^VZw}EBm==ld1`|4xY>6XH(@^ ze5(u*!6{QF2hVQ9DIRfjsqZQ2C!k|ws)i2AZVSZ5QGaYqjA_M5+fU57{AiU@qo#0c zaz$q}@VAKW{rfDHZWjV==i`tw~^k4UU%W zoHDK>m{M@@oBE`ZWvc{};Q_swTGcz(S-|>v+b+ofB&S`dYhTN)jL57Vm4z@&EIF`* znnNLQ17+GG%J)i;>3neBT+gSY6+EHyU(M@OJ~El-o0T(O0ZfZ(%JJ9EhJEdJeJuhr zJ6)lNe=iJyLER%8oDO;l;kE=q#Y^5b281f4TlNQKCLGgnM?5@*fVueg_7I>R6GWG3 zhfS6BZp2K?K^Z|fwsyuowuvs>MY^P7#7rHu$6jE$jiKSCbk28Mu zyV3ra>iQZF5`Ns(7|uM4B@-MIlN`@I@uM!zDJ67#rV$z<13Gu9{iH^19P2HUk)M9y zNUT+)lLgY|;+cgUEFU_OuX*y|xMuIII5Q5!DZKmcgRaJ~1L#to|A_qf_|(kADC z+4m;tmu0RS^wdSgsPIVmUL2@zL-LjZ9Ao$?yTz|a2GZ55%Ojy}P5K`B1hfY##(5eE z)tiis&to}r>Jb_2-=JH$H)OIwBpGC#2cNr?&EwR;^J1DfKbnr>3G%`d<~nl-K!zv%>q2<1n)ATQ9J%!e~qmt6Hc z6W(>4_EodD5jialb{RBo+tX9Pqnd{J-T(aJN_-oK2SKNzuH5Jtcl)#GH;H~?N}#t3Tf5WrvLNlhkDl!c5Aq)qho;Au<8 z2EJ_xBHhGa{8Gy`lj-X(MRgUHXcha^=|8*8C%Q}*_s5#5)+eCGSG^=QpT+6#lP2_V zm>A*)`7XlLuTeHZ|I4Pk%=-Z_%I7j4!9I_0GL&bP43BmxOso7a4J6Lsx|nA86k-iY z{OelYXNL!{?Pl(pKy*C4jc=;=Veow#L=WIJ4Fk%5q4^SK44&P!8hQ5O_u%BcpX9H( zQ05A;2RxLYm*ktGC@{9Gmq}`u60MQK312kV`7-;fI)Z7Y2@`TLn~8OuqcdalVH?0iV~N=y7Se5COP{UD z>TIquIs35XRNrZ0{r>t(jn&A{SgHXt>-W=xrpb8!1@`nhUl@_8rl@#-%(4QBEbh|n za$2EzAr`)av22i$0T*AV1}4Gto#w-{?S?a@^ZcS3)IN15@Qqt8m~Pp{v{zex`-iK9 zej^;gsN6;j4U{JHScsN%WDLt@ed&!o=(4X{MVlzjgoD%;dkjhBg@&N2>4fAZGN>#X z00ifRJ}kTDHc#v|lA%>*5xqtyeI~shUsS1%ABm+>W%hmP|Y z>@>qa{Ti*<-;iTT=I44*YnGfmFFNV=wka9j7UvuZQ*h4T5F{JsW$s5NW)59&+LQ_C z(t10W2~BZO!=h&_y5$@0(dOh1dN0lwY=hl{Ga>~~bMHT8Z@==RjGWdlII4=FNy4q}A!@Ud``ROa^P@f3C_?w?2RU>xP>~6V=(gLHo;U}PCWA0zi_qfhCbsy+hB1}q*{T-tiVP(-CT|9=32wcN}I8M z@V(>0%4xI0m8`oYveSF|S)G%=i#-iE{g^tObtYuX&W7_I7s1x_ z)b*g@Z)|lW&OKDEz5r03fGgOkts0O4;i8IG$Uc#>9s^Vn>z&vdJJw6y&l>{dIUIF@ zgcQsXtgD=-uSL^#(41;@kLwOIvGX)4w+gLF+cP-&E)G9b`R>;Y>kxGn8cog$`p;_$ zjN~f6oE7M=alsQh+h7x_7$)K<6!8GVkHq-1KG5|a@3xUv3VNT42gz3HHdTMkd772% z@NTZ(9ko_Iyxv1pRMjt3b?HF9g$K^F5$lA>=NWma6D-2Z4kF4VPWVH)tju|T6AI`+9I`_#RpJ&>iKNIx?ZXuFz z+U}`5BMpEdZyBvX0hB4yN}onw_9^>)sh33UPpPFuDhgec(b=bqlkogn@hlhb0x~~c zmHCMDS5!sqs5tclyuG$-to*7@b@?2~ZB0LvY$KdzR#r#{YlQksc?W%7<*UJ>>XJTe z#3ps8$?kRg5Gpe?daA%INwpX-c%%_rF+Os#oa~lDd|Rv~+h5EZQNQu6b7Sd?{h^$* zLNPX}SMS~CQ#(ORpZ{0L1c0^`)=5U1O)wiWOqUZ$u4vL!}?5!Rw;N)*_IXd)TT&Khe05F?cFfmAv7*tBc z$Z$jFVRm9eL};ix9jR$A*R=1IH}i1-2V8gFzlI@rxR4WP)+pN?$1g+&7F5IzGXMbE zWICGMC5A1L=a8p338L)>r=N>+Mt1yh2sT2Q>sc13V)Ft+TEK4!3F>Zh2w771OMKex zSrZ_CuZ&=W2Fb+XP;V}95eMXt)V0RB74b{E=t|t}>;wx@Q`XGXxb<7N$nOpCx{!jg zsrlMUH@2c9tP5+*`#-wYyn}7;tgVm4+RewaJREua z`%JApxL;Cd^)i+7mqge3iZrcVbRiy#FAC@N$jYZ&2j|(wh59P^C0u-tgw(5d&V9v| z4T{b)v?MuobN+}>o;(@>HPJKSMR6QpBCfVT8&_Om1?9lC}ud%8XoL)9qAzNE!A+c^yRWyxXqbSSKpU?KkRq^QuvY} z>X<6$u>d7m9&JA$RU6H2RN&RKtd>{7?2Zo6qjb^W*+JG|Dp2ggBt;wX0nP)iu`WI1 zHNLM{u$?+ij|k-Q0y)jB+Put8%{jU=L)S||9x9H?m!DCrbzYsTyGb?J{!(!nwWmVe zD7_BD&);1jr$z7=>bkCG#kE#Y*#xAsfIbo_yt=XSgIIsx2_~GsT`9vzv#T=mesL#r zdkVyLAfP!NIsTazE@(s(4JOGRkISXbp$&Ed)lvGbCbCMHhUAF1kv%@W`Swcc`{&Y6 z^^)savtBMSu3ufO?8bD3?lA-=rY>cc2PS<1fv9jhDJxdB`kzo%$Pf-$3%^>hghyEw z(!^s45m|qBr;CQPePE%(lh+lqj>0H73DKsfeyDW%;dsp@_l)+v=5#7+;XIHYJ({jb z{L-q{etw-`ijX%a>UlYFOq+-Vh%!xG)PZcI;Jyh+ zH0u(3ASh`X>2Y&KOsfZ76}#G%&gJhj)Q?>!u6i)SOpc~a=6-7wSi)YR6MfJo=X+-# zTh`Yiwn~e1{2+OvKIK4GjU7v5q(3NQxLBoc3ypqOcV;W|3Y~NkLYt@uXV6sqbze0O|-I6 zT2b0|FKz?mZFX+Q2l;F$!z;Ze81mAD{!ON6V@L!T=7i(KOTEn{uwMt6F?Z2v(s?Yq zEYm*V!Oome&ukqASU>lN3KXAl@jK7t=dzFw=Ie|vg0HS3oAwWMwbPTA=wrUpAXIk; zs~p2VIb>ciAdvlc&8%W9ZFi&7(BngHTPChE-bX*4r+lmR!LQ8J#+p^U^>$$>-^FS( zSk7=oD-ta(vk)U~K{#Vj<0i5Ziw&=m5hikiuA^RRXo(jC5W&dZcjF`6{bcFX0^*|O z{t{5f+mTXGCmHS4soF|ntb>~9Lo()0GA79YQE2d*OMLD(@2Zp*NS0KTTe)0f0Fv!M zOU5h@Nz={0CpW;m`1(06-s%A(-q55KMUC66K(3U2T_8+GBs-SKP|tAMLtj=HX6h0t zdbLv8q96RzqbrENW^4)%`e40{SOO1^RFI!nr(&Xi3H>8P3*r$R)0{L4^(SC?Rz-Xz zdX%lPF5berRZ_Y4)OIc+&XH7nf-e!f2JhGGB5M4M2sM$ULd7^ur|V}$p@x`-t&VI?$Zw$C1R!==CF z@%P_^>8Z~9>l@Ft4U&>wJOq-)q(%)7taNv6oOS;Q2Kp6+XSn9YR+}LU<+=2GhwQ6iE(9k28#2i+9B z&0z-A2=&6OdZ$O9G@i;W)26?kUa%#`8g`ItvP>29M#iQ4vqBF$LRI`C_la<98_(F2 z2vT68ib;O7a913U#Ehno9Evy)v>DN}tfx^QVnXhA#7>jxJ%;R?sy(VlEM&R!!{!KUVwOxqVxjpE9FUjHfKvE`=nU5WH8CoE-fTRC%|JVgX}u?4_&9z&5JZlIg);<^?ASB zS{a8GI`LI9Gxr`U96w(do%MC~Cgy#pT=BtketQ)uu3hB>X(dJ3gXJ2|KuRWBr)$AfqA~>b-RN(9}aSH1u z?~5OMq3HYoKo@lhVi*kIGFSjW*!!N-9C62#$UV@b` z?N9wV+m9Fr*q2wNCCUmC5?~a88a0A1SPu1pen6|-49aiyTmbv7UVx!cPEVeWP>wOY zp`}FEZE7fJeR=6zJSk&d>T!fe%$rE*l~CL+Ug{EM>RDx-#n*Xf+yHNBhU7AuO>^hd zeOr%V@7T6=fUUCLHf;SyuMlk~Kjer`iNc1Huu9xr_om9Jc8*^vJYhhqD>ybPGa-x_ zj5H|f1hLaUPhH^KLyzCcTaqjY6tEL&;`E+ShrO9v%phR+IRSbFv7j4$eAM~lf%fIM z(BwN>6TxZ9G4^KiBg2i*m`&!pqf-#zUc zcL=F4L6%@Lb;DIqC?TrI>mve*4$;p>ekaUkv{wxFM^oRg#x9-1=YJzcsw-v$!GA-< z#HcLEL$tU{O-`L3walWR){{6tW}dn!!4#0oz?J7HYjsJllZlK^Y(UG%WX3)&V7cPk zMh+|wfrWw-ab47;ip5_9)H7JA`sMh~{W^Zxr~rLTuWEFmK zc62oGc_hhS6xxHT1(W2ieghY!PL=z;%jxx4tc$HI;a)5MiYb9xIE*Y8#Hkh$?zYl- zJA4Y+k;2SE@olch;44Yj865wg}XQ=t=%T=S%guBz{{e z$F`sq>lB$AE_lZ^#;i%Q_i6vqftsNSh_MIn zT_;6@$CGd>^BqR_Q!iZ`|H`>uypSwDIH-lYBnmqX{hr<}*S}aPNoJXL#AI-N_h3Z- zXif)z>HJ6kPUI2{bx>LpizSI;0Kz+na?8h($4U1P@Q-rC`9Z{>_R}hN^mP_ZueTa) zJ(k*(=afB>Q#Xo|gkGqSp9dmL7vGQPuah%Jp9W6Dd+w%W3XfK3Iq$5FVR7;8Wg!z+Pk_s7GZr%F}sNyQH1;b;Z5tQ8C=PPqq11dTLk z+>T*^liv7NOPc1p&jWc_)k#feA|gP6P2X^$5 zBEzr8<35dy6aHqLjrNfWVmm1%b;?te?j>a=wTCU$7g^WMnuf+&uG;#%=cFtK?~Y<2 zYeC>wu(N0scc0*$4CSZL$)bg(wMb{!GH*@qN$WGNu|ow3=1r1MJQ*rEA+K#+?f1*K zUXRp42~(~_PQF!)+U7LJ8mQrfWG$@Ulpt+AT_j(yly2idd*1WTrA-pC?hW$49#}E$HwT`FVpL+B31!5H?cv$w=lj$o9 zo%~9DUaLsGhkxn#p;ygE=}0dr^M%v4Kr)i#u#>sLgy%`XC%P2FmKO<948?bU>! z9`Nr7UonKYs>O@3;FO(aDNKqEH93Tt|0!T1RAkJ`S)eG%IUr2aQOfB+hCI1p$=Clb zJ#B9SQv^WmCyZX-noUF->n!;z24`eUWgzz`7_UYiE%TfnZE*68C__VvT=9rZWa2uS zcSnsQ%ZqetJt8H6;q}JEDV7~*<9(44z#-!j)A#a zUs~pWnIU{6YrIHNRO$XxbL#kGrj@P{V!tI?gm+)=45})g%qjNuUd~CrCn9FY?9a>8 z{*exR8|F!Kt_caii|n1VmgT zfN=*$=;WBR@^tA(rzB95N?>O3OTfNs7;ech6`J&;A3?0%0V$y`O9;xJpw~_>72s=W z{E9c9b-gh>Ll?o~&jCiqSg~O<>w;f23;k=zoJIO1Q-^xX!#@`0dj-uq+M3Pn8*J@T zWZW61HdCjbfLgb^$ReC!pf4$fm(dMs6Ai?+3U_3D=vYSs)Y7sNVwPqkB$ zt>Wm;b#2Gh(Kb|=pWEr)tN7&%_W^{_RBMU?kshrWokB>KQhHJMh(@DxA;7iPTtvaV zac>0Y!|SOLV+Ob%NM9R?7sz{aa22XkKLi_F32Idy{t(+6I$mSg)ogR|K4|>Y&Rn}@ zxTFAQyvePH^{2+{JpJQLog}oY7eHuah1lPv346xX9rT`|@*_VpfFyfglLQL@Vx(*1 zE#hN16hsQJyG-Gu+4`}uolZcib~;pr!k8sE9@lmopiL38Q9Y6&ggKlvTwU};GDJf} z=XjQr=9|v}Cb2cM4oX*RE~gdXipJJm98O&FKGoLy!dfVMqAd16X=ddz`Z3RB*3FMx z!Jiqm%8IXZpWrSz(d?$#YdEz*p-|Rn2>@4Y0QP6r{TIB0deB9pRC5W~`PyLKe1PU6 zJ>&<^7?5dQxXaoh25IBqDp4U(AN$q#LBPJDS?G74^xu4;fDnMikXECcK$9;jf&Icc z>d59C$T-Q}f>UBpvj&HuqUlOh=W^ga9Wh{v+>i$x_S2KZj}m#DvYCy*0MmR%(#Yt; z?fV-5b@wpkGl(1(Q>u>8(_=~Eew%*u2If9mVk{}tEpRkBkD$5%S+t=ZL3B)BQDwq&KOv1F@1*roYqA|9 zQS+)!aroK*J8T9BrJW-eklI)7bs=f|@*Ko3h|SA`4e>v^-1|M1_HU9cZ4ws# zo4d>2pIV5MY0QW)XxJ62>k?&TkoZIs-~wQSwBS4?6P0})j&lK0D%2)IuE5x-y==+)@MGP%d5Q($-Y=Z_Z|)K%PLZRFURyb!oM=8$ zm=wD3kXc72N?$g;{DS#wiqGk)U}~=DEWl$Vcm4JKz23)IDZ1@W{5J?eG<$fW zDEgX>ARx4Ok;mc_oQAqfk5EZKifvcTKiCe3SDyn3M!{El6n1Ban-{MGsu=u*c-;a< zt(kcBo#Ntha2YKl&|Za_rP;)a832v@RL1>2RO+C>=^$!{POWd=YM?#>J7U-P8{WUy z@3**0X$R-mYptDa<3gKnuS^%%pe(zaF2MI$$QhuhR<;#G9)7p zd8A;Tsv}W3xyV-#XX%vKM&}}NEokwYCT#K=<8p zW1JN~Bz)w6=n{c{a?Ns8{~Ra$!HPd!W&APq; z=~u1w;X>~;%HXVyYc??lq$Dm+BZgm!C@=*k?G6!w=E!^pi%=!M>{A&D=Ykr-dsV?@ zVcP_U8M8ZSjQpLRPP0t`muW2S!40^k+W=hC6AeG07Z+scv^p>7p8wO^xHeD1ebnz* zwA#0~0d}%&RcCb`Y89v;s3N`xvu2AX%cT$plsWR~7+l};@Z}p5G`_sQm=U~bYq{&o zawwT}7%V4GbQa)h9A;K?F4`t0uRQe?2tei=)rGv2sM8!$oZFbJcJhu;A&P_p%Kv8TaXpfJk3-2aVoy2vgVARPDq=$>+1plVX?3PL-YMZfDv_UZ6#=>N{b{JS7Yk0I~?x}EkUW*l*^NpqIHN;Eg}XA z1@MZn|53Q2xG>$rmcsSla|3k`*9AFK9_xkE#@CGP%IhkQZXy9Y3jCa#GG`IXl+ zlx)fN`*5#hfN@%RjShx}1k=N1&nHadbT@!%o_+E|GzeAujCswRoxI%_eGGv zd>9*$6k^)DpbT4k-X#HB`XH?|DCQK*1x3R9Ya`aR&?d?J&~M4k{nGXDy8fH~A-lNC z`ZdmZ0BggOdKNOmtY425QV;md{stLf9n>T@uKv+y6z_tAtDNeY@nEiUHh&I4?nqT6 z{kmQUQG!*` zDuXfS{BGSv{>pRkBC=4qgKSOYb+NKJOhkwtxag4NTo(Ye5warA)2_X3yf1Ofa5)|Y z2+LaKjL%+r?o!6VwZZiKVRZ>o$e^|#0Z1@oM>D?Ls@N9w=u>bbeK-|4n0y!Q0i#(1 zh%R29=UR(h^pTK7&LMXOwSpa_&&9#W%Hkhfw*Oc&%4=)Z5svDyylv<_T5RY#1W||f zbe$tfjQ_F?4YUcq9`{$&-_#-fgBJB42Jz?`aMem)N2WXfxGjKIHrAL_x=d|?6CNNP z-w6<{YIfLlF^qbOI!Ukit&bI(_o{jSs6Y6(tK2X9?s>-QVu!^)E#<$|6*-wOtv7j< zwA{nLJ)jgb;J)pnP1yhNWB;RTzT)ExKW4<@3Z@hN%|ZV!EVoMajwMkqCG48#_>XM} zF)_2OhOL$EWOopf7rWdk&?#vO^t}wW1*UmjCo2D+d)W|RW>s`Rs%f!sS#AWU59LD` zzO$KF{qtaPGV zBSqahE5OM9R)|$#a{+nd9GXR4{f)>2~vZ%sedmjRl z;anMp^VhpTuO&m>FX^8>4nX<|d4c%~*!uk1@Nah^LjZ%_lZo2<>#~VTVi=b7PO(zo z`U)0t;u|8*k>8!+J0mJ=04A5cAgZs96E(r^~$-eMJy^XO_+R&wlB(APNhDMqQgM_6WMPQq9%UTZB3X zD#o2(g&$6>L~~j#^vb&5AP8VmP;sug_pMP&(!PT@uhx59FO`pj{VK6INyQa@I+CaKy4iIn40W5N~Ia1K_gWzRLPr6!R z;^B(ek#_U#1Kr_wAWq*#(b}!R6i)BfF#eyPRR8**Nc>S=l8lMk;$woMo&?&bYExIc#;&pvs>Up_BAJb!9kh$P_8kxw=JQfX5n_Q1{%fgGGUV$iQo zvP^n}O=1AlIhDc~)HOG?$~WpN^-3Z6Y7;HeG1me8@LuayeFMJ~cKzu$j`6~@u0(;h zY`J7Bm-WF4b^R@S)6UOb4z{lURYdxu_l1&VR|0PsHY|oOc}wBtjt%g&`#%+s z9UC!{Kh>DKhPctglZ9!|XpF2v#~0(Od%evC?CYikNqK)#+W2ssvso+os=L`WYm6KT z9Rv8{%!i7$t?;TpZSzuLioscC(V{MX(Gps znQzyB-q;q#0C6l&xkRVuKCR@A?CXfh(J1vks#rSPe72q=_)R}Y?x07z;#`$%EmG)_ zry)4)7$j_prhjof-s!`4K9JidBx-Fj|Kx9ba+DVftq&Bf7?+xD>OQ1$%ah?-w1Y6j zO-zMO{Li}pxM7Z^W07_RUhDzQ06+hSR;87te&o|lM49LOo6D1BeQNIarDhRDf`)UH ze02kKoc5QPe5-?Oj?PTUe-)_nmr++dZ*shB54#J^QfpX_ClkB9+n^y<1zu%05En1T zFSoJJ#$+#2E271O%7J=;8b9f~M$>6L)#s9__YR>_F!lYItBba++9Rejqa8A0pDRDS zfu0VH{lC67pdXNofWD0--gU`1zWo_rp|WJfM@=&X_YqOhF$P4PC8FV^VrJScwa(l0 z^a-19>0PF^rHQ7;vtvM-p%hxWXXBD>9`5NgBI^~=_jD+KLfJO53!*7BallwE*Oi^UOU0O;E!$Ca+iGfq zxm{1&=fL}G6O+(A+vdRgmen#Rj*B)yFWicuc5(&3KpNFX0eSD#4y=Z7wOvr{=A;3_v{ZxJ$}UXvl|A!7xn>tJy!AQH?{ev zD=RtNu@Q*u^D8wo!~Ey%1Q=i^zySX^zx5sc7m)+_{ea)pR@B%@AM?`KBsC1s!_pv`Ke$o3j%Rb$lF0=A!1fW_WY7pDtvZG07sw^BLSF>_ zgWop>qAj^<44Mm!Wu)c>UctbiUQkR<>T7TvAu!3BCEp7Bo~xX(F)M5W*}^`%+8;HM&goW&FZL0e zIo9)~FPjs!V=Xi$F$x0)I<=vCy9scQYp|oU{&a3P_?9@jnwm1MY2r>kn>Ud zX3}92WclaL&kP4P6;`KcU*l@Rea0P0xnjopEsAMYMk?U`H*EfT^y z^7p&Ari-oUGQTMKfCGL7?GaK({;7g-ac{u;iDUU1`2o#|DJ{&yv)9R9;op_3>vS-5 z=ubdVN+98)Q0uyhl%jjh9`6|I!|U!a8ZK~6rmA3!?62KIvS}-WY1jeiA;tF+y1t1N zZ-(Z5OfLz&u08+Fai;x>B_n@KZcJ--BbjEv@4Fg#v23$I1L2m zGt;lW;EJvK5l8Vtg-#miY^nOS3sF z`&$l2z1=3J1VDwxz*~zBfsDrZ($&#^SMb+5i$01obUwmJPJ#Q=fG@fNMLMXd)trk!J?fBh`v zu;~4MUBtIO)6hUF3Ry7kN;IwAs>z?3af#D463hRp0zg{@;5@$*8iPavaiTTE^1Z{o zp8A#8@r7Lv)kqT8*jiHMiDE;s+l?p8G*Kz8CdqouNaX#h-9K`p=cK-`@%4eb3%!xBCa~Ct4##rRJP9#~h>gK6>?n)Lb8g_bOU| z=08mx;rY0tld`G~D{Nf{VKXImyTFTx_I3s0oZH{yf{#&zYAr#?)S0MD{*ZRa2TQct zr+T0l5IXbU9@T*R-LvOvwyD^AK)|TYjP7Y=4n?Xn(DQJ& zI|eK)s=1wad*s)qLc)r=RX^&JLc2N$ZxxXD@Ac3Me$_lSH@NZbV0r^B5OOaw@-~g$ z`&$bR>wweDbE5Us^>a0vmP-`)q4~a>ZLV-{a10xledOzXXj|ZT@A)rTSBxw*_nx zI`j^Gk1yx$MUhH*s+!qdK0=Z3Ie&Zdxi8srO*KPp0m2DHo%IYLk?c-a+be*hBXa3_hrM}T}_Srvxg_KJz#_7*9rJv75b548U#WFZjUhVsr`&25gYx% zqg=+LMLbAv)Kvc{m2|BZD-c~W47 zzg0<{%dD4@N#5hUhe@Ah-q<4+A^pGONLwsW0S z)TNK=XZzpJ2c#;xFu{}9%ii51K*aZIaE!6% zn;s!)+V+m_BZnR*r7~tI5Fcn!fZ(a6A}~Q7^Zo}D;2dO-wC}7D_ba`uiZeW_>*03o zaWOSUkB5g3(!xE(p@+%o1T$bQ}cZOZ;arx z0FkG~R$O7CLImE;pzlDN+$76~LYAa0C+Nja+Ts>|(jgli=a49y-rLKIdsY&!pdq)b& ziiu`59qI|yYIZWU;Z2U7iO-Wkx0g*G`a-&ksqs-@-e329d(Th99PZe8MHksUkZTF* zyMLVg0su@IIo@tofcokCBSx`qNdnDqiQ5+gm)b;N68) zpC2whJ+HZ6wkdbz76Gz3gCo_D!y+~YT@j~h@yNFefGtC}U3Lz{Vv>Thub#kbeC!Jg zx!Z{V+Ud`q#naD}?B_mqheAbx7Vy;e^WBWxjI4d9NV=?N{{SC*!+=!mym_u1Ko|!| zpJS=;EPAFMYhjBJ+Uhqv}oaiW>WV znt66jrk6?R`GaQLdz%}Xvl7+l*sQow37{+3m|r3m*BB@cJ|CMmKAmHlsr=+H))vct zx5vlRpXYx03toRG#uM~w8%<-QcB!)vnA9Z4|2uH4nEzBn?k^2*0-F{9%@%g5mI2o6 z?i+yKdE(M-G_SO}kFSq<09>XSDi=m}(${nFxL_lYFOj=#15v(FJ^r1ST4raBB+64@ z_K|9H%H5srAmCMMf)_HGM)Eajp z9P}zpq`j{02|NVMB0e@k_Aw4iS=6KjtcD7pPYs1sdfyI1uopk0k>}~vEyyV{D)y@%GAZLI*oQUHBYH#;;*!1My;0VlgNDJIL#%%wl28nNVh7R(B-Fajqy0& zZF%(P*X>2F2bjElul^AQiJ$7-J^ec6*Fs;Pp)0<>4=3a?`J%PvcVFHw$F-0zooF+h z!iXDVDfu#Jo6>8ndCv@$!Sx8V+Ab$zJiRTv2xyWt6A{=~e1;j_?vc3W0TwPJH^I9+ zap?=cH)zHAwEgNDL!l>KZRfseD<<-(Tso>7tL1lFOLvT&q5|KpZ+YjTBO6d43W`JcPPu2oPOpIz4o}LWS`Cxz8ZR1)%b)r zIp5#*Bg-02i}r>mf$IwqspqZ&LlA8%hdZGvnRA6dMxXk?Bh}+$ky84R)DlxQy_+$_ zUIabZRaSLAv=BOcf3DtWr(lz0M_3HG69>? zK;ZOPbyr6M4y1Q5fD209E)&6BZWu9WqdTnMjGFYctg18Sn0oP---;_$>_9mmm248t zMBYbR?)9GQc<5KpIS#s1es~xL9Dkj+mz`?d{~Lfc4LEy z)VF*Y2!lC-{(e7B(2*%;WfY^|O3BP~3xA{gu{RC$9`Ei!_Sd_v;)fg32YA(;EoWL9 zTmh-lP%>l21!WBP?w2<|epwb}nH9*U%0qp4{!TFpO^_+(ooC;g8EkyBs7RX;B9Vm= z6?phw%Io+l=sSq2+Hp&Qn3JhWiJxLqnr~&WUEpxKG7GfN=o%9BTeHn1+;+8o&}z1H zr(Z+!9>lq$3D`DOj=Q%cV$=ZTkD;kENvOnLRiFyO9Lg1-OM@KsWq5HC@xlJ&6EZ-zhg+cz$C<%@gCC!fc?QKR|y}=XR{kX|KO&MD_Ax%~C3@F&3S=1NX~Rtl<53a8Jjc zB_*JPe1*^LlwWc^#kJ;V9i&HERQ%LFIH3pnM`H5@eSqsDJ686Sc&kLEsBm%y)2|b7 z_)NO#bH_XT!InmcQl-;4_NwDP8wq+Bd41x!*!eq;$?f`M#c_mn3-1JEoS}cwv7c~~ zPCkV}Ym$zq3yAz06m53HK|1r6Sv=Ym=^Q>0L4YW5*zeIdp8s)@p3`yC#9!Xcn1bMo z#M2YM{QMm#7mu$5e9^~>0ZEZ99wRc(_saGg1l}UB z_ySVe#knML$2cHX`uON~SMp(RK=yZp9rlv$-k{eWKV+c|ifHqAf7MVo#y4u$vcc23 zo;Q5QtrZ<_sfhOnbwh`_@pcAWGPJ`mzBbP8`@r2yQslx!GQMQobL+4JB-UyI$ zyVoqB8_M^rn(_j+BX9*!o;}sRf6~YR5mA!+16@+Bo6t-A54qc2SBrJwdd@qh50P~d zqQ3jE-4D#jXJL=7GdqC!j@%Q+rB(F`*n^z{|81L|!|DQP$qvbPsf?N5JcH97REce1 zhyK>J;y!~5OtuSDxyQNwf_9yw>Bp5CecAq3@c7_kO>4*X044=%=?qrabO`cFu9aGA z*?7f6W)Sl78vCxfXxJ0Sv0s(z@8=3mY~b5A#J^Zj>?C~9YOzV10g#1!WA+7O_x{2R zwG!op$RC~ZX$QFFI*qHyg7wMZHvaLjO)ht$;%^fETf5g;dLCV#004^R5ARtbu=FT? znpGCMg3ncJU3p-Z-Z(#K-RO6($Nz#bRndD2X-*r^W;R$)nUB=_q43!NNy6pr9Z+@& zkU{iebmdK}vPQBRB_w>ZrpF!Vfod5C3RL@|EQ&MxGc4=w6^F#f&rG}cmXtz2? zCW6QFqU^c_=iT|N#x*0L=BsVJ37q82Mzv1wlj?@U*+u%Q zjtzb{6rQtZ)*S|H_&hej(ux9xkN0igJs(A5y%coe+l(O7Y~vZqI0N*JH5j5{NW}ZS zlef34rubYo^^I%3YZB4WzL@vr4TlD^Y*WF+eqXD`lj%OXUsS1-yAB7faHKEo8N7+D zpcdpB6NK25t^ct5=XyQuoPa!8!!nPkAvR~gW`)!L!AC_Ys$66OjChGApE*VTB?7tq z?4nGd{BAO`^~NkD&E6p}t4+||l_&|FXbtB&MzBysX8e6szoDJ9daj5k^M{!G6YnYV z)%r1IN?EN6JdPvm@M2%$&#qb^o8~q3U%v0)qYPq+jE7X{S|7Xoy_IUCGs5^ZO%((o zfunb}DgFe%dVbumaA&Nvv5)OCW@LSD>9fBbb9`L(+iPFN2R9kV)&hK+jx+T-k<*zl z=gIB)7~5rduyLmMEUsS?QM;FStX#-ymHR4)+Rfs0t}>{lv+=5#m#U}qI;4Rs?uC1eG}gRqluNAmj+b)h5S847Reqt8e(udt=Tp=3{)$Se(Q? z`q8eAb7NE+4SC=^nf?7$q*qaC^>i<`{(3tTS1bE- z^!Ocdx-yj_5VJhiMP?|tyAD<-O$73d3K@_l)RasWN@o1S7vsONSE%y!cI&&FqOzY% zN~-z+PqII3ac7RH0qF}x-6n^RF~Jkj_?#4&5A5Ym{(v`fEqxWs&gh3;iu!}xK#8zs zzKqoOq>4m^N-FV1hu+Ia8R;htMSA|nYO^ytTdLQ7ZG*$ghj`#oP4A1ehx4%ZMw7xm z0`_Uwyu9FE`;L32ZY{Pa2@(p>a7CEs8{B(%{-Cc zM~V8F2F{8;RRLVi#^Xu)`=>hN@nmGnFGZO`_Gi3vW!41%UOw%xA4Ov-3f)ge8@)5wo{VKJ2kHWG0@PCtlD{^vOIfA zQL)&b;i>-_!~?QCv9zbT0sz;U7G5InkDOZM&tR^w03oS!V#MWwd8S!E!3^hY*x%F3 z|Cy@oWT6i4C?@^3d7#JLow`SD;86D-I;^MJ7z_~G#QqFdGb@yRD}L4rg7v|3@dm!f z^gqf-^?$4WYN7)ic9>F&FI4$w6i4$7x^7r4!{Pi{vIs()sC9B6gk z4+n<}i%ZgkF_2?~iPT?s3}tuabn`B&3+D5muyY#F z$UAGzbNp#DcM(bDGB~@(`0iDwID!}*R%=lN?kwgnp+Z~zad3yGOelvd@*_!u-JI#n z9Def5NFJk=M{eQmcR$!VIz`R_iR_F=s_t~J*VV6+xu%~DFB9i%PI*sibi7s#hwe+m zdiGG@d`81pR8L2k~K5nx#Wh6(a8a&wvM2k z_Nx!?24Z-R3=j3}l(1N2daY*5H`=M|4xW5(=MU7%R+{ixUCZ<<(kpa2nbbc^5pJ7m z)k(NwyLAj8hNa05uh2EzZC*P6O?gP zMBmVV0$#TXoL(5z@*^5bsu*gHd6{4MNb2eeWD{edVc=pw5^p$^$i`KerwlN);}@zx zyTSAHk%Z{@Vhhz;mg(%M0+Fp@?k?x;RD)ZWm$otQN2uho6D(=k{gkmjvSodE@xRl( zzcRmClDMiL7Bi*cWhLe;Ir(8`00}ds5rO3ggP*x)pAm%8=w=&p_OhPpk!L2`-%)78 z0Ehnn+}@}(?64PVIC9u8;q%zcMx^E(qUxgI+aM2c|0=KxuoeIM9Ra94>lW3xa=7fX zhf}!)EjvbRU&b8%y|nx*T@6WnD#!qHaq*3UA0vOS3I0lF$>a=M$=Z3|{@?ocr_7h+ zIiT`@RkR5F>(>9X8ULFUM{oicT(zw_J8u2|IMw%Gk^;wIy%dd z|0O7*N(lk#(dU@y|0@~)YjvIy4LJasuvjxt|JRXF0F-U|GX%N6J^o*J{7)A|{V8+V z-;@5o{vUKeG%WWlgzEoS5B&8{e{S>D0t3Kw7a^%L|2kCo*GV!zB`}_HBQj}20ILF7 z&Cr$U70Jiz5=Z`bj<-|32SULWfXu0xpWlth-`bewe~=^-lDNvw2HaPs)Z?&cIHPPL zubv8b#OJ&h~fUz8S}r@5Y5?>TKA68DDYqBvjqS@3o~f8{&g;1W&_I} z&?)`_^K) zV@_^~jpXel1wu-HC zfE$r4kUCud`lwZF7k&HI;kQ0WX}+sycUi#in6AH!w0$2eyA+Kp`@c zckVN~``5~nP|FjAa7CS?vR`bKv9@b3s`yB#6|&yweBWaeXtdlPpG1=FE}V%Zo5KE( znsTo*^c@AR4-Z-DS9iY=goO7la^vEP%f7#*vdLuL*&){8s`v1%>>A_-0kGWA)48kM z5BT%SpGSY6D-}A6$HW2tK+GMUMr#FdRx{}%6zsPni zPqwQ1VBR5m{$_URX=1O(J2w&zID)>PNGI;B4b7PBv}YMb!%_S$34$|Dwm*I(0xTeJ zdg&B&(TVTC%vz3nE49`8rcO4;i%pmXo>)(Bf)vMV8kTgcP-Wh{ryVA=j3zYm{y4{y z6fv;a`!oz9qCbcD@Y;v}*4pzftG_^Z!s()iP~qAjYQtj8-#Onhwvg3*XBkJC>ezH( zTyo80x(aP(ST%KzN5DKB9K-CMq<8BM)th_qXRbE`zlRg@nygh#iH~L0^d3R4TH|_; zp;t@A)>Mq10~y+H)V9XpbApeM#a0Ttm_yqtvG3641>7Y^Rv_0RJc2Gr)Rc8dWob$@99ksF!=-okwHV$ zdiX!Vf&vb<)_l}1gJrjs#p&kv{#Uv5n?2P9XT#Ve8cniauKb?J0W&)4I>|Kozvlb< zWlBT}#`K~LPuC~rOXSIDScMag1gd#0nn#(esK|+NEl*P)h<~R}nFp?^2(ukZ{~75I zlJ5!7UJYH!G9LGuZHt9m=HU?MNBEnP_Xm0zq4nFO_Eyzznw=KxY<%qE)@4Y(9AB@C za@Y8_nlKs&%$xG>39p}RQmRuT&}uu6F$`*#BJ68$I%u&e%zG1*K9Cx=_(w z%KK8rGLsdMt1^W>T8VCHZ6+(qhr`CI)LQXjnUkaDrz_N4D-)E~ViF8?AB`aG;aWz5 zH%k)<%o+lg-r_o*(5ck+RNq@TWa79T{M6x9QSSn$!J!l}xg4e&@As;~!<{lORgH7MEJrarK1`^VZ8-8L!vsVX|ptrW6V>e3dv0 z&GtnMYxTM@1iWOXkx9uHy&{5l**v~7vvzv)^qduOBWbL%1?b6n@eTb71dVj#BA$rS zHFv!}m(|X9`ORhyOkaw=wu2l-MZE97$G;F+KvZY0?$=^9kEf$7o4@x;K9ue^BQ#yE zcf43JSQ|t_va8;^6#VaA5UT8pHeF-x90IvZO1DJe7W827i`SYXYHc5cwJy|Ckl2gh z3h<#Y>r#ZJGQ^McMo7o-G*GI(8LZsh0Y9J0*n7I zsDNyVvhw;>O6|w*LJRjh8g6SkXwQo|-}vaWVlgrFwg{406YZb0A1w(so5vEQa~a6v z`ImBA8PI6atG*kX%^P2!K|~qLqAt2RNoLp?5^rF(*Eirk5=#hmtI2=-avtk-^Gj(^ z8C1UA(o~Z_p3qyx;O^iAv0Lic%HWg+0o;^CKc`I`#u5neK(cSmy4V6G&219yY+Sdk z3F0(xkLA8%Tc!4}Z9EvqR^-nkNMZ`QycJyOcT=hKzexDsy#!eO>wTM96LHFzGg&C7&7B>Gm;{ zx5Y{g6Zw)k!T4|%{z1mlARwhty2*Mvc`stPK&-0BWC}5;0zX2;-R-qaAQAo3*%@bs zdX^(S`Ju7l+kbYFKkS*@0_46!WSy!?nBBFdBayPPZO=aq68ZbFy3@c*^()8lY!bKZ z-T=LxemvDohDV*)lD(@Iy=+v>gI&F@)~yUULokbZ6y@>3@Wt!<)2m16ln)cch9vzY z-&eCQK+Gt-*eRWguU6R9q+k-Zo zUsjDV?s@MAq;A)0r^0W8e~yPDAm~>GT&Aq(v=tpal#Z6c&X|2wm@nkWkg4KqXIPN_ zk#*}XQ}i+G=>GD1G|F|d==!_LhE|~8w!NTi#T{M|%^69Q^j7-RS(f*-{Y2l}z=s=tkoWtrGhsS*cLTcHnn+exO^tB$bU4`6Lo5Jk7lX9TdYCDqcSO zm>{6zGKmA@Hiak}IZG!ws(va5~%X55Bs`)iKj^n@F3npC!(QDTwUG200a40AJGUm zPG|6fa(f|P(<{tWhCbVlOz3u{^+^K6-^0L+F>QxjSxY-s8#C`RCDK0L z(q9rH%CntFdNFfq0B@obR>m`5&-QjK&b`A^^2G1l4w`q0txgzjgw|mB%_^GVxkjy` zbeY5b??#24#Qhwp$Vi=m*%ck*4?z*=PPM|xuO{=P5la-y120XXhj#{y673R@T2~&Y z)GN7k4r!~TGE#`XcNONS!SpQeMk+k3|D}(hjiTf#*KdKc`j@d~hq|^{i5PxahU6V= zZ$)`gE{C`Hug%7|uFhI+<~$Xad|%5+&95GN%LbJqZO@+@UqCK88M}CmC*H{Nah5MC zK4@R1M%{VkyEKB?`hRIxyg6VA&M7I{FF%1DL0bN0W zG$XW)#=Fq(kX%^_-;UjcR?IqH9x@mcOD#rkeJQF}5yAN=H(KB^-fy$GVxSO@cR@>tXQ#BO9^X4oV~S$l-{XypY&v(S7all2&8;;g+Ep&Jm9ZX`6Q2B)hDN z)ssgH=AviTwsyE!Pl=Jq+BIxi&r&tjT)J~6bbFc8D~d8gRsdXYLaWkO%sP4yr(uxz zqI3M>aD3mm-(;g#ZfD?P=WQ%ZgcEJalLvKj@jV#`k^m=W=sxhrNGmX4dU@T)GL*hA5utC_;$G36G+vpt#@Mckt^Db2uoUjo*nhWLC&v&AnNn`*V;KqDo!$Sh#^hvdATo z7d{dc?6G2qNz~~Y#d;nV{%3iu#Gi4jgST=Tdp582w+e(#icK|X&Y4Pm;(rq@Eum*K z$aduSQK~Pz-iO2G+}MW~P%bwLk8nDFiM?bxek#u)FiXasGAJ6Ahv$kgwf6SGO!|i% zV~aFsWFnawtUg+oPXoB-6MHQ1&54z$Ybs~4h)Q@mUu3Xe-PWjEenx*Alpl1~>wuzI zWJFkY7wluoE%=rRX^wRH`aOL@)n_&Ru?KsQnq=*Crs>9G`E`FnUR({0`HB-XqL*I# zrCDq|e|hO_GI&CPc;Uf~{a`uF&Tk+qMSI6utAQ%`^fb~Rvau!W;I_Ax{HTo$6BRH= z!a-U_8f$OoQ+JAPvLP33m+%Icbsm)KVd^Ou${UDhYJEK!NS^=eo@?1&@B~KFz;9z` z(oT_=+wmZnmr<1JP0g*ni+8tVwG&JrPG=Fbyw60!YLsn$-*pS8u+JvlcS1P&tx4@v zZ6nM^RGFw(qEh3uFcIH9Nl~k#(peSvKg!zMS~hk(2IgPtMRp@weOH6HgT&O2p^q|! zdFC3Dx{7iax}G5n_DlM1ct0@2^*eUC5QZeAqz9@O5%(4tXUwbAR4(-Vv-Gq(at$6o z>!>a>B!=OvTrYzKj9kXIs~Dv z#D_ylVGV*?pgG0_&bxpFaGn>4Vfn>&M}3K!pUAo`@mVH6F%uFz$;S2jZo+4_^SAd9 z^%~FRxWP2pq-x<>5^+*(rLmTsiv{c1YJ`zTySBknD?RRvFyu%w@o1jLk*~!dhiJ;1 zD3svSZ2Q8SGe_vMTMqn}VDw~`GrW8%V>nOU>s4=`R1#FgwW$eE>$BH|$FbjrcsP`{)$hBf!H;v9@olIFJ^|8Vee8LYwe)-E zRN2(jHnu;1ov@;!>{TlKj@_Vnj$@eLlEa+Tm($%01{N=mE)hzJ`?#s6`cF#sb-u#U z*ycCJBCUsKgMS{Yk>|)nVV3YZ=1- zsN{0LjL)mAx;{8^)Ist7^;*J*w|2P$9G&HxUo1Ng`mixi`cjWlniPP6{Pxg zic3m@5nPZO{Ck$gdE}GU}+$tU(j;1;spLZ1uW!5YFFxy|kYu0)QWO zVzh3>WkC63dbn&CDTbq51iuh+*^iURLor!p#WQPQ73Kb50MilAy4mz! z7(x4r8z1F;Em1bFiGxXcC`*;_mj|wgeX5~BZnQqtd8y?FMhaWJY)Qha=mZD_WL6q? z#yld(91JE@!@uF}Fs1PhNIfP#OOxN-eaZukWOWM)J?~0$drYvXl@P=gaGyjAB2iVHBnDO0A`=>}xO#OHwl^_x)%RsYjxdO@6cFSTfBx#ct#-vHaB4B%rxCdc&JhE=Aonj(huRS<4z+r0$tXF|OO z?TGa<7NVoG&En?wMQF~jY)`|4d$?KB7jT)irx-ro8YY1yWm1aX%)szZD}Y1({IgMd_;#%bHY_k-^f!$A#k_rS!3mgNDnOe?^hhs(L`NlrD+eU}O+KA8N2=>D-*piw# z`Brbvt4k#zFWT4i?t|9_>fVl{`xw?@5*&^h8E>fC z^@hx8@{=^^l*Vk%R)=~DTOK=QZ*Aqs&hvUVEXcHOPj?CCg;U5-+#rp0wF4wnWx;I7 zBgTT?ch{wuZ2XW9LLbUY@Shpk3=~Qp7fj|~^P@Iv4zTg^EJoenMK_lAgx``)wAf+L zie+{Vh$fjA!JT8>4fpyO<}dwblBMH~Q;p_anC-LtAanTnJQR0$ExrTMH;;uM)nX+w z1J%6zGm{S1G_LTLV=Hw{^K!=PJEYDfwf+0myZo&`SpMSj)3hXhUUGrQ^%tYud_!*K_(458zp5l+u0WUY91kNUU$G@_V_u({6WWV3v4g+KVAUHY3vzV za<~S&CreVFm##}yhW~)lB+aC8UlnNh;)G4?)`%`&J=uN*jw@E}45uo*?_9k$CFKwP zrCwK`7wp+OBmnATuwP$(xWBdaye6nn%ni(BX3@?Qb382ieYWva(6G%m%7u8%Vbs1& z9uLoeTkzqo?2gAb6q9Y3oYPhrhD-SkM;1^&eSwQZPiA-%7aC^~0J1nHE0gNUq28UW zt0xl7IyXJ8vat_Wl4_ElbH5O`Mo|}-ScCW4zWe%07Q-WE=djVhOa5HwfqK6A!l6wM(%4L+Xq}C|1QTt6;5Bu=YgQSbW8{f!ETp2nj9r8yeko8!UQ> z_&lnM);Sc5YBEPeIX!q47L`&BD+C`m0^( zViNI%>9h{H$x*Al3>bg&G}6V?B;b~3vE^bn+KV1P<4QpAYiyLi zfBo|EUFg?^RYGWbyM9a3jSdn*T(&B#@;ev?a%zk5Cd;kuHLS;*%izyjK>|c3;~e%l zmoM7Qn$z9(xn_4Q23(2eOesBz{S$s>cI3nRqjd3vH;O2W@yyJ1ddP=PH668SJ{Z;7Y_Y-@wq>$<%dk&QmvE5g>iK8#u*Vs? znp}X1`R(DI=1@S_A$qO06{nbASlu!o&-zg+IyK$n9dU0K6m=vr=ojawu2Wx9>x|7h z?>L+vE*LDa2W(03&YfzW?$OUu{l06o0@HbmIWYV;03tpobCYD-P5A^3VHci~7$&&I zU?3m2(+xq>T49`VFUWki8JCR0XMuv~-nL{XJswtYdY$tdPk^ei6Vd@u?YY$&iQvg= zHx_T@C*U;5MOJ#K(^&S6B|ss8)p|IFfma%+aXn;!;(oT|*)qo9ZLs$jvm6oqDtCIR zWTo)sG3MoGDTFoO)Jx}2gUZ#k^AYui$VBMJ0s<{o$vLqa3QBwJ-X0TV8Q3#5|JkvYSOKsqQ6ho6{H-RW2?fq+ z{C*k{U!=l{KLA~M=0VI@oDbsA_d3l^1xg?7oWfY_NU03`cPMX#-uwM1V%;0>%=f4< za#8^w7UGc7gPER@4TEY)H_x4CCMd?L0eXkpgwFSDX)h)U6DD9%q8AY&a)d+WSAT^hvo z6T?a-C(E5G9e4M#0R+C=vyu#+GTf*tzKf9fu`0I|YDs>}pj)975k+*l?B9FV43y&; z|;{NK*4Wn$7d^X3z4OR$) zC=|L7HEx4d%uX)-B0P*W@%2TVD^e*ZDrTJE`2E889!gB@KxJ=bVd;Tccwmfz! zAw&itI13SB=Xfo-p{l-V%e(IQD`*yC2{0zd^DM8PD1wRD=qtun$gb&Q0$!?S<1^U4 zi&DQ5l&EU&%63V``xC*oHKuQHFMP_)hBHU?JF9<$xZQTe62G1}!ZpY2f>m}B(AE*0 zTLfXuz1Z%zr{7J=IdTV(r4gXuzU;l3tL@A`e;FNO`at8XVW&+iXT@G~neetd^{9G0 z6yB7}etP+)l9D)L$xy<;atjedKaL0MU?A5xjN<1p4CGm#>wotKAaZUa-%TS?uFFpt z#K@rR<`uwWmQ1zJa?I?1goCG3Ifts!D>jS~XBRxDuYGUT>&_ zy$Ac80H$K|ixSnbT5Y*0J^nIvD%xiPt}c7cY`GgSM@oV@dmwrWD2z>NI>J~|hb&%d zk22fmhZsebjnt$Z44Q{gKXOUCVP%}1@2Nlv&WeCn6sC=H*d_ds)AbX~tA=Ug>n&#a z8a?FC+LU`%cF4%5&3uBDzqlbNP`s;EC%CU4QrK|Ev=1Dj`CdmW6C1SfO8vGV!VqkyavS9^~;yg_zc z11kdelD^3OZTa;CVHmarJwGiKpzDphGX1^nd1{M&zq|o1;A|BSk0A&l>~}NY z8`JBnvU=WJZ;1i5?K|x_a<8|eU5W}iA`?fr9ovrqHe>!9*xjmZW*-q;*(OqnvZQjd zL^%1B+#KYF07sHv?^5_6t#vs7v0;k(+}G$dob}=`UIfn8LK)Z{Y~W{A;S@&jJjt$eM-@^K~a$ve2*_YeE$7gtG*J995PwF@X@ zTj4{4bH;@N>)mfxl^d1yaKS4$Psmjzj*h^CQdZuSdsm&a-u)rNZd67pPK9DypwG=w z(M8`j*ERqiUt{J(VNIN9ot!WjjQLDnrc_=`j1z0+C4jq$@tCk8HR^k~ZC~sGoMx>S z%{OQ87_0At%L2$fgTAi?>-ww&W#`y_71YC{big9DbJFOV%9+}Du4A-zGdat-K5K2z zVJ2-WCFcMWyC>i!&uVt|xc?IXr=bAn_}2bi*wH2WH)~L3jerR*#$xe*fIeNc?~v`< zC7q>$+4z(YgUN!>&*c{jVvZ4=UoME=iQ(ob_MzK-o*;0wl5KY_GaV&gdFd2`A`zD- za~d7}_G2dHk!uP=eek9oMu6`rWU5?*)jv`P76x@Ki$xnXXLS3LNd-mY6~gRMA)z(V zA#FyeSU8WALI!=?Ey#rXmH{px;)m<7HMz-55DGLRSg4$n+lt$d!g4_KKJ3(VMigau z_hZ#O%HHQ230UmXcEjv)e^BhY+cQ_HQi(v)jXkzFk`O6VK28CyfrN;p zXeGb>hkKEPynNc}j*8w)M=<)g1#8t*9$D<+7X9&olsQRYC2&V%dH^s9$Dl+ZVMUvY ze3O>VBW{1rL2K&X{|fksiVB7IDBcy(fbT* zT*zW8n!fRlvB9}+6OuT+b!}-i!RiwJHUig-?UVLHm)Azhf4XE{!TZ1UUfJvXGS!L{ zEqnAw_1U(M+ZZ@{?tpSyVC^evCPRZH=|Mvxz?A|$J|>Z*ZzFL{sSl)7^TbCpB(CNv z^{i8;yurbX<3>rv#*)$XrNdvOhWPquZ&dibrGT5*IP$(3gig{|X%Xipu^k+vu`U(M z;o}es?a-?aoz1N!CG1x0s>DL7DVR$srIvBo%oh&b(+cPy0;redfjf5!=`MEA z+f7Q@f}59WJ0aL%gXmz1DQkv;ej57DbF|-Q-}{BT|5va-Q+R4TVX zgBn2WB*b;5XMr?^(-VBGRBLsK=bbtGkiqGifElqN=dImM(eOLf+doW8S#5&veLjWg zN~7nT8EqWBRhlz}t)Sm#)3^d11#DUrYWC$~(On-&xAu4p zHmZY*xyH9n`IxSKk-}QR?ON~Lg>N^hqU<6UT}ufk8u0Y zNh%j^5xdEm$?|Bk+OFkfGWbz?+QG6p^dgx>DC^MS<<@Q3ihT{?nsuAP4uOi6*OT}I zo%p$*H8xvk!_9tYJc+?Q#Mt8w7~b(gdlnWrx>R_2(iW|?v@H%9~aSU2%g zI`*^=!9Lc6OZX@XTH!d-BPm3ROS=&K$oRc{4}2dZbOx9>sMj&vL+iBha6xk4$LFb zFY_H+U&SA!Gl_QOhq0YV$yJyY6OM$T8gB5U{ZoRdLJbD`Y zsq?7&Q9CmR_}oRPzQ=6W`w&9*nEdwViPszTL#Q6G7ET?TQV`%X8VK>fSO%2LVGScH z04snMGbnU!&1mH2hx0u{&2_IvU;J%ux6@Ju*Rb<_PBL5zAK89%Ef$AbvP^RR+IQj5 zpA{7DAZv2l(Tn(rP(z=K{f^0D)D(s+V(68{LY;e+uHQZ-&_gyY%9V`b*U?Go=6}79 zoyO&#ThB72Ff@`x`}>hGYC5)J}S2i-)L5L z%;~iK0!sgOiHOmghW6moWX010;y#yDO!l+;r1wfb0Jbk+-MO?obk{V6d~zE=)^U4l z9a6c*qF*aL6Vp`(x1lCx&70{fZ_thS%<(8={&|fdYGgR(17Yw_j49O*)ocW)L@2w@1-Y#EcW@ zWP?IeX^dRAdB2&CF1lVhE3NPVenYmNhbt^UYCRWyw+ED3i8W&x*RFX8Id=ISDULEhe@eRZeZ^0EJwJ>TaQxolN?NQph1_QC8xu$hD9#;t&#zUgG@}g7gC0KQd7gX*4NCBg~u({bBo* zH`P8w1;uQbiDH=$Jg6oN5i#dDLrE7CXNP0Q{XcIv+}0rG(HkWEoiAEu zidW^agli#ny!g>U7Z=Y32Vka}wh(r{`8D0M`iAmiox2@*6U&_H$1W9sdEJj|JCt6K zuQb{(X{YP?7UUcTu9$_((A=)Hq1mn#HniW(wi@sJKeT;yRFz-1t{~F50cntKK|(^h zyOC}|q@}wE#1{TS^C0DaL7P%Eu_hg$5kxc3<42mZ?61DJlMls`R2}MlUI zckvDa3b>H<({p^oW*^w#9OF1Oow9E8;E;22>D}eDBI$9jfGH#2oqoL{r5M$tE#gP( zb9Vz!Idnpv=7Rx9`A3VJUXPa&E54h zxz7=^Sp9OQh|V-Qy5(3Kv>b<|I-wN?vZ+N;sy`Zlps;yj_D*l77TeD4)!pzEX?zd* zO48{icv!*0+pn4LC-9R6#t`qw&u4a9bZ@wQl9c+Zwmg;IeYU=f)%?FG-inW>KGR<( z)I>9MS5F%B{U=xnpvEQ-JeGbSp6CVrg^FFsIAkJ~r4Vr~FMULon)=aO`EM!>L28~1 z5luP@XkBT2d;e*fO4vD-Qe**h@ku4yr-dgkcxs%--)&r4sx)Xc8m4KrRXT64|27-j zqZf;)@EgQRw)nEiWY{2R5`*?Y>djeuSj>6yRkwz_Nt&S-eEKkR+v@s#4V2gr%=Z3c&o_c_88$*66&z_hLbmGzvL zMHK716soV&)z(ZqyO!oLy!MmKG_z4;pg|m;@Kg|I>g@9+rC=~|Uq9gCB<{4fq{wJJl=6yRxnNMD=u3QVo-=#4ao1R4 z0OcRrem#uOtfT5iR4`@KE@Fjnl%G_1R48}0CxV^mLhmq~75tVjhDvR?QYnpJ?uQ!d z2~~i<*{v{h7q%Mr$%%n??tRVBeH%rHj7grZkVcewpCea>%@XR@x7z>Qu`Cp|W85Ik z8bLlgn(mWn;w=m4YMyU7rvwUQ;y1aWcxSLF7RO=TUbv2)ZWPhW! zlz?CR;GY75|8lUuA7Z~34Z_W76%8FZ#?2u^d7+Wd(i%oYCnW#M;+*0mI_@$&H;UCy z+_2-S!}g%R-AG|zv-Q6;&hmFBb7XwAn<88sNxMj3aWj02})6AKCr?F<~LlNxzy3 zxAOj5VE$hW|F5Z0!a-*Ni3KY3!T;liWv%X85Qd}`r;Gm|V>?QVM*My$QTXV8o?@h^ zyaeT>OrDBWfc5_|OIbA3fpm^nr@MdBa8tk834RcrZS-7;&re|_|GRp?-5~{naK5Lx z=}KMJ2Kt%utFzry10<11$=j?LM9;j=q zO(nWgtQ(|Nc0Ci;EAFuL`C4fH?^BLN#OX{jSHk$xUs)4Cew+NIOxXNHSh$oW^Vw~ z6`EROa?$+*5{*J#H`s#2!J)SvxuG-}Hm}+lttswHBk1mLMxKP#uK0eAHb_9OMjHre z+56bd)Yzr{VN=fy-!mvs&H&V1^qgQ-@i{Jr?D@>Y+umcW{Nx4T4V^+C7ViwU$36e{G0r zIE6)*8ZZb)JL_hlPc(W~UEiF|Wj){Wl%njUbl9HY0IXUHkyhnA$7G27<6qi?gfeVy z4p7~4o$c5)j?<}Q_rblT?GxEx9R!1(m4o1%0fL7;G^a~n1CZYDZ%)^i3z*l& zDsW5!-AWdq5UDFGWu zU`tBkj7AD9S=qQDm%k=TON}U5UZV5ev~m0sx6PObgZ@%eoZeSR;BbM8O@{*oNqqty z>R0iuM>6?}pRdDzKSX)l1I)oL4KH(-6Sp!(CYmhn^9u|4u*Xkn{co=ij7EX>74>@z z!sN}-ViZLY ztEFo5sLH{rD93ectl1VwNR|5l2I9kxCn^(_d-Yq-i!G<>U5k&`f47hGT*ve0M1gDd zLqx7AbGx}k0n%uGu-FOC-sIC?DS%t`D&r0i+ihO}ySdD8M`=9RnXD>c&E!!5ti^_h zcDlmCCO;k&>*PE&srEj5HwVOk{SE&zDJMVBB;6qb#DEpm7W?z9JQQoe7X!J2PX*kL zU$c81Tk?4x<{D2H3Ux;joAu}2&Ng}XgW3mQtMh}gQhi=yVjAfvYz>6x5Hu@_9WTIh zVJAFw-G;$7!NYAgr4forY*^UO+|Uf>cXE2N=#M zELlKtO%GVi>lW)pje0l~jdz?gEX>)MpdfH~pa>a3Gb%qdYb5%9Hiie3MPy?tv@=$*gH~I3D4vfvI6`sBJ(P6=Qj(H5g?DkP%l(emkQ|yX{Uq{gowA z35cXAG>|?7(Ru;R&s-ofGIqz8`#2FYnkeczqy&A?74!Q^3>B;^y*XC|e4Hv=QwP zhYVGEg-&SWSqF<)E+qw(#Vnxb^4`5?f!v|KNip_gI!2@31~lRcgvLIMUtQcv@Pv4P_BfB7?H}dV)xP(t%jB&)2zB-o6=HQVFTVh? z0XjFeg1G3*0ze?KhjIFyjL&J}ii$pJozPsOi!&KJB-W_Tc^}uP=2z97Qu<3Za_?;p zP<-)$j;r;!w05>q`@+$GtF*Qc&|bbhkjgs)i&Zy?{7eq$q`U!pTrwjVDl3+}GLeT} zndqCa&r$a3A<2YTrT9yMB4{wf# zRfL`Xs&~#A`*b%0Hq9FQMiY|_0e>5vidzGR)<>s%F+9WC%_&xdXB=}Ff{6!)GDgi5 zbrvv{i!V8QvHb%N!464qTN6pZYTfe0_Wh-CI?gYc)|wuo@}@ztvt4?NB5uWl44Wr! z%goI&2Kfit1*i9~9@0cVWRv%dR(pjcDjK2I1o@|cjv7f7G5fY%hsXbq>$q+k1N#In zx}+?3j{@O9xaD3e3y+ndUk?vnD3N5l67Qck5v($TVjW_7qHjdqUItsvi;*u0HYcUW|?H9vO#~=6oT+uj=DKb(IM_r%-?|UxZ~6nW0D5;W1a=no;n! z+ZhA;TU3Ti?6mI~Ec!7yGy#a8Ta3H*z|<2vUXjnaUi%)L^?tx@c89G|PG9VshS|iHH@eJ!Int}R60 z)6(`6dQHAU95Bb!D2ZajKxP8he1${?I;#0;UH&@rqSQ3=SXx2i;bA_r*2pB0EIn+= zDpl1ai|9^_s-NYWCvsg+zN)%*Jrow9CR^ye035AT6gYtjR!vrvDwO%Erec;a#Rrlw zm_n_)nQkbbU%U;uG1;;v3z;cVH>orU-kZ@z{GMnj0;SdjH&!;EJU{Y`+p4jezv4uF`EAkicQL zuv3(pj|YK`IX77Y0-@M&pnMqzTpRtM&Z6P{Ok(}uj@C8${s=1LA_jVquOm2U(uoSR z-guQPOEO|n@vQ1cr;{rO@xOP;&cfOWMk#&|coO|!eSpq4QqAa2)k(QP*1LSzz{-X~ zgp%x5F4TaTNf-a=nMnM14BqInvg+nX#=MWQBkzf$g`{8iPVn7j$1cWRegp{mm>f%xA1Z<|1YgCd9?@=EXb&4Q9zA~ZfetR3GG-cwtVL*CvNE^SmC3@XxR_I(R!p}c`xfF*R?Natp zSl%(i#!>U(MQ`JlUmB&yy!mrBk&BzGd{hsda4*drp`5FK1;V|!2tMkEt^0csDl%&c z92KqKK##;$uca54X%r-JkLXpZs3AF`2L7Jxmn=~SCGHCkL*uP!S{HPQAWG1Nd)eU5? z9sMh4pPDJ|&qZuLm4GRD)x<6>o-3F3&Ea^eaUC@U z>qEMpVrbSjtzX0(8hBr%EzO2tuGpuuqN`|ZD(jMLXEEvc*ZDiVZfolBeJ^(GU@sn| z&amQ)NsnDPFE4cbevjRVOiZw<0|K?1cP}m=txrQm?fCo7j_kbVZvfKZLhD-g(aW*a z+3whzhA#a#Y|KA#(X8yzE1$HZAY9{YxaJe?gTp6;x&YcD1U{(O?_a)uF@bn0#B0%j z5^?UHhcB0r`eU1NGi=;!hw25_8s3A7{znS|5Z)=N*euo1Asjl&X3jrDYpPag*CCPU zCk$#ky3MoY#v&(1FFsMIY(+3nbdT}e_&ttkz$7Vm>_%)`UW{c z*f4EF#YHxbtD~XB#c-)xB63qrCr-u1(en;38`~fn z>Agk}ZRZ)|nfyz$4Iy7wu@o{-@{Nfs5);M!2nABLgT-OZ9Wq30kNLi)05M5UzsEMa z_yvn0=L|y4fd?G@HxXGA0VCbo?97f`B!~|i<@!Ct)viez=ysR8{TU$~*bzi$A`m`< zr95nexODy(8h?0l)Hw)9uc6%A3RFOyU~ ze)X85S>k2bvj+tZ<{RW}F{ryCFx-Rk^du8Dk%Y61>{10wB+fG9 zCYG$NUx)aCc)_9@hnnh&`p~Ri3ItRn8EOxG(rvPFD%TnA+7&@->hKN_m5wQ|Gwy&c zs<)$w24{MTR!k|^M$X@a-5)PffAXB}aFxX%{E34b5awAh<9yL%J}eT%zJU0H)z@tU zv6fLqE^JR>Xy|RvLs=4S`u;UaIn?CF*AVS#Ja;6n))Km*M~ z3Avz5Kx2Qnu#9>5#M}z_g)>YF0b&(l=+9Sio%VifCoeSoc)gq2&O0;lTY5JEpd7kB zb#s*ANwH3hkxlNZF9nwN!cm@B6t-k!^-!`xo?`pLK`~il;eNgLd?$)R4;AX4IfgT8 z1YE>nb%Hsz#F%e{L3k~d${8fz-i;&IO8M?`8?iWMs%6&xy#8~D_BQLXy`9kG7sJ_E ztNYWPJpWz$5YCI)MSHxGA00P;9Iyx^+2U7(8pfV4peT)~Vl%Fwwbp&r2KF)EATItiYZfW8gCY9VovKs4|u= z%1->k<~ik+a8M;F4fCv_*<_7KM!(IZC_hrO+ilV^y&+c~QKvu@%-v;&j4H1r;(CXx zN77McB^P^N;iXm2`f%*z^hx%jF}<&kK=DCDkTQ+^)Ce_4t2+ziGB8R`7dHq|fW-Y! zH@e2@D)_!kKt~s1OZy3>m^4bYMcfPNMPf!2zH7)9ji+Zn)&=fkdyP)P0Ow2(R{AJP zgNucAx{Ah&L5obk?<0J%lrJ+Y8$EyEjWTXFH2Yq8v0a?f5DV;w5MgxmY0EOteLg(F zgDrHCnl|pm<03a3tEOdRo6o4lJRut>ZdC3&rF;A5*ngAvRo;ct&nLNhKIsGkTaPK9 zS9I98xEvX4tTD6ER0p%27&*owiptkt<|;4US=Az6=|)E=C?E@I96u zlSnBX%H)p;MRAk>U|HQl0qkGUI<;tkxj3Nit5Ex@TVI-wn$Cs@e=YouY+vqM@+FQ* zx@*a+yO%bQrDy;cJ9euogo}%=O;x)y01WZ8%fQ>`F@Wj^UuSv$>rBU?3@~n6MfeB+Ro&{zkMi3vNaO61)4vB^|4&3x zG*#?@dZdairnrU@PB;V!@u5$r%;$eKQuJbh3nWa3=a!y=snm4odxOF}SEQi=*9X;i z|C-Ey_fPC8wyG)D&PUj(&i{yA%O0Vwt6y^YV=zAW-{>>f_oJqf%q;6Yo|*($h}DZPG30QsqD%0(_ZLjCUv9gvMM7&?wm9D8F|{*OZo z{x}=ka;n-Y(z={S3rF_D{lL{PH>WKA9gzR`Yy49;@sS3=(IhPh)&JpB{qK4HJG?Hc zCkfvA|JUnLCec*bP4i5`oGqC5^4$J2DIhC|7|2dbB_vAs&F@j~YtWhF&59gg6d`!bcTIZf5Dz;@oy0&_XTpU-ejnw zAYR*EUMVT~(q%n%;ERyHa{9~HHb3KN!rlPtLmd6Dnt#(I*iV6J=9uATTHtyq55qLq z#?Bj!p)B|J{{{7p;+LO8TK`I?&~hQdoY#_pf`#7U+8{;ow@@rndZ5~qK*DX^!E9X7 zaj$K$uR07i0F#s(xR@6==oZ>D@FBDPQ?I$(c%)1$;8v2zqRS~9iK!>;vq(@91nB$w z>KvDr0qPEMn{d4>JaXU&*ElCcBGSAkmI@pVkI5>=fy&pe!b4<$e8vNz znG5)aa-Wpw+E@pv005XETPEBf8o^8&@m7xbJt9yu_2T|HQzPk+-0n8)^#OeVJN)nz zBd;Qt-5K4(6rduNencS(GVFIH4 zIiS^HzT6Y1)w-Ts z+o=ETMfYASBr~bJ=`?jmr2o8iF;0d&uF>;os&UTuEaT}gNaf6F6NvfqyKP%uLBX<& zt^2(P^6%4?>kvrNJuJ!EV$vE^BZvpZZnJN>sYzs1Yt!xqiYJu!DGmpJsNJ;I{zGKB z0Uc8cpZ!41(|Syfk8@GPFG^J4An`Hj*aDJgk9;`aV&1-@%J-fe-KvQ@PO1i(vG^F_ zOWEej&1bqzUQnP?(qFUmt+>odYLa!wcdzM;<+V|fIvwnwi}a@Kg)+R(c>f?Ql_0bJ zzRMp7p6Zp%%!MlyPw%7df7M!vIH)u|D%(dpu@0hCg?S+8UYa&ovVF$Qt$brt2#2aY zO#J1%v)r3t4sw9aFbZS%Ku$E5>qzG>VXHpm;*wh#mSp3<$Sxyka7od zBz|n{uJ1-++@JkBX|0aHUZj4W7ysEN1)ONr!LdD1lsjqVWob*-zngL{0g~VKfsDdF z)bh7Dcm=|w_@v?(uJj$5uXu&eW}L^g>2pce05DAta!obkRO$4}>5MT#r=M&mD?4#b zK^h}_-vMWU2ehEGHSPxq9{-X!ygnM#&&I~J1`su{PV)$phUMu z=XhgSrWx=mQ(++yEt4u-s)dWMixY?=OAN&C0a4O;APlYV^tndd%MS?W9fBOJJlM8N z2477Xr19Dl_*8QeL>r}>MZ6D~>xdp7e7!;%dPc%jlh>w3gpDpn(U1Ld-6^FxpeB>jPpQ)s5jQu{+Nta|lqN{@;t7UgfE2RZ^ z3|yI~K7F`~C!?5`bTv4wl3_EL6&LHwI@jH(WB#sCzqTyn#RY4dg1o`>K4(mdl8n&`nH0^_)vl% zqvq@Y=}N@5D71b08eQx|UkZ;$_kezkd**l4Fnyr+^#%lN%`A+xts5YrS(BT&Cm#NE zO6o!(ndQ5rb)h5L=wtUeb%tEVE}^~~6kT*NqpG(*Euk`AY~C-rM#h2WmrnMCLXbLS zskbSRIk5$0*KA}gb`746KJwJNmN9HYVmM!EC&s1=o7#ZY3CTlsX~{1qqo#P{r@!sb z3&!Ckr0(_yKZyWygx%m{(bS2$J(k;0;Ob4lPCu|US2)Ac9)22RQ2bDMGpD-P^{sNefKf-3ZQz#o^`M@s9_IC(IC<7uVfCH&#+NR+w;mW zesXvA$c$eQo$5ch0OH2h^xQ@Alk6^Y*BQ}i>4QYo6KlSH6F+ICE&iwLN?!a2QxT<% z1abc_U29}9r0*z`y|~p5t0VafLr6w65Xkc~rND7BXCL8{SHcP@YI@lwZ>(I3wMt6{ zRmyPCz7U!iNilpAW{KT*LZVu!=pc_ztZZ}x^&7>^uGR*Ll>>CU3m>avJ3hT?uN-VA z?r?so{!_s=0mbb4d?8g8`2yu&o!bwvUBLX1OtFWBT!hb@Do(wxHZO@h24NiYer|Ok z&P&)jkTb;QJqLTS$-2}4qE7rky=7E~^17=>I3N6QDIQAq3p|dCG1`>dSmg#jYZn*Q zs-BP5(h{*YowkAF`#F@8=A#eMoQZ^8MwSBRm; z*EED$k6y#O#{+3(+LF5a*^&jG?Dt-fI?o-oCZ-}8wjolup-ueg=S&W2;3|}D3XM$6 zyKtXz3={fjuSkyG7&@pnQf`zPU#OKqJr2kTB)XJ8b9TxgJCd6}yGZX##K$&K%7Bx3 zu0{XhA$qqiFY6!@c!_P<&Q_zi$PJ6v)cbxC$*^*I|$F+TCzhzJ$7V0Q}9<(|_3iQ&5 zd4dviL|QtMqyRD?2a4gav7fJzh$UMo&R@?u^r`NB!_!;U$n{wZ<;>7`eTU_0zwYUe z!cSQYhB)X)8kynNVXX1rPHT7 zwnURyuiA<`Nq(1hFDKS5Ss+8D(8AFp6-5`9h_J9SLg#yR3Ps4SdrTF&$GO)3Bpy2+ z4@%v?v+?3qmx;nZ|9K&vSt~|urr%}n^ErmaD-g|WJ6ZR2X0Ha>oi0SfQ1c=`a8V?Q z+XgTNy;yL^AHp|hX4XM&1c?3%_+kAE;B2T+(;S=j@jP3Iw{17EcnJ#yfsx5B?#W!J`j2uQ{J^p-K>pQFFs!)iJkB0-Fhk2L+yHykzA*?t7sAh2XvptQQ3#`)!p5VSJZVTv(meY$ME$c2h3- zfZsnlRsma2aQ(F{RcGVsbq|bd*5+O2S1zP2Dodis*HOa`vFaFEJCbpji-{)L@oV zKZ?gdOzqhxg4mmNMIF%WtFDOW#zi|7k{%^Xv{2nrl3j@YK*r6%wm|Zveu;~~z#cB1 z*rJTp9<12nceA}#*05W7vjfV=xCqg*9CB`uo(74!uSg*A=P|CWLzW`ih|EZdSkT3v zI8C15pFO&FwKtmX9@&J^cv6|8QHBENybU*Y_jW(I6}XB{CSK7r8-RJy=Y=1UKLmT{ zT_ayui|W*Sh~Vv)ALxrDoPs*u7v7}6!`yjtVTB?lmcE(dZ2etgK0QWlF7-vQP>j8o zZ5&sKqxd{dgPMF(k!u;gfHB>%!H2flpJ)RsNS-ciGnCSQtRK4<9JEF3y*9!PeUYK> zjhs>ZLvd})!CiT(p{ozmsE)3~C;P~CeeRjnp7Jnx0q8&-n-rj4Xq`v+$%-Xu)xq#7 z>%l_s!jpF(>}-vfaw$tvi=6f9R~oulkom~G{?+))b*RrDJJhLj&hUq86s!iH33=Z! zf*N^%AH9r?-=C^3O2~~>%Pz_j2BC9JJ7fR8b2?F1yd~bpXw2iW2+r6&%(KcKZ`PVC z##f#?fkca0A)J4L6>R$>l`cVCG-)Ce*vw=|>_ZV0$Qv8q(3MGjxo&M}?Cmmk)oCw$dw z(ld1DMxM0bT+f$(Kt!-iE!P`o{v6IdkU$i*Co$bt(UxintnSRY{MKsNr z?v$NTFR9A%o$U;8jt42W8>Z5zv)1&Qmx^fe`G%(RC$_g{NXS?-^n;h;rv|0dY)B0k z(&iA?rZJ^oIle1XvRIv>;k+KStGt=-^~ji8ogFmr?ihetz(`+YuJ*-?&Dt4tHKY5k zr@2<1eL_RGj2SS{?;U`055l1>siUoH94!nT*BeuWa^7R`3#rEpM=&1f9V@Nd9j+$F zCRPm|oHz9>m3QzWpvragdmIb1*23TzsvcSI@F17!$TXTfwm=DEgODm79HhdQ7s7Chet}Cv*;K= zFkv@bW>{;4eC(;mtifpCe`B&O;4~!oW@fnPLp5l~Dyv`Qyb>KySK6dFnhk5dbd>>M z6lhyB>NGall8EyR+%WYfi>&@&#}}6y(+lBRHe^&!JhZYYJnfQLtt25Vr=4s*_;HWa*@Pcgr6`DftyROPESJ55$6gUibI*P#1RmPO}b8i~UP%R$r4_ z*_fj@KPe|U57qfM9m9Nd2YiPsBojBA2lF~}r`@-FPp}#r>y~*S&iIGsaRvT7?*zrG zMTRaDXj`nRQbj<8F8#KFxA5G-Ee+l+*y-ob(;>V3waDF^beSh``@o}}V}XZjQ?_np zc2}L&7iLRYUyqJ12JF?G?fAD;W>yB{IsU+4ru01sV6ep*gR7{|Hdt(_i>uR# zK7*FigOET;D(OGdwzYXh+ukuvKhM6LC0->^shY1qZE9-9)T z@Hj`=daevQ(o$HKF8scp;e#3xLF}wAirypU{$(n;0>vBnn5)GV508HVN<(kO_-rga zA#ePtonC)}${DvYdqJ-Fg_G0L$+%u-f&bl2xxrL*gho;N%gCCE#iEUW?*d>q$o2fi z5t92yPb^&ModIV7os_@6zv`4fY|5ww=47-nSrCM0kW0ri zaK$@@_>mv6IbZ6% zy9rU;yDXWm4i*i1k^_n!6M)>gr2eTkK)FbMGINl$Zow$In_WQfU+@LJN-nVVXCU3@}l7Ug;4P!3~NXADp2)zqGHk z)4R?`8U`5#MDj^Eb0K?dnwyJo<2k4{rTWMC__<>Awx% zN}qhDd4;UoaQ2Bcx}b%T!j>M!bT=?r0Oelwf;H+cf6kXGqC++yW zW4^?XM{Nbv-u`(#Ei^FVm{!!T@p{VFppUe3v#P~5{`--;d{`=i&ZlO-$68#&knyT+ z0{j~`ru%AjkUVVRA0F~aNWS#)bC>9YuVl%xl!@M3u$KZ!?>!0usJix1Tq3B5zl6DYz@R zqvvZ;T}{mTpQFoCKUX)n?S4|oO6 zzIY${%fM$WW{;Y&HDvCbrFEMV$008=nc{FDeje))YSb$+0&EJU@y&WB9Y-I=#9v*8 zrM$>>{nqq@+NiI<*FsxXpjJ2$qX$S%>B?+YDPtK87Y6`cK6GN6UH zrX)h1xWL-iV{LxI@3{2{rVVwZ<WTRD zA!oK(xX;xdo#%I7-J4iXWwef}QHf`l-DKaf4nivt#&rw%9@`j6H*c2d6dt5ww!5op z{)%Snf+q?f)s3w_J}Wua`!tr;#x-8zLvZN*^yu=f5v1ao*JVh&0b9nL%f4>algH zX50FQ%_~GC!=|y_S2m@WS(@e0zI9BIYX0lltg)Mfg@ds@wztg}H_q(`7GDCU->X?< zGy1IruqiE#M^}eN?;N8_FO-y4Z)%n3h%pz9cPZ)HMm`nt6R$6FljuuH05YHoJ9^xj z0r?iRJY&?MsTi3;-pa;d;UvUXq(6EM9(QA_aui^Z^7fxcBy6(@2;Et&ve3=I)o)J` zmzx{*h7dOv>H6sesoSic8c`zP{_87nhB9`ld)+lN$1r~$XKp>$yZ~a&j_$q%{VKVE8EO&NKHhwj%DOnz@}MOY_otHKA~&Eqw`pZL;{b z#YlAdQKJ*{iaLdlTL~u?td)f%1ybbD#w~;+2wLm|v{=zBN)w~GuNr$Uy+86)f8ExNuuA)93`F< zIr%ZJ8QXr-HS^`Zti67TuEa4}J*G8mv$kbT82)|C^jZfcZZQd?Eq}9H&8+mKq6`{n zUCNq0HidejP+Al>j{9oNXhlD?upizqePr_KX$iV3~LP9 z%PtI-F{T5&BX*C}3q9+7wtuYbHKj?3d-PavbDtE(*woX$8%(5uX6qej3DlfU>*7k% zsk%9lw-jo5=cJhZ`~x>y8w2i`UcZ;M70UR)n$BRX!wDf2Ywm5SlJ1)0Zz7Stwj|6k zJ)QU2nd>&2GID9qnrc0p;M|M5Q`su}vu_!ME5M)>gvX}1A)^Y=u}#MUOhKazlk^^m zHg{|xS=Xq&r#cqDMck4oMUyy$y_@Sf@9>xrH_rlR?)ydJ>6KDtm%2U<`(_!)%E~4q z^S@qv!}@ltOjBak=LY}t@z0m6;znwI!Z<8wXr{}AOZ1i$nf5VcR8N{oo_!=4tCjxR z;;|9$Qx-%|g*x2NCipDV@AwO|zC0i|FWqXtE8_cjb7(VJdlzuL>Db_NwljWsZYH6r zPgmNSk9~}0TEg*VVnXN7IANwA<8Xm;d|HER+~+DkcgrU0-LP(2QN(|J#gZbKzyeXw z8<(g$UUr|l3x3-1DaktABhIdE_jh~w`NGbE`I;4%$WyR6lv#4C> z%j+n&xc6&mMSTn&0rL>sAm!L@gmZ zgX$1x*$V5E}-!h`Xo}nW^o=#76xfG2VYM)I|j1S5+{~%N&08SIUFN^z>xf8o=iB zT`j5U;ToSS$!-;?UO{`B%cOik@G&xy#~38UYkMVPbjrFJsb0|2OB>(qEi>s>zxk}B zdrs=R7p!tTcIRZ?-vc`$JQfjL6;~0w35tAUtY^ApN=Hqt{>AeaUq~1!A_%)*@;|IX z6wx#30lAwCo;J5At?A>aB}k6bnRFZ={Pc^L$K%p}GtDSh=)hG(pWqj*%W7?D7@V9X&6s%6M~SsR&IkM&zD zQ(49cI5LMwsYAk3l2?1B{Lfq!F1B_~GK)<@*6(!IxphB4wQefT4_K4bMk>d?adS(q z@bwux3R0VwvgY~v%jA_nyB27t|xuWy;B@ zdA)tf)rXLu*S2Jt+7wF3U{bFho2#7^C-@5Ohk?vHuIs{_A~i)xI$YQGSFxXtB=@u# zhvP^wUcOvJ@VQ)aQR4%OJ&&7g-C73~QguOLj5Q~!1302555;YN&h|;IE z`-RT$HX*nmHUfDqk|W|L6Im}VUf1Rfeo}1}Z-N%Auv_N#sT3V8xM7WKNj=NZBf=>AcgD9`4mOXko@1anhd4} z!xtwcQlb>hG^T<$kC8tAG4iXZ2AsDjv4K#*ZCFbG%!G?`Wb2E_Ye)5Ytp^D=fe`ZT zMu={otI61_^|t;=^7s7SkkNT=p*8pSx_z~BYY8+Av>BkxyF`kwV&bMqSOo-{&YZjM z4Fv+78X%#Z>-?)cW4YgoKhWP-oKCK(nP3MG`l8mS4%4LJKBd&m(@W{@3zW1-YyD(w zC&v2fw4|_!Y`P`)?wU9*nhJr{=tY$^tHj;0xxKtepTA@avl!yaK|GAF+VL`1>QQPwi{{kxe~7u;3iJ z^)w@Q-H-W5k-jA>#G5crb)-~HY>s}0)e`(cYbilP2#pBukN@bqgJixiY58rS&t2&Y zbmKL3{WhdpM4CRQ$gIbMxgaQ{K`!dBU=n-wX^U6l=9slFs#()PCy;e=%X5 z@DwOklf$9F_(jxvh|$v>CaBJ>aq8SzHJMk?>!ffDy9PD_42&2Hn6ar}!?;+#U6*d8 z&H_VwDQ|CY{L;?YKXx7}jHXfRJ5|QaZDPMz*9MvGr8)gY;D@7%UxmlG_5F)FV`yzClN)$%&b!#Px8in zb-OGxGjsK^bQY+ck{-?!HwCKh>-aK$ItzMTf3$!WC39L${<0Vc>aBlV9<7)H)H#KI zGDA`l%?6i){VEjJ?=*I2+iLji#sQ7j+l9(a?oPy)Y_zYBy|bI~+_(^eVq7&Vsrvbc z9784b?^IW3YiptPL0l8s6Lvo>8G&snQ*t;qdfzzy5g5VPwdJXbtDs3*e&AySCzd1j zm73=9rRh-MfI4#8v+eQzv-}eMChf4y1<#X+ct#DDiJrJ*n1JBm{#>v(1JLE6=6RNp zkx>Oe>wM%oLGoXj4fXD^a9ZIFStmn}md ztGRu?HGdYc<7C+!xR}*NKaB~@zvT?^kd!YR@Nw{OT^~rz23T|4qQ(lRJE4O9{{HXV z{NcG_u5np(>456p1OPpGUl8`l|J(%gsq_-zIwSOyoAk&4C8<^cN-n1>cA`Ij3c?5! zB`3Vg*kFp-4O)^?pVA7 zc?J8Q`Q8r4-ngC3mWiz7l95&nAu9bRjs@A1uhxhkAALa~bU!ly;Xb(a>5O?z^L1jn zgOJ$ZeTfc|?;DjR3SpxvyE)szL^vt3U?jsrf?LCO7vuNuzjNBo>t=XgTL28z$N{Oc zGcSPdTmkg($k%JAKHZs61pHyDM}Jt5|69Q`t>|1OO7IyDYD#WBUbNbs-=n0}cS0;tFUV@E)M_ zEbr_v0;hDwm}R(0_<#E3MELS1014~;=C5zpcR;q#p@-O|SC+Mj3SgJT0M)fxfMzD& z+<{E!j|$3LKg(9ocU^+F7|slw1<+|I_ps1yD*l~sKhVg5qRHa|YSN{CO=#PwwBK~0 zkM!aN&ZWFKsg%(DWtMjjX<5f*E9$+TfzO>&zEW0DGphGuq&>M`n{~}xPCpCKIAG`k zU;`#fl6t91mW>4}-}~~eUjiI7S)dH1C<$6>PR0KQLESe=!>i{ zs?ZZVYQcan05!D}I+_xFSaeASXkDQ)Qk8g_(bUOSrAO0;h5rn}6SdrR2sXUpJtq3zwYr5#PB^ShJ~ zy>VA1;IUys6TJL7`*BphUhh_f_-Cc()$wCrlsm1hX-Husz*>aeF`=2j5RTVqtd7_& zoMRH!EE6+w(Id6`!46~B69u%U5WFT?OxxmvDS_bP>VkYQfq!|#bU~#LH_;1`fHs^b zUeQkV*mZ2!Xaupu&%B=$dX)F~al*Q~X+UQZsT<3H-ZP;57({LZkjESj7ezoj==9{z zMSpfA(jrP3cwc4XMlP?c!0!ovJvly(J!rmB2y;NEB(s~MMRY|!CJPb?=sHTZZO#t^ z+URI^hvQR{lapV!!HBK_L}Cacvfop$mNTeM1<b3UIL}K9PMs5|t8b4O{96 z1`Q*h_|kD(j?uXR9P~AS)ccF|hJC5A{`umkYl(LDP8~`*;9zv&Ma}^IaGbkmaB!Qv zr+YIR$R%IU^bzSysX_uD>7R{2rM|=dEbkR?d}M^|bW0wu9qIJl;wQAKCn3xr^q{3+ z96#8-ICA~B@vm|LZnfnRnz5n8rO21SOLK+8mWV6D@Fj#ZpbNvWx9SmZ9WczFU1#k3 zLSj~BtuHe?kENMoAGt8vxO>8R5;KPWL&WPr9)b2`emj7#QbiX!MC-a3Mkcm1*WjWv z!$JC0?^O?Q1_}rR8>JP^pRV&AVu{otGb#p_;9GLv6(WBw!5V-eK7LVVF`6^d?B(GV zJ|qE*C)qi*(Zy~WS9=L*x-`}82Oy6GnC_;PW!-k70P2?Z# zhE!bZ?bQi{n!1SLsLUUr4>MZ7K|q%8NW$&}+sxHlEcKeB4^JKd40^BUvM&+!=*-}p z{Y}4TsaCv~-b=-T`k}Y}OpK&M1IcNk5g-9+0AcK|q$gB}{$+@PlW;o%l#lhH%X@pw z=vAo1d{kc+0P=HA7lv4LuxqG*rr~sMwe^gp65cXVkuv!<1=_(I_tWTNof^yX(Jx>n zQj>NfbXTOrit`f@UPN1SEF=Rfba`UGWPoG*^6N**9@N!NGSbqTt!g=*sRB%YJ_x3 z_zNTTD{#67tpY5c+0t$Z zsF)eQ1X3;FaP#xh1+cFBb4VqSx*kCuj~up?)YB;*05$ZZ@!cB)ss(C7Grut5>VybP zZo@0Jm4)w)=0?3hetRfFBSsyf@OBKk0bm{$AW1~6b@O@dgwfZ2ifQq3q9L4^o!W@$k(iylR8}iJvxoj&luWord!LvMCPS@Bg0q~7 z){?c1bfwDPeWVE&HRQtFN2uN*eQnp;Tj3TgjADe%@|>)boDRE4&B!7&9^ae$1^;V5 zNRb;0YN&abCSqOLcAz3p#|s!H#fbW{3NBhr#1*5ddvAhFx<1iW|C?u4vOVW#RhWX6 zWrLgn9$7_TFxWm1UPlblj|8VuYs*&TzPB-3qQ`GN zj)K9%2&O;nh)?l7D)V)@y%9I!tt}eK#w*Y_`EZz9Pu7E|EFohilX3^ zn2wsLW&qu@hr~mq&&)rk>Kbd2(BENg1Ly9oW)qS ziE-T+*EXVg)I+flRm?*3L^Nb)zNw+QzO&lq#B1Pr%W3!OCSQ>n`?K)eu;Zu5B3DB~ z4I1jPm{>)N&@)>T zqR44T=}I2TNrgnKs}$ROCG+zaESM_XJ0VcfNRYL`1*rKFFs%^R+V615ODsYpee!|04Psxd{XE|r|2J_{m@@@ zpi*d~rMsmyMi#u4OnHj(WoGCndo^(fPhOpnl^Vbt$p9O-^ox-H zD%lfsUHF&KjFR0^9P74ryk#I!1?)@H>==%Av}J~XL!gF&aJ*%q>{fKTFrC2J74CrCik`Un%&Kf+-TzR6b=6#Cym+~~IWUNjZeI*(l77^j)7})F z>--saTqTfmvExDBiK$r~Gy2f=^anHtODb#$$5752a=`8W2xrKQ5Z22x@A~$pSHSzW z_B{CW=CtCQv-owGLO!@&zt^8zWe`iA7Rrc?agP9XD^7>W0Jj?PHiEz}T9=%vT?Q+2 z6>w?3-$+n7UzP_P2Kv4!k$cHnEd&;^4b%FC1-uY`*(e~)jH_$(W}URzFiDj;{Z0^ zdx>`}a8mxYq4$T$-5WTpj=pqRdbND5cVb?%DmQREK;Nb(q!oxi1BdASS&Rk`u|S%Y zlM|Ifl22Z-*{!d)H46*@pu#a8;FMHfgn^hRv`=XLLB+|>qJUpZwX(z5WV`$ftotL7 zGllIg4WAT60ZGBNvy0J-9R+pe^8Olnb1|D$OpD<~C`dvMD;m#vE7-P-?oR|eC;al$ z=Euh_Ls*IeFgl^vNKOOFG`-wnMy<2qdn;HNisXPSIxjw0wNp zhi-n^AiOny-_LMTUk%aO?u9nAK^{VN&`7`soVcTKD2CiUd@_5S);FLsJ0bz7+WPjybdQb@ z!JMBpEb|KiTx}Yz_>%r2P~$cZO&AnY3TJ-fotLVogncJG>qr&4oWd)zT8$?@Fkv6g zZYqf_PI#%ye*3$@rb%+qJ9f#mimztJi!vQ`K;@-K(H=M&RJumd)~LvSL@MRoUJ%`aMC zkn9+}+L~_a>Y7;J6ihOpfHM*ERO%c|MdIIS*Jeu&+)WrUhk86U$lTHrtoPyEy6`<( zcC;b&o7cq>DMB|#YD@d__?4|>iv@dLx}X=CoD@~wN?mUGf8+JP z=jq>nNAm#p45VHJW&v#p{>)ncUl(?iFwe7W0{U|vwc6i&j%k2<+)kS9RR8_u|H>Zy zbzwubc(*Y8)W#}9K2G?a;$61H+%1=3Bmffp&u=A@g=?gTGyP1+81tXw`aiE%O<-qb zz)`j&!3zH{OfFb#iOTK>$p3!OA5TAK2S#vpxo*Gt4Pu<{r@xcm)QT8JpF%@A-hyI?J9GnM;MdSa!g9#%^Xx-P-5s?-2W;5fKLC{XB8L5 z*2QVI*52gk;$ngo_%j6oB~ejR*A?#q31e%j-BPbQ9($_5o5t{Q_ zQpYxZ0#tWMRFq?w0dJ!(zBGS>Sf@DJGGwZjw-T=YlP*d`wnPxc}wN zaIV3o_s5_uv;d9M;Bw>eq;XH78{;%0p(8MEfPv4M_#A49xR_Y495r_7tr;XAp5)&t zsQ=hwk5VptPqyf6g#D5%a$kMfoDyMq6X@M}=H#+sIp3JySl};=Z!zyLWcuLusXO0W z@!j%zFxZnNYu;0SzrpM)CW+aUZqE;JSdt|&iBxogPz%dM36}zm~a|ACn+~3!;`0HBFG{41V(Wjx7fnzjstQGhkFv26*lv~=-&P7kJC5V5MP-Q(T z!{=m9d(e0n)F@#5z1imeWOh_hsxl`c0ok`p8-@7e!yAt4;tA8q!`!tJ{u>LW(>Zq1 z{_!$4oU#0*c#bO-u9^-L%-$V1ZrkbjiQwL&KdrQIBqp8GNV(!|5vo5BcmF6S`9nns zi%>5DIk>M5eOqp8A#9=2B18a&SXyPfFi)UFoR|f8&UlV+9xgD4>gthQp*Rq3TPxX` z4|z{RLV{6AhZED@*tDoYZ6`zgQp0);`W`kvq0JTswwHD*#slYqhJnGQhN(@JRqg}s zb$ig%k9Cuiuj|g%ZH^awXyIpWVsh>-QEJl{VCh&?#sY(_@1XDfJ&#!tlWc>5PPuja} z&fZ)C_EgsdXSnnLaF_+Lghuc2yWmgBd_^5uwrb!mPEZ_Ehu&UZ!mT-SX|Dg&`?`bT zWnL!0w@VI55LBj-PiD}mwy8{9gF#w#g1z*~0@`r*ZKo`o>$hkSk^Yv2K}@Ng8nQdzaM65TBI>gUc3_keVuTyDTMlB@OSJ0nsJr*! zfQn}wKm2gVt%IDU$LA8CB4c=a<}zb`agGBdG}i(u(D$aZq%UZ+=A$~dueG)8Yto6;iUm#x6;QE6}75A zKCF#gS>yr}TS{>4c zlF8xAPof$CO&9zMpLik#uI2OkJ(%>hzoKJ%=YH0xcYU$PoD@%IeJRP6G*<_TsrVzt6oCZ^#Z)N7|GXjVqWyB z@FpCznyWx2Opzw?LDY=$*JuN&rxi=)jd=GYYfGXAaN4>1S*;%Ox4Z_>g+8;*Te(1L zhECsZOcB(ujb*MH%bTHbYMpbQv zWfLYrO14sa1&%TGZ8)FIWG47~Nta&3`eubZ36o-f0yE`Ce2C@2HW^@^v~t~LUBv?A z)BQhId|VPBPAecA`0NM-xBoJz|9MeHy~rIl?0&W_J%tjQ34munmz@IhezBP)ULj;P z*kz#YP#RvZnFg8p2Q}<2)zLyiEUY*qiZWfNs&SGRVv=T!=_oF}{{J4zfBBrz9dNTW z;m;5dbaG=evgzPdH90@f1kycxg_nLg@N-t{??SJ~IK~66M3S&ipFiIc==ZN;nC%L< zal~GN#lo@^9A!;2&7VLM%e$4X{}6TojwQw8_~>w$y?_Sc_yllFLW*F)^luds-vCEs zCHmlRUmO@mG(D^hmc*-9&o$%pAz?Wg$=6K(=)@+IF9I%IGCo}Y-&*cRmTQuQU+xI>vI}{6k#div`zs(nd#4np?*Y|e3ySfEQXCa zCw^6$V3PTz(f9^K@-{cq_7m^^@&__#7Yoi}K-L*8<3wb?^*_s_s!x^eU@eX9;ls!Z+qS=j-RxDvx$JWrz->I4R=zf|MTDKt|v&Zf#7`%AAkKHLMUuaVA_y( zi`P2;!8=a_7!}*$C@22_hdgHjzy$bnsDtr8NcbSIj!qImSO0JeeBzV9VOS3kFZ=)2 zAAhX688CJ}$_~%Jzr_z$7Ql=AnjmQ}|FlT|9jyUt>iY^9dwPt~Uq8p4J3_P z=d~5W|9&&H;=>#~M3UG!M_f_8+eB2&SE~6nkc{;w^7UV9=+`dQnkxFvsBtgt)!)7v zwhe&s7}OpJnJND5wg`*`W=hm;hWGDbGrHMFA=$qfn)+J_5dKC54Dj8&vqH+>4)8e- zu(p9W_m1a(yKwL50DZt5Uy~m9zef#Bf?vBlup~>(4{2}ye%vyT(zs^5@%=H)@Z4{; z6GZX(2(!*Go~oxOl!|&a;hR0t|9FXaUy)q#HmB?#QAw)k9;8lEea2xQFM5)B@zw21 zedVGBgk=?oX^uoXwzI^t;w|Inq^K~Lz@TN7>^j#=ydhP>5{5KvZw2F;pP1kj;xPg3 z+JY$}i;d}foLD={2DsT<(a6&th2LAGLV-+>TnX1|lKNW=dwoo53N*%YO?HaY^>)_u z3Uniqu95kr<&~z|2XZt-kx3jz_hS z%!wgkz!@w#q#rxp5Y_9eFz`LkAjYaDY3dorD{w$3mDc@%_tC{!3?bpfpp^#GZ;^P{ z`#9sPq)!yUfa!8U!p@&j6Y#w4%ylRHoOTn`X_Jv`WW;GRWc>LHyKZb|$@i21jn6We zoUWmlW9F&bDg3WW_H~qvIBN8T>RFSF~@$b!#2Vjre z#$T->AEoyv9A;@+d}mlNH7|>DBO@0^X{=g&w40VOQ~~3G8!d!RiPQMJP`T*fCf0Q; z4}0%ErLKNu<+~WtjZt2wb!u_x4fhVKxMdYqsq#40{VD2ap(=?IVqN-g2J;LsJg6G# zd8DDP->u14YAM(MG`Yg_6i>ni&1h~Jl*)mVQ0PUTq*q&I5h*1`N`c}bSzi9pq4hq^ z7q#)I3?F>7z%C$V$pQw(caGZmOzaP{Rgyu@wzOvqNjwH4xGCKD0``P3A+d7{FIim{ zCPnpYD^q8#?V*RCz_(=V_D39`)pus%BLm-vG4#Y)L7Z&(!c6%q_n$s#d z66h>5qA5kjJc<1ord==EGS;nj*sFo_B*a@VF|q@dG*hZ=-*spwBJj$R39_>fcpU5x z>!L=*K3UkU!>J{}-`h8;@cLsR{p23K6lp`IKfJ3gj8c}*gi3)@Tzh=_;u7F2>w@=@jFT`)C1?fZ;$?bm7b%o3L? z_hsS{VT;oIu8HpV&;O_aXp(yRo046GAa%1GgJm{0RE;;!# z7`DZn^j?kc@Vj#LK)Q|mK*bB9q;yJ8;Pv8_LroJX4QP1HTm(g-Ul{{i7%Rs*Keam? zgQu>#qGKF$Q06Gh+vT-a@55%L!I4Fn`H1DgtdE-BoVTr;=s@lNy_o_0b^7%;Cc{F; zmV$NbHEtXgh4w5H(-s1qJj}IU8fzTXouh5_dwDF!gL!p({B8=F#wF4N&$F|Q)Or@) zlnvZ<1~NJvp2E{-ud9^G@Y1hu?37KtE%@n!CwlgUEmvY(^t%{)kIopS$@1!9a#%eR z0Y51LOZS_AwNmiGndEfsCEOd0ODSd?RaKij{Wgn+bw9tO5)-r4+i^rMv{s0f-B&8w zu-(^|S3d(Kdo1=P7Mca;m0S9pke93013>6&!-6A&Cb`8{1oSOsOT+9bk`d7(`ApJA z^vEUa9(z`e>%2!_{;*nPCU7OC6!?ro%D;_+1v*<;X4&Q`XhasXV^Dhbybcva9SBYe zG02Ep?D2MVofCZZVE{WFC(oag7fU>XkED5`28o6-=6L&Ze%i;PJ@8X3kqHvhl3Hd3 zRoZ-Z_hI;3gKR$+Z;JbL(ouODy*JDnf;$X|W$zUZ&9rw*%9m%#8o2mBj4EOZp5VuP zhXZAp4aZ{Mc6zQUFV+VZo@Mf}b#JQW1W`#E$a9fAC`4H%JtdjX2`=h%{jAF-lleem zW+Q{#<98>7J;qLpIJzVxNHKB#U^<9BLaojL1i}Vxq=C$+wRPt?)izPd+@I8@US7Ue77&K{upj)=ug(v#iuk zSY0u?qx$|n8d6mGsdS?_c0t{?vTin8+WHMoiPMrL8{d1 zHp_6!i<}&%;J1i_RK1I?Kq%XPA?kW#M&eg~^kset;dx;kWdbWh%Y5nfJsC`!yMt48r&#WVGC)3?soz|F9r zYRT~$t+n)^zrU17Uz(|k+6zR<=mJktpmT&Vw2kJ5RSB%j0?bKJRrR`DqpMiv{Yz^0 z!Ux*V8)!0zaVN!U9XW59?D^NV*2gyVOp~>BmJ`-MtBpKV%QZ>y;^qNxv&We%U?NgR z4MD4{Zbv0UrJaQ}q$3o%Z_M&pxJ|6Jk;0mPmPEKE2`4yEub!?IazAY>1<5vbx&4wa zUh|@^Cl_h-SUo@IxLhHnQqtl`!J4)c_Yd6uRN!^VwKvmTetIyessm%gXQwN8YnnX! zYTYCG4oV3vzUmp$OT3qruVm^dUGL^+K5}WkIwyQ1jbOpimw_A+J!DoI?V=jZq-l>@Uk719 zE_|n18|ju;!&$5)9Xsx`b54}Nx_--CDxb_c0MdvF%?_PGK}gIMYT_0%Fog&6c@hw#E_!bGdqK1xmlrZyw}5I9W!1PYHdB-*# zxU9w{7`5!kwMnXCnbDPfT`VR}J@58RZ=v2)g{%n+0xxu#Ol?`{X$q1CTNY=J=>W~A zU$;7+Qc<6FTU{!Z5GzsSVycikU#nWM!03T161%uheF?#;qPcqx%L_(%aHzMl+Ndy@ zED=TdfofJU7y0wu?gRI&4a+Z-MeC5*nBIDgal5yCxLfU;w3&t%o;~MXo~Z&?TsxmsGa?+TVj@e`jwuzHc6>w5Gh$M2Z}3~_Nlhj@DpFyD<p%`E&{1oCDcHK*{=`(^&6~C0H9`oPr%#Q#1kTP)#){cE z^cK<0ba6nvU&pGg=QU|v)+b!ei1vGN&#EW3`-Br59JD`4^V6m?q5`=6VL2X5tUh!X z^8Zx`_z{Us&b~fG^AFwtheYdS#)~kyq2;yl^Zn9M9Pwd?_Rl`ApneQ%ODlz*_62)e zcJ2v*aBaVsLZ^9P4ARljV#w$ysOdGHpqr3uc7vzs*+IE^*853kT(`sCZ&k#kDY1-m zypC;o#LU{ZUlp%r-^LJR=0Vadh0K3FoLcOvht2raTI2RdwBFDFse&v4CXq0Dm#0z_ z=b9vw#tHmSe`aYeTtpZ{U4~jYrrpO<+MfRQDg~s!7C-mp+*@lqz6(R!oIu;YT2^u>Na)Rwnf+0!`vlh}Ud=2mmTWJnL$gyZT5G?t(i@=yXCGHoGuNlCBg-=KmbxA1u1 zZRmC8SZA!wYD(jvZp75x?jBQu^Yg>g6jJS^g;{W<-zRN=?CRM~qy@5m7SZvmRNXhU zH}`sP^l#4H{&1cHV|x1e;xVUga!fi04YsbDkOwXA3}aUiIc z!ds;NJ!nmY>%PUOOA)@^KT1^-Fy4B^&<`|!KmkC-+pkP#Q>`ku(w7*UOADA5+Z8X| zXLvgKG)eCZs{IJt2}?RgM#^S8+?+9QT|`eip?eezhjCeBRUgE!*1*LMnh~X%ebqbN zTnw)nQW(&hrDD?H`DE1ESe{a_k7OC#TDh!U(+6n49UZA8Mkh<7lWFYnF-eEQ_*0PY zy-Uo9Ad$c8$Qs@^!V%c6#yxZLS-~rc)q1!Eouxj9!4&y68&i-^CL>jA5Q({tS~zv# zt<4nWc^}83Tq5=r*N42~?V9bH|M4C2gO$=e+J9@Ee@z^?^e#G9R2K<~xjFzxIiL__+zgv%}nX z7=c9k^#rQpX%9qgZ|n2EreSZx_S2eJ|P5|Lz%?gKCJ=;MhzOIS)Np zqSs&B-dvRb{4Mum8I4P1g7t5_tv2aN5hq4Aa2Q$3X7TLiiuvT3do%c}##l&9dtNr_1Fb;RiRfOW8cXJ*9juCzvrg%q<(xx$!OcQ#Z*wqtvT->YcMmbWi#<#$eQT zIDlymsxs%zZYE z7@VpW;BpztiFxamiPBfk*XDp`QT1FfU~g<4F02Cp-|`j}Uwj;M2&s76P%}Dn(2`a; z@&V+ctXwgz-8`BD3i`UYT%_&Rd z?bjoWwaP*LS!6{35g+Iy;NMI&`HU2D`4nfZsn|84AhWvWKtnw~6@I4ojc1sQVGG)* z6`?4jKLd5zJoPt&i+AdI3=Y;Y#+W{bw!|^>dErvWF_i}6tiS?&Rvb8w#deckt{%Y9 zG`!~CExBg=fIS4|_ZQOhZpp^wY+~d}{NCS_Aig~`tzETgUHbeu8XzMG%fvV?yj#-= z@!9d{s{H6A{SGE`dCb}8`!brhEiqp8jY%V7tkc$>`|`xLpvbT6OA|t;jFQC!%Kps# zP@hNT;0srw_(TwoR=~05Jo~e+`1+WtxOflb=k+hnniwd%=Z6wiSgL?Rm;;5x`8|Ri zVZkyAz4E)Str}}P3=R!3BnMN{)kL?7I`Sn`j$*dMk&05WFK(hfFR6^tA!F>%A$asf zE9Uk)V)-PYz5vmcSH(uoN4Cn8Da$jeF{$a!6OPDADCm8q=!hE4w1PNfuQp-=WS|-H zZy3WIH+zyQ;=YQ7@@5kmdlTZ^bnFB%`xAR_7PNU zn(Sp{9Up(^txszyjUr>i@@&sZGE6|0o$S&%x0IcXjula+U=t=#LzXTr7~S!)nPonB zXcWt#hq)%fVJgg-KK9w2rPivoC@pbx*}#R?rxQ+$*gTP-FMN-Xq0guxs$x4(tec;iCg4=> ztFm}1MdpLy+pE6(10IvFStF=(nBs*^Oshw?sRi&T5_RKMYwed!&gKc7d-~?q2s6v% zwG^7Mciir1tgIm36|&1CUQEF|c4pLWQvIw-c03=`Wc*6YOw@waVpyUCPp5RT+v7A` zITNUtZGH)p!X5t`hOX;IGfp!%#iK2YxGkeC!e-4;89_CjP_yz8%o>vn?{7r_B(7}L zYPLMH>6}^s1Ua||(LtE^Cvn`OES>tAPDf#Yd7e$1bg>vdf({zSD zmvx3K%YB(S9Dk%aFB3=Nv7W=T&&cTJKCY%^a(eYj_p?k4BwrHA;8hl$nJB@b?DsYxW z+a^cH9hF@_53dLs&uV)bZWckrfc2os+)_G4UN+4&0wfw%1*u60wz7=8*0Kx|E!wbQ zX)(J`-X9FQ3!dLifrZ95B(8RAS~zXT0&z;n!>5zFoN5Jx9X`Iey5r|gI1cULvD^h0 zI7g`F%awUv+L3NeK`~!rUfJQ4U3Bs$H+^XEHo6fC82%_qmlX4+&8uHVFy zo9w+$!Tz|_8b2PiMhcPh!-u%!qwQyx!N1WwJy;UR4o~&2wN#Bc6d9<7Ds7rCv)UtNL{Z3-mel7w+iIbFG=Ar{3^>)uVNJ&J+lX64 zk)Gd<-$C=8_B`=P`R0MVJgtehJOSk_RKbMxx?G}B_|!@C)rSCorW=}OKF8ud{?fI zddjHX7BMPLi9Z4I+-96t!k2 zO~lmlJU+RwKo*x=n@vFQiHjMwSN`_VzK|?Q-C&aA#nRyD=vzY(zT5s}jz&pIzsn6e zBSOd$<`Zag9By%(v}MNLwuX!9EDf5VMtOEKfWtywq{6ZY)V;*bZ>FGXrVA< zNs5QOKg#r0X6kyd{1D_@XE@`nWtspA0Vn4l#}4LA^%v8q9f*&+b;xzi z90m9KY3-+kFF_jG^c*w_wy%N%zb?JPTEi=F29X?51fP8%P#0;)$OP2>+5X;oKk>{;~LMvBRCKJ zRyXRez(U0DEteKq(c98I-Z14l2cq*c+ zD-K2}2NyNOOp(V)^GQlzl<6N^{n615fwQsER~#&`UJT*3RY0CN z3KdTppBY$=;XfkgnJ%;|@&Be0X;DQ}wwvSjtRGvFdL7rv5j_Nk6CG7FUU$#rPxo+N zeUK;YCq>2sv48w^chPH39U}Uj=w{q?>sNE}tk00J+u2zSH9Ni1=jeHdgI1V6QWaia zkNw69sV0%z_^32XwZhHo7ldPREe~47H&=^IO8$Gd=qg#6nb|%q^T+d>JZr-};9+Q) zc-S+kN}7nZ9{g9Psp&1F87?1_JPt_6T85HY!xEWB_k?TDj*c)C&mvdqA)x*|mmVpg z!-eTDuZvB4`7};(|4(84GnA52uC4(#`~noBBm|x<*h)^xkIo$#E5;!c2}Sk-FByq< zmG=+Xi$Ig#sJ$IA4B}VUHUexxno|0Q4V#r)>9vTgKa@*t_}p&c z9WUKvWrLCiD?UycU=p~iZGd?_pxS8G&Ret6Q0vL>OmD(^;Z2dI@1Uus07D)GgVk={ z@$8IRbKoG=mbQNzyX7mui=MDvaF^u)J;|0&t?2{kg-$c*N-=DIbUk)a@fl0Z%8aQ%UIfC0f{|3IZ=V;ej=)BXL=lTuQ=>l|+B>GlaVlAEyT>7=u9g<*XH3(k$QCK5I$d z7)+OSDsBvo)B?`mu|m%3%Lm(d!m_Ra?}_pbs`u= zWD@P}v)49M8|1wb}F>{!m9kmo7qJD0vu={DFJf|~S6W5&d=oZA3wpa~(5>g0B zBILG7Ji?;YIvM5HEM*cW1?mpqp5exg7f$?$UGtGH&8U&hMcsqTq{kF{_mdPiA7B6j znzBC;V}U|^bqqf&N-2G7ap*cCwMvu!^jq8U+=b9pHTMy zAhZa>QsiGi@ZK??(?r0*oZg`cB`nK)TP;muY+BOgp+&u($XgtB)-KBANcXxNU;2wfof)m_bg9dkZ|4#0`GvA$=fBtVR z7K@d1pRQ9~wd+*vcfZdgt$-51G%bHR{BqO~CvTk+M(w#H^-Y9!WCEUqq)s=YLIU;{ z+G?H zY~ZLhRlHMF%>lEUo#?u}Hs^!HWEy2Lq2wl9T-G$e^TKKS(h|mv+u85(pT(U(9meC*3kveg^2UbO ztT?Ak7 zBjH~Z_nHJO_rAQT7BhbHHn>}C!v`|0{Cg96lh`$Jhy(>b<%Xa=6~g~q%z*Xmzy4sF z{_~+#6;VgxouN4}MU)$1^$GyER7xxXw-j1q_DU9D<@68eT!Zy*C4}$0Rt^phb*?9x zPN`b4XvE*MmJX32r*suW!%U>oQWu*RK@TUrsa_&U>>?^ZWqwH();NZsa^DAd?WAV5 z4CjS`NGp>zL)g3yx;-8VaWo;`yKlnLULJ|wypyifY=l1tasKmJ2AK6c0YK@!bok{- z?rLu%TPw5%pc(pmo|gAlim#>cusz?lV##c|)?u5ImtfbHS?y6`?cwG;rkK-QRUT^) z;c>g-Q933F90^FQJwEaXqkXd&p;HjnxlhvT*O<%2IA#eGpgN%lXE8vZ|jYs>zs#4fBN1TFvn zXgi4^)q%9#A$+8D(EoldV!gi}R@Jru1nPg)|B?TJhqAq4K8%E{L;CldSik_+d&Yd( zFFw*Ti#jDn{qzY$!0qBJK4YEqe?JhO;;*Fd@`uy(e@^3&>|X#zvRHTkIfOvCGXExfG%T`egP z+)d5@{y#s5TtNa(0JE4$Q^Jm~^xrFWi9e(L3H#rBS0Zl`Ew9f!zjY^z>3>WZ!O1pKiJpFjN_i~b03*6STQ0Cji!8Vd_+r+aN> z1{10dARlT26Lq&CNH`362#8GN%*<0387nR4XPs}ug>ig`x2HdCmMH;3l5~A;+bGRg zz+O;Pp?F*>|JySwQFO8}IV8G0RRCa&b@+uH1Olzv-fD*@L}X5sYMqXC$_;m%jVMb(ALQ`h$ymixP&=Fq|Q0p%Y#5y@DVa{X3a0h20Q zLxY+*-<8-{99ufA5mQtpiF=?Elah7-Y&JTfuKnBUC=(*~Xd1LR^H)YYd>Eidv-b*%of?VF`Yv5w%g(JX?*olC_fBZmatJ*c zYT+ak^D5|~o;-%8yKahIiVc5%-D*inaO7NixC^iNjJ$DM#veOU?7ZaD=ECVws%7GF zwmZz?-El?a!5kW0v7>=kUeCq3np^L{lnbpb_@_Gr;S%u38u_kT-plm*4R9)RK3mfX zMJAxt)zz)q??15-m|O)o%KFDZL6NJM-!bvo-70o7c(lrrh@jHZwq zwuiH2b;d)9GBJ0x1B6Ly?OuDFil51n{3(tBYGW0BbRAi=X%VA%7Etg+4sf3GnZBa= z{{|(^O}MeO(#OwTOhQDtgM``wu!t!Ac6FzB#8uY zd5Qq1fa3mcuBV6e+5}5Hqkyk&?|@Q?WRj{}c01G4k556pWsbUP06#Y!Bpnw#^wLR? zsLP5x_@J(}-Ru#q zih*1skuaem;B*veYkzS0%#DcPw94tUD**u9b|R>9;sGBp`5M{gzW`ma>AYyaAIpPw zNcZj@5^-Ezm&QkzEMhi6Z;T+h@0fRu86Q?$xG>0V;9CxQ7k4}5;T9;Kv)@`F6&nVw zUzX?vZqPees>EIJSe|P1y?B9DUEmf@yUl%yHu4tm?jVABuK_wX@OYS(W|Y*|*Z<*a zYT}n{9RSTD=U*<|uTe|>HvlySLx8IJ?*F`NKKZd+1VoKXfKUw7y298j`2s#!jW-BC zU^hwZ0I>DrV}A^Oquxk~Y$kk1xcBqL03bvCVb}-X3?OLVF92X)T@ApVLbkPEQbZ)U z>Mvw>XPGJ*@_N?gXcv*jvu%Z*z{N8+g zo=<+Re-y1eJ70!J;If7j&HTpd`|M6HgckzbW@)8d3>))Z0+~41&585nw&d#g!Axlk zvRu1Dq>fTqh&SNCyIFZ%8XWP{ zc2#rz>GkDF8VJ;tDP6p5Z1bMTX;^S@aPv-E5FSmPV%=|lPXVSpVu$f}qTQbSsIuk+ z-(nLBy`u*@bY@-HV6>g)s})hsWKJpk{p$DLa@(&Uk_ybb?P*{GiSgiQHKM7ZOwsya z4UyBG#yRPBpELWioMOLG2jcblM-~u=i@f6u^7rfXnO$NZKOJ8?AsDckyIL7L4MtwS zc2)P&QGHpmTJthkby>J!h_7zDl+tCf@mp4CHab6JS!@nkXg3Z2$%lwBf29|ldm``0 zX%Oq&vFD|+G2Qk0s{9m_@P7P@&d%b3*a+W5biC8r!N-R(wd+PfD>)2XbFkx2yOZ=7l&9Q>K)jzLN+&;;+7Bx1IOQ zo?nRM;&Vr7823N-v6wzW>8*uzK1ly68a4?sS&1&Featv3m1xxpd#qDRt=Cz_<|?02 zxJSm;u6F3dnclj{g=T+Ms8QL`IECaNemPjw*r4b1A;cvSg&}CJqVn$K_YiKLZ=Nqr zk})FU`e=mYiEo785_)J-G_dFf(8G(bxtysg4p`tG@wRxj?uMvxLBO})<7YcjGLz59 zbN?r(j5*Dlq!^G62!#=6J3nTvS&0i1<3O9c?FWr2PEMp?QXqAI%HK1hj|_mwwFtXj zp#96z+Z*TH`@~DJkF~;XJQ$y>J9b~eb>$EFPRS|8peOWU@80H6J7AsaV()?X`+og? z_Oq?aT5$`1{?9?>o5lKZt`R?~&tD}CNaB6VDr@X(mOes-`jf=7L)#<8pl5?MD;uVz zd<$aAi5%BF_9TJlZXQT@k5GK#(=u3S?9=)9@V_i;w^lJYv-hsRpXUxSgw-zC9-|%~xq_`f0 zjD<>GfGhLKq1_cQoiy*|)Qzz%yZ1%1tO9Gj<9Qd%2oNC7Mt=De^|)P%qmk*-CM7vL zPD@ffNWLoqf!SFTt)#<(z&5@MXbw(TJ>woUql;)Wb=`H)ikfTaRpa1F=A+bzs`og?9kP|hf%UQv%^ zhD_z(MPz;zXkubYvKu>)bf^p1xI$*y?*jcvg zyg7-!eUCSvC-}}{`A4OlUQr+S0>{u_tUJH_>$TZ)RYp1*JD!zLICRy;Qvu?&-?M8( znap~>T_j&jNT4|ZHAbh|qv2)WG}h0P)793eR~Vtd2z-kvMj-01O#{^V8roaVIN1H} z^&iW&N6PQd07uoSyORy_c5)3lXX7nraYWn0O>6X^tI#+qsh?_Z{rK%W^^&jNX}gWv z%j$V=7$#>fN3E`35#Q(R;Tgsme&M!U zf|8HV+22e^WOV=2@4K+)H#lVXN-J)=0zO@8Oo}oYK*)M9oT-y+Jp&Y2D97hwv zSedFX9@T9UX@X&K>E^_jeksPzZRNkIZ#&YymtSj$u%2xwS-JgvR=4wxe{g}y`VX_L z+GRoOqHzQh1UU6ag_aJn=-gpr1f3h@(C6DJKY*$(Th($%Tc+FILUcAsGMSINZrkx- z%74r3>X7Y#W*9Olbs)seb2F>l;kW7gD29zR)i|%`=c6}D&P70u>Vq5=Z?n{pkf!T7 zbcFLMB1Iy1c+v0WW}$R$kHx@n0WrWCHqVVT{wdl`5$;Y|f2D*Vv?ce)*yNZl5<Ljd`*eTC#J88oi1V&y zF#tKpcI>PKm}J;yvxS=Aw`g4YiaVReFVKhqjsg%zw2kPq$LYVAC+jrf(FT82R_y~8 zzZZhT04CH^rDij@k!Q zsrTEU+`>T8m^yy}Ayf&1kx9TI8?zNl9Slv10aXA@)bm zmDrJH-U60qsTCydBw-}+B90IWAXZEahLicU>&YMd4L+FBm>ZfJx@PyiM{h483H>EB zzCF@+b$sy0R-%8~3 z-va;ezTR*7_zm$s-`eC!8p78;BQ7 zM_wtnL|XHEfrt2fly$rB5C(btH;gaWF($WieI6ooU>S3`L?p!ck^sA z?A`1(nCrL|OK%)uVNgsc^mKPxKF=yGYBCEqgS)S$cTtka3MRV@E z#NKZCU_Snr%YzHM!QkJH&ZYfzPOUAk+KDlRvA!-1vpUV@T!SUbU?(ByPEUQWGW7e= z^*`ZD%4}AfGdjo52l9Sa(F$QOcjhM(CyPH~XYGw?jcII;rAU?cej-1(CAHZQG$S&@ z=X;GX&_hQp{}hu;>uA?3X6p^)>G!;j{^@(wTQWi1#m{CMh?)H}8I!=iw*`3t8ik>q zVrFrn)<}Fq{=JpQHP_?2Ycy=T$$-z%!sfEo6C!aaJm>yYZX6R(=$=cJKi6opw7n~h@ z3cKQpYdWqQc|MDC0#^$~7N8J0^rB^5cDF%{C_t~G878kYMdfSHIPKSO*sb#GzrjO6 zl8GT~e$k>pf)viRyasK2OGSa0PHl6nQ0J0mxkouo1u+SKdfufB z7o2)xbE(!(+gCMhqnhu*z50oHMbtPX`036}kb=Z6Xlnk#iZb0!zxnnqbqg$L6o))k zqS4lblW}iw&|kNF1TPI7;7EEIZeht|cX2w1sss@Q&kJfon;htIrmj6GHHn6MdZi^5 zWz{7WI|@O<;RZLuKH5RYGPKQY3ru>x?8!)^*ATch8UZeKh2gt0IMh)IaT*l^es|WnD@!=`qBwuNhS(;i|Xwd{5Qa|`)sC< zOXYnz=H>37F&rJ{Bie8uk;62x&B6Mt5}gi#y?Ds>Tt~+G$4=qlUtfk}xj}x{t=D^$ zCP5HqA4xOcf5t`b z`SpnX+}NPqsw3G(v+B?-hTn2aY`Q<8X0Tc7OH!0Jr{1H(_jPaBy1JiUl;j*QFQLp zhSoiYF`{bDw2vsz<(x|-Q6!+zsewEci%wj12#|tm6N(|$8Q!DZW1BTscFSmedN6XK zP;QZ@lDizg+4SBuA@@h94Ai{#OMHR#p2VcS0dFal>V*ak5mmuEg>qF;!&C+u&sWs` zaD{G8)D}|BdECqY@B-+ib|S|R7C>V%R7t2QB+-Y(h4K)B2oW6eH&2vF7T(dS7T!G& z(Tq@R??)5GgWKA@$B=$IaG|`5N2YDUG&0f9{3$dotxgpVUr~|{pymhRLADc34@O-X zA`?D)G)cmpB-&bO&A$l(}(r0+9vJXzGobWYM)%GaPwS&)sK| zm!X40q6HS0zAQ9}@xs0KhVKarQd^i3q7!v8h84fweWbTzaB1{+;Cs4f!UkIjX$z7ISPQCrk0#*$vFJ8V_wfDh0?~u^A+DHx zff$`*Azv6qcAQZ_5Nh&mLn$r@S&2tC$e^*oFA z7JGRweU#qR`Mbv~0_iviT^!J$h1LvaEwy0)>~y$ji#KfM^YI>RKR4f-4#UZhmX$;8 z_J_4R(8Ia!8DyA5ZWm(JE}7)*n-$z{daXIyi;c~nY6OKzkZFR+L{6~Y4U9~bVtM!$ zp(F8qT5fi*RDb;A+#mNQfp*X;6}(@m)_1@+K8(r30#~&6EGlX=wOK5T?y}nk4;GtQ zu$tO3-#e{NEr>5@n%ELU5p#NDn9eSkFn%H=ke;-tLGH86wkHAos)Z;>HF1X%{K53W zF~^=Iz7SkVm11A3?2<3TmAxjMi+L!$@8jTU3XU~@>9)H4jVb}eVSK~u1aZO$9q37W z*6&2|C5LX3(-S*{D@QKJAw?9i)LX(_a5xmxt44bWD1T$^S+-UT5Nq}ENFglXBEm%t znmi-QnNub5q0q3CBKWt_@A^)lVs5Y&YWpKwTEY&J=ghPR9T;~|+%RA5DO8onzcSLb z=L_TrBGMiB=$jB)@i8O0La=nropSb)YFbB=ttIpH#{ zOoatPCCMQkR_S(3zHPVs>I&k80`m!e5TIoFz02OS2@^%!6ekuT3lfFf2oR<4naUFk z^7iT}$c|{$j1;1t{z1Z;0?uo=jrkEs~9$1h=yU(&? zaM5CW5sN$Fd4s#34&;TiQR;F#k~)|p<=R^DJ?R?R!(La~@O7D6|@5~p4#FTkAMr;T5NJsblQ z%T+^`s`oOm!5`CLQy>~7flHx8B2qg_41!420n4J>VQvahQBrGz%>{^sTA1MaNkNDd zsA+z{nb(WOa7-(*Me22XZ*lI)Cv4(F+W{{mILDk2XOe!}RH~*;gW7>m#9}l<5yP?m z@zXZ5VTg!~azm-(Iv`)LLiY=LU|gbpKE;>nq)0 z<=PoSP3*H7A*easU!%Lj)A@d-!r{$pFWb$VM=HnU0#YgP9MZuh@6@_TXw|-~_>I&~ z0_AY%ER}~i>|wlpYMsp@J(&>Fu$k0>dEfoa^2_iChkOd1bf-?VnV#yh32TO;)V#8! z({~p<3yutX3x3;!&TiYS!za9&!zFh}SNKc@jmIkg+chpMmCw%P!{^s&lXbESXx`9a z=xDAt=Iu|2J-&`Lq06M+$)ql-P`CaWs{Q!NaaPrF=XtXuE{>Rc-H&@l+3B=gFv+Nr z-c;JF$vd3T&$?==M%5&n<*qxV1rm+m_8jLn(!mXQ|H>Duj{NbAy{&&U@0 zc@d~q{fhotD_Zh82qZI8S}PIN%H@OHOLGy0XEZei&NDE;O$=vd$=Z#r|ZpL>9Shkr3HkZT|#u173Zcw2dJ`SU7NzyehuO@y&Ddz$JhY=_doM&)PG zOFimP`owccGh~#;vFNY1{DyA3aE`TLM&Six$Yh7~W~>(Tl6c*zHjP;kcB&lyt9QN= zzi*|(OAOZ2?4YA@bvo8_Q`S(KplNZTWWrhDg1+>kLzmbNcNOIb5*RWin`@#<$sEIt zSGVS{+FLO>P(Ep!xj80V2hYvQL_#LHUGnax8$G{Jv&BO@1Qt{+a1@M^QDey9&N{-d zM7Gcb;H6<-K;`;A9$?}jP6d)y9~7P!&iZ5ETNBT|FOQkz#S%(c)pz;nI@kmxs~%L3 zo4h$;nBfoLW1j_o8Qi2?x0|<+eDIW8&zL7WC8QKW4bn$C7}-_K7hn*i6($UV;|Rh* zFCn712e`p%_ZboR2OFDV_A2c99Rn$kz%L_eZuJVJl(p4^P(FT#$__0H2+tjsjn!}ulD~PK--tx^KuCr2=I|mxiWH3~H z#$(?|{ZlCX;^VLNNcydPG2x2>`d^C}mAWcp_$g&b6pL*Vo`|)3&K|AJk;XaMq?Ed( z$h|{vVKgEr)b?rJ0F2FJAJ%YDCqAq!XgMP2JA->sW)-q_&sVG?6$&kjqr*C>H)u&2 z&p*aWuCPq`rX(Q|9$Axme48uW5hUX4gppg@ZP(tLrRUCvSM^VgSKFji*ShWQYx85< z-_*qr1{ByFjA^-Ri7q!8>)xjC^Q`-O$1iE)1D->KWF{0OaPB-eGtj*-1A=WDXQ3Ru z_P)xGj-JLL-YpPAl6+!x>@~+qo42qHDnZB=r8A}#(w<~Tw#{AA9?I2zWc=#pPXAo- zp(dfgizRjQ&Y|iN2L*SJ=%87R*TedZ%{GfxD&WyjC-RF;X@}^=>o*i~)B2@3rQdD7 zlS_^TWb!0F55kKA-(8W(si5s8DTWrqO5rc~=U6bhgKOi=NVYEg^#zk0@bi6GLd$Y6 zQ)QnNuCe+}`Z@Xyrx*GRPJ#VoE!_(M6xz9>^n)glc=|jxq6hmL@~CaU#P<=3lSIJF z1kL|Pl&(17AI^)t8e1c^^kK?NBa4cV;Sn02PzQjHlpSTT%sX&T8bhE~Sq0MjD{U_!k-wbRC= zY9<%UErm%1Kw#{4W^ucA1O=yIexjUwE<2KBIM5dj?^BZC3!ZQy*b$&Q*=TH<0AOI( zMflqylJ8jpz2`_-b-2JPHA&<}#28TFi5z{RxdVX+iDb5c`FHxj@lN6aVY_-9IKLpP z?6PQ2`bzh6jJ5c%bi4cA_s?Rv0p1(!!6Nq8If>q3{@c8zBkUGm|G=m@oJxVA90@jQ zv(Ha0Iy082ZQ!jwEe!^t@a;=#bTe$zKA5jJ?>6(Sy!9X1NyO#wO08n2hP9;rhz3_7 zJLW^yfOdXHMe#=oI-GPicoci(tP6LtKMhs2yUMyrmyKh{Kp_A zi5O=xwY=stjNCNMEt8qGdLDg0y^>IJz!tr&Xj5jDoO6F6>Bz2^ye z#NIz{A3!A&xX)Tlusk%;i%Ja#)gX9%E^|WU z6a66F5wcEr<^N4C*NU$wC{`ESWVUYGs$%Z?IGqUkRcCxc-ZM4wAN!|J0U>Dc)Pm|u za9ok?h**hfYmSupL6|o+1ohT$i7E3A$#5BMy?Qu|1agaz1A)Q51jk|zMuW!;KIJuQ zaBV@hol-K(4&9jZeF6;j=Vy~dnX@QKVtg=wF%BFX@9fn>*h(~&;`XE`I^q6W;=>4n z4u1%9;bACm8Z@fZn|^JriKnYr66)O%7K$1+_XOLOkcl?q2sO4rA5D^1JxYSO$`-!5 zunfTTak)TvP6pBWM6c^sb#`(fUM7fXx42eqk}0?x@8{C_(o_bA3UHFtm>%8kBqx~| z0UOG{X%%G1m5gwLkif`R(o@AIQxo`!cm{fIJJ{`akQJE@Y3$6v5h%br*?|1eRP&w^ zc*ozJXs7@m+BZuP1-^}j2H>&m7qF((kqAKC?th^Bol|=h67mZWLohat)>}*%ezQEF=9zh8a? z2};YRea=x?jqcmO|2xoF1#H-KIv#)A6C&p;-g5_sHgd;Xh&YxA8cm1k5-9foo= zv0_cxX$SKH7a;b7MZ{$ia9#It`)!(Ovz?-@iv~OWSA+m$@Ul8(hKY;!a=heT?>gU7 z1c#fc9>&<$2dBh|vM;*4jUSAn;NuS5r77Hffqohv_c$fh$1nyUk#Hj{bd56GXW|DJV% zH0sEY+FgT46y}Kkb)VEc&Byu;ZRbvEV&9_BZfyZbfe%-3}TTKnC%0_R4pNobF9vdMzML_lmtMz>3 zn=@bqnj}u>Ap)d`v$Lf1wj7^qK>zg<$@ar?bxWH$q3Bb)L?{ z@8!b)a*zSQfGunvgC$Y@D?p50T!eI|%5t2=z~s_>(BeyZ2b_w~4R|$Z{v&!SSVDjN zY_4$lnbr|1rQNp)zOu>iL2R(>I9+Y~Ry$)Pb^J>;%K~RwOJz+reDjL!T`E)nKtX*d z1#Iwhq(XcFc-xP%Gm{$wjq3vw)im;hCHF+=;$b&=bh^1=b*pkkQ6Y%zp8mPWYq3;W z4d4l$tx2ouZvcrva|g62J6$kD*UU-t8fFBX$2C1|URx#gx-{kZy6eiugM+r$Hm zjKC2L1`wEOvm{vSHWuKYxL(p=Iq?o4M*EPV8ZHRv+r^{N&Ye2@~yFn&4f~g4*}Vh$Rz`O$L&@I((1&WM^L& z0f`bPptUk7PEoszyYMK@cD-ca1c-rEOoFQb0@LTXMj>J20U$ihu7}adPUP@Lnc&Z# z0UP3Lk1UVfjJ4^F8F~H`Kw5b3hNdaR#O!leR=N$~G%+?m+SCnE)=i1w4*^6)nhFK+ zorW2?E8EnpJpzR=Ap5ST`P25q?!CD7j`BO<3)#qv^7BJ zIz%(9M598{Hm7O|tZNxZbE8^X3c=A$r?pD-`s}wPqa#c?ya`va-$$%5s)fN#r&KxQwecev4@yLbiX$`XLRqXl4~S+ixz1BK#5 zJzyT^eTDVT8Ge==wMxy;FGFm;%(s(gWYMec5R+ysC5|x;(oeU{M*XnZaet|#L=$(b zZh8i7OF;PX$(4S#?N1ya^cpQ4;5STWkyAjfkZ+vm6IC$^>HtE=nhp0%lf34XZ;As~ zCO)t2sN1Sb+C-Wc9FD-tEDM`OuG}lE3CAD*cWs3J4E0Aul;66;!=Y2g zk|qGm3byBBU$GBbJB_2t^{(?fGs|{K1pou*t!Euc0QjvpE!)*!*Ad9?BGjTk{FPXg zUJIfRm9QFHZK3d9$1ki(906q2+p`Y@(d&wQqE`_!XkDMwJ=f?rvdkI51T&OylFpNY zFhi+Ywiy$fV9gO&$jy_Py+5JVKFBBDfB^EAg7mo$h((~k0)jIyd^T%pVEDD42{%?F zMG@X|W|d}N@c7_45n%PhI&T8h!`~AFfT|+94kUVJ%n+QyeMOSgEeb5d-9C3}PC)#j zeg|z27YOXzdPU$(G6ZqZF_a>m;>~(*jcd#Tf0aO6@B5p;XJY(m8Q_h&7BZI# zzN){)NkoU#nt{+%^`WjN`8LD@$0EJ(01dVMpj*fG}Kz!a?{D6!%F%8Lh`aahLb?3d7qe)npC+ep4s7nJ;?OW~*GMAg z0U^aR8BZny|B}RyJNz;A3o{|nC7`M>B?JNIvBd%LeF#P|W`1@wE^~KMYugNvT=ytW zh*$<_WJ&iq+RVi=s2JPw*0hFS1wZ&Rcfurfi$N$kUu;t3V6J{!M$UP5DqT_J@sP_^ z-(L?yK0Xu9(Qm|MK*Z7<@c?ujJdzE-Xuq%hkeCp`*fe=p=iZktXwBKL+>fnIA0a&8 z9%%lSVf#!<(4Pw^#s==xqpjkVU>C1w665W`07=mQ|bn;-aUs)!N*t)I_= zNf74jJ?V?blJ<%w-9o-4)Z&X3J$+MN6cy{A1*}X;XxS^h2E zId(ao3lY87b>F8kj0IHMgZ@`*8zh|&hg{chQ7QZAsMY(XUm0uJro4##r-CLY%$^WZgM5^@{aggiy%4(63n6k3EYdJ4>KI#YSMMLHx$l2sZ%vr2i7Q zC#9YQGXy4SdJ7;6=aEti#y5Z+F7Z|}WCV~evm!Oq_wSm>F!(6cN&J4h!;c`c&FVvq zi6Df)n;;tm2EC6+{4w=8Lq>@Z`VzkYeJaAP|!M z$gCG?{=9s3hoO}`o$}%|Ehkf}=epSS1ql*wW3i8CU=l*b7l`)m8|pn!#G>ASsMqhK ze?>kTP30?e8jV%^loO_rDxtzW!oy0yl4Fyq{*_?K;~uzxUWf}(`xzg(`c1LB(|O1; z`m0?Qbl7(uewj5E1>+*UmsX@a1}&DAzJn&*p^0GX*oV&UU|DYZ1x~l>9A+&V;Xv7l z%9CgMUiJ~R5N7lkmx7I8Uca}*** zOWe2DrvK6ocun+;^v!n6zuUwz1J+*PNp10L-O>)&qIrl2sJCml7?b7)a(^t(tN329 zDCArx1eXya>QCF>^dy)?OY?n#wM(ETT>wrW6(z(8@jRcJW|&h=MX}1EOlU{}ilvSJ z5ibxMZguw|Hn3YH5-vp!y$~OfIl*7SxI3Pnk@6!LiA6(6QCd8im_iKe-Kk*02dXNv zNN()reCiFHoG4%9kyusuDz2h1>JskLCZpN`HC>M#!*!>JM4C?RHM?{wT#7QQ`)FU} zTrwF5p(mt>De^mW&rhs#XzYSZF+T`=V$Ev4vCvpU6N??N$5Z4$Q>0QFeoVA4 zf-0vjgRl)DzMcZ#i$t)TWY%&RjmDhfqG&`+{-k66c&n~GV)DG{3(YP&Tu?;4R~O^6 zk|dXmx#OAW0LenL;G5EsuD~x9nTT@&mu4yfy_6;uuIQXK>y=2D6ibEr39KxHd?`oF zgc~*GR*-01p~g#+=_|H0#nZ5gh|hM+-}|j3v$8TjSN{RlqDP1(m_2oH-;DOKtlRBc z0K_h=gG|RU{2?NU+yZ|Er-Q#EttjS7TaqH}`Qod=)Vp#pb|p!7%_l?$S_{tO<~l)$ zZpEIU5Y8GWp5PMrD?(@luO+_jEah>OW`F}J5qwj>%_>9G?Q;NxN$cJ zz_xEEsfQ_qA4B+8xT4j&f9!v^;UEeAkSr){s;2wrf3AO`417;h+m1@HaX)%R4Sf(i z#1zybw|~voaTM8^6Gf=XtlCHB$@{1?1Q*j+vf#2=<}!D+!Tc!WPXCxOr$wnb#kH}7 z#f!s-zYCco!4Uv^Hn!uW-LlcFJuT&Em+oq@W~Z(Dh`d$RmyIxj?w0K&c^bio&)3rm zKNPgze%oGymghIkXIaaN=fWd9WPe z8{p4N9@R1A?&vw7o>yIiqda@QaF^JBzND1c4t;JS1)Q&7HKnUsGRg-oDMCRLbd6~ph>bd_bsF| zlDv79ZKRS}DjnW}9lDXTQH%>$!SJgXX|7{==e2yaTZTDK_EFRRaV3lp-6X z?ASdxui&2uH`B7+1s0SqIYl<)vQbY`<*Yl2>Lp&kqmyOZP-DT!7-SrJo@OO&Cz`)W z1UN9d1x9oE*Uw7*$K{Da*t0!pcweq(Iv{#m7CcZ%+KFXYBN(v1O-Yt`6)wP9g^F65 zPolREbl`k|dRsb6Q})3#j|dAT?SV(FC0DS&-(uZs>gUBWP+*_}gYf@uzM)~62J1&S zBN;Q11@1Qz}zbb-JNmxhlNqqhDSkcs8sY=1=MvuRqE7mSF<(z^#KiG_vfuI67mNzBB>9Grf? z(J!Ad=lJ2eOmA#&Q(FkWX5VV{o})+Sqs&UeVr{R2=k=8MOTSnXz2fdoYRNX?-H#8LLYqut7@f(B>EIUT(=hBx(30S89r3XH zVESl@_;2!|CWs;I6ZL~P)&#gE9A#5ytbX=>FXs=g(u^^ArA%u~$Vs-6*d4g__GP;s z{R;iCgOU`2J(tXCMkctia}6=}6>gvVQqjp?T1*F^ELmq zP)r74Ny^b4xeb}cSMYQlYAg=M#s}gsfCa2wEle(3*l>p?7O_~hpV7oAoF0HEkin>Gddb3M9 z|1M0!bB4*d4xd+;LgDG&f0RdN$4n;BhN*Eh*c|U&+l<9>C2L&5hZ@0v>c#7!O&SXh zua97Y>zRY5c-o9&yj3gsxSfdf~EaPzyS zVruUT{UMRAkx;K(gML>L;>agTGGL!t#CMrX)=NE1h@tm3jL?bA(tbt9Dd@0PZ-W&(|g*hVJx^Q1T~E3d{abu5oM?6!p^y(*`sZeu?(X1XDC+VnKb3;%@#|Kn$N=#KoE0x7-a>Qd@1U18A{0wX`JCHNeix?RhPho^wie+hks}VUDxaMqN1$CyJ z7cr_IDPSWK?^$@^nw)EGFdkDi#=*{*`gVDT?$zYPIh`y#HLg4obVT&kn};K}+YWRK z>W8=E>YA>)+&I6N!|;PZI{U$#q!ldaTBK!tvXXkMshM`PGiIa7 zM82RU`=X+QMW+$|f8_#CLw`Om^jo5m`Y$i(*{Zv^7$H=r^qEzND(rsNmSFHe)eMGs zIrw0Soeax64M>X&hYSTH-^0F8`p~uRh2rC2wf^?$3JE^S7?$84^=X0M^kDN)H8|#$mUfj%|cBNIVC{4IOr^N82U%+z}6lD_e z<5LpDUH0sbo>fUm)EmJ3#OEZteRV#t?{KRBdfA&(xf3eymloEM@#*Q=E(m5g3nuo0 z9E!`O%Ez%}J|xpk`DeJgrUteVy$_#{q>8yZI9E`qUng!&Z|N+0IU3{o4P08M#fssI z)sNo)&Dp4R4aZG}h2amcQ0G_aQRU%LJ&Eo9o!leNL&+!5SbFRZsfjdK$xN8PAR8%t zwyzkNr~;b=Mgwt2=WykV)=Pck7ZCB^BV_(@!H!+!#D*B_hX8^r$0bM`*cY_RFS$N4 zKUnr%YGCfP+mfy|xYfL&&8r)}>|!}Q(sX*gI{O6|ec8l&BycZka^9NGmoJGMnm6m^ z)tYvC_-G~lwUZYo?w8+}@cSnzmsB|Rc@}5;&wMK~xStBTzfi6}8|Z|zLQkB7uvMw? ziW9QkR&SD+=%|2?fLn^hl@qL=0v47^l;qNFeDqM5U$COcg<%EkGd|HH1Mo z2mY0p$J#|14XK9on|zsj^x8Y|F7v>nU2O^1^s5|SToW2gfJzh|k8n7*C?e-yMXAJz z)Y(#`87$erfSVnSjus|;fq>YLNozr5b7JBvj3^ zVs9*4_Sns}h1qO6BA-u&&wsW$nB4uEx0+9k01Qtv`Ja`S_BN->_bw|=FDo_&i=1yt zsVV!=20zaW9VR5 z8&<&1Xvp=a;P_C$btROInYTzz|J_PkTA{Lmg%a&3t$r}IYx7ZA;QyX}$Bp#9x4k)0 z={F!^^sHLkOZ>6gdW@FWZuliv&hcf{ii;=BShw)bsYw3EEjFoAQ|?FzuBhT4m|r5{ zaHzed@IjPP&`=uiBh|ThB1|#68q=_2-(F-nUza^f37%~yZ8U#6Vyqn6iq?9=4L?1t zk+`k-yfWiI2PC88ID<9`+t|p+4tg>rpXN$H0p3 z&I=rG`v!)iOM|!u-}N|abY?`R@H305+k^7lO75)xbgti7>P;jS)MGQG66E5NY?*TT zI5d8|JoL3ONg$*8J(WY{;VWvkgXgQ)mF;|VUUuYgVAQT5B7=SLb>nL4Db2nZ{=;Tl}Ew^N}kXr7Q-mm3M+PitEp1Qmv&bFbvWd7}}EAb)33 z|9d178Ywgqu`j21luuI8jxk;yp%Gs!{+7T~#Im<6S;iDQ6oxu3XZ!5TCdH<$dfg#W17>e_uRh|*os4U6vX?vm~<>246DyE~*sO1is28tITOsYUmh z_m9yDK;xW5(jL63?BHviHGq#yX}9lNLVnY5ZLOgyu?UG^d>qEF z2aga4I97{knga>B_M6pZ#V&!DOWz8^O1P$C%@17{y8E@lIT;q)HPXA2iRS)FMYp{sdx}985jGKt zwadj*@Ldr1bce93=TRyS_*Wsflj)#DjgGfuj^9fRJYr*)xZV%+|* zvM=fFky2B!dVf?#+N@h!z~-k7HP@@X+gbD(Ll80LPbTB*;LS6unoKem)Es#YfB!E} zWpOY+YB~KWM;ReED3kBLzayj?eIRx0`0>N#Zz25KH<%=D=I;#TeO6!OqToy|@kw4O z_X)I%pgM_Y+@e$`9=jDsvb&XjYVkFX3tR4;!mUErvJ{s4dFCwebeoonq6<)IRlHs) zNX7U6qik1@LY>oP>Rc>}bVyGo@l0CPy4QF#r{?vit)L1$rKArzdSI_~R~O1L)uUj2 z8GKIlWvBS4DxoCTSGePOSBI!X;iCSZE`opa0bQLiLP+;|`zA3AStaGFX5x~>JcHM1 zM~CnIcO=nw^d%KU43Qq3b7mdp^7ZD+j|CfD?M~X~zLQlw^Q~HVUGJ6+50%3633FS` ziCCa(i$$$H?c{%v`kh=dvC2kNdW$heQ=y18!r5h-LltwV8j+qw&FM7B2{Ow! z>4k56uCWbb_HL}UroYiw9ID^oNh&{&5#lq{Vl$jWofNb-I(hQCzodBugoghIfgt3E z>OitHs?HW8lT}0o(E}9TbQXcC-J?Ov826=?JncN1`%z1>vqdS*=_S!`&YKUr#_c~$ zcKsgysL_=o3*L*}ciwdPJRVp$%{625OgqQp|L~uBkEa^>u5l%O{I{r%_yJF^2`5udB^@g5s)(jC}Pg)j40mc?XW@ZU+PJ{S*{iy z?U`iw1UCoL;vY>_DBGX!l#hn)bU3au$*PUeAgS+m`nYR)(FI4l*3G5can;(EA78S( zdHcwF;+^Ci=W@bgUvQE}2k~9^Ch(Z_)muHku|2ITEuK{8?$o2sqz-Uk65Xhdc2mm3 zU{#un|tpLX86#G~mMLQR$-HxNVRC`^YDTT35G8TJ0 zFXszd;M*G&-(5aw9yN8%sn)*OoCYBUAL}SGRlH$O9gcJAsu>5f=E?_Lr_tZ*{PFjH z)@%!XdvU=5ve3#$@td8NkUNyy@s1sHuWGK75x@lYx{L3r-`@IM7kpQ<-P$6YX&L27=OqgLD zR`bHJseRX{$_X0b?|X^(fQe(z#7E%nr!&~R)BR&CoBf)cUE8(HqSfH>PDSHG$#^J{ zc8lR+XX~m{yjHD+^h5npaB9((1RmTrgUDh=6Jn0szhCX23nmlV)yd3JUEXJ=ZxRy` zMW(Y1QfGH&ZB|(((h@aW40vlWS@4f&4~XVM6!MTt{m853v(maA?+KbM>P~ z&--y(-)ctuZIjk}TKMgKbnk}iy(Tx~PUdN&QniEpBJ~o@7*c#sg;CM_Awk&+0TP*B z@X3bm{yKkQ`=vv*czo$N*u~vF=3bA*p{;!WTZrL-*ZJI-?w{%WIF;@A%4Y%82aErt zoH(IIvObuhlZ8zIu9T#v$$L7h9h!&Z+7b=@b-%rK<5-0>Cgoy_S>3EmviyuIy;KD(7yXs$oQA> z>#A1sguJ7z;{-2X-`==KoPQ)LE#fW^t2!!It>)8fIs1KHq!W0O@B9+ZIC19yvsSyVAE-fG&-{o5O*YV$Qx_$TX&U_kW2UzFZScXxbaNM z-X)t$?Ov#2a*JJJky@EXay2W~ZIr(QvvjUw>!fpbAm9D5sl_j88)bSa=^~*Z0s_UME$YRPERqahFe+6u5z1$%6QNdQ{ZKTj!kq_DFB>tRnNa8BA)bHqLc!R|37FTW zGux(Pky79B$$Z}({F^NH;i!*dwPATqfbt-q{U%wtz@Pr3-4}$;yKCNqj$@AJ(-ypE zs&&K%lBQ2YK>h9&>igHQ6*8uy2LFd`$zXQ zKzr?)c%mt~Ec`Gk{Yfk_5756!W)x+cf-TYUBE~KNACL-|PP~ssUcsuzy9x)7r(f)Pez7@g%AZkV7 z8C~tCdp45V+D>#g@H>Zgx|6z6n%^CP`cb0`pjvdMpc(g*<~v2XD3 zyQ7z?xsZ}y#&i%=sB^z+@D&@%%_uy3@v-| z8->)8b@mkdsvD-PThIYedr98ha|Hl<)BGym1GKCZ0G)N^@3V_P-vqq@JzDF?ERrhO zRq^wmiVb`K0BPv1`CQ27u0-LmZUes|ao7yM*kpSs9y}?Etd*Npm8uzXFe$L+bwr=r z%en4D24F!hIJ@dKg(c1MC;)+S%cAp$&t@6d_H@0h1%K0rt~i7&sJU`lE|k25n1kZ_ z^Ba}q)0A(+>CWwYy0VBEp>J=K%(S*H;lt|T8JfC6Wsd-Zl)_@FMzb@GD$WXiOt)E_ zPk18V{?{+twG#rg=NH$8izH0WyK+^H^4UDUEWiML_)5xQ;&oK96?Ogo6U91ymIcqF z*#X55r{~-aiG8z7Zzpi^lQm~>SmSbAsszZDMOJ3 zZiSR;;=|FY?$7Jk4wCz8LBLWH*(7q0H5b5&H0+vpQdAQ_Lv>b37MM%`A(*)h{K{Ds zw{jR56xErRX8+QOEZVbE%#Bq|oDl+u0S`p+;`C6S&pEWi%nZj&*<4SMJ@1Y4?AJTM zw_Di>FUTh-ycdo#}2GBPE!g7y|cUFK& zYwbHCY=rUoIPYoUG~Y?nmMO3vO$6Ym;_=1MM`DyvcfXGeE2<}L7vsh$SenvV4n44b zA_leQ^2k5GmsQeKbw0PuRvC0U1bh!;cc04>uNFVnL;V-BDFNr|TJ1ibyCY=t{54S$4 zsG9)8fJJ~dY{NPPkhdG3p8$773;gtm_mWLZGzwO{C+roqY``SnUY7GV0EeVrjPp+D zEPRhAaODR^?G7-7k^mJ4wHgA#sk(vh)vP{;gCYRecHHO((wRFuB=(4Y)eTn;#_mZJ zberw-)yHE@!S6$-ryWHdTaWoWvsF2u*f^ZE=HY3-_#{-B>FLXM{y;S(;RsK9w-`rm z(7M+N!$pQ=HB*=qg_|sRbn~)X^O$3G^nAO6W$0cIjm zG#Myg`>?Ki7%il@WeA+yMaGy)vnvy#Rh{0Ms@dPW?Cl#n!<> zbwQ)?jJJczVDc6)lT$VHJ;lS27mMZb76BBp$YLU=TIqnbsrl%T?nK!~62cJTJK*LO zAgYW77^~LF-whW4U_IovY)i%Obr}cDb$ul}B(C3Y)&;i?+g_nQKF8Dt;EbkyRAA%_ zoVv&Mml|;akW)#H*Y|IDaIOPmFG(s2=YxRzLl%&!?f}+6IiRy@nvD5J7fj;^%xR%> z6E%&aQ5h!M>Dg+4W7ThlO_ssnD%W?cz5`yZjZ|!LPT$*>=u6nGq$VZ}bI8$hH0K&f zQ%UK$@Dw7IgsH1NPR&yN)-&auP_oPE7t9A24-@t{@?&N@)^~^94*+l3Z10?5f4Knk zh*r(60mO7aL$(iiSih9-sJu2J8(MUY(=M^^vDohwGyDUL<OBW#Fje zWxLi24XNrORft^R*`R9q7L<3eRJ%5TO8Xg_$Y+vv1#}Tg;FfmQDpF0!ffd2ni3!yn z*rWwasSI7GVTv{Sh<6&gGYY)NY~2;;dA8?vma=j@9vXe;`4v>QRV2IH(1e;xD5{Fm+#nAEA8HE%^+4x6-wb;Z$U!hgE} zrfU%Kxh8LtFT*!C z*$PpP_K0eP>Ckf`Mx>G94*_dk-ttr%9&vUE68_D=5PJO3+f;Wxfal$ASy4YnlVVfs zmR&JsZhc|e_aWkIt)62)W~uwI`}M8RJPWlylx4wV3$3hUh= za{C1P-vO&nDl(2(tASavS{p+|2N9-U=OcsKZFJl`K$rhs=5t1O;lK3bvt($${8%+{ z^b}-D%7*HTDAFn(YjbcNDx5|{To^f-i%N;QdITWxST1sxewW<41WC!@g5FYxoONQ? zLi|UGTYhCu;}D5=@H)G?LGlp^`Cg|S%Qjnr3Ge$r_tdvjp)7;>FMWyoX(ln!va_GG z-O5*B$~BwIEb3YR;^{u9X>3*rL>@SW;W|U^7!cVjtdpz|UrhV@{{T;%D|9vtnCSC5 z%PG<-{OTT9BWWHG?kjAW>(l>BDt9AHE{&->(HSJCq34>c3$&&Qm?MdyM6mA|)^xEa zA;MGu3yWn%LI-AZ$OZsu^ym+sc+BfN!!P^}mly!Rk~1aYfnP|)hmwE>FRuEH9Dy%A z?+zsR$TpwE!nx%W$qw>iLIPRd=7i1N0G$=7z{+PLF|g@|^}uLG0CN+R2gBl7;DZ7W z$^eN2FkNi!BydbI2nmOC3K#exSn*=$nvggo-RC?eohcA6Eum4S_@+C;gQqRAP<|f= z+=mIHA)CZcsg66NGx}9BX%f)#Ofr2B)gv2DDizIqvTCZqJCR*K{ajN@9{iXE&!v@)hUwk zC90$kD~?3kWOdxvOjspCzqc?u>X69|3f!*Dfj6SO;t6&0pxwe~Qe@_yp!q^m7|@+$ z=9f2hoiE03I4(^L)rJyE?Ui(I^;ieMycQc_!Gibr*rh@@$~L*xDB)s;>D|)=RYy)lDbvi->iugb@ww1#H*JLA z-LnW`iD)YkV&&xnk72nT$_hCXcQ(e3+IYsuSi@ni{!N_7EIKz*?NFO7Zj<+TjY3L! zRlhT2y@e+x-8Rq>p2Y{hG%0EGFpq2fp6@KGcrPCEfZgQVfC)Yb0$5?H2=rYXy5GbooBNjg z8~c2rt^LMJlotqLvMz>xvT=7XzUW>IB19whk?){RG=yI^xUpm=*VB(c(%&5=rZx_o z?c1-^*PpdOO2X?!$P%f+eMRMTxaXN&pUD+87f55{bfecwE*Q(LQ2Wu~RSqFi9?fU8 zsw8G=Pm{3&z9%<+QfK|U5*i_bC|4Hg#zlcdl4W<@_{~FGhmr_`jlux4xarTu#3#IxO-GRvBA>Bk2WU6dwn$_N%+n94u+wfW;q_Sst~3Me=E~CrH4^+$3ch=wPJ|7kKw;jo zE_QuP3TMWOfuS92ieCjD*ZL$-igZE5Z2o{L>r_7|5JRTnrpvV)WZ!z+fbo77HsK2B zMmd}7NMD22EbQgAT8f(kl@$iNIIFkj)!S+kEkWEA$kmF({P?6mFio90EB?+}2g8X{ zS?=U28%+bQ2Q^QiO=sy179FTK?hNJ0NV|^rEEXNcN4K!4a)c8LUCzPN{?Xhc*YKxl zDhmH=n~X-w)~5LsgETrxigp86bNUkPDJ%BRtwW2w2(qtYxz}WuDm;1Aeij>k@Zlx` zwC2GfQVAWx)dBlcu>2iH+Zn%oOVzfCK&k@;NnZK&tN z+{NXnV_-doKTHnU)H#>RlLzG=`vPD0hB{9Hny8ycBYxOCH2T=J+}9zjz~W{t;MK<( z;3yp2A~GOE9%5qDaGte?Gune_HMu%TLM-R{bJmB85(jzKn!@Gg7-$lj*CGy(0_yqF z)8?#3cqw?0kvE~qEdB>;X17tk47^bJ=iIL$TF!HT}VOGaZ;FkeB2f!^K3s*?L=%G&K0d>Rdk>YIfTQ~bqj2r}hl3}X zujd5s;Ek@D*!nD`P)x2OHpBX%dY~YM^ZMTD23yqG@V#x0h(ums3Wq!DVO?B%J3^-} z0t%z)lMvBdwP49S_T6`$GD)cOgqGU{RGQJ21U)Xwh9se|!d)lXnhPR^Xl*$SAE-2M zML_%SBWAHTw0x^JT7To33Pf-u@=JZBoZ7~V5WvfsnfTN%jkiHi`rA%IJ1LwavYyfw z2NM4yFF|wJ1QmaXS!Bb!F0*2WMc%q3kvQHq4E3iz%X2IUh7E)BvfvAPtMxaepD6k) zewZ)^`{5Y<>4}J_PJV_Pb#ePV=QzEd^qVNfokn_OKn$OA0q`lx&R6RBT4K}D;lw&6 z%UzLGko&qJvCp%f49k#9lp zz!a+OpU8Umi69}P-?xz4Qb}iy1=-g9xo+Pi{v7jb3^m0u5J|cd_0Uq&EI%`7@5k9s zHbEhxVgecnIA+-MFcR^mAD@F+drpHLh%}YZ%}MHzB&$RxlV?R#w;~geFCr$rRIBbn zR|LVo3B@jyCK&vupHx=)W9l^EPi(5UtBEa8bNbPsvb5;7JVkho=(8Eyrz{L#QgmJ| z33dkAm@B}M2n{Y|Tt-}c9B_0|YNxw6@;$p=?9Y8yHsfc zbnz8^5!z{&35f~o=AMgLDiuBA=vwInFNqnL8MOo)3MM)-851e5jfO8m4Z?;N5o80t z87V2q<>`|W$;#?YSGo;1!Yz&oY{zkLVr8kkVy?q8(Sk@%LSZ)EZw7_4r!;AL=hvwe z17{wrCv(PoJ?;>wvD+UNeEs8AH<0oSBg6rvWnsmMz8u}CNKZ?gz=!RRsWl)KGkNry zH&Z5N6&6;9YWoZ1$9S7eNdBX8DL4hN{E(#so8<7im-a2U1y4S@+Kzh(Nr*KNoa*2K zQh0mB0aIN$Szck}BaP_}-b#HlUk18H<22hpNTYqcTjqFY(x9a?E5<%8c_CE)a&{}%gz4+Y{)HwXEjd18 zKDh|1QyBP*>gmI|!whT)o)M8Kf;agI&ZPjI3T&oWW>jtQph@Vt6gHv={FKXF!FK5R z8?){UnC`L|j}n=r`@|CisUL^j{NMG5?fJ72aM^|i#rnyRh1chA^HIh$C#UTVT|OoR zm%7|7-R+d?Nv z>cihAH-)OiV?hF%5XSP@#o^$w_v|(wKSvUrSD>u)fxIhwXc(@5FifhWav}7pgf>~4 zrj2UUH%2h3Aa{nILb$wVBe@19L^|29&Ioue8C>;5l#mTmnq_ape!?BN$Xu6{jP$k8 zO{^4IK`LoHvxG5jpe>}&*j8pHj5psW5V<;&xW8J{+)Plx0RjrynAz%ycm`;SnrvD& znJ}{YJQjHNb3H(y4GuVSoF z@w(W3$sd_K;Xi3gj_i82^^)UV5pSyXlJvldrGC_M(@$$I?8=$g&%&U^0p}C7z>m2m-59B>aY578 z_=!=_bSHVV8xRo9rGcq%69veWw!G;}<;9st%=7L^*7t7y=1>WJ*lN@9NwWzod?nka z9~x+XCciVqGG4Hhdgtx}r6-WB{CTZ+)1#%Do1CdY%+5ppq6j}MC0868Ms_K0x7z}X zQzTnCcMm2$oFP&i1pn~KF#m=LS(wVyuP0xihYztE2I?u{9reA}CMJD*Gu5-NJKzgH@66v`ktV+K=6kHb5FyQQRS1|G2 zNdaHef)ccp1USIq9W;d=d%JE7h{gs5YFO?bKb>utv}x?eru<@9y$m4WGlm>7hXr|q zM4Qw%6{MNGFnElOLK2SoznTW3ALNI{Be!~^QAtzGJWP6To+%`7oJh;9g!RHcx19?3 z-ak_LeAz9K)D7>#c&BD^c2IvN^~k@3W(r{&98Lgn>Wm7bw#3(o2>CFhZmD7OK1IPJ zB-v+3ryTAZwpo92N9=)=pW5T1T5<#Ofi_y+DnJ-E3paCFycRpn zB83tdqT$R6Sj*Zs$7VJK7c_y4D82B3DoSL zfu@Qt^aUJa3JHQYN#w^iChodxaU4N8Mp2&^3Kc11+*E6#_g0X{`~FbcpnBm>e4WAf z_#H5{{dhxe!laMeXKt2dPFFBylpTd61tKDsULKw^_Z8uOCd)$IV%}oedEH~y^kWCV zLBOusI@!aIgge-Uk;w|NJHS1OT*%eb06(W&PmZe+Q(BeS;0{n$@2Be`V-rkP%xHy$ z%(Kbg^SbC`<)TErnam}of%O;mCeLAP(be@)mWS4hszJqy@JoJJj6x@a_S49kALH_T z9~D-z-sEVK3-yF?xDYQS8d+pCmbb-2g4#_pX?i7tA5P}q(6*$TT_4a2AUmv+;j&6B8)%Wp5!P3I){dYy}68lKXVFns(%q@Lpc&B@}RzAxk$ETVTTUEEUkg zYQHT>$1f$8gRJ+f84K<>q=hM5bdj9E%}}D}vReS7y?Bo}7cl$CEEo9LsE3H)wrk{e zyTV5ra5RwWQ;R(GeEj_GZMknXjFL#eIvyN*5Dl}c6}(Y1u|zk_(Z^?ERaX-vdeMYy zIQ_Z@6lXt++2L2ezzAW0oUdqF>vQFmE|&n)I1`ePHpyjhRQeK8iVOaTI!72RR>tgM zPIc-t*^Du%FW%gFRPSZxYo9WsbMZaJL8~;m-jcxE8^%7l2@3vVSzeW9Y2KLyf>h4) zGDmpx#}J#4Gs^=GkAQ6$ie-=S_PV#z#=7DkoHY^T<~ylyzEqokaS$m{&PL!5kWZcc z6w_8ypKW8C!d7E6%AfZYUHH8Tw|u&$0~IIv8 zeG@QjAJhy#F{Ai#B5vr{-j!6AxnIfU)_w^L56uO&i;&By(x!unpKyA5uTYQiY+$g5 zr50YXQ7$bbByF8eNv~jXqZhDUBX)eFkrxwuQu~@)~%*qOP(y1j0df0$0TZu!l1R$n7FGgxFP4{=|bl> zp-Y$UeXi~&Ny5hy5Ok#Ar8{sIte8)pHgWc#Vm&E_+`l5`KYYq+H;&=#9j>rrT@JJy zTq|iq{WNByXLIX*ExiRKki`Y@iByNtoH}wBXO{P`;<+=ROQ)LtR?P4Rv!(JfwYv5$rP|i(rXsLb%dDNNhCiezlnoRq@l9}r081=;X*M~R`b%+G8%(&6Xuy> z=3X3Li2Z`uV4`-;Rd>1!Ez@qV+XWbI!Sak?D zu6*b)LJk)9cHjeS?g={kYbGy*sb@F-B<3KQvxTJ_HX zQ%K!rJ34Lrzu_Jwa~PC$IlVgvDn@!?P4jmZU9h4-XpJc!0_e5tP&n{K!yGfLSabr) zOvV2m%>Aow`BfLS>q{64df%ajFI@ZOYjd>G;7C1Fik2{$Vddq!r~3-9_TaCliMrDUgRur?v@hbRI_iR(=Z6s073Bmcog~=;RsmE4!cHeh(oaB1ouX<$pImGRF>4{3+&Mc7Bz{J+9r;v2EKWr-E467Ug0004-#O%?KwUJFtiUt=w z^FOuN02$yFD6Ki>)bk~b)c(cU4ADXY5b}jKNLEgr4dFk5lK8Q#QlFnJpW;=c^3=V8sDu$A-wtLFZutx z@Yl1~5C3ef`Pahh1o;2_6wqq#@%l&HQX0PbuXpl)7r_7PAAz@rS`d6QUNP{${`bHC zQK*|tss1-A)0_YG6~QrGME;K?Ku}5i;jgmM%YzxSX!f}wZ$eCxZjn+8@vfzje@+xS zP`~lGT~6F7%uKUF0ei+dn^nJN`c}*~V=@PzH}17|@>;9GZ2cNPt$ZTSu_)%YXqGyZ zylDXRfRLs0d%K+{#@lDwHlzbgk0nnrxvN!cFjI5@Yb$9(}rL9hC2h%>7 zRx18G#(Nj%J4?t^LuZ}4!zSL1$%1>2^cwz5!sBZ->E+5L+5!o&@&#>RSk@Pl>viyy zeeL$ed2OM7^!J*6+lg-2u+W~T$7y%h%PTi+pG{?S0%??0m zOd2p?nq|Aroo~GWVK-Zew2bW_X@R>g5E@i`b4IkdI+DT_|08Z^T_aLQ^IMgnWG51B%gD z>0FNaKEO3Db-ufIxF|vAzf&vIPF76-kiqNR*uz;(!i9F%LmvSFA0E2~x%7ud#ZQw} ztUK4;ow5%h?Av|v>Z6iimYY)w@b%C^jc+DT&8Mq;o@8->1Gt9?K~hdX7Ul6H!MXKm zkK|<2-N1ep|0y&prP}XpeoEepEAfSQ7*Y$01LFzpa}~L%rrp+wyW+?8+evrenQc!` z>3Ot&N`B=ihEb0|Z<9>+1+3;jfq@iT)GkS_Al2p)N1P)$kI#~8Ed4txg*(GHwH%Zz2P`^sMgh_-m`qRPmQ{4;C5 zMxiii+_ON=CAQZ~soLdmR+^#htmj2@=ozRH zls1Im300Ou;H$lf+L+BtQMyB;&MT!5={oA~QzJOyb>iReR;>L~ zYIcIso~>YTzqFxN^yAdJk51D!@7s@{4Rdj0crc^iNk-nLD%^L}Q&059r^c0eMF$m2 z?8wQAe~!{p?p8A@Zn>oBk4&q)^rfK z+fD>LxK%^@Qw2ppT$V`7YO6bA3d6bJY1@Uu-JjZtLLl2~?OoLZqUWQC+{ZH<0iUMW z_6S$2qq&!s)-CXBOc1PV-*I$J4xs+%FE>cQu;?$68Ke32oXsZ4bII83(&d4}YZ6f2 z@rk{;aQV>5W^bT$dug3R6>059ybqA*ir{jxz_;xEB?JgTu^t$h!{4G);cR)}#qsEC znXa}%73T4MCgr}1W(E(0S+STr8*42$FB&u)A2MXWX8}@^4p<%9+AgJI1KGMs38{ z9u2j()~8U`tAi)37wwLwKHA;6B=|f$=$^v)A2HDD5p2<0+TU8{GeTcQqn}NBIr-L< z^}<%gx>dfgww3Xxw7Q=z$#7`34@L9q;BYLw*{Yb1-^7 znPa;RbF=!o$4TLb1e{fcM0lNdyLk3@q06^Gv7YhY!lVx-0D$2t_}=+ch8FWGT=3~K z@ij$-#jxuQ(P8k1rKr5u+!TPB5p^h~#6X%$j#|{QtxwMKIxH2CD4ydPPLs)btwj@U zO-J9w87J)kmZU^jbjqRPOuNI;ygRX2iyY75n*lC>c6y{3kUW&9Qyz)RavGto0g{G> zUbRR`5E}Qk4T}=5P(eC}Z3b|6qY_uh=lu2+?^P-mxa2sV4{+s+3%#>(sGv^&DI z1(ue8%p{a$!eWK&LstbqvO);LB$HA4#@SCY4K0Osb;#kUpD}Fz<#XzrScnGDEWO(I z;0r`(tjvOBK6Y;>Pa(h$w6j64h4U&)Zx;G2jl!@U7Xt)SrU0-O78#hBfU#wtbP*7_ zwWF;ADlS3PC7|Z+^W@;&x}6}~CgKkS)IEd~!14AGPlyG>B0sgS z3Y#Ow+lQJBlM;tw<6Ws@P`U0X@3|35?X+TDKtSE7Ilhoz+G(*_-nlb2kfN|HT9B+?}7F?9*ZIu;-q`)Moy`4mJ8~FGN26 zZ4S`^=a=tW9KpEEo*j?&dssObz7z5OaXu^Vvp`_6o1`(4TP8vF`JBBI5Mjc1&}dhX z!7`eRnxJ+Oz!%IF%;cMQqb(x$i*=RNdR;(uAiKW0aeuZ(czUf?hgNGCXbowO&PVb* z$6oY3_NrFT%>}xEbn3s+8@0{-=-99@&PyP2+N-25>RA4I;3ZjZ=e5psw_@~;JEH=j zPsw*G`6aLF1sxAQFTgwBfvn&q+sXfQLzPMZaPsSdHdm2Cf(xlNnKVSS3nKP z-zo{E-TLCUIKM4EIr|XOD zqLu(E92M$yU;<}4{@mj+;UFhx9twXM4m9L3aweBjr;xbg1M&fZyT78(0xkziAe*Sa z5a_KJq$3;2>EzpQjJc?~ouyt2w1X? z9Vwo;SXl0TZrkg;P+M0o)}{YU}yT}`#dcT=#p>g;A=VP2)@=62${ ziz9ZdJK+!0P-vDw7vu$Q0`L_4L~WL8iv;V`qg)H|D4(VrPpqwb^I>M~Cx+(jgsAzq zFAcYx{a2%R{(xk$EvyAt4n6GE>kcNwM9!H}eFlw0Vu(%s;#{5H;2QDvpSy@EUoYA_ zKera;bCw_rLZVxoNNSifgG7@!0xznpiVHz~!h~p}yEAmD=?S%%BLPoY^`eNL|Ljr; zI^{cig+1&5lKF~&dfKLLO5&LWa|-1&Rt}Ms70_XI@1rDOO(4&0@rz0_VhE=fxdHyh zlNINQt88jQn}e)LX_0dF3EVcKGpTQIy`#ZS%ohuW)8W8wvRU}c`(|Lmw*dAkj{d}$ zKLGKy$BPWyVRe>hHV~Wln_m>PyTybTtm3ICMb_8jIXBNIVqJN~^Y^#BHNxyY98Nr5 z=HoRsZ%!7jmhPeDuelw+G@R57$)cLD5K|KIY#vOVG+T-k+VW_4?A}IOJwKkV=B~!7 zm^U-V=>Mu%X~|cSCY+b-okm5fo=4K>uHU;K<+#!hpGU+y4OTYy%^g*-Gi}db_~wyh z?EkFJoSyW8`ow*|$h=m2ku9omzLsAuN#4J8l`oYgmc%Y<)0c^%Q>$k(f8bBl>Mf9- z=2inb>{tXxE>~)$YKRX;4DLxvy1AFtm!72@uNF1yJO*x5+V>sxlC_jvPpF5ErP}YV z;XafI5_Sw8ms-}8*vYE*IrzSmbgr-(D1v($!oT7#D=N3A(|uoWv0X8ae!fD9*-M^q z?P_MY>eD;F-*1Eo6EcFbJVFWoiIRDSCax>S)N84N@)LmyLHJctF(y561uV6yy5ae{CI2jH@g*T)c#GQETe8MFj?%zd98BNm7b%>x;Z zsR9{}G^Yh#_ca{^jV86LMnDm(ht^p0aWTjR#^^dB1^Zi+YPTq=;$+h~Lib=4Dot2H z-=FP%2Z5Am<>@`r@hY6bnBUR2k#Uw2I1L2nu|CZDgsg2utVV2j&^hZUaj*0ZBgYGH zvxtGEk+;0Yp?DMpa@K<=xD_OzjDWRbtqEiq&{5VZ&$&8VRV&zBsh7j)*|3?85>K$T z7~ve9%03ZbzQ_f@c2pgN9+}1)Fh%5p2?ttpBXcz@5PgaQ9+D<}y&jp3XWv1zm)?Y_ zXy@ThUz+u*8p=Up{zqgGumxA=<%elvz?`6fxZuchV*7z${{U<^eD%g^-y+KpN{xM( z3vz#t{QLTi{j!Z!KB&{PcK8dcD5TXS&i9!9(6O1tjg7QWQy#dV7_lJhe9(jDV8Urp z!;jh?C5b4L67*3fPBHB^eNhtvf>ybKA08p`CNPm6n0B4U7fC`~q~K}OZ`b?MtSkD+ z{+T1Yp~JP0_ow++lp+ir4m-P!>y~JwK~tP$=M1S#BR2amNt6-V!jutUZ%ei^e*KtS zN&VcP=Ib``?^ZR?!I|s?6AB@}S%cQfWk<#FbLS-#W7MB$qn3VN7wV9pX`_0jm-1)3 zM)&E8?UG+h^u0ZyjHp4@M}V%FT3S6@yPdt@Il3r)dmzfHoaAcnE7)%zft)GG2N(L; z@ZL(*y>CY@Wy1Bx8jC!uS-}-4F(kVjF^1_kxE|s)_cjmK*ImGijE-#U;An@y6v`)k zz8XPBbX%8qu(l~q%eijY-LT9+8LT*gLnqVTb`ek?N>3*R*EW=>k3R%TMWPCP=14-; z5A}f9L>#iYj#8yAJVuIb1=M_gmfRB*2MARnho4Jma?<%kyR3SGU=I>3^iuy0vz%Cu zDPSc+)S5!CQ``eb>=rVCt3}IVZ^D73D+p5nGjN@svWF(ZwQUWAX&Qe@B_AAiZJGTj zduPEt&J4*^ki?~7ZnUa}-RTC)J_%$QCxK*ebHrgAKhLvoW@@ErJbD?5Av2Po1f$NN zN|mBd{Z<5p%kg-FWn&*0?pzOSn!V87PS;l5ch6j;KV1vq2}lK-#mBmK zlU2$mlwQtrGZM04GZ|BCr^93j+t_eEi4TCPF5?`@Ta2r6;DIV;q@ zIPQ2ZPVX6NUacCL4na+-R<-L!$O~Lgd3D~4TMp}v(K38963b5M-w~qt*$n}eYRwI0 zb6`#nI8f3T5?>INBI6);Y^KNZXelt{YWBp);6k-;+_e4F;?v`cf?e&P*W%mbS{K=- zL;ygg24nDweR}3OdpndOW(`{~7b92vI_)UX=SUQ$D3C?@H0lFsC)x*3VorSx><2r4*rJLhiG( z$zJFl!^`SXUYHxE=ppT;@)HA2?7mCT3TrNbZ7Czv^KtTgD%rGS*k|BAO;2oy%p_eV z;={&=oaO>rovgRHn^cCk*xt#@9!Ep2*-h@sd}3P1*7xYPSOjA1I!(Dq&?N~xx8sw+ zBkFc)wm`pD3?igsC=vl2!)_92jvO5+8>c_K&Am}!?F;(p$a?XFG;a_eou#_m8(+2z z5NsY}IP}KADE*24y@y4no8`dqVUmoROG$$~KkNZ-T379CJjW?2<6-yP^GM&*wm$yKw|#`XTRq zT3qRD%64;D%h{ix-?l)fK#+zB!)QOx>a&N&_0c>d=9g?#o__6wtwIEe%iq}}p(s#3 zVV<9QEGw;3Eol1GB=&;zGlLj6ahQB!e!9weRFT4&(1m-;`ez{9I^)?kiLU zl|E)RZyRJFvDCMH5s{Sa7V8j4mV37imP~ z>E3z$k=2_6F~$$1A=#aGEPm5Ddih4z2$B8|50;jX{ABq0S$WLDQ);Krn;o~VE#ALt z!~J&Mg9JAdcWbuh?6*P(?ETm0?Iy#d{WN(JIqN&NeFe#$2v@aRHsYJ47HbQ_GuA$^ z_QPixb&N_7R(?Q7^F>GWwD_3U#O#Tl$b5_`f7my9%;*I zTIOOtO+K4d-3}=hUwWxZhLo~8{#xSn-L=DgE;HFILeJMM_lUB?W+s=|FHyGq{6t7_ zU=h*zX&EVel-wxP(%h3W4&1v@;A5CL&Jot;dzXdMAL$FqnElk(cW^R2#F};?=lj!{ zZMCC(bdP5!DReIKGt8_2q=z4iERXH7j(z*iKori_>j5p1VEoc_3i0OegMmLQb;)vu z7!l!ht9?t9#bn1cwuBhMAcD~H`_CEj(U=zbe>#^Zic^b&VSe=ebCyZ~zdZC}{% zqGJw^YO!Utcztn`07TYf=2i(6QFSu6FBX1%PFIC3a3llb`(l-a2$5!(yLK`k@8> znYJ0^Pe5ibfH|6a6k{Rh-7xA(=k`+@OQOp=N}?6KFWr?NQRJ7JA!%eG>HW(L5|PLK zIDUZ2kjJ!(%n!b_~UXD2x%WJk}b>r{YCK}vitwx>not5?Aops@c{%$C8WC@ zLdhWn1ZfcgX#wey9;8G`DQS?BR=RWO4r!^OYp5Zmr2aEL&-?!Wx8C>r*P6vb)_`-L z``qVTXYYOO-S0Z^`9Q*~-=Tfq=FO%-YHV}9V{d6dJTZ~(#S~*!o_3v#BDEcBrd6$S_P3*??65RF$T}_g&C?{2xqQKYa4K`b-N_sfwz;g6Sc z)4bDMX6~xy6@xaoCaebx_`59tUKE+8nbx4xh&HkXw)3v80OR$GmIYJ2U} zn|!76IxK@!P}VmlF^`IwHp;}v9EyaCm>{-=Tu`N2l>@IvNth2{+NjInU1`x=yT)-- z;nCJnsI?=j)fEra0aq96y$kN*EJcHdbO~mn*Hhulmcpy4;nqnWn3Bt;! zY_D%Y56LfU%#q;~hOo5#Ue%rYb>Z;zwMFlai#dy0mYwlA>KWnU2qyw>8sP^o*`l@M zy9&y)bo2F1s;@~hIkP?9#;?vM&8xahJk5-ZS|KSuksbC+sG!gat`@$qXm@Iyi5DEar5V`y^3Y_n{dull96K$|ojmn>*{OJlzUtAaty3Eh;+q7E z733yT*-FtI+*Eg;AftagfZTJRl*Mz@M&umg7S|s4n4dfHMoc@O3xxTpi+AYcV}AG+ z>-+jgyH3ZesI9LF7nPt?kUS#k9t+o2{vv2^XE^#WT1hscLRnc?vLwngPw`&%q$i6L zUY_v$#HKe*_px64p}cqo8&+Eg(gu=-6kV{mogP3w-1h8i9^q4VeuTpdvm*08riq7) zPN(-wjJr#A+Ew_oilOn{FV&Wa3i_0e@Ai!rkJyn} zXD1=Z=s|mfO+Z8ccNU&B84 zrFSyz?`GIXl4PT_`lCE~c84F}WT=gc8yZBAoR4{H8T{7guys2;Fj8E*1gx^Vz zt&?drZ*P?~K6_PAaQFe$govhcd#Zd?os9jAoIAI?&;)$EZ(5iMPh*4(%SMQ6%qQ;8 zC=BE@jgxB|{4MS(c5TDux8p>5^)f7tq zn(16!T*J@EcFG`9@{)DyZm&q?%gX}fk-*0}a%VL&AEOIguioE=Du(ig-ZX5)D@*~8r*Un;fZrktPnH`^TR>Z+8;ynKQs`Xv?&i;l8`-I#ts zdr_K9)!m;{T|Pbx#2gY760^2&J#{yad(qLCMD!CDx- z+^Ze!^SOf#f<8hm+#@B%O9TFyJhHG)#uq43VG_N%juG*Jiw^tiCDv{DyL?mqdbURI zSB6c}zs%n>?R*~;lyfP5MQ!@#XoDy?h{V3r+V{6h&x1$FI~mFNnju>L8uMszS$>H=QK|qKdn-5aZ^p{<^;OsLr`_us@%+kzd7q@?YF(eiPJH^8amMzRnG^HeOag ztLgCce2K6Sof^p~&RG09>Nn4Qa9NNm+e#=LeLex25mi;9xqIn+t2+%@m$?kL*>yX)VR>;^Fv?|#b+)1KQZjz<$TNl;60KPYQ@U(7fk{P^8& zF3Ba+3p{^X$_`<%gIeC5VMwr{PHCEaI?Loz>8GRJp98j|I1wYCrl*g6+HNEWZe1v* z`Ci4`2S})?OPxyzcwYbWYf9|Y~}e5=$wpY_xin(SVak={EK+nfC)lq*+MnN>_M zSG;)aE+Lkw1ii%nt*(jrzs`6MujbAjMYh2e(XN%;e1>M(XEDq8wWY6flMxPBOKfuYw4%($IE7KJw zW{ig~nFw+#OxQ$Pq)|A{U<@am;0oIA{w^$!LF~8K&-R&IDd`#nT8#frV;OWTS4(gl zV?`WyM!H#)e>0F!O;O)CB@Nwt;&mMq&WO08GCc1lac!*-R_h;OvwaJfhg}|>A?&6L z1M7f~+ZoQpf*uE_hOTbjZ??2M7@v6aIG>=e#uwvEt-4pc;qs!9E(QHMnK^;$= zZ&n&IlC2i^eKo57b4H?n^85}4-eo66xs)rH_gTxJ`mDeG<+gxcPH@`Is~uIAI=PI~ zlo%4r%%b^)QoCvkS9kcMV(P2>dd5$zz0ZHWh&9wbWbdebLE{nv*5x{v#+SPPbzSCT zl-wS4@3oMRi)K7JOxE&|*+`aXvcUX}qE&rc&0qVX4t4(y>f-!o;E}1T{>IysXr8?M zKZ9xYzS+d^YNyD@-ZO7SR;@qT7r}*G{+*?%*%IHBDfASrywnABTRxqesrD?Uvv__| zO)ts6DR2{jwB844yx%ivtcx35Yo>k7mm=t;18P93-V}Fv zKi>{$&2Gs39({Y^XI0pJKELi&yMp~vZb)&%OUzw6NjZT4&vD>H28XCn4v42>zfB^}8aSYt{l6%cAPWOud&0hr0 z&);2uw?}rdNt82o=1LfkwL4GdW7I9z9_IL(!m4SGST`5XCw>FSxlmYtNOey%Ydxi1 zO^Z`+ZYnzYOV>D6!*Ov!@<}XKmwt`*81B%^s4ri3VUHAn5`GL$?JHki}nD>*H8_3Al!-`@^ER< z9n6mU{Nl#xOQgj0z7)k4+TEmj#<8y!2%Flu>((<2WSG)E;)`^9=sqm#W)N=znxoF9 zmlyNbS4d!8vkE9=f&Se=Tv^N!V-&bTCDSLf<9bfYkeyC3%IKW(etaNanE>`6=NpZe z$GU?z)kupc1Z=0Xs(w~M?qbod$eQ?k|iIE^;?!O@Hrmo&)((wrUI{O~`EPF_rN#gvnNL^i2Y z8r4rmYvFj=jCFSD#uLk`t&tfN+|kKx@~fKNZ~*R`+2VvS=c+wPcFlWFVY;t<^YYDk zyIw_~YYN6YBg;Yi^5fvI2J!l{$ZCVOv6f&-9P9-(*nlvyCQM+O4Ll#*bDxbwyH3#N z4Ia9DRH^A(kjB%DHqJvJi#h~MDDTSE#o^$|8GXP`6~gZ7Dal;&wtWVhB~TaWyR{R^ zokHC}XlC`06mDtVxGoSNH+=0I@`7?$m-F0F!n6)(Vzh870y>Xooxz$q&Tp3ng*Cmp>Y#ui&CqCXabkb#LE0DgDbW0Ezcud2D7h)zM;)5sr2K#~R1qa+VTx63?@a=+RlN|^S z^$wzQFG)E~Xh&s?O0nKIIYnq_>91DvC))#K6F0OjGQy$LHQ*P~uJhhPi#NIO94Bnf zrljRBo1!;a+3M&{fIl*cpPITq++z4#o`G;T_dqwCRB1C3R+V3={1bXkVG&}9`JR4q zaHrIFo9u>bfUn-IeWfQ{)0$$E!DVdsq6uKh+L4y=K38YCNcpaq^su+VU7>xN0x4%o z$mp8Vm5$HvxDYPBg7|TTTxoQ_KeBc6wl3wSc^_ol*gxeVnqwEQ@4Am7ZDm8XJS< z`B}eH*O$hKIdys&Us1c$l4UttSLt*0^=>Qfqlu6yAS9X<1EG@Jn{7CI7p)D{1V*6( zH6YOLP>geRl;wBm+T|j}I$*K)2g#tLbd4nWq>IUfcg?a_%-qYeQYu{2oZP^FUWcai zhW~mYj$$74a(N0Th)|xtW^O*}L1tcwo|(%HJcb0m$!5J_zQYg2eQ+`opFw5Kc(e9$ ztg}2rBpA$SMGP{mjCFyO__qIi6?=N@(@*qzQqKGB89OPm@?qTcL7* z;yJCh#5jTsM`<@8HT(@-Y!)eUDRM6w9{RS6wr$)B`#kVgS7h7_PAK^b`EFTf(lR#% z{u!Tu|J1?zyC{Qbo31ICm6acFoG8oG+dwS8v7azbLw9bmyc|Au*&Jg>`F^HF@J{1} zl8HL-+biynB!+sBL#Ri+_)zMxTeZ6ftpv-aZ$y^odc5p`EYrEYcx9Dvi%^6YZlxXZ z{2g#|J0&y4a}(r^dIW!#fiiF9+!+n}0cG`zTLC(%@3$bgiQ1efAi=`(-PBks8bOBuZd-q-=!(hbYSYhM(@V;xw1RuYe=&`_&~jje#ifLH}e*nb#~XexeY3 zq201N<>qz~gA2OJ4fP|u*FVZ7woO-`d^K{X$_amguK2CunxEQVtf=^GU>OD%GOGP5 z(${>eZgz#zF{cn8q+ASvG)^|{%T2cIb!TM;O8RwudOYbYMfi?K7CIE&W+F`mY^%3SrNy{WM7g+ zD4zGMC@12zgho<6Hig@Gf|y*deZX)(^Fo@Mg2Ee_Pl_Ued~U6ZI2Xg9Jn@7=(_l+D z*DoSm$mb$qD?p4~+ZZNSl5V@uaqmQ(e;NiS`w=zwQGU?ruLAd?uhiXU6$HmKEnYLz zHxap$0>cNvkl;WogG6|HCW`JM_m*N0w}IWMM|%*_RR{B6uwGh4F#RDNem1!P-;*d$_y8Za4*u# zmWSvbb`I(x<3eh3PxN_B@L?Hr>pZyJ4AB(QvDy)CEORyqKcIbX58nDg15Qo(MUs9kQ6M2F5&j<$5-c{VDL5l;U{i9NPv%vCvwx?E+3T)7nhws}#j5T6y)&@oFm>vQ zw-SwvOAVk7!H1CaW^>8ZOL6O-IX~oS*D@0lkbWNGr0vk*GdK@)sK7|f5UNS&KNTOY zz_t)6c=kn3PTW+tp^O`q{F%jDpNYM1fNV}WeX5;lvF_9@ybo`e10GoBuBAQwmLjfA znuCE=sw}Zk`jjAS(m9>pU|INM!iO%-xn5Yx5{_wr9Hg^}l0>!~=eQ~@4y+$PRbS84 zI23_%iZ(7w@?Q|;y)|9n*rsl2IViRJdn{lbmx1<#!{&Q-+=1e>?sV}G`Gc_PRQK=z z#I`8LeMYgR&c>gMzH{l)feN97J-|6uzz|`3#81$58hR9zK@O2AJuPuJ$YDre&~x1N zCxZ}6hlKRW@3zEY4T?a|?^$Prx6yc|m*HKs+U6=WX_ zyLJ`N+PGWjqL`WwDJSkL%BbOFYIvkBPvoNR*kujr0+n{Pfa0#ONA3A@1PPMb=UxbQbN!YVDs+>zvOlQ@}+1LGpF^OV3VdKq&thCBZWi z5pM1#_x;!b*uFVLc6*if1AS_A`c#M!7`gzV#3ZOqI_tmzgkva8Q5H4&B=%G1{; zA-lVB=g7p}LfZpp@^T=qvO4D|*UVVoXTUUyF_PztU)0DSv5+rjU6sKYcjMlNA|#*k z%vUc>=MWibB#~@1c?w^<1azg9TwDHFIVynOtiMqa)XNw9aqb`<`=aDj$(<)A49k`V zF1;%!a%1JA+#Ljwlc)?0XCj_G)l!TR*S>Qz<0J9*h;VM{HC5o-@e;Vc5B+iukPPm+ zLz7J^Hy~nd^jm3ll)ZJGXSHuuB*;kkI7J1wbRx)*%&}C3WaAS%qF267=|!Bfz!5m$ zo*S*lxxF&ijUVLO5bk9i(m;y5R* zJZ8owfsp$sw!Jk*8m6Uh{!T`ewhvl~9Ukz)?@^G3H7f{_L#ueEMaG9oi4E%;6WqJ` z-3cHBKMHKCiHLdbAY?~ODrS!lB0L^K_G zPr*)EL{PQ(1XnecQ31WgT?l>lv~#{y^Uukdgrt#*1uI43PgCaF=rJ#A`i05dOAvNNP!lL4?MspSRJe zna5m2zWp)d0EKj1;(k*4v9k>@iV4s)4$9s-CCm>sa-$NZp@t>!?W?n7@^|tM@tUzg zQ)WT1J98{l>nzB(z0D7oM4JAMV{$tSqo#hkthv7llL4y{9{Ko>f`;^FT@BORe5a@~ z!uxyMre&M~S*=UJ2)E$gG`;>@?f9yQT+XyQAsOc#IYeM{;`8%Fn_o3 z>eCxt9eywH8e-8^s5eH?+qOW0wBn4Jv>-S6^R~;ln#39FvmtRKm_Ny!pU?Hoghl3F z8Dk?)+r0Gd5U}k%i@Z@0R`H~Q72SK;L@**g!MgmE)uA%Dp+Sdtk9cQ z(WKB|B$kZDwBxG-83q9`PfzNRcyEw^j z#(NQIM8Ap>;8ho=;y3cEnS;45h?Jg=Wv|42_Z(M$NdHO59{wCT6&c@76|eLM*`yP_ z=^ko^%q#?Vmf`s$-?b1@?|fz!avCh>mkH^VZEegn6I@rM!oT#ooo_(7_<3)nKv{B1 z;JW}M8RHQ-2qw_ZJ#72z)~?gef=3^N&qS?;NB;>W&?o2)n%}xSVwTieF_n}WU-Qxs z%@@HBde3?pAbzh{AVMpjr7xt#scE3sHXrat{5lC6(T0Qsr83_sQ+O~nxa7~q&Ve8B zp-WaOxkEjdt0{4#ckTiKUczj$ifGq|#UH+MFJM=WvD9z0H#l8Bc}N7DMF|<~GMVxc zVewb%cEt_wbFDjPm%}LH0_vu!^pHVbBh(Qndv_fXU3*37liI%sB^Fh%Vz&lEO(bL1 z9<0`N5T2vzvqKKck95$dX0DsEL_-5~7>TSxk25Y?E%?v;I=eAFEsCRu`olTOQT;{Cn|nw0ZxZ{%`09NEv~A{?+9210k(Gv4HZNtlNDCvlI}G3 zRxvXOMr)NpOb^TO$`82plMTUBe0(<^`v^vFQo&5+##R#lN%s}Y{P(8HbJ+ffCgU3u zSOFiArbw|RAe#QhuwVQQ@*hkFjInqT`5rLwyxF6hsME+lfS$hd9>Xh6A-sFPdhutr z_zd$ysvVZWZ$Y?Un0ECw?G|Ye`HE3l;&*9CoTbV-YL$T97CrwKgJz_UxNLIC#%Qj2 zsG+|b%YLs;l})06u1FSi%$)Lro#;TS7(&fJ$o+$@V)Yvf1UM=4jfZ(T#;VdN<;h$w zQ-5}>V^azXgX#-QUnZI5I~)Y-#RzwFMezRRB&(Lk z3kAFV1C(3ipu*qv8^iMfG`e&+HBkx#STQlpSNT0=7u*m@hQ@if4VkKL;e53M8Ua@3;Yy`3H@B4xmk3=G@D_C+okz zT7^mi(XuDrbN|+FrRvX_Z!h2Nm5FW_2#a`0cl^$_6tw>Jb&(WuAE}A`{X2IU>5M9P z?4}j}Cw22R0EZ_sqTq@Mn-!8*C>JQlNefOS=n{RFr9^VJsL=}YUr4@xU(^}NXPz$- z{3!bW{Y}ria6nnO%=-K%*}v(E|M;dm4e%-#iIxQajaK>l-M%6!fa0N+@Xc%dFRbuC zJh9{zxCd*4N*@2o8~^(!V-D!{rc<1kNB@lR-y{7$zaFsC89nkbo0k5c!}b5Z>1#N+ zc%3fQuX$jIo>${2r9!7J0lVRHPWRH|zg)++kKnV7w?yY~paptf7?7rmGW4l*mLx37p8;=i3$$5@X)Vn4xMqf;o2ayx7+x^5qe&XJQ;O`M zy!&wLszdb&#MX!Odo`J<1a~lVXTd!A!~iAwTL3#<_b73^hdF`<*x&j;tvI2E%7o-vIX< zEyq72@5_J_N-HsU2^z+CGD03Y>eo55^Hp!oUxLeU6WuQPXpN|{Jt8Y27V`z%(fE%P zQLRV+JX>E?NES@DQrzY?fd9R}h!<5Nhan|m3$PyZ`rrq4iKcNqFH!Ju0^nHv*nV!t zWow+f_%h}dddRGB0XJT`s`QNpJRzpiuLqKauU-LEZ&Ad(KZL6+Xlt_6B&EPZg|@*0YQ&BJWSt#rN0erh1lpNo#ncN5jKnip2} zXZXbE_5kr#2fWd0(AaMmQ3I+9ksO>3EWk_7o376#d}7*9w*l0t1HmzVfu?SDKsD!# zMfLVQ;`PV7dQIM!Gh~LIYQcmK;-I9ns|G0P>A^F_i;)_&Tma9uBc*4T+Qz-FFWuZg zOKvToYfU~@u6#_6Jo8jWW*T?pksGo#>b3O)q;%NmHK^o{H zvu`vhyF{CRxB&tXp(^1_Yhcu12Yh+mT5gk_KAJl42Aw#UwXb0Y7Qptg9H|KV2)e0j z&~DKaxcKHNE^%PV-fdm^zKe#jPfoKh0GH6M56;BiuO1wQ1Y!tnm$bcbK!j2wP0-M7 zzYru-HcVkPg()m{P{r@j*BL-TbvVpz*DqB-UosRY<@|3*R<6MRnl?_H>MNL<~#~Mau>??CNX&z&NWdTp+M&6mKWS6tU<8LJqShbwuJ~p6bKQUNhaDKl2+T zs0iDbu4J-(_lk7hNuOVS+Tft)=6C)s_WsyZCd0lXH4sq01 zE(2YIXn!Sz z*?>&-pps4{cb)(G^5IwS z@!F~i=eWdY82qm7ajQ^zJT$Yr1BjZ+mEe)*SAIAo7ve!XF(E_patSIdM)*Qxqq(Xl zmfuJw7*b*w!-ZOLo44fx5h6O@@ARKz;IbeADV^e3ml-b7t9tdMs~3+b!P+TSLvw%C z4iGC>)4xGq2UqYs>%>vKLIDK5FMob7S#>T}Z*DybtTR>+bgiv#AvwyPAPC~c{$rv> zLX?zrL8emwPA!~`fxv)gpBVM^BmM#E=2i`a!G9=ja`>1J2Mec!lXkN(E% zE03mBfm`&^@EUuk!NE5%CMe(R^w|p6FD~1IrDa)O%l*31Za~4uiu5Ye~1$g)r9~wPC4$q9LN}$3eu3*4RhSP)S3$jvO zRqSV^U>vG8G(Ll;Q^?+P9`p=f?q+!scDj47!i#E_K8X{^IHum}0jyk~hUy5DyEt>o zpVMC67oa!OdTg|c-o^zm_b?Z3x&rSa2Ux^w>@2)QiRDm!IIQ#5Hdr@ys`sBKadxuN z1mkj7d{%8j8>dgEUZ2ljQ*G@--Isz{;oVQW@H3%)MPUD(ka#9&HP%g^y3`YR!&0`( z9FUonY54RZ)z>hl*EXugYid1>c%{2DwdDxsQDy#}I`BwnPLJ2QSXTowUYG?#lIQM^ zO>_j0`!1?E|ROlM?Th()KBQS90;gL}lks3>p=O!dGsss|#Gn92KKG1WF(szV>R3V^d z5m9swMSW>A36h7@*zs$_el+_B3$LHj1?XOGU=B}pv84q+Mze_5De!1LpTypYcj(Rb znH=53rMPZVKp>+n@7xu(#SBT?F^|6c#`y4@ZoU5mD@2kg#AX&)LBZF1ysCf_1iyF` zM5Rqf3@mhzbc&^&b7gGa;VfA2m-l;OU@#)^T50Gs?fRn22eL+h%56w6J&>EGn#P0^ zDL?CXmB?*aoeN*@bHcCcVM&7Rwoux`hnp6b&saQ%5Hg7zhuQc%2HX~WV z*EAB1HYlAc0kKqqCa@M(sa92yE!HF)s&`k)dDH_S_(=aG#*Ct?x?dE}&%ncX z6mVnC3ETGgcosiY(3;#zf{Qy(mWE9vi543F?&(>ngvOF;*p-do1 zLCuggK+NAPBd*W{TRa5{7a^=BWEPx*Ehm@qZzOP4j=cyM`JAdkNP`3XPf80oxrxR> ziq9q*E864Y-RDmc#B<4I6!biO3;vMqaB$|W;0Z1RKHw?0$3W-5(o5+Ivt)QbBHYmy ztCHeEyk2n>9B?_@BT2qCS*FY+naeOxI?`fxMzj;y#Su^~%NEKaPeST@5=L>cPgrGi ziI&*xUL>(uZA`KvxY}Xm49@7CJ6y;Tmj4=-p>w%D^kuj0huXwM7()_O_Hw%P6N(WbS8cf?_3pYjt-6$wvaq z50=lO1w`kOe0_}UY0vLfdM)=c9m(`(54;l(8XdI<=hQEBpcZENmahc9e<$C(#1TO7 zlZp+4j^?kR#Evg6#B3o0c(PaN+U8*gu)TIE-^WVU^AvdjU;VXMq)#dS3bdfWPpYa| zB;Jo&gkk4lSGLz0uT%2o_eYP8sMA8#*WdFxhnvU?!UsmmS8k@&XarRTC1QJEmjq?O z7E7pGgyiS2Q%R9A(txSfvyFU|;?~cBr0OF)0 zMj0F0@UB#k*S$QuXhjEZaRp;gRz*X0Nr^ZZ`4TwOgi^v>W8i9O(a@pE8FTG1mu+2k z$}Iy=zRm7Xr)EV5sOzEo!}3eqRg?3sc=^rXgpm7=4PAZcfd?m;ILXyH=h9kBpFjUH z!B}$-60$J(YoU2Lyn1O-_c|+KJ=vc>bs4Ak<70xYI9h7>km8X)nZe!^zY{#z$oX^+ zpO>F#!n?fvF#1(CxgykR@3i~zEiqF<-6(>#y;CUASsmhJ28B6G1+NB};{|l#w_34C z>t(ko6!2k+;2GT;jxzd$$J-XQ@}o^K#k3dcNmtR?p)2yulV_>^g~|(~d%GHV_76nG zg}PYB_k#1z2vUpN4;WkxKwIC7Y+WRCCBtd!XL*rw?9TBP`q?(ws#eR`Wa}?`+nr4-4m)q)>Ic$&+P@$Yck(-%1rbW#lTCN0%qd%WQ1aio z<&*48SsKi^ymCzGk*uj&Ro0MHfh$S^y=hYeJaZAO?dX+SE>C=}+i5&aOh;pfPcF7M z(MA!<#IL@x;A%~wtBL1n*hBQfsESd~+yMG{yeYF|x1}e%OfvytNT+`1he1v9p3ef5 z>A8r1(PTz{AP;^UgvGo%oL&cVej0>=k!&su1nqJdYmCl(k5Uri%MQzMzkbwP>)P#Em=Se))yG>z+ zH|&6B#e^GXrTU<-xU9=^=MN3LOmN28pAbovxY+x6t=yIHt|id~_qLtk^Eiq22`M8`ujna6>3U(siT(Ww?0(0AtSW%=WSI<$rs<#3s8p){L zIjNm~wA1GozW9^~gXHANjti;b1BaMb<3V8+`COJHA&+J0hG_N<_CP&zusZM9#~sUJ zAp*`L7nt(x5pUK-q^y9AQMpQ^pQP+%u!IVw>bD0=@8hNy+So8odF2@|*g}@m8`>;x zQMk8Y6Z`4Ne&tbMOrn3?=5J1N(0|{t&c9+Rl1ZMcEk*UvdoNtUC0k|JPT}j+f7Bco0H)RCR%o`Z5Fm8RA$uv?Sh@{UFB2D!91v`4Kd zi@?etb40*S$}Cop#W#aWgv^;oSUdo+Tp2yEbX4&usGT*%If~$EvxpS&+qr%z*Q$q5 z*KuZLljLV<1Cw?LAsQLwQ+`TbStSjUq)}AF-W7k{$Ps8GqZr{b+8ylvbpKVJ zBw^G6@XyzZtMqDf4RcAHc2>0S)0@ECU?Z7J*A^=j_fMuhetcY8)KFr>$*W@>)w zc0TeJLCgFn_et}ka_R(AM|@uA3f_TVA8}NIiiOn7jLGj z$cW2QCrW=Utp`;e6hB%g`bep>vfrg`ugREu;z-NpYT6LYlgq$8&h0slh9JmBHJ6UL#B9q-{)%5R%!q_Sq@jZ?fn~-9}vfmg(D-s-XO_ zvAgf4U!)3KNR0f9sM|Z>OYUdaqNpH%Hm#^%gYz?dMsGq1>XkEpmYT+srZ-`bAb@a7 zttaFh)z7R=?St8^xCbJ~_NYkP0FjEwf@4VO0ab6`h054txo;vM|Hv_g&o$d!%qw{x9IP1saWU0YvUAMptVI! zN-jhHF3KC&K~Zkbo~9IMJFj%kq@R|r%$mkz*?Qnet(s6Zxm$4t5Bl-Oe~fwlnBFpp zrr4y&nk7|ybk}oGH9?i$v-J`snqkJ$ccjBs^KAGokXeLK-pRzx{{SSQj|02Zy`aUlSpxc`)MF;<%_gE!^_dJleo%c5m_+P(Dx}Xu~ z+4jF@5*Wk(@{$Zgzh^mD^8Vj< z1N^$J02CYrR=rNz645Nmj`F>sv>sKC%ZMESsGR^bvt29x*9mA*Sp0pA+LDc+(I4@Q z)i%Y@YtvKT*amuTC!k69tW(wj^%kJ#<0QW$O3)H*bbw!K;B=9QhxWInzdtoI!%&IL z85<>f0u%aL(ea=GZ8U-foFF?Zfl{ympqX~rv6>2cj#0nJOW;lRdXVBVr z1wPj*PDzxVccJV(z&KGRS2Agpy3#A_~TYMaJVeaD@L+D<7VPxoimMvj-=Q%>dTBU&lfZ^!MO&UEj31RpDR5bpCLKk~& zvmiWn;pwo{aq*59I_JQ z`!1VKAm4BJU+_4)(M#J`z>?GS&l3nf2RoQW z>TJKB{(;9Oe4mnPx4UdlmL6+W+_8GqUz&tezW-8Ddz=A-TeqsDGJ`>knFfv@?qU>Dw+l;J{iK;|lztc0k7j8uCf} zL&tzb&vmmOUo_a2FS@{uTsj6;(P_JL9=rOc4phPN3Rh!kLb+(9S%cYoySVXpp1HD4 z_$~VQwi&#PIZlbW_nZkctWiApiM`p6?RwM1cdL))%1mD@*&%Jn_KN@ZAQ`=^fP4 zjCQoF>YZ$ivUUWQ;5x1K%dd9C16aC-L=`$ri#2fxKKv_7j|;3WpW&xu*_ueFuq@XR zGBDses&o?#k$dd0j{%+Hm&F@S#j2nsV8EYB$&K%Q(O-)M%3h}S6RQOm*0OtU5Un^ z+~Dg<=rFw<5DbeG{qpw!k8^t&x`AkzVtcNkUKIGx&VGIJkt3V4gFxgR8kLrQegy#O z8Su+rdIg}a?OkYJV+cAl7ttR~ z6`KXj5jC{~zsN9{x$(My9nt&v*IgSItHiB$&zO@>ZV!_MaBaL|e8`C1*3C6>*3Nha z*2s#LE72~CC0-2nj23{feO53rBovVM0DT!SqxU|yoTuIC-&?%yY`WF{6XaCRcJ+$^ z%fHJkV>J1~?0`<$Ue?Kh2E-C8+hEw1Qb;0{MqOwF*osU-pwxN z&sDgOZouSsbx0Y%4+tO+I_U##3ttXgXMvS1+?+Op zd0%A|=baJFnP;wv`H{`ow@9+ri3#5UBobT3d(#<+mt6lZoXeTr^XnGD^J8?6n`e{_ z37;)kwdO)jKq%u|pdF4q`HMkpiH-U-Jbe8^z~WJj%?Y}Mq1a~jTc!g?U}JlnR}BCU3? z+J1iS2!#-=#NP!jzCLp<8zUXXedDs_5ZX{ORZZ3=hSN4hT7yT6)Pr94bius6#QX?6 z`i`2)V@+%eRLRe!fxDmR{XQv)e~BFih)%0nwUBv5cmB|vD8}~*?fol&JvcN@47P{G z)1@xn{t!qvXAg7Xd6S5riX$;~tm;?+)8;$808h_$P<0UUPC!?NO8{Y#6u;UrpomYR z8T}Fcinn*EFeUim4uth=1jXGi5`RWs>}9mGi9QS+anQB;o;?Hj)EzOK;nwNg}8MN=PE^4kp?Jd<`b=DcJ@cV66l$a#Ue~RCEMzX`_$N zgg|~h=+p@m4tUK+m9`j(os916tXkr5k6yA>^!|uNa4bznbWLb5s$Dwqah1YR$x)n0 zYVl)D1ig4$Iy$hs;LS6!R&Q}L42-1$ee-l|6$4jl9qL+dG98O_&rjcDsuHZTUda9i zdX?w-*h~$A(+x~%y{ruq*}%3agmQf9+b1c+I!xPD58Vz$yH7N4U?Y51p}t>sr2DU> zhXHW>F8c-F(dUB7s2c`ff=pqZ+80lut2QIF91Xzk`rVUlaD;b+x$$t356W@%T!|Y6 zNGJt-TnEHgd^U88aDVSJo-GhhEUMCq5)+7zbcQ9q?ID3A)L!-Gfeu>k`01B);7+9%CGP_|uCUl?B48fG(&47!<+mAs(f2!s zH78&4|E!+eqKD$2r~dLJCLpt41Km8QIN?!vZ6C?o% z)N3DeonX{OKs6+u!%32nb+{H5pSa@&7K6Hr3iN?&4Tq^#aH(+6i>v+vZaC%nD= zxi{kZvEB(QLNLvAMBodwO{Al*WDf#??|raWwGln1Yh6zK z4&Sq`yW>9@)f)bsvjT7u+~}p)%HJQ#BmIMT0&?m0yIX}UKHW7!c zjANCN5m^ysMx035lC6hhA6w{{-_MPDRL}DV{9do0*Liu}=f3ZA&(FB7_w{~XSAb-* z{%bp6-;Gwf4%J|okYCs`hK~eVJZ+{VB@Oe|$$H3LeI~{cd1LGz#*|sgv*Ku$H*bQ{ zw=*lQS9J0@$0Ii>&&KfvxyCD=tsNILs|ZkQRM$C(D`6P~Hk?-o)mIvs;{sX|!C8O7 ztl~ZdS&`(Xajl%HdG#=<`XXJJ<#1>yC}n@!ZF7CKMI3)kH%T`CvEWgt8)kX{P?*u> zv7+1es_o5|s&6%aCBEjj_PYy}EKmmmk66s=bEKq_Cy!NXX}!>i2S%GkSj0)gQw5hH zOLKcT+I30d-2^pUnum`k(dPR_t&7*GXFPNTe)jPfP(_uuO*dwtd+rm`N^^?!y>X}`P(9WP1>McMQ*=Q_6JyBgVkxfiz--H~Q zdENI3(Sfm7KHXp9Zhimh&Tu;6Uk8!wQGp1`rHPj}CDi>>g&UtRctyrWQ)h(4G>Bxs zNU7m^RFX>4fh93Xz&baiG;JU&2bBU!IY<4L->jt{4ti^1`Fzo8 zu2y3CM}M$9<8$z7`O5d_uWwvkJ_f>0KlrEdyn3cLV1)i{YO$hiEi{JjFXL0j)#A^^ zsi!IH@ym6Q4I~XYAhU&V)*`hD{uE{gS3bQy%HmFfGIGE2(b$fMy0viT_LLPSC+%wP z;qMndE!a;BW?oHgMq=5{CE7QO1qShtxqi4IUA7d*=aFZnI_vkGHZd7_9>Hw(NbXay z?>Il)oSy8wAq91=tw%bpy1t{%i_Sg-v(#=wmDxh95Xv;!%N<+IPv_hF`HN75PdM8U zMt*W?8&HJsA{Pc*nNTT=@PwSt{qK$qVxgrx)CP z>#B~OJD63b3bAtMmvWOZkPCoLQ%PP%`%AiU9+~6y;I=Ybw6-E>w&IFxF}!g&@1UNf zX3dCAVV5gr*^ERt`g!xYVZKn#ne&?9DNGJD+fRD5=xem8^NrV=F}H9?KZEr zD=fA1EA^pgw$N!$92}dzTzzb=R=hen^#UTf?zq~Afs?Buqv^7T#{hW~i1U`I7X#{v zTi8e9a^Ao_s79NSuvn|pU+(}Q%7dLhAA>NKhCq$;dt;*%A>2#|p&7vIZ|-rfA}@9t zW9F0>R-b8n403$eRFmJn(OSm$Pj>I_|2wI3k-J)6XSoN}LU;Ar^`x-t^*c$GmLE%d z*gT)YigmztPfMdH{i>a=Ufm6{vi{=(a7w_E{98#Yde1of0cP!dPw(;b{<*E#&{ zzt1p~@FFy6WzTo~ZS&68Uuc;Bb@$*2)mR`liaxc*`6;ao6SdTkKd-V= z9qhj>tP=<}nJU}?rJbO7mNl5Kxh^e+Nv?fhw)?=&)%2>hQF3Em4l;3$7p?ChU;3?Y z-%o2ZkAi@Ih&9OCzmf!;avH4xz4AE#Z#`aG+xh{RQ3gUn(_cOszlg5h5JULF4_qmN z1zUo^LMdl%w@Z*U1(#I-$Nj*}7RWkKlBM;Ww#cUaDWEM0uht%w(pEO?9NhxbCxy|s z%+ydjsGK{{ygwE2S{!MZh3J^tF=ZRZpbVl|{v4?4w3`C~h{+xC8rPkFeIq`ukjH-M zVv0D^E~JJhody{SC=f;BN5TwuaxVZrCIX_+Y=>OwuJQtYrok3e;Ab|FC(+ib?=@eH z+!w?yO#Jf=eI|q&WVO<@$1rVWx1LB(y zUorp!amxRq5Uqx&!Jf-M0i}8XD9t1SD^svkPPH7om;tD|iD(@*OllA?&t6}PpFcDS zAe~w5#1XYyz+Q<~UI9*)tAO$%R(Hr~xj?=rG~}FMIq(0{Y-I}xJs=nycMpL7x;Yv&ur|)3mI0crgqGf0klr^ay_Ra%UA%gVGYX1&3AnU z44k2S#qUdEpym=pD}DSC4?2sp&Mn7iEV9RQ5B$1V{1oD6F5+f-LGZTgS|7f78LrR+ z)oOWWe|7UzB+eD2M0mTE9@=$pxqU}({LgTbTmg0L{H0t-Ly!q40{J_h(8Z!}d%8f$ z6d?L)2}mH4axDub4sft?x-CHXI{XHd*KrvNZ}4uUe8vJ0K!J}>ZEHv&qz6Ibj8cgk zMhN*(!EsaB`LnYnSPEyr23;eyX%@$wO|k-zOQkm+Y|?{SLs@G85MT#U0PnRX`#`v8 zWos!!JxeKYTb-T#tfjvEAZo@>G+_QUP+#MXIh*+2^urUz^*PMg9fY35>m~@g00Q1= z=0otI)7d%0x)6CU@g}eKn7GK{hYavOkl|nw=zx^pK%P1KQ5l*(;P_OCmH~Wu?dwW_ z(QG$>4DV)dECS}E11ObduOd+CkiNVj?QUYR0i5r-mRkuTR{fy+OgyaTLhIJV$l>Wn zmnK_Nd~e&mUEnNUc2{>*!-TcaQEtc(D_$`v*@A+MVotODJ-6vF5~derfhN>&qU9?< z+_9N+0CSvn{WdYwLOqWD3UWQTDnA($-vm6>iuvI1W-+gCZHiibSwxMcl41dXA_qkE z0|2P#%wz>;?94s0iFFD9<#{!4Ci8&uBeie2K#nj$CBdn*nh5AoVwh{Of4SO5UP^ zDFV;%^UTXy3P5*!Yab@Dhyult z`E1?1s0lm`q&oWOrS5uvx*X7%T;7FXMecolTe*F>3j$|uJV%qAed#U0Xfy{>AlN}X zM>%N6Us9FdhVRkiG)Y z@<+0M2;=`+1f=kI(q!I9rNWmG+-L==GaI@h$KrZkE`sDi;#|QTtq=X_Sm1Xjl&UHHY>o$%klk@P96Tk(= z&39@#j2py!i~r#04kpP0bMt4J$C(yQ2ZGMzStM*66Bq$H=rW^P|5Ct`%OKXMu!YI; zu~nR;J?Y62ZViAq3eBFg6^0AR@9)Li$28Q4n~IN@Zt+O918N`EYcE&9&NcN|})Ebn@riw7ky*K_5VM+>G^V zH&%&JZ+Apq8J_&qIEfTLR_Fcw1tJm6%5i!yg}g=4L>|M%Z9Z|?@^0kWN2S~~8)5+@ zJ$U+c$|dSKQ-AzPTf4Wi#wZE+`SEb9Nvy;$FU$ZCIw^$HNxK3jBe(PquXg=5YZFp^ zh>>1Qw0bLcrV_f&fNw2vRrC*{=Ni%OZNH}pqkMDnONi*C4p2-@OZ5UMg2 zc!pz*HZauFGhQaI#mdDFc@Z}jmN(fq(H7pf;dcc zgaDvV8lE-ddImGB#wav#vgq`RwXiB}^Nq&kM*MF7N^=oyhx%j}=}GNQJ&Ro49~y`y zNR%57hFP2g1WTY+jP0UQWEwK(;;9?{kr$pvplod_yVhjzURYoP3WtYODqy_sA&U{o zQjd)-3|w!xKc{Mo(ZGWwMqO0GQA4Y=j1eC6z0Eljs%3uFrnM;zzCE1`3e6a4)Egjf zU*z`FAXmR8aY&$iT8LFEvaAX;muUaNb-#D4{-eU=2}P*95l}*g<6ii=nJ)KGKC6Rm z$`yAO9++5MNFi!xfIC5n%_Odq354@A4;PY_W2P~E)RL33Olf_rK2%! z*=b$A(vgUTY30QP`({7mp(?J>0I$DNU|Do~;<0@`1&ypU%RhsQ4}qZratv@iO_&x? zfmZaM_gUP)=&Z~kIh=xGH|uf!bmH93l598xK)lwadvq)2^>{? zLj))8G(CZpA3oJx?rd`-Jy_{6eY+|PhV?yfOv<)dqjJmHQIrjRy>9^f19Nd>ddbNw zvN{B;;Hs#BR1WK1)tu3b=#lR3Lo$3%VOhsH7Q)%(Ht^E&bv1T9F{H_qz4RPOO;DC5 zFHgRVGqR^1m{$x=F6x4?(j~71=||#RrQC(gNzrmSI`V3HxxjMn&(AP4&^Ne%iboi; zHrGS87-UUUF&NUjLwSsN;P3~$j~+d;RTU-7lY-}D2qRA%MGqBQx&*A>)YGpQyTd&0 z>!reUsEZI@$pAB?LeJ=0RsJzZhx!Br2dV-Z~=*Jp!W>b#P3s$@7Pyn&gP(i)M@_lNihwBlnkp%314-t%f zM_h)^m#y^PD+hQ${f(A4m|9BMnGTJ+#906`Y~(>U#k5r%2b#o{1x~93 zN7fvOa!bUNkeIKt^A6wrG(8*FuB(TJs6dkui3zs1^N#w}e=luuQ1e^o#)tCYfNdaL zhfs?-#8Rmm6s2^ht|P|kA(KtnVnkl5LEdG|22e5~!#XLL#YOW@OIk34>!u=C~eR zxO)s}PHW=2?W0-0CQhzhu~Wk=DX%ihT#U?o%6|!mI*`z`DE75yQK|3T6k$$+!k^-IPbj5fD*PvbB~`=q#c4$&n<&I zh2Ne5#{Uehb^GcG4rz&Q$TSJK&!#X9@=$Hqt^skyD}T#0_-}L56eF0LmS=*eklcMZ;#;;#TAy={VDPp(&$xmnR*98d$$0NV4`31I!Vg+h_ z^jEPis^7=+pW~2p55$UDiSZ`*&*MnrslYCt;|7ZV4OEyyZhp^gBBEb!V*eeFLdXIB zsXcSSFW0#Lv{9G9YcusCCHZ-Ie=LAoB2682Zg#}%Klb+5MCOrm2~u7KH{qDron!y9UD{9@7Jr+N;LoEGyAlPp4K{Ld|9KJN zbQ-~9Is|_njld_-8(wt5K9Ka6ll=cJLGN_$k^J9%OY@zN&cX`Whcex(dTU)3>1Fp6tO0}7>lzg?wt6<*X#!pD}oa}y|6Mk^DBMIlT^Bn#j zIG`|~_-18*XJ!+6E_cw?nfe!Tn>rqOaEH!@kC(lxBda&Vim{^n<#yj1>MlS#CG*)< zJwExizn3b=^AL3M9A3exFL@Ti!jW)?jJM|0Y_?_9oAhE=p1*QqgSPt-_xHBGyv()J zfLZwk$8OiMhW@?$FKv_30(21lB{cfqnzR?;`^@t{I_Ca%%?7$+Q;5Nxf8OoSmrP8P z>a^RF_y53~z~_lK{M-dQpMSdsjo{vW&E%g$*%5giymWbtL(lvY0r*q8d{sVA_RfR< E0cKu$MgRZ+ literal 0 HcmV?d00001 From ccd846a9924d0b8f1e3f51b86451bba5c69280db Mon Sep 17 00:00:00 2001 From: mletalie Date: Tue, 18 Jun 2024 11:53:16 -0400 Subject: [PATCH 218/339] remove node size table --- modules/sd-planning-considerations.adoc | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/sd-planning-considerations.adoc b/modules/sd-planning-considerations.adoc index d89b408727dc..1430bcbb80b1 100644 --- a/modules/sd-planning-considerations.adoc +++ b/modules/sd-planning-considerations.adoc @@ -70,25 +70,25 @@ GCP control plane and infrastructure node size: |custom-16-131072-ext |=== -GCP control plane and infrastructure node size for clusters created on or after 6 June 2024: -[options="header",cols="2a,2a,2a"] -|=== -|Number of compute nodes -|Control plane size -|Infrastructure node size - -|1 to 25 -|n2-standard-8 -|n2-highmem-4 - -|26 to 100 -|n2-standard-16 -|n2-highmem-8 - -|101 to 180 -|n2-standard-32 -|n2-highmem-16 -|=== +// GCP control plane and infrastructure node size for clusters created on or after 6 June 2024: +// [options="header",cols="2a,2a,2a"] +// |=== +// |Number of compute nodes +// |Control plane size +// |Infrastructure node size + +// |1 to 25 +// |n2-standard-8 +// |n2-highmem-4 + +// |26 to 100 +// |n2-standard-16 +// |n2-highmem-8 + +// |101 to 180 +// |n2-standard-32 +// |n2-highmem-16 +// |=== endif::[] From 94bb65c7f569b21f5735fc3a087f22e70420a4b7 Mon Sep 17 00:00:00 2001 From: Janelle Neczypor Date: Tue, 30 Apr 2024 12:40:45 -0700 Subject: [PATCH 219/339] OSDOCS-8392 --- _topic_maps/_topic_map_rosa.yml | 2 + ...experts-deploying-application-storage.adoc | 121 ++++++++++++++++++ ...cloud-experts-storage-ostoy-createfile.png | Bin 0 -> 21786 bytes ...oud-experts-storage-ostoy-existingfile.png | Bin 0 -> 7715 bytes .../cloud-experts-storage-ostoy-viewfile.png | Bin 0 -> 8821 bytes 5 files changed, 123 insertions(+) create mode 100644 cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-storage.adoc create mode 100644 images/cloud-experts-storage-ostoy-createfile.png create mode 100644 images/cloud-experts-storage-ostoy-existingfile.png create mode 100644 images/cloud-experts-storage-ostoy-viewfile.png diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index e3e8fe133195..8076e1ed143f 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -190,6 +190,8 @@ Topics: File: cloud-experts-deploying-application-deployment - Name: Networking File: cloud-experts-deploying-application-networking + - Name: Storage + File: cloud-experts-deploying-application-storage --- Name: Getting started Dir: rosa_getting_started diff --git a/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-storage.adoc b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-storage.adoc new file mode 100644 index 000000000000..b62595871ae2 --- /dev/null +++ b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-storage.adoc @@ -0,0 +1,121 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cloud-experts-deploying-application-storage"] += Tutorial: Persistent volumes for cluster storage +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: cloud-experts-deploying-application-storage + +toc::[] + +//rosaworkshop.io content metadata +//Brought into ROSA product docs 2024-04-30 + +{rosa-classic-first} and Red Hat OpenShift Service on AWS (ROSA) support storing persistent volumes with either link:https://aws.amazon.com/ebs/[Amazon Web Services (AWS) Elastic Block Store (EBS)] or link:https://aws.amazon.com/efs/[AWS Elastic File System (EFS)]. + +== Using persistent volumes +Use the following procedures to create a file, store it on a persistent volume in your cluster, and confirm that it still exists after pod failure and re-creation. + +=== Viewing a persistent volume claim +. Navigate to the cluster's OpenShift web console. +. Click *Storage* in the left menu, then click *PersistentVolumeClaims* to see a list of all the persistent volume claims. +. Click a persistence volume claim to see the size, access mode, storage class, and other additional claim details. ++ +[NOTE] +==== +The access mode is `ReadWriteOnce` (RWO). This means that the volume can only be mounted to one node and the pod or pods can read and write to the volume. +==== + +=== Storing your file + +. In the OSToy app console, click *Persistent Storage* in the left menu. +. In the *Filename* box, enter a file name with a `.txt` extension, for example `test-pv.txt`. +. In the *File contents* box, enter a sentence of text, for example `OpenShift is the greatest thing since sliced bread!`. +. Click *Create file*. ++ +image::cloud-experts-storage-ostoy-createfile.png[] ++ +.Verification +. Scroll to *Existing files* on the OSToy app console. +. Click the file you created to see the file name and contents. ++ +image::cloud-experts-storage-ostoy-viewfile.png[] + +=== Crashing the pod + +. On the OSToy app console, click *Home* in the left menu. +. Click *Crash pod*. + +=== Confirming persistent storage + +. Wait for the pod to re-create. +. On the OSToy app console, click *Persistent Storage* in the left menu. +. Find the file you created, and open it to view and confirm the contents. ++ +image::cloud-experts-storage-ostoy-existingfile.png[] + +.Verification +The deployment YAML file shows that we mounted link:https://github.com/openshift-cs/rosaworkshop/blob/master/rosa-workshop/ostoy/yaml/ostoy-frontend-deployment.yaml#L61[the directory] `/var/demo_files` to our persistent volume claim. + +. Retrieve the name of your front-end pod by running the following command: ++ +[source,terminal] +---- +$ oc get pods +---- ++ +. Start a secure shell (SSH) session in your container by running the following command: ++ +[source,terminal] +---- +$ oc rsh +---- ++ +. Go to the directory by running the following command: ++ +[source,terminal] +---- +$ cd /var/demo_files +---- ++ +. *Optional:* See all the files you created by running the following command: ++ +[source,terminal] +---- +$ ls +---- ++ +. Open the file to view the contents by running the following command: ++ +[source,terminal] +---- +$ cat test-pv.txt +---- ++ +. Verify that the output is the text you entered in the OSToy app console. ++ +.Example terminal +[source,terminal] +---- +$ oc get pods +NAME READY STATUS RESTARTS AGE +ostoy-frontend-5fc8d486dc-wsw24 1/1 Running 0 18m +ostoy-microservice-6cf764974f-hx4qm 1/1 Running 0 18m + +$ oc rsh ostoy-frontend-5fc8d486dc-wsw24 + +$ cd /var/demo_files/ + +$ ls +lost+found test-pv.txt + +$ cat test-pv.txt +OpenShift is the greatest thing since sliced bread! +---- + +=== Ending the session + +* Type `exit` in your terminal to quit the session and return to the CLI. + +[role="_additional-resources"] +== Additional resources +* For more information about persistent volume storage, see xref:../../storage/understanding-persistent-storage.adoc#persistent-volumes_understanding-persistent-storage[Understanding persistent storage]. +* For more information about ROSA storage options, see xref:../../storage/index.adoc#storage-overview[Storage overview]. \ No newline at end of file diff --git a/images/cloud-experts-storage-ostoy-createfile.png b/images/cloud-experts-storage-ostoy-createfile.png new file mode 100644 index 0000000000000000000000000000000000000000..c00ae0660608b4bfd9164ec97372943d3d02aaf6 GIT binary patch literal 21786 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 JPDHLkV1hV$_2U2l literal 0 HcmV?d00001 diff --git a/images/cloud-experts-storage-ostoy-existingfile.png b/images/cloud-experts-storage-ostoy-existingfile.png new file mode 100644 index 0000000000000000000000000000000000000000..30fde8c02b371f1ad3611956fd8587d101e86fc1 GIT binary patch literal 7715 zcmcgxRa9Kfvc@wI972#J48!0ycyJFE2(Cc}7+`|Cgy2CE+}(l(3mV*A0|X~HBsf3r z+|7T^J?E@-pU%sjhgo~NtGd3b-d$gHO{j{pEFKOe4hjkip1hp28VU+37x0__!UDbx zgfT*a0WYMKl#0BR6j;U4&KzltKtW-QHZ?Y8mS<(`gTsxD`-WMVa2(y#LPEmSj9WX~ zhTA&9UB=zujHI`3m&pm2JAFyK8hhG6IUGCwLkh-dOp5atf6gE7LAxXEEUTz|M;Cgf_x`H~9$eyTx+$hU}Ne2FH- zr`awb_C2c_S|cah&ds6wMz+1L?FULOKB)!a7qLfvN*1I-k%WUreQm}?Lv3vf0fdSv zJ#F7U5TFNiF$E?K2xDP+TVVy+{Kg^vOuT|`anmCiVw7fXjR8M?$qD3_41H}^93KVhhFlJ_A|?R#Aswlqns9Sjx^30p?}r zVTVCPall}(u%nr|pqlinf2sq&L?D*V&h~;F9ByuI>~7rbc8(StoB{#@955~pE-p4e zg3Zap)*0^3X6r=zk464>9chG8^$O6xBUN^`M1UY(A536 zCMPfKKQ;ej=AW9v91jlsheQ8}*59K*xI}S;IsO%TQ5x7M zQq8HLHy~_3Xds=RxQ;(q2+iLY_6a5k8O-wU2=l)Ng*?tG1g(X9DGa*~5rmA4(!cz} z>QBX-1uA4LCInl=;vGIMsT#V0Bjftx>0ZA*8X6n67uC;O;;&wwFX$`DdFssx zWJjZ5M~M@X6cTpXSWL+KV#u`-W<~u);D;dx{)4U3=YL0Bi4GMr$C<1fQ8zpGK`*F09Xry3fmg~GTH9WU>`g?n_7%^RD z;J8;at>ErnH+?7Ua`>wf!G#=$3b^hjIXHAb(e87)67jj_vs+|k(JqT?aM>Bq)Hc}I z+R}-{7+~`=!JbW3&+nW5O!fr3$ouw+>-X*XXI6_RZNt|;yFxd2c6Fw8PUi50=tJRot3NC2TC!*g3JnpTQ$w=#G&Ih>#;Ghu^Wj^Aq<+B zYq4)cIZq*{?&mD!Jfc;VmFty*?6GxqFJ~)EgROrYaZY}f-_a^Hn?2g7{BZ3WTBN7R zuG(tjJo9@Xit25vZMyYDWeE9L(6?_ec?E@-nHim}pG6axlUgM@G_o!_^`66&PPkI9 zi$7pvV~^L`%s-xU^CRiSe@$9q)N1IOp9|XlK7KasMua5m8Cr=*g{shFU%c&mw~Z&N zPn)yH{DMudns9yE{v#fj5qs3aYbm@CimDG|6tsh+By;yT75q8bD zwWfCao9S+gOy8GWQ`v50IH__LETJk1*mZPf!8~enfTNhgga#i21Cws!T|zEOK21>H zUC7SXIee)nI+$L+W=@x{mfkIDz3GOY5itqub%l~}{k2svTqY5KMUnj@lOkq=QsTqe z)a*!_<}Bw+%+ zD-1yaNirX!;72P7`nDB=WVNWO$@ypqy2W7p=gha|t&6OY7g`JiV6#SNOY6{?Z|@JD zSnvewS!8&;YWcC^AYp!L)9#P?s_)0Q|}IRvLdxo&vu}xJSsCD$5aKN^5@Wk7b~$u$-zc3TrwL zwWv6*)vvKew$Lhc*b{NbhM>I36ty{$(!$?sQn2-su^5_{!7YZ-nr4;D+ z(R+gy$XJG~GT*EdTPnGs96=pZ9=l08eK%j0E+TDMa4F=&eQY7Nm5Sjd(^eWX^h5}pQr4U@JU>0|R@0LRff&%E3i=2!AxP>3$KbqiGr@t=iHDz898Ow7!)%wjt2|+-X;c}x2qYzf?QgPc~ zs6U!9jeN3=rK*xC`eEJ4AfZC{*to8!;?O0ZevFgqD*scO*ziCV&AEnN(5%K_nv}j( z<|$IfG;et59f6p9RyF8CsqY(jQelBs_pX_};KKdRi(6wG$UWJ&rTK$UtY2PL23Vbg zG%2Hc#ZpYHscq~2h@|e5Jl^IDlQsO%59?o#IKGOwjojaNOQ=8h*PoIK{zD$~6tNFu z8F(5QEB=kh-fA~cCO=7l^^eQZPo@c<_3EBTYP*;pNe-zciq!k#W+J%t9MU>vyKz%K zCu6dRY*C+3UW){Q?#_W&nXThwn6P@Ni$2Wac~xfse+gbypy|&)WAr$IMkjm48onhrSU(#B6^@mRZD?m3L4U_qwFdyl)5ux3c~CSgP21J<^o_=c;O|RA2FH z8A;U?0*;MlE)CzC|IUBMX*zvy-ukp8tJi;q$=HSGYszBAk#Wq5q_=HO(Xi?jx9PXE zw^wJpOP@WfZpgIQeXi4%h@PyX-WXnWp^t=P_ACe43}NY4wE~-1!Y2F*t^G9^s&a3n zi2M6+1`h)(@=?9sD%?+2ATHSQ$~2!y3Sm|2lJ-hMhs@*_8aavO<85LYUH~R6dUE#O zd>?jf@g6uF3Msz&QiCzp&oKJyH;cbH>8l#S5ep(`odjY@7DD>lb9{dgv{~5j_hStdzn-B&>|sD1bFJmT8y!e{~WA z>LYBDLyw4(!1;s3iS$VdiS_Jn`MC9h!U>2_a&OhOz3+>aPCnj9l=K)B>^d2+v6GqY zX~&z7(WxB=pCpE&nj)u{7JA=ckIDIBpnXR9$oj49k-iifbQu*DpH0NKhZ(4^{A7G3 z$#kXzN@-Au4}DQS4xw9?NTNXrbubvs{9Ht4D2c(S1R#|@;r~XQ^s)qzf0qOa2Z}X} z8~H4SjRC`Y4z<2RF_#HoM6N9pgX<)*pqUe&tvS250f2!j0l*+k^a}?AFoFOWRGuY@ z01QF^2C4(a32f%3h{}&gpC#|GSw%Bk!6R@kRUNK@Re(~Z?T-@1X zBLf$Cd(KOIy`Zqg&CLX!I~j@*ah#XcN6%ri#=yp4@q_s2jLk=|EqY4|(n)*lY&KmT z>IyNx*6XT2FOC`Yu9A(&97yPPtBrFnr3Te{X*c9%2vUKR;8b#8OY92~$nm4(7Y8;` zGR)>>te1b7X1{W1*V^wmP>i!HH!x_$n^)|IX0iAz$N~`~$M9F{!;v~aSry^hnr~+R zoHi`L5DiC^4YFSkq(fCQKo=h@lc_i1O4S7S?x|k28+B=dskAn0#eH!t;koL~3o912 zpN2DA7umR{pC!bt>5hZ*V-}|CYlVN%8Pa>zC@x-ZWjS0fGYFY2Br*WxCQ!nek;DThcN<4!%J`?fK+FbOi*p(ZOaaErhD4vT*Ox%m*z2?p{kN^J+ z@C?Cw(`K*xf~i+ShPo|AhB^(}`2?1%;l;8^G*J4-V33`+kW!Rk1fv4yjpOsiEQ5j^U?C zP?dDd|2+1$&vYAE=@M^fvR;-88GpShNMgpQ&}(ZK^rox9J0_^~SW zhp(n}%4sxwH)W%>w{i)w3{{REsTS7^Z(_B2ODp+KCa6Dwww{C_gnUOj*kGB1Svam! z@iC>Ce47*+UCQN%YTl0 zZeBh-T%g+hiW|4mjpRx*CSwSkEm|i$tYf0RMoFUt9xoXDTV|!Ox^R+M9|DP8Aad_ zUth{N%phu%lm}k2tm4VLHuZSbs&8(ui^p7bN_Vm5>(wM~#2BUh(^7{$|$HZxYd>tX)9?EcVlc7ETsX9tZuQc>7b<;MQ zW%0H#T4oY8%s}hi)t(CooRV5{45~Z(hh*3pStoU6RS1t>ti*&0IC*`k) z>D~_A2Hn!Q#_1YZSaSBGM(?MdyOTmX&L~AT%Pl5f- zb!Fg?k?81c^vWV;<<^`XD8JY%yZG3V8avJfjbdxd(52#M;83wv6&GMH8M0g&Met-x4;{i_ADStMvga$Px$%>j~tdjsTcnQFH z?VcMmwgBg)0#x{_9S`Vs7}EjWjwzO2SKxJ<0VMcvY#;g}EI?o6o1s8$D!{7r;xtvN z_5nZ#MdzV|ayn4)3&<3Fs5r^t{#3wIy8=M6CE5{t^r*z&010c-1%PfrT4xN^Pg3<#WL@O}Fjb!7R2wT@mGL1R`ZJySpl~YCQ>31|0B@@%@fU5}Y96F*|Ds zU}OLc#A1E_dj@cbk%Ni~aA+ASPUAGb%m;X{^5Fdj!t@Iuk_JFmrd$9JfD{0`Sxwf~ zJb;Z@z)$&rc>tt@JODB-F+3a)u?G|dkoJIYV8#cJjw&n001;&%f(&@JKp-&a0QXf4 z`S?-*_W{Mt+;*FX&JbYx@xWluD?sEWpqR!}2OuJh!%&d!BeN5up(02>5diyKvMEb( zkFNL0Qbi1emh7&Qejjw#8+C1a2=`-9Tu9WZyIlaQ8s~A%<)EFzT)n4J5N=YHF1~ph zld?l&Si!0FqlW<2`HF{vW-%=`@PS|uAJX_mom5vleY`y09!r`=rc{Ni#N zhRX|N(BYXd_kT#Y8bmi(MRaI4;+*K~7^O5f=-Jv(F$}upC4-3eC>H3o?p$rqLko2z z?#_ORCO0{kTR)#v&gqb{(Vn>%BUQ{6v$6g!kiX+K{`Q$QW>b>#!K;C8a$%v9z1ZgLm!o`1m+1HLkj_;headXh zY}MiAsS09Z$as-qoUo^ifw~rtrPIdKQ0EX??_z2aTZrVYPo4hrWG@>j_4S?v-druS zB;0%VM&zi=Q*9E^GYCwv4_q5UPQ8`jW?MR&=N-2$zVfq7&Cg1Ww!?bOX2pgr_tMJB z>`!n%{Z&WB^ffeP?c*dj=EW=EoDre6;^<1S>E%la%{=Yz#pI4m(8MkVi|q}=j1H#d zO0TQ&)IN+yj#sIMIZx31Hh8|8t0&#A2UIP2qeD>Lgc$RndXDX=O5`wzHn+A@l8>_3ez>J5bV1ndGtsEcm$`X}o*eHB z2=MCrw_Uo`JdIc=N=c8^r@VxPBqFrm@dP$K!JWVEb%hC3QlIAzx(|Pb7uN5rDAI`z zoT}`)4!6QDQkEc{-otJiVnJz7kK8PdC^0#Ub@OtXn!GZ_1F6V&#J8x(w;l_;6)Fhjv8 zu*z7@dhOjhqaAna(*I&@=V>~;OT~HSzBcvQ^eNlB8O?*?!TIJElh)+iLX2+B0Pz(} zE0xli%e1p&npv;)xc*@{WM%GNF=miB$IN8(itB#LJjOv#_PU}wj;%1`L)1g|e?fG( zQ<66c0d@Qtb)}@C1S+%S+fKX)1a`AioEC-tUe+`@5X^tLUQOjRVf{a`xLa( zgKuf3DI5Hm98E7MdUl^gHzsS4EA6^;O;<4YwfflS$)D zjC@L0N=O@lbF}ld#K{O=l{w-#Vxzs+wk~Z}_a1_knK9*58~ngU^%&lGY;u7Qw^;u; z@lY8vzcz~?QMw<(2V>ddmIU+S!0uC_(IwCxD>-d_#E{EkB|hYn?a4;y-V_^W%4MYy zWktnTJs#NykN}j#@>x6n1H{kqm9M1M2>Z)MMKnY-%EuB`L(Q{Li~$OO$^;shciFMy zWB_KYbl03^AZD}x_;O>{zp4?cLIyC|z^W$Vzg`%)e)jav7mN>5ym3tgP?CaR5Ejfo z!gK)f+5wAt4aP14E-Lr|U`Vr$;{eZFfNJBI?TsgJ#27IFG-|#h>Oe7YkpS@Yci}DI zVh^mM(x-qb_(mQGfVID4g54i4|H?g`F zK|^i*EJJOhEZuo2=@7^wE$QN2{SJ(eI_-5%gt07tsz80b{a9-mu$=CbY;RK*WTwo) zogzQVwvOwDlk(`;TU2P-T38r7e$#zV zNWi(&+F~(H{>|r}JLoDxLYx-LN7QT`jBRIeh2q0gxE-tWBW-PxJJ;8vON4~mnS_Kv zU$3vP{m-wjgVOE{w_;D66JdM_H+^_mg5L<(GTTw#$kXVVhNQKd3&_&O&B_+!g-QCzu>LI}3Eba2=4WO3Tg1~zhSlhqHj9#*hb@Z;NEjr* zDvQs;!XoWqV<)NmSmod9fF#4};OXfu$YW|Nm|JIb|zfs_SD0FMBzfS>k$>K}%|Ht&Q_~a>s2N)R4s_Ksw^nLE^WaIop zDMHg5nrDSmX{cWjtv90fSRU)<%G1Oh(&a$wiz?sB zZRBs4b(Kl)kO9{x9!y<`*K^1~Dejxsz(tw1dGiPNjl3z@+vP7M%er>AwF(gWIJfO> zM!%*sG^I)t;=yEP0j};sNo_dR)!7OO*m3+3*s2Tn=;CPfr|DJyeuCVULyqq%9ju=% zEu9W*H-Q4{vwnZpkE$M(1(V2KRPZIWUi~Q{Pbd}#vyO3p^r4Ky)sJhtOCoI%LCpB_ z`__+=v}ub_qA#i526)-b(i<{`&!LDrT}E?chIy-nx6>|Q;}A#D~I9Rx|5xmEVeYr_*Gd&2fpt{ z(kjo_CUO-C%Z@PjTs-z)ooU$AMs3bj{p?qtt4^-3&fSj2lt}2<8HQv|XNyegTvr!@ zu0`Bh&_x-NUSH7rog_p_J=hHE9Yrg@0Z@ z`C({Yvq9#bA5JaA;PTJA=HmMx23JIWV3FMQ#rK}dS&zXCpvc@V$K^`KQd<|3O=UMV zxXidlC^z6xeVgxeA*eOOI$q+iTu0Tw%oo)JlXRfRmo3^m`jMvaMEvk1sxTY}wLV5Oom!~^NS*X$z9`2(ms2yt)6Hh{8q z#~n(deauFm(&wH@EpnYh+>bAxz4e*|7vbH|)0F5ob_EGAW&x8w$GGZZ?!QwbU8pQ$ z~$RFFaGp@V3i0-n`!q8ZHkpV(x zS?Q*TtWRzWEt4XmqtZv|z~-E4c*o@X>zx4MF0bD~i*j&yaLw|sicVtijB|CISNl?Q z2P%RfabCt%EzCzPH)7tciNE#2BlMh5;@4ZHA$q4$%hNeI-ps-@GbCeb^D!Stj{I=$ zvmVD5y$wJbonr+i%Co0v0k@I2OV)XG-$ckY}BypHt;AP*vkkc*5c0g>6yZJ4lo%!QIQcP@X>R|7A-?gR+0j@NHm1nAqUdePqHgDpRpj?s| zCN4E8GDYBErwJ}TUTaRJf7f*(h;7RA!(`{#E?PMAjQ?&uhxFri!B?q;+rT=$XS;=^9G(&t z%OrzrI$Ms}ONKzi%63KAH(UottBG3JknF{<&1y+UYzdwTpNtjas0| z8M0Vg|Cmq>J*Yb#SSDXcQZPg`gjaCck)_Uoz)tX3D`*hSry)Ip9BAl=G zxOL_5g$FbE?EUgG8a?S6!&i&@@t3vJwSRq&W-!S^P(`SfE#dH9#Xb=ONVk7TSw7ln zm0L?DPL*Yoo>%yMxRK8-Z91q0)kW!H$1pC?y5B)?lEumHA}}{c6A$G$Bzjjpbg|`l z8uRSco1W0bp(i?jMk#Hh{F4vl4K`J22M?)e4APT!>K0^cvL@&BMp6&d%pJ*a25Kn9 zpb{IKIhzzfC?X3hG-AUH7(}%UTUoW`M>1uq4bd!n|7on*~mbrExVQ zR_oq)qB-Y6yF9Kk?1h2oETX;%?_z{|_XlCz-c#p`$@HXkN*}oFAm8?jorl~;p$Jks zo}mHqxT5@(O^UJ7j!m#(^mEp>I&n=0wQBlvDD;m>%MU9JhvIDSszKHR%YP`YrP$%+ zlXU^<=i^WL!>4Ts`MEi{g5u=GjvIW{dj-Bd)Al9{|>Cka?j&Pl~{MSm*)CjAW zO~5i@=@vOkF3fqP*ybicm&9%RtVvCujd8qMHCW=H_1a_YW#Ch#y@VAs?`6}u-mH#M z0Ai;RZ^c05U~kka_c`djS0C-dw0*9NoTEkTH$1(S%ka24Uze>UATA3`&GNWpz5`KE z?>M6zk515y17jiP~1Sv*ZxFxQMq z0c*=b3970Nr3eOvG8Vs-ln=xZVD}$BE0yX)242x>nzb!1UY;(9DMb}SN4bpPQJ*J&-JfoWxexC zY2cFgUfp=LeS-)QWlZgIX5;#Ym<}VfLwdJSHd`BZGIKQ{U88~}S%k_23GCN9)d-MW z(YR{sU8M))IIYdynNdI(8t1!Pzc!SlB}-S-yqf8h*&d1`c9uce6DqzJR>{ilKQ?t3 zP@4PZc-%=^^o|DNp-(8q@Ut(*^ZS>@#y@Oq zB0K>vT?qcpC?fwlmu6{Y_E8k5KWrzB`8Ebq?sCZV2!buG4>sv#QF#{V$N6IeI}cT21ui5kFT3N!=BF5ueAJNqg_#ax zew)Bm<)YANatFHf?NIK_5LTLCd{PT_)>l8ocIyfq`eqY28Vb;_(@FFznJOwO;t>lp zyVeJgqUU=+C`UwXW4p>i&_Ir3ZSlKnrKfSd&^lYNW%aA#UU7HwAK=to&}2N7oA9z! zvj&1Lc%-dc>-CjC>~s!3b6)9sMn^8o+f#T71i+~77*x#((#hoMJ=Aitx>;V>-JX;S zw-I;jKcKmF7o#GzT#L_~*VQ4ykcuaPY+a+tXJECDj?ke~IHxnON0{5b(Pd}dnD%(s zO42=qayVN_KppINLwt#8V7j8nYXK|-&rmmt0q=O&u_)k$*s`2*T18gjpq#EZIL?U15u`Zg`^h* zcSmBXaGkF_1-YdlJ7VIM@`ZW&3&&vX;SIrw9|J1Wxf1@Fw9iL)@i73iKkcs1%c`A( zh0j%zB9~Snq8%>`IrTUSt`)JxvrKa>O#2Cs{S}{9#0MW!yk|P`UVuo zhH(3yPYvNi68?hYv8H@<$^27oG|dg7*{J|h1{H$I@CI2ovjJDuoR)XUe>1${SU>{v zxXYB^km-aJ;930m6;S3kB{S&&$^`@jS7_;n&?>vAo3;Ugc z*-8y>d&fPZZRuw@E<5@yt2h@QX)24~ELhf?~>;Ve{usGm-$ zc1z_3xPWnC<68{c%q2D9he$$=JHUnW0T)PI~Aa2jV}2> z6Om!nkC@bLomRp4m?QOCK zF2>BS&hq)@oXYEan$W9R*iZe|$MRR3Pv@OTS2s((iuN)GHRW3Yz%aVxMPCUV{bJIZ zjYojf%6bZ_f8??svb21NvG+hJg0ksrDu0iRp7o(rz}bG{76ihy?#T$Bg{}hRu0Euh zYMYg=_Kx7fqmxYazU9@Qt*@*PO8n6P9|>@h4TQqEG!y6B5fzT3%|KwY3Ut6v|6VlY zu%vd@y_3jpxhu-Ie;0_80c^Jt7FFJ(Y<<@ABZr2?7M!VH*pPt%atHU`hZV$=*>n{9>3JUgS^%0 zOfr7yJmrXvlO}h@n@GCod5J;9g4wj+R@pExBnO`*_g;wiwC&`F7cV~-4l(&}TYmk% zHRn<{H>ASgVgnp`OeGreGABmWQ&ur_8oMb5#{K&tEIP_Z6M9;7$?MM5!*=nqe;kw^ zhTfpWi8LtnhH*<9Hou%)%)u92TD* zc2R7pYPP8RUK2Ve(}rfgwlJh)@$@-5a@fgx?(8Q!ms-Shte=qibZ`^Bfs(4?Ae92S2*K*z?jk?yNT6yxx>1*@kY|!XR7>-3Qk4Ozl!ZlBQ6Wb5+!ia1M|| zn>1cBEqdj(InmFqgckqWb2!NFMr~vftk@s<^OLoGZeVSO*W?QqlYiRpF-$p)%3U}4 zZddm5j;b>GcD3B~d`p-5#;F()b&4^__ySk{F5HG&h}(<5j* zkbEDd;tSAww&fLOVe-~=wSBxWXA)r5UbB^eybGAz#lF%mV9`xwfjLXoA$otGc-Nfhba5g1N2?RqPN`Jmq=oO^l z6k^Ebfg?-W;v83w7dQ@;az6hAxeY^O;?+MU;KQQ^^xu?=DUgsle)|wUH~!Q+MESKy zE#U1l4pw?+<|&(1*kNPm(2&7$_}=`!Cf{aZ~trZs|X_q9H@Z9`98r?TaRELD7i3&>e z;99I6Ql7$)M(rcIg%C`Xt=&+% zcnG+Y!a1SzI1?Wrtt&RjSN9%|-pT2pyl&plZY55v){^^}zkK(df$p>iU-@p~(m=Bg zuv0nr5Py{KLwy&eQ-xDOW_P=MSqDDz0L%JodvwqEoagsvJK`|iSI$=RtqAuCk{-Vb zk57g-F;c0B8d{H|vaP}lFD6Ax+Q;QnwOU#mn3R*G(R`cPdf!OdCul@s?Y>E*FB4V? zT}gaxtTanF?Yl^_hbmL>;7S=JN0?}Q6LiS@Jwuj#97Amd*}6GXa5QH*a9}U6hnT#* zln+H((;Lt;;P-NYXYmxi4w~6N{n(XD5!Cdu1-)8bEVz;F@e7Lzzm7Es@i8Pv_Y>m6 zKO`q3rk1@Hap<0={aFW7LkQ{`?IDDV(@UjN{!u&D31WPPH0^!3E4ckp7s zg*pcekId|H_$nfHd~l92e&!6Cn?0IW7;6;CmV(#rYQd59x$YEl`)zk8pNsqbcIY&> zP)1l}xLx}F`q`|AhdxC#q(wME-lHZ{5YnV_UYIm?`hXRakDrOn*`yG;3PF5183(3m zD4)?o!Q!Sb8vQ@0=Tprp&klFB4cEJzddwiH& zNGbS$Ku0#TgyMl_uGrpVecCE_e6ZiMUNjcBm4|jPCdJI3CazyV7IOHcl#WN?Q-H?v zV#^OW(b(ZwMO8HgoECoT`koz>ibqbsdpM!Es?+8RFn8IMR2vCimk?%y7&WC)!oNPGpp z1Q6Njk-5!+vCHL6v>f_AkxcNE>R~y>9rOa<9ex;lY6KRQOXT0dowe8%_#p}+`RvO3 zKwAP5)iT?Vm@FbmEL`eZ`^Y*(O~MO%Hx|6C3|)Eo?N8NmG>pU34r&Yh$JT;||SID1mt9Djp=v$DlWdL`X0J}zUjOHUIjMhtcMg_U@M=G8}pN^Ua zC!Y6+WtRe(chOgp2gz)E$^6nBPvV^tmjSCm-|_0bA(8k+D&_F>fzb1r;|>W~06tx? zJGbG{1WA`S-vUgWE5ox%0Pfs>;vNF$PSTyYUKtA4 zQXmEWU2|EUteu~B;h%Eq0oSoS1@E@^J!w&NEne|I;!%-oi|kBiqcnBQX^{x`@?Ake z&d<*E{N)-0OHUx`Ug7FIMq94*0Rq%^TNFvLZxPb&IZ=XL>gX|}kJ?lvuJ)Gr6r<%T)6Bm{OSum^Pux<*5LZt(1C` zltvLN;i|j2h)qO(;y`rTm0kCUfn6a zse3FtIC~m{UcS%k$Ol8Mob|S8`47mknRa8+N&=a zKI0MH>sJm>`X_}ehSwb51H$$8K70H>PyY)mjLv@7@ zm45Q@bDWx$g8k?F>dV@kz?u(Velh^h_w+1#5FBj`AxZ+*_Qo;Oe1D-kgGGC4;T%jC z9(%1;^?;@P2BpEw!I>3^G}))V(vHuC%|XqFaOIggRk!l(JG7e3g2 Date: Wed, 5 Jun 2024 15:47:28 -0400 Subject: [PATCH 220/339] [OCPBUGS-32109]: Clarify availability of virtualization platform in HCP overview --- modules/hosted-control-planes-overview.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hosted-control-planes-overview.adoc b/modules/hosted-control-planes-overview.adoc index 515e5c1501b0..51ebbe3675ef 100644 --- a/modules/hosted-control-planes-overview.adoc +++ b/modules/hosted-control-planes-overview.adoc @@ -13,7 +13,7 @@ You can use {hcp} for Red Hat {product-title} to reduce management costs, optimi {hcp-capital} is available by using the link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.9/html/clusters/cluster_mce_overview#cluster_mce_overview[{mce} version 2.0 or later] on the following platforms: * Bare metal by using the Agent provider -* {VirtProductName} +* {VirtProductName}, as a Generally Available feature in connected environments and a Technology Preview feature in disconnected environments * {aws-first}, as a Technology Preview feature * {ibm-z-title}, as a Technology Preview feature * {ibm-power-title}, as a Technology Preview feature From 982ee2aaa0490d2fe40275c8ef488decadb7746e Mon Sep 17 00:00:00 2001 From: Ben Scott Date: Fri, 7 Jun 2024 14:26:41 -0400 Subject: [PATCH 221/339] OSDOCS-10717 adding ca-west-1 region to AWS docs --- modules/installation-aws-regions.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/installation-aws-regions.adoc b/modules/installation-aws-regions.adoc index afc349204c7b..d5f83ae47323 100644 --- a/modules/installation-aws-regions.adoc +++ b/modules/installation-aws-regions.adoc @@ -29,6 +29,7 @@ The following AWS public regions are supported: * `ap-southeast-3` (Jakarta) * `ap-southeast-4` (Melbourne) * `ca-central-1` (Central) +* `ca-west-1` (Calgary) * `eu-central-1` (Frankfurt) * `eu-central-2` (Zurich) * `eu-north-1` (Stockholm) From 342986dbb34c11fc869a6667143faa9ad351ed0c Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Tue, 18 Jun 2024 10:07:34 +0100 Subject: [PATCH 222/339] Adding description for image --- modules/nw-sriov-about-qinq.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/nw-sriov-about-qinq.adoc b/modules/nw-sriov-about-qinq.adoc index d75393439417..af94f031f68a 100644 --- a/modules/nw-sriov-about-qinq.adoc +++ b/modules/nw-sriov-about-qinq.adoc @@ -11,7 +11,13 @@ In traditional VLAN setups, frames typically contain a single VLAN tag, such as QinQ facilitates the creation of nested VLANs by using double VLAN tagging, enabling finer segmentation and isolation of traffic within a network environment. This approach is particularly valuable in service provider networks where you need to deliver VLAN-based services to multiple customers over a common infrastructure, while ensuring separation and isolation of traffic. -image::693_OpenShift_QinQ_SR-IOV_CNI_0624.png[QinQ] +The following diagram illustrates how {product-title} can use SR-IOV and QinQ to achieve advanced network segmentation and isolation for containerized workloads. + +The diagram shows how double VLAN tagging (QinQ) works in a worker node with SR-IOV support. The SR-IOV virtual function (VF) located in the pod namespace, `ext0` is configured by the SR-IOV Container Network Interface (CNI) with a VLAN ID and VLAN protocol. This corresponds to the S-tag. Inside the pod, the VLAN CNI creates a subinterface using the primary interface `ext0`. This subinterface adds an internal VLAN ID using the 802.1Q protocol, which corresponds to the C-tag. + +This demonstrates how QinQ enables finer traffic segmentation and isolation within the network. The Ethernet frame structure is detailed on the right, highlighting the inclusion of both VLAN tags, EtherType, IP, TCP, and Payload sections. QinQ facilitates the delivery of VLAN-based services to multiple customers over a shared infrastructure while ensuring traffic separation and isolation. + +image::693_OpenShift_QinQ_SR-IOV_CNI_0624.png[alt="Diagram showing QinQ (double VLAN tagging)"] The {product-title} SR-IOV solution already supports setting the VLAN protocol on the `SriovNetwork` custom resource (CR). The virtual function (VF) can use this protocol to set the VLAN tag, also known as the outer tag. Pods can then use the VLAN CNI plugin to configure the inner tag. From 9aaaf72aa66c2a53b7d2568bdcd190c67015acfd Mon Sep 17 00:00:00 2001 From: mapandya Date: Tue, 18 Jun 2024 10:35:56 -0400 Subject: [PATCH 223/339] Moving egress firewall; Renaming network security --- _topic_maps/_topic_map.yml | 6 +++--- .../configuring-egress-firewall-ovn.adoc | 0 networking/network_security/logging-network-security.adoc | 2 +- .../about-ovn-kubernetes.adoc | 2 +- .../migrate-from-openshift-sdn.adoc | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename networking/network_security/{ => egress_firewall}/configuring-egress-firewall-ovn.adoc (100%) diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 39a3a51ed9be..b49cc860aab6 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1272,7 +1272,7 @@ Topics: File: accessing-hosts - Name: Networking dashboards File: networking-dashboards -- Name: OpenShift network security +- Name: Network security Dir: network_security Distros: openshift-enterprise,openshift-origin Topics: @@ -1320,8 +1320,8 @@ Topics: File: editing-egress-firewall-ovn - Name: Removing an egress firewall from a project File: removing-egress-firewall-ovn - - Name: Configuring an egress firewall for a project - File: configuring-egress-firewall-ovn + - Name: Configuring an egress firewall for a project + File: configuring-egress-firewall-ovn - Name: Configuring IPsec encryption File: configuring-ipsec-ovn - Name: Understanding the Cluster Network Operator diff --git a/networking/network_security/configuring-egress-firewall-ovn.adoc b/networking/network_security/egress_firewall/configuring-egress-firewall-ovn.adoc similarity index 100% rename from networking/network_security/configuring-egress-firewall-ovn.adoc rename to networking/network_security/egress_firewall/configuring-egress-firewall-ovn.adoc diff --git a/networking/network_security/logging-network-security.adoc b/networking/network_security/logging-network-security.adoc index f5e8d2b992b5..9edea938d43b 100644 --- a/networking/network_security/logging-network-security.adoc +++ b/networking/network_security/logging-network-security.adoc @@ -34,4 +34,4 @@ include::modules/nw-networkpolicy-audit-disable.adoc[leveloffset=+1] == Additional resources * xref:../../networking/network_security/network_policy/about-network-policy.adoc#about-network-policy[About network policy] -* xref:../../networking/network_security/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] +* xref:../../networking/network_security/egress_firewall/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] diff --git a/networking/ovn_kubernetes_network_provider/about-ovn-kubernetes.adoc b/networking/ovn_kubernetes_network_provider/about-ovn-kubernetes.adoc index 2366d9a28447..48032ca52d4a 100644 --- a/networking/ovn_kubernetes_network_provider/about-ovn-kubernetes.adoc +++ b/networking/ovn_kubernetes_network_provider/about-ovn-kubernetes.adoc @@ -46,7 +46,7 @@ include::modules/nw-ovn-kubernetes-session-affinity.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* xref:../../networking/network_security/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] +* xref:../../networking/network_security/egress_firewall/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] * xref:../../networking/network_security/network_policy/about-network-policy.adoc#about-network-policy[About network policy] * xref:../../networking/network_security/logging-network-security.adoc#logging-network-security[Logging network policy events] * xref:../../networking/ovn_kubernetes_network_provider/enabling-multicast.adoc#nw-ovn-kubernetes-enabling-multicast[Enabling multicast for a project] diff --git a/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc b/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc index 47006d1caee0..34819aef791c 100644 --- a/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc +++ b/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc @@ -32,7 +32,7 @@ include::modules/live-migration-metrics-information.adoc[leveloffset=+3] * xref:../../networking/changing-cluster-network-mtu.adoc#mtu-value-selection_changing-cluster-network-mtu[MTU value selection] * OVN-Kubernetes capabilities - xref:../../networking/ovn_kubernetes_network_provider/configuring-egress-ips-ovn.adoc#configuring-egress-ips-ovn[Configuring an egress IP address] -- xref:../../networking/network_security/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] +- xref:../../networking/network_security/egress_firewall/configuring-egress-firewall-ovn.adoc#configuring-egress-firewall-ovn[Configuring an egress firewall for a project] - xref:../../networking/ovn_kubernetes_network_provider/enabling-multicast.adoc#nw-ovn-kubernetes-enabling-multicast[Enabling multicast for a project] * OpenShift SDN capabilities - xref:../../networking/openshift_sdn/assigning-egress-ips.adoc#assigning-egress-ips[Configuring egress IPs for a project] From 1be3b76f77d435048335702c252623dac7edcbf1 Mon Sep 17 00:00:00 2001 From: Jason Boxman Date: Tue, 14 May 2024 14:16:58 -0400 Subject: [PATCH 224/339] OSDOCS-8766: Add configurable connectivity check - https://issues.redhat.com/browse/OSDOCS-8766 --- ...od-network-connectivity-configuration.adoc | 47 +++++++++++++++++++ ...d-network-connectivity-implementation.adoc | 25 ++++++++++ .../nw-pod-network-connectivity-verify.adoc | 23 ++++++++- .../verifying-connectivity-endpoint.adoc | 1 + 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 modules/nw-pod-network-connectivity-configuration.adoc diff --git a/modules/nw-pod-network-connectivity-configuration.adoc b/modules/nw-pod-network-connectivity-configuration.adoc new file mode 100644 index 000000000000..3e02c669801b --- /dev/null +++ b/modules/nw-pod-network-connectivity-configuration.adoc @@ -0,0 +1,47 @@ +// Module included in the following assemblies: +// +// * networking/verifying-connectivity-endpoint.adoc + +[id="nw-pod-network-connectivity-configuration_{context}"] += Configuring pod connectivity check placement + +As a cluster administrator, you can configure which nodes the connectivity check pods run by modifying the `network.config.openshift.io` object named `cluster`. + +.Prerequisites + +* Install the {oc-first}. + +.Procedure + +. To edit the connectivity check configuration, enter the following command: ++ +[source,terminal] +---- +$ oc edit network.config.openshift.io cluster +---- + +. In the text editor, update the `networkDiagnostics` stanza to specify the node selectors that you want for the source and target pods. + +. To commit your changes, save your changes and exit the text editor. + +.Verification + +To verify that the source and target pods are running on the intended nodes, enter the following command: + +[source,terminal] +---- +$ oc get pods -n openshift-network-diagnostics -o wide +---- + +.Example output +[source,text] +---- +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +network-check-source-84c69dbd6b-p8f7n 1/1 Running 0 9h 10.131.0.8 ip-10-0-40-197.us-east-2.compute.internal +network-check-target-46pct 1/1 Running 0 9h 10.131.0.6 ip-10-0-40-197.us-east-2.compute.internal +network-check-target-8kwgf 1/1 Running 0 9h 10.128.2.4 ip-10-0-95-74.us-east-2.compute.internal +network-check-target-jc6n7 1/1 Running 0 9h 10.129.2.4 ip-10-0-21-151.us-east-2.compute.internal +network-check-target-lvwnn 1/1 Running 0 9h 10.128.0.7 ip-10-0-17-129.us-east-2.compute.internal +network-check-target-nslvj 1/1 Running 0 9h 10.130.0.7 ip-10-0-89-148.us-east-2.compute.internal +network-check-target-z2sfx 1/1 Running 0 9h 10.129.0.4 ip-10-0-60-253.us-east-2.compute.internal +---- diff --git a/modules/nw-pod-network-connectivity-implementation.adoc b/modules/nw-pod-network-connectivity-implementation.adoc index 66c86af6a9d3..3114e356ce3b 100644 --- a/modules/nw-pod-network-connectivity-implementation.adoc +++ b/modules/nw-pod-network-connectivity-implementation.adoc @@ -12,3 +12,28 @@ The Cluster Network Operator (CNO) deploys several resources to the cluster to s Health check source:: This program deploys in a single pod replica set managed by a `Deployment` object. The program consumes `PodNetworkConnectivity` objects and connects to the `spec.targetEndpoint` specified in each object. Health check target:: A pod deployed as part of a daemon set on every node in the cluster. The pod listens for inbound health checks. The presence of this pod on every node allows for the testing of connectivity to each node. + +You can configure the nodes which network connectivity sources and targets run on with a node selector. Additionally, you can specify permissible _tolerations_ for source and target pods. The configuration is defined in the singleton `cluster` custom resource of the `Network` API in the `config.openshift.io/v1` API group. + +Pod scheduling occurs after you have updated the configuration. Therefore, you must apply node labels that you intend to use in your selectors before updating the configuration. Labels applied after updating your network connectivity check pod placement are ignored. + +Refer to the default configuration in the following YAML: + +.Default configuration for connectivity source and target pods +[source,yaml] +---- +apiVersion: config.openshift.io/v1 +kind: Network +metadata: + name: cluster +spec: + # ... + networkDiagnostics: <1> + mode: "" <2> + sourcePlacement: {} <3> + targetPlacement: {} <4> +---- +<1> Specifies the network diagnostics configuration. If a value is not specified or an empty object is specified, and `spec.disableNetworkDiagnostics=true` is set in the `network.operator.openshift.io` custom resource named `cluster`, network diagnostics are disabled. If set, this value overrides `spec.disableNetworkDiagnostics=true`. +<2> Specifies the diagnostics mode. The value can be the empty string, `All`, or `Disabled`. The empty string is equivalent to specifying `All`. +<3> Optional: Specifies a selector for connectivity check source pods. +<4> Optional: Specifies a selector for connectivity check target pods. diff --git a/modules/nw-pod-network-connectivity-verify.adoc b/modules/nw-pod-network-connectivity-verify.adoc index ed47b4432cf4..8a85a15ecbea 100644 --- a/modules/nw-pod-network-connectivity-verify.adoc +++ b/modules/nw-pod-network-connectivity-verify.adoc @@ -6,7 +6,7 @@ [id="nw-pod-network-connectivity-verify_{context}"] = Verifying network connectivity for an endpoint -As a cluster administrator, you can verify the connectivity of an endpoint, such as an API server, load balancer, service, or pod. +As a cluster administrator, you can verify the connectivity of an endpoint, such as an API server, load balancer, service, or pod, and verify that network diagnostics is enabled. .Prerequisites @@ -15,6 +15,27 @@ As a cluster administrator, you can verify the connectivity of an endpoint, such .Procedure +. To confirm that network diagnostics are enabled, enter the following command: ++ +[source,terminal] +---- +$ oc get network.config.openshift.io cluster -o yaml +---- ++ +.Example output +[source,text] +---- + # ... + status: + # ... + conditions: + - lastTransitionTime: "2024-05-27T08:28:39Z" + message: "" + reason: AsExpected + status: "True" + type: NetworkDiagnosticsAvailable +---- + . To list the current `PodNetworkConnectivityCheck` objects, enter the following command: + [source,terminal] diff --git a/networking/verifying-connectivity-endpoint.adoc b/networking/verifying-connectivity-endpoint.adoc index 57e75e4e899e..fd26fff9b76a 100644 --- a/networking/verifying-connectivity-endpoint.adoc +++ b/networking/verifying-connectivity-endpoint.adoc @@ -11,5 +11,6 @@ By reviewing the results of the health checks, you can diagnose connection probl include::modules/nw-pod-network-connectivity-checks.adoc[leveloffset=+1] include::modules/nw-pod-network-connectivity-implementation.adoc[leveloffset=+1] +include::modules/nw-pod-network-connectivity-configuration.adoc[leveloffset=+1] include::modules/nw-pod-network-connectivity-check-object.adoc[leveloffset=+1] include::modules/nw-pod-network-connectivity-verify.adoc[leveloffset=+1] From bf2ceb3614e423069e9da6143717b5d401f974df Mon Sep 17 00:00:00 2001 From: Ben Scott Date: Tue, 18 Jun 2024 15:59:31 -0400 Subject: [PATCH 225/339] OSDOCS-9895 updating AWS AMI list --- ...installation-aws-user-infra-rhcos-ami.adoc | 126 +++++++++--------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/modules/installation-aws-user-infra-rhcos-ami.adoc b/modules/installation-aws-user-infra-rhcos-ami.adoc index 1da8f0986e05..d92561a0ae53 100644 --- a/modules/installation-aws-user-infra-rhcos-ami.adoc +++ b/modules/installation-aws-user-infra-rhcos-ami.adoc @@ -23,94 +23,97 @@ ifndef::openshift-origin[] |AWS AMI |`af-south-1` -|`ami-0493ec0f0a451f83b` +|`ami-018de6b1be470b7e6` |`ap-east-1` -|`ami-050a6d164705e7f62` +|`ami-092f09a4c8aacf56a` |`ap-northeast-1` -|`ami-00910c337e0f52cff` +|`ami-001c9fc85b77505f4` |`ap-northeast-2` -|`ami-07e98d33de2b93ac0` +|`ami-0a5d7f1966d88fba3` |`ap-northeast-3` -|`ami-09bc0a599f4b3c483` +|`ami-085a2726ceb4f5eeb` |`ap-south-1` -|`ami-0ba603a7f9d41228e` +|`ami-03f2c19071fb6eab3` |`ap-south-2` -|`ami-03130aecb5d7459cc` +|`ami-0c82522890979d94b` |`ap-southeast-1` -|`ami-026c056e0a25e5a04` +|`ami-06e5b9d16ead6c55c` |`ap-southeast-2` -|`ami-0d471f504ff6d9a0f` +|`ami-0ccd429129fbf6bc0` |`ap-southeast-3` -|`ami-0c1b9a0721cbb3291` +|`ami-096f9b4d41116d95c` |`ap-southeast-4` -|`ami-0ef23bfe787efe11e` +|`ami-0b511ab55f9f7d052` |`ca-central-1` -|`ami-0163965a05b75f976` +|`ami-0e357287c651be1f2` + +|`ca-west-1` +|`ami-0b1692e5776740901` |`eu-central-1` -|`ami-01edb54011f870f0c` +|`ami-08b13fb388ba5610d` |`eu-central-2` -|`ami-0bc500d6056a3b104` +|`ami-04777298b55045ea9` |`eu-north-1` -|`ami-0ab155e935177f16a` +|`ami-05421993a4ee567b9` |`eu-south-1` -|`ami-051b4c06b21f5a328` +|`ami-00959341869d34746` |`eu-south-2` -|`ami-096644e5555c23b19` +|`ami-0a745b610522a87cc` |`eu-west-1` -|`ami-0faeeeb3d2b1aa07c` +|`ami-0e48f85ec57bd7baa` |`eu-west-2` -|`ami-00bb1522dc71b604f` +|`ami-0c015b1387acddc5e` |`eu-west-3` -|`ami-01e5397bd2b795bd3` +|`ami-01e466af77a95b93d` |`il-central-1` -|`ami-0b32feb5d77c64e61` +|`ami-0a1b706793b54d087` |`me-central-1` -|`ami-0a5158a3e68ab7e88` +|`ami-09d58e8b2099ae5bc` |`me-south-1` -|`ami-024864ad1b799dbba` +|`ami-0f9c259bc4346599c` |`sa-east-1` -|`ami-0c402ffb0c4b7edc0` +|`ami-06277517d966881a3` |`us-east-1` -|`ami-057df4d0cb8cbae0d` +|`ami-05483066c3caaccf5` |`us-east-2` -|`ami-07566e5da1fd297f8` +|`ami-0c704ce516493a479` |`us-gov-east-1` -|`ami-0fe03a7e289354670` +|`ami-0695b2cbdd1ec4d48` |`us-gov-west-1` -|`ami-06b7cc6445c5da732` +|`ami-004404a0eaa427b39` |`us-west-1` -|`ami-02d20001c5b9df1e9` +|`ami-0aaa56637063be772` |`us-west-2` -|`ami-0dfba457127fba98c` +|`ami-0870c7a3d5ef4d2b3` |=== @@ -123,94 +126,97 @@ ifndef::openshift-origin[] |AWS AMI |`af-south-1` -|`ami-06c7b4e42179544df` +|`ami-0d96d447d3df14f4e` |`ap-east-1` -|`ami-07b6a37fa6d2d2e99` +|`ami-010236402dfba1717` |`ap-northeast-1` -|`ami-056d2eef4a3638246` +|`ami-08feeb6d9068bb12e` |`ap-northeast-2` -|`ami-0bd5a7684f0ff4e02` +|`ami-0772082c119147205` |`ap-northeast-3` -|`ami-0fd08063da50de1da` +|`ami-05bcbb13493d0516f` |`ap-south-1` -|`ami-08f1ae2cef8f9690e` +|`ami-0034a539e8adcb817` |`ap-south-2` -|`ami-020ba25cc1ec53b1c` +|`ami-0fc56b7c53c38ff70` |`ap-southeast-1` -|`ami-0020a1c0964ac8e48` +|`ami-0b50a0e92a58f3ad8` |`ap-southeast-2` -|`ami-07013a63289350c3c` +|`ami-0697a9174ae206182` |`ap-southeast-3` -|`ami-041d6ca1d57e3190f` +|`ami-05ae309319a7ad504` |`ap-southeast-4` -|`ami-06539e9cbefc28702` +|`ami-00500414843baa657` |`ca-central-1` -|`ami-0bb3991641f2b40f6` +|`ami-05e76bf99d3b0d4c8` + +|`ca-west-1` +|`ami-099fc953c221ec590` |`eu-central-1` -|`ami-0908d117c26059e39` +|`ami-0d2e2698884020b71` |`eu-central-2` -|`ami-0e48c82ffbde67ed2` +|`ami-0a96ba21ddee01719` |`eu-north-1` -|`ami-016614599b38d515e` +|`ami-0ab8a1070d0b1d9a5` |`eu-south-1` -|`ami-01b6cc1f0fd7b431f` +|`ami-0d0465299a8b196c1` |`eu-south-2` -|`ami-0687e1d98e55e402d` +|`ami-07d5aa3c6d468c738` |`eu-west-1` -|`ami-0bf0b7b1cb052d68d` +|`ami-08e7d209f26c09c80` |`eu-west-2` -|`ami-0ba0bf567caa63731` +|`ami-0c8336d4e2c1f13cb` |`eu-west-3` -|`ami-0eab6a7956a66deda` +|`ami-085d804b98acf0648` |`il-central-1` -|`ami-03b3cb1f4869bf21d` +|`ami-02ce030e36aeb7643` |`me-central-1` -|`ami-0a6e1ade3c9e206a1` +|`ami-0dea3ac466040b77f` |`me-south-1` -|`ami-0aa0775c68eac9f6f` +|`ami-02ef2a46887b9786d` |`sa-east-1` -|`ami-07235eee0bb930c78` +|`ami-0d19817d31b2399f9` |`us-east-1` -|`ami-005808ca73e7b36ff` +|`ami-04859c888566a2c2f` |`us-east-2` -|`ami-0c5c9420f6b992e9e` +|`ami-02f7e4a5dc66361bb` |`us-gov-east-1` -|`ami-08c9b2b8d578caf92` +|`ami-067ef782980ea96ad` |`us-gov-west-1` -|`ami-0bdff65422ba7d95d` +|`ami-0ce67540c1bb2319d` |`us-west-1` -|`ami-017ad4dd030a04233` +|`ami-0a09c5d2f287718a3` |`us-west-2` -|`ami-068d0af5e3c08e618` +|`ami-06b94e64e595f6cee` |=== endif::openshift-origin[] From 27e51a2908c522e55f7595d1613d810dab0ab990 Mon Sep 17 00:00:00 2001 From: michaelryanmcneill Date: Tue, 18 Jun 2024 19:16:20 -0400 Subject: [PATCH 226/339] Addressing missing source secret entitlements module --- cicd/builds/running-entitled-builds.adoc | 2 -- modules/builds-source-secrets-entitlements.adoc | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cicd/builds/running-entitled-builds.adoc b/cicd/builds/running-entitled-builds.adoc index 8673fdfc77f0..fec730560aa6 100644 --- a/cicd/builds/running-entitled-builds.adoc +++ b/cicd/builds/running-entitled-builds.adoc @@ -11,9 +11,7 @@ Use the following sections to install Red Hat subscription content within {produ include::modules/builds-create-imagestreamtag.adoc[leveloffset=+1] -ifndef::openshift-dedicated,openshift-rosa[] include::modules/builds-source-secrets-entitlements.adoc[leveloffset=+1] -endif::openshift-dedicated,openshift-rosa[] == Running builds with Subscription Manager diff --git a/modules/builds-source-secrets-entitlements.adoc b/modules/builds-source-secrets-entitlements.adoc index 25e0947ab2a7..4e671b4bf2a5 100644 --- a/modules/builds-source-secrets-entitlements.adoc +++ b/modules/builds-source-secrets-entitlements.adoc @@ -10,7 +10,9 @@ Builds that use Red Hat subscriptions to install content must include the entitl .Prerequisites +ifndef::openshift-dedicated,openshift-rosa[] * You must have access to {op-system-base-full} package repositories through your subscription. The entitlement secret to access these repositories is automatically created by the Insights Operator when your cluster is subscribed. +endif::openshift-dedicated,openshift-rosa[] * You must have access to the cluster as a user with the `cluster-admin` role or you have permission to access secrets in the `openshift-config-managed` project. From 97f64adfd15de015b555935f2643dd46d6861548 Mon Sep 17 00:00:00 2001 From: Misha Ramendik Date: Wed, 19 Jun 2024 14:34:02 +0100 Subject: [PATCH 227/339] RHDEVDOCS 6058 publish Pipelines 1.15 on d.o.c --- .s2i/httpd-cfg/01-commercial.conf | 2 +- _templates/_page_openshift.html.erb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.s2i/httpd-cfg/01-commercial.conf b/.s2i/httpd-cfg/01-commercial.conf index 63737951fdbc..04f57032d8a8 100644 --- a/.s2i/httpd-cfg/01-commercial.conf +++ b/.s2i/httpd-cfg/01-commercial.conf @@ -358,7 +358,7 @@ AddType text/vtt vtt # Pipelines handling unversioned and latest links RewriteRule ^pipelines/?$ /pipelines/latest [R=302] - RewriteRule ^pipelines/latest/?(.*)$ /pipelines/1\.14/$1 [NE,R=302] + RewriteRule ^pipelines/latest/?(.*)$ /pipelines/1\.15/$1 [NE,R=302] # Pipelines landing page diff --git a/_templates/_page_openshift.html.erb b/_templates/_page_openshift.html.erb index 4cae4062563f..eeccf566e03a 100644 --- a/_templates/_page_openshift.html.erb +++ b/_templates/_page_openshift.html.erb @@ -227,6 +227,7 @@ <%= distro %> + From bb7c85fa48659e378417066cda236ba881aef8ee Mon Sep 17 00:00:00 2001 From: Brian Dooley Date: Mon, 24 Jun 2024 11:02:22 +0100 Subject: [PATCH 298/339] SRVCOM-3046 Adjusts distro map for release --- _distro_map.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_distro_map.yml b/_distro_map.yml index cccb8a0a1c27..83f31201cb8c 100644 --- a/_distro_map.yml +++ b/_distro_map.yml @@ -326,6 +326,9 @@ openshift-serverless: serverless-docs-1.32: name: '1.32' dir: serverless/1.32 + serverless-docs-1.33: + name: '1.33' + dir: serverless/1.33 openshift-gitops: name: Red Hat OpenShift GitOps author: OpenShift documentation team From 6628377dcda2aee94d63b19347c0242b7c4267db Mon Sep 17 00:00:00 2001 From: "A.Arnold" Date: Mon, 24 Jun 2024 14:07:35 +0100 Subject: [PATCH 299/339] OADP-4378: Error in provider variable for OADP ODF and Virt docs Signed-off-by: A.Arnold --- .../installing/installing-oadp-kubevirt.adoc | 2 +- .../installing/installing-oadp-ocs.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backup_and_restore/application_backup_and_restore/installing/installing-oadp-kubevirt.adoc b/backup_and_restore/application_backup_and_restore/installing/installing-oadp-kubevirt.adoc index f8051773df4d..c6528a15d8f7 100644 --- a/backup_and_restore/application_backup_and_restore/installing/installing-oadp-kubevirt.adoc +++ b/backup_and_restore/application_backup_and_restore/installing/installing-oadp-kubevirt.adoc @@ -6,7 +6,7 @@ include::_attributes/common-attributes.adoc[] :context: installing-oadp-kubevirt :installing-oadp-kubevirt: :credentials: cloud-credentials -:provider: kubevirt +:provider: gcp toc::[] diff --git a/backup_and_restore/application_backup_and_restore/installing/installing-oadp-ocs.adoc b/backup_and_restore/application_backup_and_restore/installing/installing-oadp-ocs.adoc index 6b0061400905..b8ea72d897b9 100644 --- a/backup_and_restore/application_backup_and_restore/installing/installing-oadp-ocs.adoc +++ b/backup_and_restore/application_backup_and_restore/installing/installing-oadp-ocs.adoc @@ -5,7 +5,7 @@ include::_attributes/common-attributes.adoc[] :context: installing-oadp-ocs :installing-oadp-ocs: :credentials: cloud-credentials -:provider: oadp-ocs +:provider: gcp toc::[] From 172fdad6613234c3a8e3808b0f50598e624dd029 Mon Sep 17 00:00:00 2001 From: Andrea Hoffer Date: Mon, 24 Jun 2024 09:25:29 -0400 Subject: [PATCH 300/339] Typo fixes for main --- ...tivation-and-account-linking-tutorial.adoc | 11 ++++------ modules/agent-installer-architectures.adoc | 10 +++++----- modules/cleaning-crio-storage.adoc | 2 +- modules/cnf-configuring-kubelet-nro.adoc | 6 +++--- modules/cnf-image-based-upgrade-rollback.adoc | 4 ++-- ...mize-certificates-add-service-serving.adoc | 2 +- ...igating-an-unavailable-kubernetes-api.adoc | 4 ++-- modules/kmm-validation-status.adoc | 2 +- ...l-volume-manager-operator-using-rhacm.adoc | 6 +++--- modules/lvms-restoring-volume-snapshots.adoc | 6 +++--- .../microshift-audit-logs-config-intro.adoc | 2 +- ...multi-architecture-enabling-64k-pages.adoc | 20 +++++++++---------- modules/odc-adding-health-checks.adoc | 4 ++-- modules/odc-editing-health-checks.adoc | 2 +- modules/odc-monitoring-health-checks.adoc | 2 +- modules/ossm-routing-bookinfo-example.adoc | 2 +- modules/ossm-threescale-integrate-1x.adoc | 2 +- modules/ossm-threescale-integrate.adoc | 2 +- modules/ossm-tutorial-bookinfo-install.adoc | 2 +- modules/ossm-tutorial-grafana-accessing.adoc | 2 +- ...ssm-tutorial-jaeger-generating-traces.adoc | 2 +- ...-tutorial-prometheus-querying-metrics.adoc | 2 +- ...orage-csi-vsphere-change-max-snapshot.adoc | 8 ++++---- ...ry-exposing-default-registry-manually.adoc | 2 +- ...try-exposing-secure-registry-manually.adoc | 2 +- ...e-based-upgrade-extra-manifests-guide.adoc | 4 ++-- .../metrics-alerts-dashboards.adoc | 2 +- .../otel/otel_rn/otel-rn-past-releases.adoc | 2 +- .../lvms-disconnected-ImageSetConfig.adoc | 4 ++-- ...achine-config-node-disruption-actions.adoc | 9 ++++----- .../cloud-experts-rosa-hcp-sts-explained.adoc | 8 ++++---- .../enabling-windows-container-workloads.adoc | 2 +- 32 files changed, 68 insertions(+), 72 deletions(-) diff --git a/cloud_experts_tutorials/cloud-experts-rosa-hcp-activation-and-account-linking-tutorial.adoc b/cloud_experts_tutorials/cloud-experts-rosa-hcp-activation-and-account-linking-tutorial.adoc index 87a2f52f5a79..a365020dacda 100644 --- a/cloud_experts_tutorials/cloud-experts-rosa-hcp-activation-and-account-linking-tutorial.adoc +++ b/cloud_experts_tutorials/cloud-experts-rosa-hcp-activation-and-account-linking-tutorial.adoc @@ -68,7 +68,7 @@ image::rosa-continue-rh-6.png[] + image::rosa-login-rh-account-7.png[] + -* You can also register for a new Red{nbsp}Hat account or reset your password on this page. +* You can also register for a new Red{nbsp}Hat account or reset your password on this page. * Make sure to log in to the Red{nbsp}Hat account that you plan to associate with the AWS account where you have activated {hcp-title} in previous steps. * Only a single AWS account that will be used for service billing can be associated with a Red{nbsp}Hat account. Typically an organizational AWS account that has other AWS accounts, such as developer accounts, linked would be the one that is to be billed, rather than individual AWS end user accounts. * Red{nbsp}Hat accounts belonging to the same Red{nbsp}Hat organization will be linked with the same AWS account. Therefore, you can manage who has access to creating {hcp-title} clusters on the Red{nbsp}Hat organization account level. @@ -133,7 +133,7 @@ Do not share your unique token. . The final prerequisite before your first cluster deployment is making sure the necessary account-wide roles and policies are created. The `rosa` CLI can help with that by using the command shown under step _2.2. To create the necessary account-wide roles and policies quickly…_ on the web console. The alternative to that is manual creation of these roles and policies. -. After logging in, creating the account roles, and verifying your identity using the `rosa whoami` command, your terminal will look similar to this: +. After logging in, creating the account roles, and verifying your identity using the `rosa whoami` command, your terminal will look similar to this: + image::rosa-whoami-14.png[] @@ -174,7 +174,7 @@ image::rosa-deploy-ui-19.png[] + image::rosa-deploy-ui-hcp-20.png[] -. The next step *Accounts and roles* allows you specifying the infrastructure AWS account, into which the the ROSA cluster will be deployed and where the resources will be consumed and managed: +. The next step *Accounts and roles* allows you specifying the infrastructure AWS account, into which the ROSA cluster will be deployed and where the resources will be consumed and managed: + image::rosa-ui-account-21.png[] + @@ -191,12 +191,9 @@ image::rosa-ui-billing-22.png[] * You can see an indicator whether the ROSA contract is enabled for a given AWS billing account or not. * In case you would like to use an AWS account that does not have a contract enabled yet, you can either use the _Connect ROSA to a new AWS billing account_ to reach the ROSA AWS console page, where you can activate it after logging in using the respective AWS account by following steps described earlier in this tutorial, or ask the administrator of the AWS account to do that for you. -The following steps past the billing AWS account selection are beyond the scope of this tutorial. +The following steps past the billing AWS account selection are beyond the scope of this tutorial. .Additional resources * For information on using the CLI to create a cluster, see xref:../rosa_hcp/rosa-hcp-sts-creating-a-cluster-quickly.adoc#rosa-hcp-sts-creating-a-cluster-cli_rosa-hcp-sts-creating-a-cluster-quickly[Creating a ROSA with HCP cluster using the CLI]. * See link:https://cloud.redhat.com/learning/learn:getting-started-red-hat-openshift-service-aws-rosa/resource/resources:how-deploy-cluster-red-hat-openshift-service-aws-using-console-ui[this learning path] for more details on how to complete ROSA cluster deployment using the web console. - - - diff --git a/modules/agent-installer-architectures.adoc b/modules/agent-installer-architectures.adoc index ad6635367db7..68afb0c3cd53 100644 --- a/modules/agent-installer-architectures.adoc +++ b/modules/agent-installer-architectures.adoc @@ -8,23 +8,23 @@ Before installing an {product-title} cluster using the Agent-based Installer, you can verify the supported architecture on which you can install the cluster. This procedure is optional. -.Prerequisites: +.Prerequisites * You installed the {oc-first}. * You have downloaded the installation program. -.Procedure: +.Procedure . Log in to the {oc-first}. -. Check your release payload by running the following command: +. Check your release payload by running the following command: [source,terminal] + ---- $ ./openshift-install version ---- + -.Example output +.Example output [source,terminal] ---- ./openshift-install 4.16.0 @@ -49,4 +49,4 @@ $ oc adm release info -o jsonpath="{ .metadata.metadata}" <1> {"release.openshift.io architecture":"multi"} ---- + -If you are using the release image with the `multi` payload, you can install the cluster on different architectures such as `arm64`, `amd64`, `s390x`, and `ppc64le`. Otherwise, you can install the cluster only on the `release architecture` displayed in the output of the `openshift-install version` command. \ No newline at end of file +If you are using the release image with the `multi` payload, you can install the cluster on different architectures such as `arm64`, `amd64`, `s390x`, and `ppc64le`. Otherwise, you can install the cluster only on the `release architecture` displayed in the output of the `openshift-install version` command. diff --git a/modules/cleaning-crio-storage.adoc b/modules/cleaning-crio-storage.adoc index 7c948efa446c..f2aa0b6bd199 100644 --- a/modules/cleaning-crio-storage.adoc +++ b/modules/cleaning-crio-storage.adoc @@ -31,7 +31,7 @@ can't stat lower layer ... because it does not exist. Going through storage to Follow this process to completely wipe the CRI-O storage and resolve the errors. -.Prerequisites: +.Prerequisites * You have access to the cluster as a user with the `cluster-admin` role. * You have installed the OpenShift CLI (`oc`). diff --git a/modules/cnf-configuring-kubelet-nro.adoc b/modules/cnf-configuring-kubelet-nro.adoc index 5c89b2462af6..805d1c5f94e9 100644 --- a/modules/cnf-configuring-kubelet-nro.adoc +++ b/modules/cnf-configuring-kubelet-nro.adoc @@ -8,7 +8,7 @@ The recommended way to configure a single NUMA node policy is to apply a performance profile. Another way is by creating and applying a `KubeletConfig` custom resource (CR), as shown in the following procedure. -.Procedure +.Procedure . Create the `KubeletConfig` custom resource (CR) that configures the pod admittance policy for the machine profile: @@ -41,7 +41,7 @@ spec: memory: "512Mi" topologyManagerPolicy: "single-numa-node" <5> ---- -<1> Adjust this label to match the the `machineConfigPoolSelector` in the `NUMAResourcesOperator` CR. +<1> Adjust this label to match the `machineConfigPoolSelector` in the `NUMAResourcesOperator` CR. <2> For `cpuManagerPolicy`, `static` must use a lowercase `s`. <3> Adjust this based on the CPU on your nodes. <4> For `memoryManagerPolicy`, `Static` must use an uppercase `S`. @@ -56,5 +56,5 @@ $ oc create -f nro-kubeletconfig.yaml + [NOTE] ==== -Applying performance profile or `KubeletConfig` automatically triggers rebooting of the nodes. If no reboot is triggered, you can troubleshoot the issue by looking at the labels in `KubeletConfig` that address the node group. +Applying performance profile or `KubeletConfig` automatically triggers rebooting of the nodes. If no reboot is triggered, you can troubleshoot the issue by looking at the labels in `KubeletConfig` that address the node group. ==== diff --git a/modules/cnf-image-based-upgrade-rollback.adoc b/modules/cnf-image-based-upgrade-rollback.adoc index cdc361319d3f..142186b157fe 100644 --- a/modules/cnf-image-based-upgrade-rollback.adoc +++ b/modules/cnf-image-based-upgrade-rollback.adoc @@ -44,7 +44,7 @@ $ oc patch imagebasedupgrades.lca.openshift.io upgrade -p='{"spec": {"stage": "R The {lcao} reboots the cluster with the previously installed version of {product-title} and restores the applications. -- -. If you are satisfied with the changes, finalize the the rollback by patching the value of the `stage` field to `Idle` in the `ImageBasedUpgrade` CR by running the following command: +. If you are satisfied with the changes, finalize the rollback by patching the value of the `stage` field to `Idle` in the `ImageBasedUpgrade` CR by running the following command: + -- [source,terminal] @@ -56,4 +56,4 @@ $ oc patch imagebasedupgrades.lca.openshift.io upgrade -p='{"spec": {"stage": "I ==== If you move to the `Idle` stage after a rollback, the {lcao} cleans up resources that can be used to troubleshoot a failed upgrade. ==== --- \ No newline at end of file +-- diff --git a/modules/customize-certificates-add-service-serving.adoc b/modules/customize-certificates-add-service-serving.adoc index 3cb4d86fb9be..a4991bda43d7 100644 --- a/modules/customize-certificates-add-service-serving.adoc +++ b/modules/customize-certificates-add-service-serving.adoc @@ -18,7 +18,7 @@ Because the generated certificates contain wildcard subjects for headless servic * Do not accept the service CA as a trusted CA for connections that are directed to individual pods and must not be impersonated by other pods. These connections must be configured to trust the CA that was used to generate the individual TLS certificates. ==== -.Prerequisites: +.Prerequisites * You must have a service defined. diff --git a/modules/ipi-install-troubleshooting-investigating-an-unavailable-kubernetes-api.adoc b/modules/ipi-install-troubleshooting-investigating-an-unavailable-kubernetes-api.adoc index da84830e2a61..cb3e39e1a977 100644 --- a/modules/ipi-install-troubleshooting-investigating-an-unavailable-kubernetes-api.adoc +++ b/modules/ipi-install-troubleshooting-investigating-an-unavailable-kubernetes-api.adoc @@ -1,4 +1,4 @@ -// This module is included in the following assemblies: +// This module is included in the following assemblies: // // installing/installing_bare_metal_ipi/ipi-install-troubleshooting.adoc @@ -17,7 +17,7 @@ When the Kubernetes API is unavailable, check the control plane nodes to ensure $ sudo crictl logs $(sudo crictl ps --pod=$(sudo crictl pods --name=etcd-member --quiet) --quiet) ---- -. If the previous command fails, ensure that Kublet created the `etcd` pods by running the following command: +. If the previous command fails, ensure that Kubelet created the `etcd` pods by running the following command: + [source,terminal] ---- diff --git a/modules/kmm-validation-status.adoc b/modules/kmm-validation-status.adoc index 970b8f5aabb8..34a3c66c28ee 100644 --- a/modules/kmm-validation-status.adoc +++ b/modules/kmm-validation-status.adoc @@ -25,4 +25,4 @@ A `PreflightValidationOCP` resource reports the status and progress of each modu * `true`: Verified * `false`: Verification failed * `error`: Error during the verification process -* `unknown`: Verfication has not started +* `unknown`: Verification has not started diff --git a/modules/lvms-installing-logical-volume-manager-operator-using-rhacm.adoc b/modules/lvms-installing-logical-volume-manager-operator-using-rhacm.adoc index 507a590d7cbf..a65cc48969f2 100644 --- a/modules/lvms-installing-logical-volume-manager-operator-using-rhacm.adoc +++ b/modules/lvms-installing-logical-volume-manager-operator-using-rhacm.adoc @@ -16,7 +16,7 @@ The `Policy` CR that is created to install {lvms} is also applied to the cluster .Prerequisites * You have access to the {rh-rhacm} cluster using an account with `cluster-admin` and Operator installation permissions. * You have dedicated disks that {lvms} can use on each cluster. -* The cluster must be be managed by {rh-rhacm}. +* The cluster must be managed by {rh-rhacm}. .Procedure @@ -129,8 +129,8 @@ spec: $ oc create -f -n ---- + -Upon creating the `Policy` CR, the following custom resources are created on the clusters that match the selection criteria configured in the `PlacementRule` CR: +Upon creating the `Policy` CR, the following custom resources are created on the clusters that match the selection criteria configured in the `PlacementRule` CR: * `Namespace` * `OperatorGroup` -* `Subscription` \ No newline at end of file +* `Subscription` diff --git a/modules/lvms-restoring-volume-snapshots.adoc b/modules/lvms-restoring-volume-snapshots.adoc index 5aab9a9fb6ed..716426644abc 100644 --- a/modules/lvms-restoring-volume-snapshots.adoc +++ b/modules/lvms-restoring-volume-snapshots.adoc @@ -6,7 +6,7 @@ [id="lvms-restoring-volume-snapshots_{context}"] = Restoring volume snapshots -To restore a volume snapshot, you must create a persistent volume claim (PVC) with the `dataSource.name` field set to the name of the volume snapshot. +To restore a volume snapshot, you must create a persistent volume claim (PVC) with the `dataSource.name` field set to the name of the volume snapshot. The restored PVC is independent of the volume snapshot and the source PVC. @@ -43,9 +43,9 @@ spec: ---- <1> Specify the storage size of the restored PVC. The storage size of the requested PVC must be greater than or equal to the stoage size of the volume snapshot that you want to restore. If a larger PVC is required, you can also resize the PVC after restoring the volume snapshot. <2> Set this field to the value of the `storageClassName` field in the source PVC of the volume snapshot that you want to restore. -<3> Set this field to the name of the volume snapshot that you want to restore. +<3> Set this field to the name of the volume snapshot that you want to restore. -. Create the PVC in the namespace where you created the the volume snapshot by running the following command: +. Create the PVC in the namespace where you created the volume snapshot by running the following command: + [source,terminal] ---- diff --git a/modules/microshift-audit-logs-config-intro.adoc b/modules/microshift-audit-logs-config-intro.adoc index a83b7609dcfc..c5a70512898c 100644 --- a/modules/microshift-audit-logs-config-intro.adoc +++ b/modules/microshift-audit-logs-config-intro.adoc @@ -27,7 +27,7 @@ You can set fields in combination to define a maximum storage limit for retained |Audit log parameter|Default setting|Definition |`maxFileAge`:|`0`|How long log files are retained before automatic deletion. The default value means that a log file is never deleted based on age. This value can be configured. |`maxFiles`:|`10`|The total number of log files retained. By default, {microshift-short} retains 10 log files. The oldest is deleted when an excess file is created. This value can be configured. -|`maxFileSize`:|`200`|By default, when the `audit.log` file reaches the `maxFileSize` limit, the `audit.log` file is rotated and {microshift-short} begins writing to a new `audit.log` file. This value in in megabytes and can be configured. +|`maxFileSize`:|`200`|By default, when the `audit.log` file reaches the `maxFileSize` limit, the `audit.log` file is rotated and {microshift-short} begins writing to a new `audit.log` file. This value is in megabytes and can be configured. |`profile`:|`Default`|The `Default` profile setting only logs metadata for read and write requests; request bodies are not logged except for OAuth access token requests. If you do not specify this field, the `Default` profile is used. |=== diff --git a/modules/multi-architecture-enabling-64k-pages.adoc b/modules/multi-architecture-enabling-64k-pages.adoc index 43a14439473b..81e295e723d6 100644 --- a/modules/multi-architecture-enabling-64k-pages.adoc +++ b/modules/multi-architecture-enabling-64k-pages.adoc @@ -5,7 +5,7 @@ :_mod-docs-content-type: PROCEDURE [id="multi-architecture-enabling-64k-pages_{context}"] -= Enabling 64k pages on the {op-system-first} kernel += Enabling 64k pages on the {op-system-first} kernel You can enable the 64k memory page in the {op-system-first} kernel on the 64-bit ARM compute machines in your cluster. The 64k page size kernel specification can be used for large GPU or high memory workloads. This is done using the Machine Config Operator (MCO) which uses a machine config pool to update the kernel. To enable 64k page sizes, you must dedicate a machine config pool for ARM64 to enable on the kernel. @@ -14,11 +14,11 @@ You can enable the 64k memory page in the {op-system-first} kernel on the 64-bit Using 64k pages is exclusive to 64-bit ARM architecture compute nodes or clusters installed on 64-bit ARM machines. If you configure the 64k pages kernel on a machine config pool using 64-bit x86 machines, the machine config pool and MCO will degrade. ==== -.Prerequisites: +.Prerequisites * You installed the OpenShift CLI (`oc`). * You created a cluster with compute nodes of different architecture on one of the supported platforms. -.Procedure: +.Procedure . Label the nodes where you want to run the 64k page size kernel: [source,terminal] @@ -27,7 +27,7 @@ Using 64k pages is exclusive to 64-bit ARM architecture compute nodes or cluster $ oc label node

    bELqN1%SB0a!f=S8#d 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 ULFM~6+Tn|Gc5t_^x4V+@FG_4Fod5s; literal 0 HcmV?d00001 diff --git a/modules/installing-oci-about-agent-based-installer.adoc b/modules/installing-oci-about-agent-based-installer.adoc index 75530a612e99..162c28b5364a 100644 --- a/modules/installing-oci-about-agent-based-installer.adoc +++ b/modules/installing-oci-about-agent-based-installer.adoc @@ -10,6 +10,14 @@ You can install an {product-title} cluster on {oci-first} by using the Agent-bas The Agent-based installer provides the ease of use of the Assisted Installation service, but with the capability to install a cluster in either a connected or disconnected environment. +The following diagrams show workflows for connected and disconnected environments: + +.Workflow for using the Agent-based installer in a connected environment to install a cluster on {oci} +image::684_OpenShift_Installing_on_OCI_0624-connected.png[Image of a high-level workflow for using the Agent-based installer in a connected environment to install a cluster on {oci}] + +.Workflow for using the Agent-based installer in a disconnected environment to install a cluster on {oci} +image::684_OpenShift_Installing_on_OCI_0624-disconnected.png[Image of a high-level workflow for using the Agent-based installer in a disconnected environment to install a cluster on {oci}] + {oci} provides services that can meet your regulatory compliance, performance, and cost-effectiveness needs. {oci} supports 64-bit `x86` instances and 64-bit `ARM` instances. Additionally, {oci} provides an {ocvs} service where you can move VMware workloads to {oci} with minimal application re-architecture. [NOTE] From 4b1bbce93cea952a815b47daf31d67f867298b4c Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Thu, 20 Jun 2024 11:51:00 -0400 Subject: [PATCH 324/339] Adds two commands for procedure accuracy --- ...tallation-adding-registry-pull-secret.adoc | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/modules/installation-adding-registry-pull-secret.adoc b/modules/installation-adding-registry-pull-secret.adoc index f77a503f5a3d..d5a09344924b 100644 --- a/modules/installation-adding-registry-pull-secret.adoc +++ b/modules/installation-adding-registry-pull-secret.adoc @@ -99,18 +99,50 @@ The contents of the file resemble the following example: ---- // An additional step for following this procedure when using oc-mirror as part of the disconnected install process. ifdef::oc-mirror[] -. Save the file either as `~/.docker/config.json` or `$XDG_RUNTIME_DIR/containers/auth.json`. -endif::[] - -ifdef::oc-mirror-v2[] -. Save the file as `$XDG_RUNTIME_DIR/containers/auth.json`. +. Save the file as either `~/.docker/config.json` or `$XDG_RUNTIME_DIR/containers/auth.json`: +.. If the `.docker` or `$XDG_RUNTIME_DIR/containers` directories do not exist, create one by entering the following command: ++ +[source,terminal] +---- +$ mkdir -p +---- ++ +Where `` is either `~/.docker` or `$XDG_RUNTIME_DIR/containers`. +.. Copy the pull secret to the appropriate directory by entering the following command: ++ +[source,terminal] +---- +$ cp / / +---- ++ +Where `` is either `~/.docker` or `$XDG_RUNTIME_DIR/containers`, and `` is either `config.json` or `auth.json`. endif::[] // Similar to the additional step above, except it is framed as optional because it is included in a disconnected update page (where users may or may not use oc-mirror for their process) ifdef::update-oc-mirror[] -. Optional: If using the oc-mirror plugin, save the file either as `~/.docker/config.json` or `$XDG_RUNTIME_DIR/containers/auth.json`. +. Optional: If using the oc-mirror plugin, save the file as either `~/.docker/config.json` or `$XDG_RUNTIME_DIR/containers/auth.json`: +.. If the `.docker` or `$XDG_RUNTIME_DIR/containers` directories do not exist, create one by entering the following command: ++ +[source,terminal] +---- +$ mkdir -p +---- ++ +Where `` is either `~/.docker` or `$XDG_RUNTIME_DIR/containers`. +.. Copy the pull secret to the appropriate directory by entering the following command: ++ +[source,terminal] +---- +$ cp / / +---- ++ +Where `` is either `~/.docker` or `$XDG_RUNTIME_DIR/containers`, and `` is either `config.json` or `auth.json`. endif::[] +// Additional step for allowing this procedure for oc-mirror-v2 +ifdef::oc-mirror-v2[] +. Save the file as `$XDG_RUNTIME_DIR/containers/auth.json`. endif::[] - +endif::[] + . Generate the base64-encoded user name and password or token for your mirror registry: + [source,terminal] From 08045c016219a28970eb0862d279081486b890fc Mon Sep 17 00:00:00 2001 From: Andrea Hoffer Date: Tue, 25 Jun 2024 12:07:27 -0400 Subject: [PATCH 325/339] OCPBUILD#7: Noting that builder SA isn't created if Build capability is disabled --- modules/build-config-capability.adoc | 7 ++++++- modules/service-accounts-default.adoc | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/build-config-capability.adoc b/modules/build-config-capability.adoc index 13f8713c811b..4b685eb36419 100644 --- a/modules/build-config-capability.adoc +++ b/modules/build-config-capability.adoc @@ -13,5 +13,10 @@ The `Build` capability enables the `Build` API. The `Build` API manages the life [IMPORTANT] ==== -If the `Build` capability is disabled, the cluster cannot use `Build` or `BuildConfig` resources. Disable the capability only if `Build` and `BuildConfig` resources are not required in the cluster. +If you disable the `Build` capability, the following resources will not be available in the cluster: + +* `Build` and `BuildConfig` resources +* The `builder` service account + +Disable the `Build` capability only if you do not require `Build` and `BuildConfig` resources or the `builder` service account in the cluster. ==== diff --git a/modules/service-accounts-default.adoc b/modules/service-accounts-default.adoc index a452f5416f6d..4bddcef57641 100644 --- a/modules/service-accounts-default.adoc +++ b/modules/service-accounts-default.adoc @@ -60,6 +60,11 @@ Three service accounts are automatically created in each project: pushing images to any imagestream in the project using the internal Docker registry. +[NOTE] +==== +The `builder` service account is not created if the `Build` cluster capability is not enabled. +==== + |`deployer` |Used by deployment pods and given the `system:deployer` role, which allows viewing and modifying replication controllers and pods in the project. From ddca29750991d07c40cb8ef12a16695ccdd78471 Mon Sep 17 00:00:00 2001 From: EricPonvelle Date: Tue, 11 Jun 2024 11:49:40 -0400 Subject: [PATCH 326/339] OSDOCS#10177: Updates to Terraform files --- _topic_maps/_topic_map_rosa.yml | 18 +- ...assic-cluster-terraform-file-creation.adoc | 279 +++++++++ ...a-hcp-cluster-terraform-file-creation.adoc | 268 +++++++++ .../rosa-sts-cluster-terraform-destroy.adoc | 61 +- .../rosa-sts-cluster-terraform-execute.adoc | 56 +- ...a-sts-cluster-terraform-file-creation.adoc | 542 ------------------ modules/rosa-sts-cluster-terraform-setup.adoc | 6 +- ...of-the-default-cluster-specifications.adoc | 31 +- modules/rosa-terraform-overview.adoc | 11 + rosa_hcp/terraform/_attributes | 1 + rosa_hcp/terraform/images | 1 + rosa_hcp/terraform/modules | 1 + ...-creating-a-cluster-quickly-terraform.adoc | 33 ++ ...cluster-with-customizations-terraform.adoc | 18 +- rosa_hcp/terraform/snippets | 1 + ...-creating-a-cluster-quickly-terraform.adoc | 32 ++ ...cluster-with-customizations-terraform.adoc | 72 +++ ...-creating-a-cluster-quickly-terraform.adoc | 41 -- .../rosa-understanding-terraform.adoc | 5 +- .../terraform-modification-disclaimer.adoc | 2 +- 20 files changed, 837 insertions(+), 642 deletions(-) create mode 100644 modules/rosa-classic-cluster-terraform-file-creation.adoc create mode 100644 modules/rosa-hcp-cluster-terraform-file-creation.adoc delete mode 100644 modules/rosa-sts-cluster-terraform-file-creation.adoc create mode 100644 modules/rosa-terraform-overview.adoc create mode 120000 rosa_hcp/terraform/_attributes create mode 120000 rosa_hcp/terraform/images create mode 120000 rosa_hcp/terraform/modules create mode 100644 rosa_hcp/terraform/rosa-hcp-creating-a-cluster-quickly-terraform.adoc rename rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-with-customizations-terraform.adoc => rosa_hcp/terraform/rosa-hcp-creating-a-cluster-with-customizations-terraform.adoc (93%) create mode 120000 rosa_hcp/terraform/snippets create mode 100644 rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc create mode 100644 rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-with-customizations-terraform.adoc delete mode 100644 rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-quickly-terraform.adoc diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index 9cd4d877838b..bc35e654d8fd 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -220,8 +220,6 @@ Topics: File: rosa-sts-required-aws-service-quotas - Name: Setting up your environment File: rosa-sts-setting-up-environment -- Name: Preparing Terraform to install ROSA clusters - File: rosa-understanding-terraform --- Name: Install ROSA with HCP clusters Dir: rosa_hcp @@ -229,6 +227,14 @@ Distros: openshift-rosa Topics: - Name: Creating ROSA with HCP clusters using the default options File: rosa-hcp-sts-creating-a-cluster-quickly +- Name: Creating a ROSA cluster using Terraform + Dir: terraform + Distros: openshift-rosa + Topics: + - Name: Creating a default ROSA cluster using Terraform + File: rosa-hcp-creating-a-cluster-quickly-terraform +# - Name: Customizing a ROSA cluster with Terraform +# File: rosa-hcp-creating-a-cluster-with-customizations-terraform - Name: Creating ROSA with HCP clusters using a custom AWS KMS encryption key File: rosa-hcp-creating-cluster-with-aws-kms-key - Name: Creating a private cluster on ROSA with HCP @@ -248,14 +254,14 @@ Topics: File: rosa-sts-creating-a-cluster-quickly - Name: Creating a ROSA cluster with STS using customizations File: rosa-sts-creating-a-cluster-with-customizations -- Name: Creating a ROSA cluster with STS using Terraform +- Name: Creating a ROSA (classic architecture) cluster using Terraform Dir: terraform Distros: openshift-rosa Topics: - - Name: Creating a default ROSA Classic cluster using Terraform - File: rosa-sts-creating-a-cluster-quickly-terraform + - Name: Creating a default ROSA (classic architecture) cluster using Terraform + File: rosa-classic-creating-a-cluster-quickly-terraform # - Name: Customizing a ROSA cluster with Terraform -# File: rosa-sts-creating-a-cluster-with-customizations-terraform +# File: rosa-classic-creating-a-cluster-with-customizations-terraform - Name: Interactive cluster creation mode reference File: rosa-sts-interactive-mode-reference - Name: Creating an AWS PrivateLink cluster on ROSA diff --git a/modules/rosa-classic-cluster-terraform-file-creation.adoc b/modules/rosa-classic-cluster-terraform-file-creation.adoc new file mode 100644 index 000000000000..2258bfe2d9f2 --- /dev/null +++ b/modules/rosa-classic-cluster-terraform-file-creation.adoc @@ -0,0 +1,279 @@ +// Module included in the following assemblies: +// +// * rosa_install_access_delete_clusters/rosa-classic-creating-a-cluster-quickly-terraform.adoc +// + +:_content-type: PROCEDURE + +[id="rosa-classic-cluster-terraform-file-creation_{context}"] += Creating your Terraform files locally + +After you set up your link:https://console.redhat.com/openshift/token/rosa[offline {cluster-manager-first} token], you need to create the Terraform files locally to build your cluster. You can create these files by using the following code templates. + +.Procedure + +. Create the `main.tf` file by running the following command: ++ +[source,terminal] +---- +$ cat<<-EOF>main.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.20.0" + } + rhcs = { + version = ">= 1.6.2" + source = "terraform-redhat/rhcs" + } + } +} + +# Export token using the RHCS_TOKEN environment variable +provider "rhcs" {} + +provider "aws" { + region = var.aws_region + ignore_tags { + key_prefixes = ["kubernetes.io/"] + } + default_tags { + tags = var.default_aws_tags + } +} + +data "aws_availability_zones" "available" {} + +locals { + # The default setting creates 3 availability zones. Set to "false" to create a single availability zones. + region_azs = var.multi_az ? slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, 3) : slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, 1) +} + +resource "random_string" "random_name" { + length = 6 + special = false + upper = false +} + +locals { + path = coalesce(var.path, "/") + worker_node_replicas = try(var.worker_node_replicas, var.multi_az ? 3 : 2) + # If cluster_name is not null, use that, otherwise generate a random cluster name + cluster_name = coalesce(var.cluster_name, "rosa-\${random_string.random_name.result}") +} + +# The network validator requires an additional 60 seconds to validate Terraform clusters. +resource "time_sleep" "wait_60_seconds" { + count = var.create_vpc ? 1 : 0 + depends_on = [module.vpc] + create_duration = "60s" +} + +module "rosa-classic" { + source = "terraform-redhat/rosa-classic/rhcs" + version = "1.5.0" + cluster_name = local.cluster_name + openshift_version = var.openshift_version + account_role_prefix = local.cluster_name + operator_role_prefix = local.cluster_name + replicas = local.worker_node_replicas + aws_availability_zones = local.region_azs + create_oidc = true + private = var.private_cluster + aws_private_link = var.private_cluster + aws_subnet_ids = var.create_vpc ? var.private_cluster ? module.vpc[0].private_subnets : concat(module.vpc[0].public_subnets, module.vpc[0].private_subnets) : var.aws_subnet_ids + multi_az = var.multi_az + create_account_roles = true + create_operator_roles = true + + depends_on = [time_sleep.wait_60_seconds] +} +EOF +---- + +. Create the `variables.tf` file by running the following command: ++ +[NOTE] +==== +Copy and edit this file _before_ running the command to build your cluster. +==== ++ +[source,terminal] +---- +$ cat<<-EOF>variables.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +variable "openshift_version" { + type = string + default = "4.14.20" + description = "Desired version of OpenShift for the cluster, for example '4.14.20'. If version is greater than the currently running version, an upgrade will be scheduled." +} + +variable "create_vpc" { + type = bool + description = "If you would like to create a new VPC, set this value to 'true'. If you do not want to create a new VPC, set this value to 'false'." +} + +# ROSA Cluster info +variable "cluster_name" { + default = null + type = string + description = "The name of the ROSA cluster to create" +} + +variable "additional_tags" { + default = { + Terraform = "true" + Environment = "dev" + } + description = "Additional AWS resource tags" + type = map(string) +} + +variable "path" { + description = "(Optional) The arn path for the account/operator roles as well as their policies." + type = string + default = null +} + +variable "multi_az" { + type = bool + description = "Multi AZ Cluster for High Availability" + default = true +} + +variable "worker_node_replicas" { + default = 3 + description = "Number of worker nodes to provision. Single zone clusters need at least 2 nodes, multizone clusters need at least 3 nodes" + type = number +} + +variable "aws_subnet_ids" { + type = list(any) + description = "A list of either the public or public + private subnet IDs to use for the cluster blocks to use for the cluster" + default = ["subnet-01234567890abcdef", "subnet-01234567890abcdef", "subnet-01234567890abcdef"] +} + +variable "private_cluster" { + type = bool + description = "If you want to create a private cluster, set this value to 'true'. If you want a publicly available cluster, set this value to 'false'." +} + +#VPC Info +variable "vpc_name" { + type = string + description = "VPC Name" + default = "tf-qs-vpc" +} + +variable "vpc_cidr_block" { + type = string + description = "value of the CIDR block to use for the VPC" + default = "10.0.0.0/16" +} + +variable "private_subnet_cidrs" { + type = list(any) + description = "The CIDR blocks to use for the private subnets" + default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +} + +variable "public_subnet_cidrs" { + type = list(any) + description = "The CIDR blocks to use for the public subnets" + default = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] +} + +variable "single_nat_gateway" { + type = bool + description = "Single NAT or per NAT for subnet" + default = false +} + +#AWS Info +variable "aws_region" { + type = string + default = "us-east-2" +} + +variable "default_aws_tags" { + type = map(string) + description = "Default tags for AWS" + default = {} +} +EOF +---- + +. Create the `vpc.tf` file by running the following command: ++ +[source,terminal] +---- +$ cat<<-EOF>vpc.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "5.1.2" + + count = var.create_vpc ? 1 : 0 + name = var.vpc_name + cidr = var.vpc_cidr_block + + azs = local.region_azs + private_subnets = var.private_subnet_cidrs + public_subnets = var.public_subnet_cidrs + + enable_nat_gateway = true + single_nat_gateway = var.single_nat_gateway + enable_dns_hostnames = true + enable_dns_support = true + + tags = var.additional_tags +} +EOF +---- ++ +You are ready to initiate Terraform. diff --git a/modules/rosa-hcp-cluster-terraform-file-creation.adoc b/modules/rosa-hcp-cluster-terraform-file-creation.adoc new file mode 100644 index 000000000000..8a47da932ef5 --- /dev/null +++ b/modules/rosa-hcp-cluster-terraform-file-creation.adoc @@ -0,0 +1,268 @@ +// Module included in the following assemblies: +// +// * rosa_install_access_delete_clusters/rosa-hcp-creating-a-cluster-quickly-terraform.adoc +// +:_content-type: PROCEDURE + +[id="rosa-hcp-cluster-terraform-file-creation_{context}"] += Creating your Terraform files locally + +After you set up your link:https://console.redhat.com/openshift/token[offline {cluster-manager-first} token], you need to create the Terraform files locally to build your cluster. You can create these files by using the following code templates. + +.Procedure + +. Create the `main.tf` file by running the following command: ++ +[source,terminal] +---- +$ cat<<-EOF>main.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.20.0" + } + rhcs = { + version = ">= 1.6.2" + source = "terraform-redhat/rhcs" + } + } +} + +# Export token using the RHCS_TOKEN environment variable +provider "rhcs" {} + +provider "aws" { + region = var.aws_region + ignore_tags { + key_prefixes = ["kubernetes.io/"] + } + default_tags { + tags = var.default_aws_tags + } +} + +data "aws_availability_zones" "available" {} + +locals { + # Extract availability zone names for the specified region, limit it to 3 if multi az or 1 if single + region_azs = var.multi_az ? slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, 3) : slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, 1) +} + +resource "random_string" "random_name" { + length = 6 + special = false + upper = false +} + +locals { + worker_node_replicas = var.multi_az ? 3 : 2 + # If cluster_name is not null, use that, otherwise generate a random cluster name + cluster_name = coalesce(var.cluster_name, "rosa-\${random_string.random_name.result}") +} + +# The network validator requires an additional 60 seconds to validate Terraform clusters. +resource "time_sleep" "wait_60_seconds" { + count = var.create_vpc ? 1 : 0 + depends_on = [module.vpc] + create_duration = "60s" +} + +module "rosa-hcp" { + source = "terraform-redhat/rosa-hcp/rhcs" + version = "1.6.2" + cluster_name = local.cluster_name + openshift_version = var.openshift_version + account_role_prefix = local.cluster_name + operator_role_prefix = local.cluster_name + replicas = local.worker_node_replicas + aws_availability_zones = local.region_azs + create_oidc = true + private = var.private_cluster + aws_subnet_ids = var.create_vpc ? var.private_cluster ? module.vpc[0].private_subnets : concat(module.vpc[0].public_subnets, module.vpc[0].private_subnets) : var.aws_subnet_ids + create_account_roles = true + create_operator_roles = true + + depends_on = [time_sleep.wait_60_seconds] +} +EOF +---- + +. Create the `variables.tf` file by running the following command: ++ +[NOTE] +==== +Copy and edit this file _before_ running the command to build your cluster. +==== ++ +[source,terminal] +---- +$ cat<<-EOF>variables.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +variable "openshift_version" { + type = string + default = "4.14.20" + description = "Desired version of OpenShift for the cluster, for example '4.14.20'. If version is greater than the currently running version, an upgrade will be scheduled." +} + +variable "create_vpc" { + type = bool + description = "If you would like to create a new VPC, set this value to 'true'. If you do not want to create a new VPC, set this value to 'false'." +} + +# ROSA Cluster info +variable "cluster_name" { + default = null + type = string + description = "The name of the ROSA cluster to create" +} + +variable "additional_tags" { + default = { + Terraform = "true" + Environment = "dev" + } + description = "Additional AWS resource tags" + type = map(string) +} + +variable "multi_az" { + type = bool + description = "Multi AZ Cluster for High Availability" + default = true +} + +variable "worker_node_replicas" { + default = 3 + description = "Number of worker nodes to provision. Single zone clusters need at least 2 nodes, multizone clusters need at least 3 nodes" + type = number +} + +variable "aws_subnet_ids" { + type = list(any) + description = "A list of either the public or public + private subnet IDs to use for the cluster blocks to use for the cluster" + default = ["subnet-01234567890abcdef", "subnet-01234567890abcdef", "subnet-01234567890abcdef"] +} + +variable "private_cluster" { + type = bool + description = "If you want to create a private cluster, set this value to 'true'. If you want a publicly available cluster, set this value to 'false'." +} + +#VPC Info +variable "vpc_name" { + type = string + description = "VPC Name" + default = "tf-qs-vpc" +} + +variable "vpc_cidr_block" { + type = string + description = "value of the CIDR block to use for the VPC" + default = "10.0.0.0/16" +} + +variable "private_subnet_cidrs" { + type = list(any) + description = "The CIDR blocks to use for the private subnets" + default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +} + +variable "public_subnet_cidrs" { + type = list(any) + description = "The CIDR blocks to use for the public subnets" + default = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] +} + +variable "single_nat_gateway" { + type = bool + description = "Single NAT or per NAT for subnet" + default = false +} + +#AWS Info +variable "aws_region" { + type = string + default = "us-east-2" +} + +variable "default_aws_tags" { + type = map(string) + description = "Default tags for AWS" + default = {} +} +EOF +---- + +. Create the `vpc.tf` file by running the following command: ++ +[source,terminal] +---- +$ cat<<-EOF>vpc.tf +# +# Copyright (c) 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "5.1.2" + + count = var.create_vpc ? 1 : 0 + name = var.vpc_name + cidr = var.vpc_cidr_block + + azs = local.region_azs + private_subnets = var.multi_az ? var.private_subnet_cidrs : [var.private_subnet_cidrs[0]] + public_subnets = var.multi_az ? var.public_subnet_cidrs : [var.public_subnet_cidrs[0]] + + enable_nat_gateway = true + single_nat_gateway = var.single_nat_gateway + enable_dns_hostnames = true + enable_dns_support = true + + tags = var.additional_tags +} +EOF +---- ++ +You are ready to initiate Terraform. \ No newline at end of file diff --git a/modules/rosa-sts-cluster-terraform-destroy.adoc b/modules/rosa-sts-cluster-terraform-destroy.adoc index dd4a1afb2e8e..917bb76b9c55 100644 --- a/modules/rosa-sts-cluster-terraform-destroy.adoc +++ b/modules/rosa-sts-cluster-terraform-destroy.adoc @@ -1,10 +1,13 @@ // Module included in the following assemblies: // -// * rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly-terraform.adoc +// * rosa_install_access_delete_clusters/rosa-classic-creating-a-cluster-quickly-terraform.adoc // -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] :tf-defaults: endif::[] +ifeval::["{context}" == "rosa-hcp-creating-a-cluster-quickly-terraform"] +:tf-rosa-hcp: +endif::[] :_content-type: PROCEDURE [id="sd-terraform-cluster-destroy_{context}"] @@ -14,11 +17,7 @@ Use the `terraform destroy` command to remove all of the resources that were cre [NOTE] ==== -Do not modify your Terraform `.tf` files -ifndef::tf-defaults[] -or the `terraform.tfvars` file -endif::tf-defaults[] -before destroying your resources. These variables are matched to resources to delete. +Do not modify your Terraform `.tf` files before destroying your resources. These variables are matched to resources to delete. ==== .Procedure @@ -28,33 +27,29 @@ before destroying your resources. These variables are matched to resources to de ---- $ terraform destroy ---- -ifndef::tf-defaults[] + -[IMPORTANT] -==== -After you enter the name of the ROSA cluster and confirm destruction by entering `yes`, you cannot stop the `terraform destroy` process. Your account, Operator roles, and cluster are deleted. -==== - -. Enter the name of the cluster that you want to delete: +The Terraform interface prompts you for two variables. These should match the answers you provided when creating a cluster: + [source,terminal] ---- -var.cluster_name - Provide the name of your ROSA cluster. +var.create_vpc + If you would like to create a new VPC, set this value to 'true.' If you do not want to create a new VPC, set this value to 'false.' + + Enter a value: - Enter a value: <1> +var.private_cluster + If you want to create a private cluster, set this value to 'true.' If you want a publicly available cluster, set this value to 'false.' + + Enter a value: ---- --- -<1> A valid value is the name of the ROSA cluster you want to delete. --- -endif::tf-defaults[] . Enter `yes` to start the role and cluster deletion: +ifdef::tf-rosa-hcp[] + -.Example output of Terraform confirmation: +.Example output [source,terminal] ---- -Plan: 0 to add, 0 to change, 39 to destroy. +Plan: 0 to add, 0 to change, 63 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. @@ -62,6 +57,21 @@ Do you really want to destroy all resources? Enter a value: yes ---- +endif::tf-rosa-hcp[] +ifdef::tf-rosa-classic[] ++ +.Example output +[source,terminal] +---- +Plan: 0 to add, 0 to change, 74 to destroy. + +Do you really want to destroy all resources? + Terraform will destroy all your managed infrastructure, as shown above. + There is no undo. Only 'yes' will be accepted to confirm. + + Enter a value: yes +---- +endif::tf-rosa-classic[] .Verification . Verify that your cluster was destroyed by running the following command: @@ -104,6 +114,9 @@ $ rosa list operator-roles I: Fetching operator roles I: No operator roles available ---- -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] :tf-defaults: +endif::[] +ifeval::["{context}" == "rosa-hcp-creating-a-cluster-quickly-terraform"] +:tf-rosa-hcp: endif::[] \ No newline at end of file diff --git a/modules/rosa-sts-cluster-terraform-execute.adoc b/modules/rosa-sts-cluster-terraform-execute.adoc index e7b08386e518..fd5748e63be8 100644 --- a/modules/rosa-sts-cluster-terraform-execute.adoc +++ b/modules/rosa-sts-cluster-terraform-execute.adoc @@ -1,9 +1,12 @@ // Module included in the following assemblies: // -// * rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly-terraform.adoc +// * rosa_install_access_delete_clusters/rosa-classic-creating-a-cluster-quickly-terraform.adoc // -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] -:tf-defaults: +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] +:tf-rosa-classic: +endif::[] +ifeval::["{context}" == "rosa-hcp-creating-a-cluster-quickly-terraform"] +:tf-rosa-hcp: endif::[] :_content-type: PROCEDURE @@ -43,13 +46,41 @@ Success! The configuration is valid. ---- $ terraform apply ---- ++ +The Terraform interface asks two questions to create your cluster, similiar to the following: ++ +.Example output +[source,terminal] +---- +var.create_vpc + If you would like to create a new VPC, set this value to 'true'. If you do not want to create a new VPC, set this value to 'false'. + + Enter a value: + +var.private_cluster + If you want to create a private cluster, set this value to 'true'. If you want a publicly available cluster, set this value to 'false'. + + Enter a value: +---- -. The Terraform interface lists the resources to be created or changed and prompts for confirmation. Enter `yes` to proceed or `no` to cancel: +. Enter `yes` to proceed or `no` to cancel when the Terraform interface lists the resources to be created or changed and prompts for confirmation: + +ifdef::tf-rosa-hcp[] .Example output [source,terminal] ---- -Plan: 39 to add, 0 to change, 0 to destroy. +Plan: 63 to add, 0 to change, 0 to destroy. + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. +---- +endif::tf-rosa-hcp[] +ifdef::tf-rosa-classic[] +.Example output +[source,terminal] +---- +Plan: 74 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. @@ -57,6 +88,7 @@ Do you want to perform these actions? Enter a value: yes ---- +endif::tf-rosa-classic[] + If you enter `yes`, your Terraform plan starts, creating your AWS account roles, Operator roles, and your ROSA Classic cluster. @@ -88,7 +120,9 @@ $ rosa list account-roles ---- I: Fetching account roles ROLE NAME ROLE TYPE ROLE ARN OPENSHIFT VERSION AWS Managed +ifdef::tf-rosa-classic[] ROSA-demo-ControlPlane-Role Control plane arn:aws:iam:::role/ROSA-demo-ControlPlane-Role 4.14 No +endif::tf-rosa-classic[] ROSA-demo-Installer-Role Installer arn:aws:iam:::role/ROSA-demo-Installer-Role 4.14 No ROSA-demo-Support-Role Support arn:aws:iam:::role/ROSA-demo-Support-Role 4.14 No ROSA-demo-Worker-Role Worker arn:aws:iam:::role/ROSA-demo-Worker-Role 4.14 No @@ -106,9 +140,17 @@ $ rosa list operator-roles ---- I: Fetching operator roles ROLE PREFIX AMOUNT IN BUNDLE +ifdef::tf-rosa-classic[] rosa-demo 6 +endif::tf-rosa-classic[] +ifdef::tf-rosa-hcp[] +rosa-demo 8 +endif::tf-rosa-hcp[] ---- -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] -:tf-defaults: +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] +:tf-rosa-classic: +endif::[] +ifeval::["{context}" == "rosa-hcp-creating-a-cluster-quickly-terraform"] +:tf-rosa-hcp: endif::[] diff --git a/modules/rosa-sts-cluster-terraform-file-creation.adoc b/modules/rosa-sts-cluster-terraform-file-creation.adoc deleted file mode 100644 index b94fc342bece..000000000000 --- a/modules/rosa-sts-cluster-terraform-file-creation.adoc +++ /dev/null @@ -1,542 +0,0 @@ -// Module included in the following assemblies: -// -// * rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly-terraform.adoc -// -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] -:tf-defaults: -endif::[] -:_content-type: PROCEDURE - -[id="rosa-sts-cluster-terraform-file-creation_{context}"] -= Creating your Terraform files locally - -After you set up your link:https://console.redhat.com/openshift/token[offline {cluster-manager-first} token], you need to create the Terraform files locally to build your cluster. You can create these files by using the following code templates. - -.Procedure - -. Create the `account-roles.tf` file by running the following command: -+ -[source,terminal] ----- -$ cat<<-EOF>account-roles.tf -data "rhcs_policies" "all_policies" {} - -data "rhcs_versions" "all" {} - -module "create_account_roles" { - source = "terraform-redhat/rosa-sts/aws" - version = ">=0.0.15" - - create_account_roles = true - create_operator_roles = false - - account_role_prefix = local.cluster_name - path = var.path - rosa_openshift_version = regex("^[0-9]+\\\\.[0-9]+", var.rosa_openshift_version) - account_role_policies = data.rhcs_policies.all_policies.account_role_policies - all_versions = data.rhcs_versions.all - operator_role_policies = data.rhcs_policies.all_policies.operator_role_policies - tags = var.additional_tags -} - -resource "time_sleep" "wait_10_seconds" { - depends_on = [module.create_account_roles] - - create_duration = "10s" -} -EOF ----- - -. Create the `main.tf` file by running the following command: -ifdef::tf-defaults[] -+ -[source,terminal] ----- -$ cat<<-EOF>main.tf -# -# Copyright (c) 2023 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.20.0" - } - rhcs = { - version = ">= 1.5.0" - source = "terraform-redhat/rhcs" - } - } -} - -# Export token using the RHCS_TOKEN environment variable -provider "rhcs" {} - -provider "aws" { - region = var.aws_region - ignore_tags { - key_prefixes = ["kubernetes.io/"] - } -} - -data "aws_availability_zones" "available" {} - -locals { - # Extract availability zone names for the specified region, limit it to 1 - region_azs = slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, 1) -} - -resource "random_string" "random_name" { - length = 6 - special = false - upper = false -} - -locals { - path = coalesce(var.path, "/") - sts_roles = { - role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Installer-Role", - support_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Support-Role", - instance_iam_roles = { - master_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-ControlPlane-Role", - worker_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Worker-Role" - }, - operator_role_prefix = local.cluster_name, - oidc_config_id = rhcs_rosa_oidc_config.oidc_config.id - } - worker_node_replicas = coalesce(var.worker_node_replicas, 2) - # If cluster_name is not null, use that, otherwise generate a random cluster name - cluster_name = coalesce(var.cluster_name, "rosa-\${random_string.random_name.result}") -} - -data "aws_caller_identity" "current" { -} - -resource "rhcs_cluster_rosa_classic" "rosa_sts_cluster" { - name = local.cluster_name - cloud_region = var.aws_region - multi_az = false - aws_account_id = data.aws_caller_identity.current.account_id - availability_zones = ["us-east-1a"] - tags = var.additional_tags - version = var.rosa_openshift_version - compute_machine_type = var.machine_type - replicas = local.worker_node_replicas - autoscaling_enabled = false - sts = local.sts_roles - properties = { - rosa_creator_arn = data.aws_caller_identity.current.arn - } - machine_cidr = var.vpc_cidr_block - - lifecycle { - precondition { - condition = can(regex("^[a-z][-a-z0-9]{0,13}[a-z0-9]\$", local.cluster_name)) - error_message = "ROSA cluster name must be less than 16 characters, be lower case alphanumeric, with only hyphens." - } - } - - depends_on = [time_sleep.wait_10_seconds] -} - -resource "rhcs_cluster_wait" "wait_for_cluster_build" { - cluster = rhcs_cluster_rosa_classic.rosa_sts_cluster.id - # timeout in minutes - timeout = 60 -} -EOF ----- -endif::tf-defaults[] -ifndef::tf-defaults[] -+ -[NOTE] -==== -Copy and edit this file _before_ running the command to build your cluster. -==== -+ -[source,terminal] ----- -$ cat<<-EOF>main.tf -# -# Copyright (c) 2023 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.20.0" - } - rhcs = { - version = ">= 1.5.0" - source = "terraform-redhat/rhcs" - } - } -} - -# Export token using the RHCS_TOKEN environment variable -provider "rhcs" {} - -provider "aws" { - region = var.aws_region - ignore_tags { - key_prefixes = ["kubernetes.io/"] - } -} - -data "aws_availability_zones" "available" { - state = "available" - - # New configuration to exclude Local Zones - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -locals { - # These lines will determine how many availability zones to extract based on if you are creating a single or multi AZ cluster. - az_count = var.multi_az ? 3 : 1 - region_azs = slice([for zone in data.aws_availability_zones.available.names : format("%s", zone)], 0, local.az_count) -} - -resource "random_string" "random_name" { - length = 6 - special = false - upper = false -} - -locals { - path = coalesce(var.path, "/") - sts_roles = { - role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Installer-Role", - support_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Support-Role", - instance_iam_roles = { - master_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-ControlPlane-Role", - worker_role_arn = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:role\${local.path}\${local.cluster_name}-Worker-Role" - }, - operator_role_prefix = local.cluster_name, - oidc_config_id = rhcs_rosa_oidc_config.oidc_config.id - } - worker_node_replicas = var.worker_node_replicas == null ? 3 : var.worker_node_replicas - # If cluster_name is not null, use that, otherwise generate a random cluster name - cluster_name = coalesce(var.cluster_name, "rosa-${random_string.random_name.result}") -} - -data "aws_caller_identity" "current" { -} - -resource "rhcs_cluster_rosa_classic" "rosa_sts_cluster" { - name = local.cluster_name - cloud_region = var.aws_region - multi_az = var.multi_az - aws_account_id = data.aws_caller_identity.current.account_id - availability_zones = local.region_azs - tags = var.additional_tags - version = var.rosa_openshift_version - proxy = var.proxy - compute_machine_type = var.machine_type - autoscaling_enabled = var.autoscaling_enabled - replicas = local.worker_node_replicas - min_replicas = var.min_replicas - max_replicas = var.max_replicas - - sts = local.sts_roles - properties = { - rosa_creator_arn = data.aws_caller_identity.current.arn - } - - admin_credentials = { - username = var.admin_username - password = var.admin_password - } - -# -#Private link settings -# - - private = var.private_cluster - aws_private_link = var.private_cluster - aws_subnet_ids = var.create_vpc ? concat(module.vpc[0].private_subnets, module.vpc[0].public_subnets) : var.private_subnet_ids - machine_cidr = var.private_cluster ? var.vpc_cidr_block : null - - lifecycle { - precondition { - condition = can(regex("^[a-z][-a-z0-9]{0,13}[a-z0-9]\$", local.cluster_name)) - error_message = "ROSA cluster name must be less than 16 characters, be lower case alphanumeric, with only hyphens." - } - } - - depends_on = [time_sleep.wait_10_seconds] -} - -resource "rhcs_cluster_wait" "wait_for_cluster_build" { - cluster = rhcs_cluster_rosa_classic.rosa_sts_cluster.id - # timeout in minutes - timeout = 60 -} -EOF ----- -endif::tf-defaults[] - -. Create the `oidc-provider.tf` file by running the following command: -+ -[source,terminal] ----- -$ cat<<-EOF>oidc-provider.tf -resource "rhcs_rosa_oidc_config" "oidc_config" { - managed = true -} - -data "rhcs_rosa_operator_roles" "operator_roles" { - operator_role_prefix = local.cluster_name - account_role_prefix = local.cluster_name -} - -module "oidc_provider" { - source = "terraform-redhat/rosa-sts/aws" - version = "0.0.15" - - create_operator_roles = false - create_oidc_provider = true - - cluster_id = "" - rh_oidc_provider_thumbprint = rhcs_rosa_oidc_config.oidc_config.thumbprint - rh_oidc_provider_url = rhcs_rosa_oidc_config.oidc_config.oidc_endpoint_url - tags = var.additional_tags - path = var.path -} -EOF ----- - -. Create the `operator-roles.tf` file by running the following command: -+ -[source,terminal] ----- -$ cat<<-EOF>operator-roles.tf -module "operator_roles" { - source = "terraform-redhat/rosa-sts/aws" - version = "0.0.15" - - create_operator_roles = true - create_oidc_provider = false - - rh_oidc_provider_thumbprint = rhcs_rosa_oidc_config.oidc_config.thumbprint - rh_oidc_provider_url = rhcs_rosa_oidc_config.oidc_config.oidc_endpoint_url - operator_roles_properties = data.rhcs_rosa_operator_roles.operator_roles.operator_iam_roles - tags = var.additional_tags - path = var.path -} -EOF ----- - -. Create the `variables.tf` file by running the following command: -ifndef::tf-defaults[] -+ -[NOTE] -==== -Copy and edit this file _before_ running the command to build your cluster. -==== -endif::tf-defaults[] -+ -[source,terminal] ----- -$ cat<<-EOF>variables.tf -variable "rosa_openshift_version" { - type = string - default = "4.16.0" - description = "Desired version of OpenShift for the cluster, for example '4.16.0'. If version is greater than the currently running version, an upgrade will be scheduled." -} - -variable "account_role_policies" { - description = "account role policies details for account roles creation" - type = object({ - sts_installer_permission_policy = string - sts_support_permission_policy = string - sts_instance_worker_permission_policy = string - sts_instance_controlplane_permission_policy = string - }) - default = null -} - -variable "operator_role_policies" { - description = "operator role policies details for operator roles creation" - type = object({ - openshift_cloud_credential_operator_cloud_credential_operator_iam_ro_creds_policy = string - openshift_cloud_network_config_controller_cloud_credentials_policy = string - openshift_cluster_csi_drivers_ebs_cloud_credentials_policy = string - openshift_image_registry_installer_cloud_credentials_policy = string - openshift_ingress_operator_cloud_credentials_policy = string - openshift_machine_api_aws_cloud_credentials_policy = string - }) - default = null -} - -# ROSA Cluster info -variable "cluster_name" { - default = null - type = string - description = "Provide the name of your ROSA cluster." -} - -variable "additional_tags" { - default = { - Terraform = "true" - } - description = "Additional AWS resource tags" - type = map(string) -} - -variable "path" { - description = "(Optional) The arn path for the account/operator roles as well as their policies." - type = string - default = null -} - -variable "machine_type" { - description = "The AWS instance type used for your default worker pool." - type = string - default = "m5.xlarge" -} - -variable "worker_node_replicas" { - default = 2 - description = "Number of worker nodes to provision. Single zone clusters need at least 2 nodes, multizone clusters need at least 3 nodes" - type = number -} - -variable "autoscaling_enabled" { - description = "Enables autoscaling. This variable requires you to set a maximum and minimum replicas range using the 'max_replicas' and 'min_replicas' variables. If the autoscaling_enabled is 'true', you cannot configure the worker_node_replicas." - type = string - default = "false" -} - -#VPC Info -variable "vpc_cidr_block" { - type = string - description = "The value of the IP address block for machines or cluster nodes for the VPC." - default = "10.0.0.0/16" -} - -#AWS Info -variable "aws_region" { - type = string - default = "us-east-1" -} -EOF ----- -ifndef::tf-defaults[] - -. Create the `vpc.tf` file by running the following command: -+ -[source,terminal] ----- -$ cat<<-EOF>vpc.tf -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "5.1.2" - - count = var.create_vpc ? 1 : 0 - name = var.vpc_name - cidr = var.vpc_cidr_block - - azs = var.availability_zones - private_subnets = var.private_subnet_cidrs - public_subnets = var.public_subnet_cidrs - - enable_nat_gateway = true - single_nat_gateway = var.single_nat_gateway - enable_dns_hostnames = true - enable_dns_support = true - - tags = var.additional_tags -} -EOF ----- - -. Create the `terraform.tfvars` file by running the following command: -+ -[NOTE] -==== -Use the `terraform.tfvars` file to change variables in one place without modifying the rest of your Terraform files when customizing your cluster. If you do not create a `terraform.tfvars` file, you are prompted for the required variables during cluster creation. - -Copy and edit this file _before_ running the command to build your cluster. -==== -+ -[source,terminal] ----- -$ cat<<-EOF>terraform.tfvars - -############################### -# General Cluster Information # -############################### - -# You can choose any OpenShift version that is currently supported. Make sure to use X.Y.Z when setting your version. -rosa_openshift_version = "4.14.0" - -# See the docs for options - https://docs.openshift.com/rosa/rosa_architecture/rosa_policy_service_definition/rosa-service-definition.html#rosa-sdpolicy-aws-instance-types_rosa-service-definition -machine_type = "m5.xlarge" -aws_region = "us-east-1" - -# If you want to create a single AZ cluster, set this variable to false, and then set the worker_node_replicas to 2. If you want to use a multi-AZ cluster, set this to true, then change the replica count to a multiple of 3. Autoscaling should also be in multiples of 3. -multi_az = "true" - -################# -# Machine pools # -################# - -# Setting this as true, requires you to set a maximum and minimum replicas range using the 'max_replicas' and 'min_replicas' variables. If the autoscaling_enabled is 'true', you cannot configure the worker_node_replicas." - -# autoscaling_enabled = "true" -# worker_node_replicas = null -# min_replicas = "6" -# max_replicas = "15" - -################### -# VPC Information # -################### - -vpc_cidr_block = "10.0.0.0/16" -create_vpc = "false" -private_cluster = "false" -# vpc_name = "rosa-vpc-tf" -# private_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] -# public_subnet_cidrs = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] -# single_nat_gateway = "false" - -EOF ----- -endif::tf-defaults[] - -ifdef::tf-defaults[] -You are ready to initiate Terraform. -endif::tf-defaults[] - -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] -:!tf-defaults: -endif::[] diff --git a/modules/rosa-sts-cluster-terraform-setup.adoc b/modules/rosa-sts-cluster-terraform-setup.adoc index 04efb7131733..4314657e5dbf 100644 --- a/modules/rosa-sts-cluster-terraform-setup.adoc +++ b/modules/rosa-sts-cluster-terraform-setup.adoc @@ -1,8 +1,8 @@ // Module included in the following assemblies: // -// * rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly-terraform.adoc +// * rosa_install_access_delete_clusters/rosa-classic-creating-a-cluster-quickly-terraform.adoc // -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] :tf-defaults: endif::[] :_content-type: PROCEDURE @@ -43,6 +43,6 @@ This environmental variable resets at the end of each session, such as restartin $ echo $RHCS_TOKEN ---- -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] :tf-defaults: endif::[] diff --git a/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc b/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc index 437ed75559ad..4ea8c845eb99 100644 --- a/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc +++ b/modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc @@ -10,7 +10,10 @@ endif::[] ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly"] :rosa-standalone: endif::[] -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] +:rosa-terraform: +endif::[] +ifeval::["{context}" == "rosa-hcp-creating-a-cluster-quickly-terraform"] :rosa-terraform: endif::[] @@ -55,18 +58,22 @@ endif::rosa-terraform[] |Cluster settings | ifdef::rosa-terraform[] -* Default cluster version: `4.16.0` +* Default cluster version: `4.14` * Cluster name: `rosa-<6-digit-alphanumeric-string>` +* Default AWS region for installations using the {cluster-manager-first} {hybrid-console-second}: us-east-2 (US East, Ohio) +* Availability: Multi zone for the data plane endif::rosa-terraform[] ifndef::rosa-terraform[] * Default cluster version: Latest -endif::rosa-terraform[] ifndef::rosa-hcp[] * Default AWS region for installations using the {cluster-manager-first} {hybrid-console-second}: us-east-1 (US East, North Virginia) endif::rosa-hcp[] +ifdef::rosa-hcp[] * Default AWS region for installations using the ROSA CLI (`rosa`): Defined by your `aws` CLI configuration -* Default EC2 IMDS endpoints (both v1 and v2) are enabled +endif::rosa-hcp[] * Availability: Single zone for the data plane +endif::rosa-terraform[] +* Default EC2 IMDS endpoints (both v1 and v2) are enabled * Monitoring for user-defined projects: Enabled |Encryption @@ -86,12 +93,24 @@ endif::rosa-hcp[] |Compute node machine pool |* Compute node instance type: m5.xlarge (4 vCPU 16, GiB RAM) +ifndef::rosa-terraform[] * Compute node count: 2 +endif::rosa-terraform[] +ifdef::rosa-terraform[] +* Compute node count: 3 +endif::rosa-terraform[] * Autoscaling: Not enabled * No additional node labels |Networking configuration -|* Cluster privacy: Public +| +ifndef::rosa-terraform[] +* Cluster privacy: Public +endif::rosa-terraform[] +ifdef::rosa-terraform[] +* Cluster privacy: public or private +* You can choose to create a new VPC during the Terraform cluster creation process. +endif::rosa-terraform[] ifdef::rosa-hcp[] * You must have configured your own Virtual Private Cloud (VPC) endif::rosa-hcp[] @@ -144,6 +163,6 @@ endif::[] ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly"] :!rosa-standalone: endif::[] -ifeval::["{context}" == "rosa-sts-creating-a-cluster-quickly-terraform"] +ifeval::["{context}" == "rosa-classic-creating-a-cluster-quickly-terraform"] :!rosa-terraform: endif::[] diff --git a/modules/rosa-terraform-overview.adoc b/modules/rosa-terraform-overview.adoc new file mode 100644 index 000000000000..00258c159fb5 --- /dev/null +++ b/modules/rosa-terraform-overview.adoc @@ -0,0 +1,11 @@ +// Module included in the following assemblies: +// +// * rosa_install_access_delete_clusters/rosa-classic-creating-a-cluster-quickly-terraform.adoc +// + +:_content-type: CONCEPT + +[id="rosa-terraform-overview_{context}"] += Overview of Terraform + +Terraform is an infrastructure-as-code tool that provides a way to configure your resources once and replicate those resources as desired. Terraform accomplishes the creation tasks by using declarative language. You declare what you want the final state of the infrastructure resource to be, and Terraform creates these resources to your specifications. \ No newline at end of file diff --git a/rosa_hcp/terraform/_attributes b/rosa_hcp/terraform/_attributes new file mode 120000 index 000000000000..20cc1dcb77bf --- /dev/null +++ b/rosa_hcp/terraform/_attributes @@ -0,0 +1 @@ +../../_attributes/ \ No newline at end of file diff --git a/rosa_hcp/terraform/images b/rosa_hcp/terraform/images new file mode 120000 index 000000000000..847b03ed0541 --- /dev/null +++ b/rosa_hcp/terraform/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/rosa_hcp/terraform/modules b/rosa_hcp/terraform/modules new file mode 120000 index 000000000000..36719b9de743 --- /dev/null +++ b/rosa_hcp/terraform/modules @@ -0,0 +1 @@ +../../modules/ \ No newline at end of file diff --git a/rosa_hcp/terraform/rosa-hcp-creating-a-cluster-quickly-terraform.adoc b/rosa_hcp/terraform/rosa-hcp-creating-a-cluster-quickly-terraform.adoc new file mode 100644 index 000000000000..7e88a8e30598 --- /dev/null +++ b/rosa_hcp/terraform/rosa-hcp-creating-a-cluster-quickly-terraform.adoc @@ -0,0 +1,33 @@ +:_content-type: ASSEMBLY +[id="rosa-hcp-creating-a-cluster-quickly-terraform"] += Creating a default ROSA cluster using Terraform +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: rosa-hcp-creating-a-cluster-quickly-terraform + +toc::[] + +Create a {product-title} (ROSA) cluster quickly by using a Terraform cluster template that is configured with the default cluster options. + +The cluster creation process described below uses a Terraform configuration that prepares a {hcp-title} cluster with the following resources: + +* An OIDC provider with a managed `oidc-config` configuration +* Prerequisite IAM Operator roles with associated AWS Managed ROSA Policies +* IAM account roles with associated AWS Managed ROSA Policies +* All other AWS resources required to create a ROSA with STS cluster + +include::modules/rosa-terraform-overview.adoc[leveloffset=+1] +include::modules/rosa-sts-terraform-prerequisites.adoc[leveloffset=+1] +[discrete] +include::modules/rosa-sts-terraform-considerations.adoc[leveloffset=+1] + +include::modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc[leveloffset=+1] + +[id="rosa-hcp-creating-a-cluster-quickly-terraform-procedure"] +== Creating a default ROSA cluster using Terraform + +The cluster creation process outlined below shows how to use Terraform to create your account-wide IAM roles and a ROSA cluster with a managed OIDC configuration. + +include::modules/rosa-sts-cluster-terraform-setup.adoc[leveloffset=+2] +include::modules/rosa-hcp-cluster-terraform-file-creation.adoc[leveloffset=+2] +include::modules/rosa-sts-cluster-terraform-execute.adoc[leveloffset=+2] +include::modules/rosa-sts-cluster-terraform-destroy.adoc[leveloffset=+2] \ No newline at end of file diff --git a/rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-with-customizations-terraform.adoc b/rosa_hcp/terraform/rosa-hcp-creating-a-cluster-with-customizations-terraform.adoc similarity index 93% rename from rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-with-customizations-terraform.adoc rename to rosa_hcp/terraform/rosa-hcp-creating-a-cluster-with-customizations-terraform.adoc index ed71e554a1f2..c15fa360a3ce 100644 --- a/rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-with-customizations-terraform.adoc +++ b/rosa_hcp/terraform/rosa-hcp-creating-a-cluster-with-customizations-terraform.adoc @@ -1,8 +1,8 @@ :_mod-docs-content-type: ASSEMBLY -[id="rosa-sts-creating-a-cluster-with-customizations-terraform"] +[id="rosa-sts-creating-a-cluster-with-customizations-terraform-hcp"] = Customizing a ROSA cluster with Terraform include::_attributes/attributes-openshift-dedicated.adoc[] -:context: rosa-sts-creating-a-cluster-with-customizations-terraform +:context: rosa-sts-creating-a-cluster-with-customizations-terraform-hcp toc::[] @@ -17,12 +17,12 @@ This guide assumes a basic understanding of ROSA. See the additional resources f * You have generated and stored an link:https://console.redhat.com/openshift/token[offline {cluster-manager-first} token]. * You have an AWS account with the correct permissions. -* You completed the xref:../../rosa_planning/rosa-cloud-expert-prereq-checklist.adoc[Prerequisites checklist for deploying ROSA using STS] -* You completed the setup steps in xref:../../rosa_planning/rosa-understanding-terraform.adoc[Preparing Terraform to install ROSA clusters] -* You have installed link:https://developer.hashicorp.com/terraform/install[the `terraform` CLI tool]. +* You completed the xref:../../rosa_planning/rosa-cloud-expert-prereq-checklist.adoc#rosa-cloud-expert-prereq-checklist[Prerequisites checklist for deploying ROSA using STS]. +* You completed the setup steps in xref:../../rosa_planning/rosa-understanding-terraform.adoc[Preparing Terraform to install ROSA clusters]. +* You have installed the link:https://developer.hashicorp.com/terraform/install[`terraform` CLI tool]. -[id="rosa-sts-creating-a-cluster-with-customizations-terraform-creating"] -== Creating a ROSA Classic cluster using Terraform +[id="rosa-sts-creating-a-cluster-with-customizations-terraform-creating-hcp"] +== Creating a {hcp-title} cluster using Terraform The cluster creation process outlined below shows how to use Terraform to create your account-wide IAM roles and a default ROSA cluster with a managed OIDC configuration. @@ -32,9 +32,9 @@ You edit the default `main.tf`, `variables.tf`, and `terraform.tfvars` files to ==== include::modules/rosa-sts-cluster-terraform-setup.adoc[leveloffset=+2] -include::modules/rosa-sts-cluster-terraform-file-creation.adoc[leveloffset=+2] +include::modules/rosa-hcp-cluster-terraform-file-creation.adoc[leveloffset=+2] -[id="rosa-sts-creating-a-cluster-with-customizations-terraform-customizing"] +[id="rosa-sts-creating-a-cluster-with-customizations-terraform-customizing-hcp"] == Terraform customization options The following sections detail individual customizations you can add to your `main.tf`, `variables.tf`, and `terraform.tfvars` files. diff --git a/rosa_hcp/terraform/snippets b/rosa_hcp/terraform/snippets new file mode 120000 index 000000000000..5a3f5add140e --- /dev/null +++ b/rosa_hcp/terraform/snippets @@ -0,0 +1 @@ +../../snippets/ \ No newline at end of file diff --git a/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc b/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc new file mode 100644 index 000000000000..df7b8f11fdac --- /dev/null +++ b/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc @@ -0,0 +1,32 @@ +:_content-type: ASSEMBLY +[id="rosa-classic-creating-a-cluster-quickly-terraform"] += Creating a default ROSA (classic architecture) cluster using Terraform +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: rosa-classic-creating-a-cluster-quickly-terraform + +toc::[] + +Create a {rosa-classic-first} cluster quickly by using a Terraform cluster template that is configured with the default cluster options. + +The cluster creation process described below uses a Terraform configuration that prepares a {rosa-classic} AWS Security Token Service (STS) cluster with the following resources: + +* An OIDC provider with a managed `oidc-config` configuration +* Prerequisite IAM Operator roles with associated AWS Managed ROSA Policies +* IAM account roles with associated AWS Managed ROSA Policies +* All other AWS resources required to create a ROSA with STS cluster + +include::modules/rosa-terraform-overview.adoc[leveloffset=+1] +include::modules/rosa-sts-terraform-prerequisites.adoc[leveloffset=+1] +[discrete] +include::modules/rosa-sts-terraform-considerations.adoc[leveloffset=+1] +include::modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc[leveloffset=+1] + +[id="rosa-classic-creating-a-cluster-quickly-terraform-procedure"] +== Creating a default {rosa-classic} cluster using Terraform + +The cluster creation process outlined below shows how to use Terraform to create your account-wide IAM roles and a {rosa-classic} cluster with a managed OIDC configuration. + +include::modules/rosa-sts-cluster-terraform-setup.adoc[leveloffset=+2] +include::modules/rosa-classic-cluster-terraform-file-creation.adoc[leveloffset=+2] +include::modules/rosa-sts-cluster-terraform-execute.adoc[leveloffset=+2] +include::modules/rosa-sts-cluster-terraform-destroy.adoc[leveloffset=+2] \ No newline at end of file diff --git a/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-with-customizations-terraform.adoc b/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-with-customizations-terraform.adoc new file mode 100644 index 000000000000..d506765e24a3 --- /dev/null +++ b/rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-with-customizations-terraform.adoc @@ -0,0 +1,72 @@ +:_mod-docs-content-type: ASSEMBLY +[id="rosa-classic-creating-a-cluster-with-customizations-terraform-classic"] += Customizing a ROSA cluster with Terraform +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: rosa-classic-creating-a-cluster-with-customizations-terraform-classic + +toc::[] + +You can use Terraform to create a customized {product-title} (ROSA) cluster by using Terraform to customize the cluster's details. + +[NOTE] +==== +This guide assumes a basic understanding of ROSA. See the "Additional resources" for conceptual information about ROSA clusters. +==== + +.Prerequisites + +* You have generated and stored an link:https://console.redhat.com/openshift/token[offline {cluster-manager-first} token]. +* You have an AWS account with the correct permissions. +* You completed the xref:../../rosa_planning/rosa-cloud-expert-prereq-checklist.adoc[Prerequisites checklist for deploying ROSA using STS] +* You completed the setup steps in xref:../../rosa_planning/rosa-understanding-terraform.adoc[Preparing Terraform to install ROSA clusters] +* You have installed the link:https://developer.hashicorp.com/terraform/install[the `terraform` CLI tool]. + +[id="rosa-classic-creating-a-cluster-with-customizations-terraform-creating"] +== Creating a ROSA Classic cluster using Terraform + +The following cluster creation process shows how to use Terraform to create your account-wide IAM roles and a default ROSA cluster with a managed OIDC configuration. + +[NOTE] +==== +You edit the default `main.tf`, `variables.tf`, and `terraform.tfvars` files to customize a cluster. Cluster customizations must be performed before you create a cluster. To customize, copy the default Terraform file from the procedure below and make the desired changes. +==== + +include::modules/rosa-sts-cluster-terraform-setup.adoc[leveloffset=+2] +include::modules/rosa-classic-cluster-terraform-file-creation.adoc[leveloffset=+2] + +[id="rosa-classic-creating-a-cluster-with-customizations-terraform-customizing"] +== Terraform customization options + +The following sections detail individual customizations you can add to your `main.tf`, `variables.tf`, and `terraform.tfvars` files. + +include::modules/rosa-cluster-cluster-role-name-change.adoc[leveloffset=+2] +include::modules/rosa-cluster-enable-autoscaling-terraform.adoc[leveloffset=+2] +include::modules/rosa-sts-cluster-terraform-execute.adoc[leveloffset=+1] +include::modules/rosa-sts-cluster-terraform-destroy.adoc[leveloffset=+1] + +[id="next-steps_{context}"] +== Next steps + +* xref:../../rosa_install_access_delete_clusters/rosa-sts-accessing-cluster.adoc#rosa-sts-accessing-cluster[Accessing a ROSA cluster] + +[role="_additional-resources"] +[id="additional-resources_rosa-classic-creating-a-cluster-with-customizations-terraform"] +== Additional resources + +* For information about the managing objects with the CLI, see the xref:../../cli_reference/rosa_cli/rosa-manage-objects-cli.adoc#rosa-create-cluster-command_rosa-managing-objects-cli[create cluster] section. +* For information about the security groups, see xref:../../rosa_install_access_delete_clusters/rosa_getting_started_iam/rosa-aws-prereqs.adoc#rosa-security-groups_prerequisites[Security groups] in the AWS documentation. +* For details on creating account-wide roles, see xref:../../rosa_architecture/rosa-sts-about-iam-resources.adoc#rosa-sts-account-wide-roles-and-policies-creation-methods_rosa-sts-about-iam-resources[Methods of account-wide role creation]. +* For detailed steps to create and link the {cluster-manager} and user IAM roles, see xref:../../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-customizations-ocm_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster with customizations by using OpenShift Cluster Manager]. +* For the steps to specify custom ARN paths for IAM resources when you create {product-title} clusters, see xref:../../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-using-customizations_rosa-sts-creating-a-cluster-with-customizations[Creating a cluster using customizations]. +* For more information about the default components required for an AWS cluster, see link:https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html[Default VPCs] in the AWS documentation. +* For instructions on creating a VPC in the AWS console, see link:https://docs.aws.amazon.com/vpc/latest/userguide/create-vpc.html[Create a VPC] in the AWS documentation. +* For more information on configuring a ROSA cluster within a shared virtual private cloud (VPC), see xref:../../rosa_install_access_delete_clusters/rosa-shared-vpc-config.adoc#rosa-shared-vpc-config[Configuring a shared VPC for ROSA clusters]. +* For more information about the AWS Identity Access Management (IAM) resources required to deploy {product-title} with STS, see xref:../../rosa_architecture/rosa-sts-about-iam-resources.adoc#rosa-sts-about-iam-resources[About IAM resources for clusters that use STS]. +* For details about optionally setting an Operator role name prefix, see xref:../../rosa_architecture/rosa-sts-about-iam-resources.adoc#rosa-sts-about-operator-role-prefixes_rosa-sts-about-iam-resources[About custom Operator IAM role prefixes]. +* For an overview of the options that are presented when you create the AWS IAM resources and clusters by using interactive mode, see xref:../../rosa_install_access_delete_clusters/rosa-sts-interactive-mode-reference.adoc#rosa-sts-interactive-mode-reference[Interactive cluster creation mode reference]. +* For information about the prerequisites to installing ROSA with STS, see xref:../../rosa_planning/rosa-sts-aws-prereqs.adoc#rosa-sts-aws-prereqs[AWS prerequisites for ROSA with STS]. +* For more information about using OpenID Connect (OIDC) identity providers in AWS IAM, see link:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html[Creating OpenID Connect (OIDC) identity providers] in the AWS documentation. +* For more information about etcd encryption, see the xref:../../rosa_architecture/rosa_policy_service_definition/rosa-service-definition.adoc#rosa-sdpolicy-etcd-encryption_rosa-service-definition[etcd encryption service definition]. +* For information about configuring a proxy with ROSA, see xref:../../networking/configuring-cluster-wide-proxy.adoc#configuring-a-cluster-wide-proxy[Configuring a cluster-wide proxy]. +* For more information about troubleshooting ROSA cluster installations, see xref:../../support/troubleshooting/rosa-troubleshooting-deployments.adoc#rosa-troubleshooting-cluster-deployments[Troubleshooting cluster deployments]. +* For steps to contact Red Hat Support for assistance, see xref:../../support/getting-support.adoc#getting-support[Getting support for Red Hat OpenShift Service on AWS]. diff --git a/rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-quickly-terraform.adoc b/rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-quickly-terraform.adoc deleted file mode 100644 index 702f2da0e0dc..000000000000 --- a/rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-quickly-terraform.adoc +++ /dev/null @@ -1,41 +0,0 @@ -:_content-type: ASSEMBLY -[id="rosa-sts-creating-a-cluster-quickly-terraform"] -= Creating a default ROSA Classic cluster using Terraform -include::_attributes/attributes-openshift-dedicated.adoc[] -:context: rosa-sts-creating-a-cluster-quickly-terraform - -toc::[] - -Quickly create a {product-title} (ROSA) cluster quickly by using a Terraform cluster template that is configured with the default cluster options. - -[NOTE] -==== -* For a quickstart guide for ROSA, see xref:../../rosa_getting_started/rosa-quickstart-guide-ui.adoc#rosa-quickstart-guide-ui[{product-title} quickstart guide]. -* To install ROSA clusters with the default options by using the CLI or {cluster-manager-url}, see xref:../../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-quickly.adoc#rosa-sts-creating-a-cluster-quickly-ocm_rosa-sts-creating-a-cluster-quickly[Creating a ROSA cluster with STS using the default options]. -* For steps to deploy a ROSA cluster by using `manual` mode or with customizations, see xref:../../rosa_install_access_delete_clusters/rosa-sts-creating-a-cluster-with-customizations.adoc#rosa-sts-creating-cluster-using-customizations_rosa-sts-creating-a-cluster-with-customizations[Creating a ROSA cluster with STS using customizations]. -==== - -The cluster creation process described below uses a Terraform configuration that prepares a ROSA Classic AWS Security Token Service (STS) cluster with the following resources: - -* An OIDC provider with a managed `oidc-config` -* Prerequisite Operator roles with policies -* IAM account roles with policies -* All other AWS resources required to create a ROSA with STS cluster - -[id="next-steps_{context}"] -.Prerequisites - -* You have completed the xref:../../rosa_planning/rosa-sts-aws-prereqs.adoc[Detailed requirements for deploying ROSA using STS]. -* You have completed the xref:../../rosa_planning/rosa-understanding-terraform.adoc#rosa-sts-terraform-prerequisites_rosa-understanding-terraform[Prerequisites for Terraform]. - -include::modules/rosa-sts-overview-of-the-default-cluster-specifications.adoc[leveloffset=+1] - -[id="rosa-sts-creating-a-cluster-quickly-terraform-procedure"] -== Creating a default ROSA cluster using Terraform - -The cluster creation process outlined below shows how to use Terraform to create your account-wide IAM roles and a ROSA cluster with a managed OIDC configuration. - -include::modules/rosa-sts-cluster-terraform-setup.adoc[leveloffset=+2] -include::modules/rosa-sts-cluster-terraform-file-creation.adoc[leveloffset=+2] -include::modules/rosa-sts-cluster-terraform-execute.adoc[leveloffset=+2] -include::modules/rosa-sts-cluster-terraform-destroy.adoc[leveloffset=+2] \ No newline at end of file diff --git a/rosa_planning/rosa-understanding-terraform.adoc b/rosa_planning/rosa-understanding-terraform.adoc index eef9faebe064..6410fe2dd8a2 100644 --- a/rosa_planning/rosa-understanding-terraform.adoc +++ b/rosa_planning/rosa-understanding-terraform.adoc @@ -20,14 +20,13 @@ include::modules/rosa-sts-terraform-considerations.adoc[leveloffset=+1] * See xref:../rosa_architecture/rosa-sts-about-iam-resources.adoc[About IAM resources for ROSA clusters that use STS] for information about the AWS account roles. * See xref:../cli_reference/rosa_cli/rosa-get-started-cli.adoc[Getting started with the ROSA CLI] for information about installing the ROSA CLI. * See Hashicorp's link:https://developer.hashicorp.com/terraform[Terraform documentation] for a comprehensive guide to Terraform. -* See this xref:../rosa_planning/rosa-understanding-terraform.adoc#sd-terraform-account-roles_rosa-understanding-terraform[Terraform example] to create your account-wide IAM roles. - -include::modules/rosa-sts-account-roles-terraform.adoc[leveloffset=+1] [id="next-steps_rosa-understanding-terraform"] == Next steps * xref:../rosa_planning/rosa-planning-environment.adoc#rosa-planning-environment[Planning your environment] +* xref:../rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc#rosa-classic-creating-a-cluster-quickly-terraform[Creating a default ROSA (classic architecture) cluster using Terraform] +* Creating a default ROSA cluster using Terraform [role="_additional-resources"] [id="additional-resources_rosa-understanding-terraform"] diff --git a/snippets/terraform-modification-disclaimer.adoc b/snippets/terraform-modification-disclaimer.adoc index 3e7911ac7de7..f5526a53b30b 100644 --- a/snippets/terraform-modification-disclaimer.adoc +++ b/snippets/terraform-modification-disclaimer.adoc @@ -1,6 +1,6 @@ // Module included in the following assemblies: // -// * rosa_install_access_delete_clusters/terraform/rosa-sts-creating-a-cluster-quickly-terraform.adoc +// * rosa_install_access_delete_clusters/terraform/rosa-classic-creating-a-cluster-quickly-terraform.adoc // * rosa_planning/rosa-understanding-terraform.adoc :_mod-docs-content-type: SNIPPET From fa396774bbd2ef3fa2ff40e11a1323a461a9d5f4 Mon Sep 17 00:00:00 2001 From: Jesse Dohmann Date: Tue, 11 Jun 2024 11:10:36 -0700 Subject: [PATCH 327/339] OSDOCS-9735: add customize subcommand iscsi procedures --- ...ing-bare-metal-network-customizations.adoc | 8 +++ .../installing-bare-metal.adoc | 8 +++ ...alling-restricted-networks-bare-metal.adoc | 8 +++ ...-advanced-customizing-live-iscsi-ibft.adoc | 65 +++++++++++++++++++ ...dvanced-customizing-live-iscsi-manual.adoc | 64 ++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc create mode 100644 modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc diff --git a/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc b/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc index 5f521b46ccd2..554864af34ac 100644 --- a/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc +++ b/installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc @@ -141,6 +141,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: @@ -153,6 +157,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: diff --git a/installing/installing_bare_metal/installing-bare-metal.adoc b/installing/installing_bare_metal/installing-bare-metal.adoc index 00655ff80cab..113ce699abd2 100644 --- a/installing/installing_bare_metal/installing-bare-metal.adoc +++ b/installing/installing_bare_metal/installing-bare-metal.adoc @@ -169,6 +169,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: @@ -181,6 +185,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: diff --git a/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc b/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc index c58904744eaa..a7779da1a826 100644 --- a/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc +++ b/installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc @@ -162,6 +162,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: @@ -174,6 +178,10 @@ include::modules/installation-user-infra-machines-advanced-customizing-live-seri include::modules/installation-user-infra-machines-advanced-customizing-live-ca-certs.adoc[leveloffset=+4] include::modules/installation-user-infra-machines-advanced-customizing-live-network-config.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc[leveloffset=+4] + +include::modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc[leveloffset=+4] :boot-media!: :boot!: diff --git a/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc b/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc new file mode 100644 index 000000000000..67436f29af20 --- /dev/null +++ b/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-ibft.adoc @@ -0,0 +1,65 @@ +// Module included in the following assemblies +// +// * installing/installing_bare_metal/installing-bare-metal.adoc +// * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc +// * installing_bare_metal/installing-bare-metal-network-customizations.adoc + +:_mod-docs-content-type: PROCEDURE +[id="installation-user-infra-machines-advanced-customizing-live-{boot}-iscsi-ibft_{context}"] += Customizing a live install {boot-media} for an iSCSI boot device with iBFT + +You can set the iSCSI target and initiator values for automatic mounting, booting and configuration using a customized version of the live {op-system} image. + +.Prerequisites +. You have an iSCSI target you want to install {op-system} on. +. Optional: you have multipathed your iSCSI target. + +.Procedure + +. Download the `coreos-installer` binary from the link:https://mirror.openshift.com/pub/openshift-v4/clients/coreos-installer/latest/[`coreos-installer` image mirror] page. + +ifeval::["{boot-media}" == "ISO image"] +. Retrieve the {op-system} ISO image from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/latest/[{op-system} image mirror] page and run the following command to customize the ISO image with the following information: ++ +[source,text] +---- +$ coreos-installer iso customize \ + --pre-install mount-iscsi.sh \ <1> + --post-install unmount-iscsi.sh \ <2> + --dest-device /dev/mapper/mpatha \ <3> + --dest-ignition config.ign \ <4> + --dest-karg-append rd.iscsi.firmware=1 \ <5> + --dest-karg-append rd.multipath=default \ <6> + -o custom.iso rhcos--live.x86_64.iso +---- +<1> The script that gets run before installation. It should contain the `iscsiadm` commands for mounting the iSCSI target and any commands enabling multipathing. +<2> The script that gets run after installation. It should contain the command `iscsiadm --mode node --logout=all`. +<3> The path to the device. If you are using multipath, the multipath device, `/dev/mapper/mpatha`, If there are multiple multipath devices connected, or to be explicit, you can use the World Wide Name (WWN) symlink available in `/dev/disk/by-path`. +<4> The Ignition configuration for the destination system. +<5> The iSCSI parameter is read from the BIOS firmware. +<6> Optional: include this parameter if you are enabling multipathing. +endif::[] + +ifeval::["{boot-media}" == "PXE environment"] +. Retrieve the {op-system} `kernel`, `initramfs` and `rootfs` files from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/latest/[{op-system} image mirror] page and run the following command to create a new customized `initramfs` file with the following information: ++ +[source,text] +---- +$ coreos-installer pxe customize \ + --pre-install mount-iscsi.sh \ <1> + --post-install unmount-iscsi.sh \ <2> + --dest-device /dev/mapper/mpatha \ <3> + --dest-ignition config.ign \ <4> + --dest-karg-append rd.iscsi.firmware=1 \ <5> + --dest-karg-append rd.multipath=default \ <6> + -o custom.img rhcos--live-initramfs.x86_64.img +---- +<1> The script that gets run before installation. It should contain the `iscsiadm` commands for mounting the iSCSI target. +<2> The script that gets run after installation. It should contain the command `iscsiadm --mode node --logout=all`. +<3> The path to the device. If you are using multipath, the multipath device, `/dev/mapper/mpatha`, If there are multiple multipath devices connected, or to be explicit, you can use the World Wide Name (WWN) symlink available in `/dev/disk/by-path`. +<4> The Ignition configuration for the destination system. +<5> The iSCSI parameter is read from the BIOS firmware. +<6> Optional: include this parameter if you are enabling multipathing. +endif::[] ++ +For more information about the iSCSI options supported by `dracut`, see the link:https://www.man7.org/linux/man-pages/man7/dracut.cmdline.7.html[`dracut.cmdline` manual page]. diff --git a/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc b/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc new file mode 100644 index 000000000000..052bd7ce49d9 --- /dev/null +++ b/modules/installation-user-infra-machines-advanced-customizing-live-iscsi-manual.adoc @@ -0,0 +1,64 @@ +// Module included in the following assemblies +// +// * installing/installing_bare_metal/installing-bare-metal.adoc +// * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc +// * installing_bare_metal/installing-bare-metal-network-customizations.adoc + +:_mod-docs-content-type: PROCEDURE +[id="installation-user-infra-machines-advanced-customizing-live-{boot}-iscsi-manual_{context}"] += Customizing a live install {boot-media} for an iSCSI boot device + +You can set the iSCSI target and initiator values for automatic mounting, booting and configuration using a customized version of the live {op-system} image. + +.Prerequisites +. You have an iSCSI target you want to install {op-system} on. + +.Procedure + +. Download the `coreos-installer` binary from the link:https://mirror.openshift.com/pub/openshift-v4/clients/coreos-installer/latest/[`coreos-installer` image mirror] page. + +ifeval::["{boot-media}" == "ISO image"] +. Retrieve the {op-system} ISO image from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/latest/[{op-system} image mirror] page and run the following command to customize the ISO image with the following information: ++ +[source,text] +---- +$ coreos-installer iso customize \ + --pre-install mount-iscsi.sh \ <1> + --post-install unmount-iscsi.sh \ <2> + --dest-device /dev/disk/by-path/:-iscsi--lun- \ <3> + --dest-ignition config.ign \ <4> + --dest-karg-append rd.iscsi.initiator= \ <5> + --dest-karg-append netroot= \ <6> + -o custom.iso rhcos--live.x86_64.iso +---- +<1> The script that gets run before installation. It should contain the `iscsiadm` commands for mounting the iSCSI target and any commands enabling multipathing. +<2> The script that gets run after installation. It should contain the command `iscsiadm --mode node --logout=all`. +<3> The location of the destination system. You must provide the IP address of the target portal, the associated port number, the target iSCSI node in IQN format, and the iSCSI logical unit number (LUN). +<4> The Ignition configuration for the destination system. +<5> The iSCSI initiator, or client, name in IQN format. The initiator forms a session to connect to the iSCSI target. +<6> The the iSCSI target, or server, name in IQN format. +endif::[] + +ifeval::["{boot-media}" == "PXE environment"] +. Retrieve the {op-system} `kernel`, `initramfs` and `rootfs` files from the link:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/latest/[{op-system} image mirror] page and run the following command to create a new customized `initramfs` file with the following information: ++ +[source,text] +---- +$ coreos-installer pxe customize \ + --pre-install mount-iscsi.sh \ <1> + --post-install unmount-iscsi.sh \ <2> + --dest-device /dev/disk/by-path/:-iscsi--lun- \ <3> + --dest-ignition config.ign \ <4> + --dest-karg-append rd.iscsi.initiator= \ <5> + --dest-karg-append netroot= \ <6> + -o custom.img rhcos--live-initramfs.x86_64.img +---- +<1> The script that gets run before installation. It should contain the `iscsiadm` commands for mounting the iSCSI target and any commands enabling multipathing. +<2> The script that gets run after installation. It should contain the command `iscsiadm --mode node --logout=all`. +<3> The location of the destination system. You must provide the IP address of the target portal, the associated port number, the target iSCSI node in IQN format, and the iSCSI logical unit number (LUN). +<4> The Ignition configuration for the destination system. +<5> The iSCSI initiator, or client, name in IQN format. The initiator forms a session to connect to the iSCSI target. +<6> The the iSCSI target, or server, name in IQN format. +endif::[] ++ +For more information about the iSCSI options supported by `dracut`, see the link:https://www.man7.org/linux/man-pages/man7/dracut.cmdline.7.html[`dracut.cmdline` manual page]. From eba43ecc64d2bcb2d20c58d35491ed8f38c3ef56 Mon Sep 17 00:00:00 2001 From: bmcelvee Date: Wed, 1 May 2024 15:19:19 -0400 Subject: [PATCH 328/339] OSDOCS-10430: Create ROSA HCP distro --- _distro_map.yml | 13 +++++++++++++ _templates/_page_openshift.html.erb | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/_distro_map.yml b/_distro_map.yml index 83f31201cb8c..02927e3af1b7 100644 --- a/_distro_map.yml +++ b/_distro_map.yml @@ -187,6 +187,19 @@ openshift-rosa: rosa-preview: name: '' dir: rosa-preview/ +openshift-rosa-hcp: + name: Red Hat OpenShift Service on AWS + author: OpenShift Documentation Project + site: commercial + site_name: Documentation + site_url: https://docs.openshift.com/ + branches: + enterprise-4.15: + name: '' + dir: rosa-hcp/ + rosa-preview: + name: '' + dir: rosa-hcp-preview/ openshift-rosa-portal: name: Red Hat OpenShift Service on AWS author: OpenShift Documentation Project diff --git a/_templates/_page_openshift.html.erb b/_templates/_page_openshift.html.erb index 3160fd0150e6..cb7a1482455e 100644 --- a/_templates/_page_openshift.html.erb +++ b/_templates/_page_openshift.html.erb @@ -67,7 +67,7 @@ <% end %> - <% if (version == "4.16") && (distro_key != "openshift-webscale" && distro_key != "openshift-dpu") %> + <% if (version == "4.16") && (distro_key != "openshift-webscale" && distro_key != "openshift-dpu" && distro_key != "rosa-hcp") %>

    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 literal 0 HcmV?d00001 diff --git a/modules/nw-sriov-about-qinq.adoc b/modules/nw-sriov-about-qinq.adoc index 59fe851ec092..d75393439417 100644 --- a/modules/nw-sriov-about-qinq.adoc +++ b/modules/nw-sriov-about-qinq.adoc @@ -11,7 +11,7 @@ In traditional VLAN setups, frames typically contain a single VLAN tag, such as QinQ facilitates the creation of nested VLANs by using double VLAN tagging, enabling finer segmentation and isolation of traffic within a network environment. This approach is particularly valuable in service provider networks where you need to deliver VLAN-based services to multiple customers over a common infrastructure, while ensuring separation and isolation of traffic. -When two VLAN tags are present in a packet, the outer VLAN tag can be either 802.1Q or 802.1ad. The inner VLAN tag must always be 802.1Q. +image::693_OpenShift_QinQ_SR-IOV_CNI_0624.png[QinQ] The {product-title} SR-IOV solution already supports setting the VLAN protocol on the `SriovNetwork` custom resource (CR). The virtual function (VF) can use this protocol to set the VLAN tag, also known as the outer tag. Pods can then use the VLAN CNI plugin to configure the inner tag. From 72bfdacb2e69385209e54877a8aff4d772c6cbb6 Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Fri, 14 Jun 2024 12:09:18 -0400 Subject: [PATCH 199/339] OSDOCS-10898: RHEL-versioned ccoctl --- modules/cco-ccoctl-configuring.adoc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/cco-ccoctl-configuring.adoc b/modules/cco-ccoctl-configuring.adoc index 635d49f47fc5..3486210eeeab 100644 --- a/modules/cco-ccoctl-configuring.adoc +++ b/modules/cco-ccoctl-configuring.adoc @@ -360,14 +360,22 @@ Ensure that the architecture of the `$RELEASE_IMAGE` matches the architecture of + [source,terminal] ---- -$ oc image extract $CCO_IMAGE --file="/usr/bin/ccoctl" -a ~/.pull-secret +$ oc image extract $CCO_IMAGE \ + --file="/usr/bin/ccoctl." \// <1> + -a ~/.pull-secret ---- +<1> For ``, specify the value that corresponds to the version of {op-system-base-full} that the host uses. +If no value is specified, `ccoctl.rhel8` is used by default. +The following values are valid: ++ +* `rhel8`: Specify this value for hosts that use {op-system-base} 8. +* `rhel9`: Specify this value for hosts that use {op-system-base} 9. . Change the permissions to make `ccoctl` executable by running the following command: + [source,terminal] ---- -$ chmod 775 ccoctl +$ chmod 775 ccoctl. ---- .Verification From 05a9b8b1a9621dac526f198329d848f2316d5453 Mon Sep 17 00:00:00 2001 From: srir Date: Mon, 17 Jun 2024 10:48:02 +0530 Subject: [PATCH 200/339] OCPBUGS#35537: Updated a command in the installation proc --- modules/multi-arch-installing-using-cli.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/multi-arch-installing-using-cli.adoc b/modules/multi-arch-installing-using-cli.adoc index 36a2062f8f68..f80faee04da9 100644 --- a/modules/multi-arch-installing-using-cli.adoc +++ b/modules/multi-arch-installing-using-cli.adoc @@ -19,7 +19,7 @@ You can install the Multiarch Tuning Operator by using the {oc-first}. + [source,terminal] ---- -$ oc new-project openshift-multiarch-tuning-operator +$ oc create ns openshift-multiarch-tuning-operator ---- . Create an `OperatorGroup` object: From b67406ecb67a6b2380df2b2f4f8f91310db2bdd4 Mon Sep 17 00:00:00 2001 From: Alisha Prabhu Date: Wed, 12 Jun 2024 11:23:12 +0530 Subject: [PATCH 201/339] To add DCs to installer for OCP 4.16 --- modules/installation-ibm-cloud-regions.adoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/installation-ibm-cloud-regions.adoc b/modules/installation-ibm-cloud-regions.adoc index 115ba1f87e84..deb07feeec97 100644 --- a/modules/installation-ibm-cloud-regions.adoc +++ b/modules/installation-ibm-cloud-regions.adoc @@ -49,11 +49,18 @@ ifdef::ibm-power-vs[] * `eu-de` (Frankfurt, Germany) ** `eu-de-1` ** `eu-de-2` +* `lon` (London, UK) +** `lon04` * `mad` (Madrid, Spain) ** `mad02` ** `mad04` +* `osa` (Osaka, Japan) +** `osa21` * `sao` (Sao Paulo, Brazil) +** `sao01` ** `sao04` +* `syd` (Sydney, Australia) +** `syd04` * `wdc` (Washington DC, USA) ** `wdc06` ** `wdc07` From 920be56b1dd3b4996856862d3e5af7f5d62f5e0c Mon Sep 17 00:00:00 2001 From: Max Leonov Date: Mon, 17 Jun 2024 16:44:50 +0200 Subject: [PATCH 202/339] OBSDOCS-1132: Known issues for the release notes for the Distributed Tracing 3.2.1 patch --- .../distr_tracing_rn/distr-tracing-rn-3-2-1.adoc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc index 470344e1f6ef..c86b2f9cc1c8 100644 --- a/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc +++ b/observability/distr_tracing/distr_tracing_rn/distr-tracing-rn-3-2-1.adoc @@ -17,12 +17,10 @@ This release of the {DTProductName} includes the {TempoName} and the deprecated This release fixes link:https://access.redhat.com/security/cve/CVE-2024-25062/[CVE-2024-25062]. -//// [id="distributed-tracing-rn_3-2-1_tempo-release-notes_{context}"] == {TempoName} The {TempoName} is provided through the {TempoOperator}. -//// //// [id="distributed-tracing-rn_3-2-1_tempo-release-notes_technology-preview-features_{context}"] @@ -68,16 +66,14 @@ This update introduces the following bug fixes: * Before this update, ... . (link:https://issues.redhat.com/browse/TRACING-????[TRACING-????]) //// -//// [id="distributed-tracing-rn_3-2-1_tempo-release-notes_known-issues_{context}"] === Known issues There is currently a known issue: * Currently, the {TempoShortName} fails on the IBM Z (`s390x`) architecture. (link:https://issues.redhat.com/browse/TRACING-3545[TRACING-3545]) -//// -//// + [id="distributed-tracing-rn_3-2-1_jaeger-release-notes_{context}"] == {JaegerName} @@ -87,7 +83,6 @@ The {JaegerName} is provided through the {JaegerOperator} Operator. ==== Jaeger does not use FIPS validated cryptographic modules. ==== -//// //// [id="distributed-tracing-rn_3-2-1_jaeger-release-notes_support-for-elasticsearch-operator_{context}"] @@ -126,7 +121,6 @@ This update introduces the following enhancements for the {JaegerShortName}: * {JaegerName} 3.2.1 is based on the open source link:https://www.jaegertracing.io/[Jaeger] release 1.57.0. //// -//// [id="distributed-tracing-rn_3-2-1_jaeger-release-notes_known-issues_{context}"] === Known issues @@ -138,7 +132,6 @@ ifndef::openshift-rosa[] * Currently, the streaming deployment via AMQ/Kafka is not supported on the {ibm-z-title} and {ibm-power-title} architectures. endif::openshift-rosa[] -//// include::modules/support.adoc[leveloffset=+1] From 0fac393d2d618b4ae709cec8ab95e03016777566 Mon Sep 17 00:00:00 2001 From: Jeana Routh Date: Thu, 13 Jun 2024 14:10:06 -0400 Subject: [PATCH 203/339] OSDOCS-10491: Split CCO postinstall tasks into new assembly --- _topic_maps/_topic_map.yml | 2 + .../cco-mode-mint.adoc | 4 +- .../installing-alibaba-customizations.adoc | 2 +- .../installing-alibaba-default.adoc | 2 +- ...alling-alibaba-network-customizations.adoc | 2 +- .../installing-alibaba-vpc.adoc | 2 +- .../ipi/installing-aws-china.adoc | 2 +- .../ipi/installing-aws-customizations.adoc | 2 +- .../ipi/installing-aws-default.adoc | 2 +- .../ipi/installing-aws-government-region.adoc | 2 +- ...installing-aws-network-customizations.adoc | 2 +- .../ipi/installing-aws-private.adoc | 2 +- .../ipi/installing-aws-secret-region.adoc | 2 +- .../ipi/installing-aws-vpc.adoc | 2 +- .../upi/installing-aws-user-infra.adoc | 2 +- .../installing-restricted-networks-aws.adoc | 2 +- .../installing-azure-stack-hub-default.adoc | 2 +- ...zure-stack-hub-network-customizations.adoc | 2 +- .../configuring-iam-ibm-cloud.adoc | 2 +- .../preparing-to-install-on-ibm-power-vs.adoc | 2 +- ...nging-cloud-credentials-configuration.adoc | 67 +++++++++++++++++++ .../cluster-tasks.adoc | 54 --------------- 22 files changed, 89 insertions(+), 74 deletions(-) create mode 100644 post_installation_configuration/changing-cloud-credentials-configuration.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 769418483d53..1062155d2123 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -631,6 +631,8 @@ Topics: File: storage-configuration - Name: Preparing for users File: preparing-for-users +- Name: Changing the cloud provider credentials configuration + File: changing-cloud-credentials-configuration - Name: Configuring alert notifications File: configuring-alert-notifications - Name: Converting a connected cluster to a disconnected cluster diff --git a/authentication/managing_cloud_provider_credentials/cco-mode-mint.adoc b/authentication/managing_cloud_provider_credentials/cco-mode-mint.adoc index 8b8486703abe..5a6c8d2a5580 100644 --- a/authentication/managing_cloud_provider_credentials/cco-mode-mint.adoc +++ b/authentication/managing_cloud_provider_credentials/cco-mode-mint.adoc @@ -17,7 +17,7 @@ With mint mode, each cluster component has only the specific permissions it requ [NOTE] ==== -By default, mint mode requires storing the `admin` credential in the cluster `kube-system` namespace. If this approach does not meet the security requirements of your organization, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove the credential after installing the cluster]. +By default, mint mode requires storing the `admin` credential in the cluster `kube-system` namespace. If this approach does not meet the security requirements of your organization, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove the credential after installing the cluster]. ==== [id="mint-mode-permissions"] @@ -72,4 +72,4 @@ include::modules/manually-rotating-cloud-creds.adoc[leveloffset=+1] [role="_additional-resources"] == Additional resources -* xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[Removing cloud provider credentials] \ No newline at end of file +* xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[Removing cloud provider credentials] \ No newline at end of file diff --git a/installing/installing_alibaba/installing-alibaba-customizations.adoc b/installing/installing_alibaba/installing-alibaba-customizations.adoc index 2fa910eb7a9c..de22f4b83f93 100644 --- a/installing/installing_alibaba/installing-alibaba-customizations.adoc +++ b/installing/installing_alibaba/installing-alibaba-customizations.adoc @@ -69,4 +69,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. //Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_alibaba/installing-alibaba-default.adoc b/installing/installing_alibaba/installing-alibaba-default.adoc index 37cd45b2c858..ce90fcd9e96d 100644 --- a/installing/installing_alibaba/installing-alibaba-default.adoc +++ b/installing/installing_alibaba/installing-alibaba-default.adoc @@ -57,4 +57,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. //Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials] +//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials] diff --git a/installing/installing_alibaba/installing-alibaba-network-customizations.adoc b/installing/installing_alibaba/installing-alibaba-network-customizations.adoc index d0e2fc1358a8..b8bb74a2a730 100644 --- a/installing/installing_alibaba/installing-alibaba-network-customizations.adoc +++ b/installing/installing_alibaba/installing-alibaba-network-customizations.adoc @@ -79,4 +79,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. //Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_alibaba/installing-alibaba-vpc.adoc b/installing/installing_alibaba/installing-alibaba-vpc.adoc index 08696b1d51ff..9bb799304cc1 100644 --- a/installing/installing_alibaba/installing-alibaba-vpc.adoc +++ b/installing/installing_alibaba/installing-alibaba-vpc.adoc @@ -70,4 +70,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. //Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-china.adoc b/installing/installing_aws/ipi/installing-aws-china.adoc index bf47bba7f9a2..77c2bcb1d784 100644 --- a/installing/installing_aws/ipi/installing-aws-china.adoc +++ b/installing/installing_aws/ipi/installing-aws-china.adoc @@ -111,4 +111,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-customizations.adoc b/installing/installing_aws/ipi/installing-aws-customizations.adoc index 1984b94d1082..7ce7e3474383 100644 --- a/installing/installing_aws/ipi/installing-aws-customizations.adoc +++ b/installing/installing_aws/ipi/installing-aws-customizations.adoc @@ -108,4 +108,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-default.adoc b/installing/installing_aws/ipi/installing-aws-default.adoc index 60b8d2ed1840..7fee3f3ab8ce 100644 --- a/installing/installing_aws/ipi/installing-aws-default.adoc +++ b/installing/installing_aws/ipi/installing-aws-default.adoc @@ -42,4 +42,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-government-region.adoc b/installing/installing_aws/ipi/installing-aws-government-region.adoc index e9c1823fd94a..13675e838ce1 100644 --- a/installing/installing_aws/ipi/installing-aws-government-region.adoc +++ b/installing/installing_aws/ipi/installing-aws-government-region.adoc @@ -112,4 +112,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-network-customizations.adoc b/installing/installing_aws/ipi/installing-aws-network-customizations.adoc index d4fae17f6ee5..9461aa5748b1 100644 --- a/installing/installing_aws/ipi/installing-aws-network-customizations.adoc +++ b/installing/installing_aws/ipi/installing-aws-network-customizations.adoc @@ -126,4 +126,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-private.adoc b/installing/installing_aws/ipi/installing-aws-private.adoc index 7bcf6eeeb279..43335975de84 100644 --- a/installing/installing_aws/ipi/installing-aws-private.adoc +++ b/installing/installing_aws/ipi/installing-aws-private.adoc @@ -106,4 +106,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-secret-region.adoc b/installing/installing_aws/ipi/installing-aws-secret-region.adoc index 8f7700d9802b..539fdd504f4c 100644 --- a/installing/installing_aws/ipi/installing-aws-secret-region.adoc +++ b/installing/installing_aws/ipi/installing-aws-secret-region.adoc @@ -105,4 +105,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/ipi/installing-aws-vpc.adoc b/installing/installing_aws/ipi/installing-aws-vpc.adoc index 9c3263e89369..cce3443c4b6d 100644 --- a/installing/installing_aws/ipi/installing-aws-vpc.adoc +++ b/installing/installing_aws/ipi/installing-aws-vpc.adoc @@ -104,5 +104,5 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. * After installing a cluster on AWS into an existing VPC, you can xref:../../../post_installation_configuration/configuring-aws-outposts.adoc#configuring-aws-outposts[extend the AWS VPC cluster into an AWS Outpost]. \ No newline at end of file diff --git a/installing/installing_aws/upi/installing-aws-user-infra.adoc b/installing/installing_aws/upi/installing-aws-user-infra.adoc index dbe0ef279466..a6bae794b192 100644 --- a/installing/installing_aws/upi/installing-aws-user-infra.adoc +++ b/installing/installing_aws/upi/installing-aws-user-infra.adoc @@ -183,4 +183,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * xref:../../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_aws/upi/installing-restricted-networks-aws.adoc b/installing/installing_aws/upi/installing-restricted-networks-aws.adoc index 6a8dd6cb365a..8a5aa665e94d 100644 --- a/installing/installing_aws/upi/installing-restricted-networks-aws.adoc +++ b/installing/installing_aws/upi/installing-restricted-networks-aws.adoc @@ -184,4 +184,4 @@ include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] * If the mirror registry that you used to install your cluster has a trusted CA, add it to the cluster by xref:../../../openshift_images/image-configuration.adoc#images-configuration-cas_image-configuration[configuring additional trust stores]. * If necessary, you can xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. * If necessary, see xref:../../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#insights-operator-register-disconnected-cluster_opting-out-remote-health-reporting[Registering your disconnected cluster] -* If necessary, you can xref:../../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc b/installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc index cee27a3c7559..12a579d9fef8 100644 --- a/installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc +++ b/installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc @@ -73,4 +73,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_azure_stack_hub/installing-azure-stack-hub-network-customizations.adoc b/installing/installing_azure_stack_hub/installing-azure-stack-hub-network-customizations.adoc index 559ede047a71..d43a78ef8ebe 100644 --- a/installing/installing_azure_stack_hub/installing-azure-stack-hub-network-customizations.adoc +++ b/installing/installing_azure_stack_hub/installing-azure-stack-hub-network-customizations.adoc @@ -89,4 +89,4 @@ include::modules/cluster-telemetry.adoc[leveloffset=+1] * xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. * xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. * If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -* If necessary, you can xref:../../post_installation_configuration/cluster-tasks.adoc#manually-removing-cloud-creds_post-install-cluster-tasks[remove cloud provider credentials]. +* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc b/installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc index 2dc2ffffe3c3..27b172d62283 100644 --- a/installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc +++ b/installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc @@ -20,7 +20,7 @@ include::modules/cco-ccoctl-configuring.adoc[leveloffset=+1] [role="_additional-resources"] [id="additional-resources_configuring-iam-ibm-cloud-refreshing-ids"] .Additional resources -* xref:../../post_installation_configuration/cluster-tasks.adoc#refreshing-service-ids-ibm-cloud_post-install-cluster-tasks[Rotating API keys for {ibm-cloud-name}] +* xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#refreshing-service-ids-ibm-cloud_changing-cloud-credentials-configuration[Rotating API keys for {ibm-cloud-name}] [id="next-steps_configuring-iam-ibm-cloud"] == Next steps diff --git a/installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.adoc b/installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.adoc index 119accb79b2d..4cad47812e6a 100644 --- a/installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.adoc +++ b/installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.adoc @@ -48,7 +48,7 @@ include::modules/cco-ccoctl-configuring.adoc[leveloffset=+1] [id="additional-resources_configuring-ibm-cloud-refreshing-ids"] .Additional resources -* xref:../../post_installation_configuration/cluster-tasks.adoc#refreshing-service-ids-ibm-cloud_post-install-cluster-tasks[Rotating API keys] +* xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#refreshing-service-ids-ibm-cloud_changing-cloud-credentials-configuration[Rotating API keys] [id="next-steps_preparing-to-install-on-ibm-power-vs"] == Next steps diff --git a/post_installation_configuration/changing-cloud-credentials-configuration.adoc b/post_installation_configuration/changing-cloud-credentials-configuration.adoc new file mode 100644 index 000000000000..e5fc30fecb1e --- /dev/null +++ b/post_installation_configuration/changing-cloud-credentials-configuration.adoc @@ -0,0 +1,67 @@ +:_mod-docs-content-type: ASSEMBLY +:context: changing-cloud-credentials-configuration +[id="changing-cloud-credentials-configuration"] += Changing the cloud provider credentials configuration +include::_attributes/common-attributes.adoc[] + +toc::[] + +For supported configurations, you can change how {product-title} authenticates with your cloud provider. + +To determine which cloud credentials strategy your cluster uses, see xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#cco-determine-mode_about-cloud-credential-operator[Determining the Cloud Credential Operator mode]. + +[id="post-install-rotate-remove-cloud-creds_{context}"] +== Rotating or removing cloud provider credentials + +After installing {product-title}, some organizations require the rotation or removal of the cloud provider credentials that were used during the initial installation. + +To allow the cluster to use the new credentials, you must update the secrets that the xref:../operators/operator-reference.adoc#cloud-credential-operator_cluster-operators-ref[Cloud Credential Operator (CCO)] uses to manage cloud provider credentials. + +[id="ccoctl-rotate-remove-cloud-creds_{context}"] +=== Rotating cloud provider credentials with the Cloud Credential Operator utility + +// Right now only IBM can do this, but it makes sense to set this up so that other clouds can be added. +The Cloud Credential Operator (CCO) utility `ccoctl` supports updating secrets for clusters installed on {ibm-cloud-name}. + +//Rotating IBM Cloud credentials with ccoctl +include::modules/refreshing-service-ids-ibm-cloud.adoc[leveloffset=+3] + +//Rotating cloud provider credentials manually +include::modules/manually-rotating-cloud-creds.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources +* xref:../storage/container_storage_interface/persistent-storage-csi-vsphere.adoc#persistent-storage-csi-vsphere[vSphere CSI Driver Operator] + +//Removing cloud provider credentials manually +include::modules/manually-removing-cloud-creds.adoc[leveloffset=+2] + +//These additional resources are for the "Rotating or removing cloud provider credentials" section, do not separate them from that content. +[role="_additional-resources"] +.Additional resources +* xref:../authentication/managing_cloud_provider_credentials/cco-mode-passthrough.adoc#admin-credentials-root-secret-formats_cco-mode-passthrough[Admin credentials root secret format] + +[id="post-install-enable-token-auth_{context}"] +== Enabling token-based authentication +//Today, just Entra. But this should be a section that anticipates the addition of AWS STS and GCP WID. + +After installing an {azure-first} {product-title} cluster, you can enable {entra-first} to use short-term credentials. + +//Configuring the Cloud Credential Operator utility +include::modules/cco-ccoctl-configuring.adoc[leveloffset=+2] + +//Enabling {entra-first} on an existing cluster +include::modules/enabling-entra-workload-id-existing-cluster.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources +* xref:../authentication/managing_cloud_provider_credentials/cco-short-term-creds.adoc#cco-short-term-creds-azure_cco-short-term-creds[Microsoft Entra Workload ID] +* xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-with-short-term-creds_installing-azure-customizations[Configuring an Azure cluster to use short-term credentials] + +//Verifying the credentials configuration +include::modules/cco-ccoctl-install-verifying.adoc[leveloffset=+2] + +[role="_additional-resources"] +[id="additional-resources_{context}"] +== Additional resources +* xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#about-cloud-credential-operator[About the Cloud Credential Operator] \ No newline at end of file diff --git a/post_installation_configuration/cluster-tasks.adoc b/post_installation_configuration/cluster-tasks.adoc index 052ad07aa9dc..6e88329a482d 100644 --- a/post_installation_configuration/cluster-tasks.adoc +++ b/post_installation_configuration/cluster-tasks.adoc @@ -685,60 +685,6 @@ include::modules/pod-disruption-eviction-policy.adoc[leveloffset=+2] * xref:../nodes/clusters/nodes-cluster-enabling-features.adoc#nodes-cluster-enabling[Enabling features using feature gates] * link:https://kubernetes.io/docs/tasks/run-application/configure-pdb/#unhealthy-pod-eviction-policy[Unhealthy Pod Eviction Policy] in the Kubernetes documentation -[id="post-install-rotate-remove-cloud-creds"] -== Rotating or removing cloud provider credentials - -After installing {product-title}, some organizations require the rotation or removal of the cloud provider credentials that were used during the initial installation. - -To allow the cluster to use the new credentials, you must update the secrets that the xref:../operators/operator-reference.adoc#cloud-credential-operator_cluster-operators-ref[Cloud Credential Operator (CCO)] uses to manage cloud provider credentials. - -[id="ccoctl-rotate-remove-cloud-creds"] -=== Rotating cloud provider credentials with the Cloud Credential Operator utility - -// Right now only IBM can do this, but it makes sense to set this up so that other clouds can be added. -The Cloud Credential Operator (CCO) utility `ccoctl` supports updating secrets for clusters installed on {ibm-cloud-name}. - -//Rotating IBM Cloud credentials with ccoctl -include::modules/refreshing-service-ids-ibm-cloud.adoc[leveloffset=+3] - -//Rotating cloud provider credentials manually -include::modules/manually-rotating-cloud-creds.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../storage/container_storage_interface/persistent-storage-csi-vsphere.adoc[vSphere CSI Driver Operator] - -//Removing cloud provider credentials manually -include::modules/manually-removing-cloud-creds.adoc[leveloffset=+2] - -//These additional resources are for the "Rotating or removing cloud provider credentials" section, do not separate them from that content. -[role="_additional-resources"] -.Additional resources -* xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#about-cloud-credential-operator[About the Cloud Credential Operator] -* xref:../authentication/managing_cloud_provider_credentials/cco-mode-passthrough.adoc#admin-credentials-root-secret-formats_cco-mode-passthrough[Admin credentials root secret format] - -[id="post-install-enable-token-auth"] -== Enabling token-based authentication -//Today, just Entra. But this should be a section that anticipates the addition of AWS STS and GCP WID. - -After installing an {azure-first} {product-title} cluster, you can enable {entra-first} to use short-term credentials. - -To determine which cloud credentials strategy your cluster uses, see xref:../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#cco-determine-mode_about-cloud-credential-operator[Determining the Cloud Credential Operator mode]. - -//Configuring the Cloud Credential Operator utility -include::modules/cco-ccoctl-configuring.adoc[leveloffset=+2] - -//Enabling {entra-first} on an existing cluster -include::modules/enabling-entra-workload-id-existing-cluster.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../authentication/managing_cloud_provider_credentials/cco-short-term-creds.adoc#cco-short-term-creds-azure_cco-short-term-creds[Microsoft Entra Workload ID] -* xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-with-short-term-creds_installing-azure-customizations[Configuring an Azure cluster to use short-term credentials] - -//Verifying the credentials configuration -include::modules/cco-ccoctl-install-verifying.adoc[leveloffset=+2] - [id="post-install-must-gather-disconnected"] == Configuring image streams for a disconnected cluster From 19b5d3b1ad1ca99772870b5a9b2df9daff546e70 Mon Sep 17 00:00:00 2001 From: Andrea Hoffer Date: Thu, 13 Jun 2024 11:07:51 -0400 Subject: [PATCH 204/339] Clarifying tested cloud platforms with vault --- modules/secrets-store-vault.adoc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/secrets-store-vault.adoc b/modules/secrets-store-vault.adoc index a9d9bbc3311a..e33fce72ffda 100644 --- a/modules/secrets-store-vault.adoc +++ b/modules/secrets-store-vault.adoc @@ -6,11 +6,20 @@ [id="secrets-store-vault_{context}"] = Mounting secrets from HashiCorp Vault -You can use the {secrets-store-operator} to mount secrets from HashiCorp Vault to a CSI volume in {product-title}. To mount secrets from HashiCorp Vault, your cluster must be installed either on AWS with AWS Security Token Service (STS) or on Microsoft Azure. +You can use the {secrets-store-operator} to mount secrets from HashiCorp Vault to a CSI volume in {product-title}. + +[IMPORTANT] +==== +Mounting secrets from HashiCorp Vault by using the {secrets-store-operator} has been tested with the following cloud providers: + +* Amazon Web Services (AWS) +* Microsoft Azure + +Other cloud providers might work, but have not been tested yet. Additional cloud providers might be tested in the future. +==== .Prerequisites -* Your cluster is installed on AWS or Azure. * You have installed the {secrets-store-operator}. See _Installing the {secrets-store-driver}_ for instructions. * You have installed Helm. * You have access to the cluster as a user with the `cluster-admin` role. From 64721ded30a8209e8d9a09af8070fcb96502a666 Mon Sep 17 00:00:00 2001 From: Shubha Narayanan Date: Thu, 9 May 2024 17:04:07 +0530 Subject: [PATCH 205/339] Removing Alibaba references from IPI --- _topic_maps/_topic_map.yml | 16 +- .../cco-mode-manual.adoc | 3 +- installing/installing-fips.adoc | 1 - installing/installing-preparing.adoc | 39 +-- ...nstallation-config-parameters-alibaba.adoc | 12 - .../installing-alibaba-customizations.adoc | 72 ----- .../installing-alibaba-default.adoc | 60 ----- ...alling-alibaba-network-customizations.adoc | 82 ------ .../installing-alibaba-vpc.adoc | 73 ------ .../manually-creating-alibaba-ram.adoc | 34 --- .../preparing-to-install-on-alibaba.adoc | 35 --- ...installing-vsphere-assisted-installer.adoc | 6 +- modules/cco-ccoctl-configuring.adoc | 13 - modules/cco-ccoctl-creating-at-once.adoc | 109 +------- modules/cli-installing-cli.adoc | 2 - modules/cli-logging-in-kubeadmin.adoc | 2 - modules/cluster-entitlements.adoc | 2 - modules/cluster-telemetry.adoc | 2 - modules/installation-alibaba-config-yaml.adoc | 67 ----- modules/installation-alibaba-dns.adoc | 37 --- modules/installation-alibaba-regions.adoc | 15 -- ...installation-configuration-parameters.adoc | 178 +------------ modules/installation-configure-proxy.adoc | 1 - modules/installation-custom-alibaba-vpc.adoc | 52 ---- modules/installation-initializing.adoc | 59 +---- modules/installation-launching-installer.adoc | 36 --- modules/installation-obtaining-installer.adoc | 2 - .../logging-in-by-using-the-web-console.adoc | 2 - .../manually-creating-alibaba-manifests.adoc | 24 -- .../manually-creating-alibaba-ram-user.adoc | 247 ------------------ modules/ssh-agent-using.adoc | 2 - snippets/custom-dns-server.adoc | 1 - welcome/index.adoc | 4 +- 33 files changed, 16 insertions(+), 1274 deletions(-) delete mode 100644 installing/installing_alibaba/installation-config-parameters-alibaba.adoc delete mode 100644 installing/installing_alibaba/installing-alibaba-customizations.adoc delete mode 100644 installing/installing_alibaba/installing-alibaba-default.adoc delete mode 100644 installing/installing_alibaba/installing-alibaba-network-customizations.adoc delete mode 100644 installing/installing_alibaba/installing-alibaba-vpc.adoc delete mode 100644 installing/installing_alibaba/manually-creating-alibaba-ram.adoc delete mode 100644 installing/installing_alibaba/preparing-to-install-on-alibaba.adoc delete mode 100644 modules/installation-alibaba-config-yaml.adoc delete mode 100644 modules/installation-alibaba-dns.adoc delete mode 100644 modules/installation-alibaba-regions.adoc delete mode 100644 modules/installation-custom-alibaba-vpc.adoc delete mode 100644 modules/manually-creating-alibaba-manifests.adoc delete mode 100644 modules/manually-creating-alibaba-ram-user.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 1062155d2123..29b9368fdc8f 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -134,24 +134,10 @@ Topics: File: installing-mirroring-disconnected - Name: Mirroring images for a disconnected installation using oc-mirror V2 File: about-installing-oc-mirror-v2 -- Name: Installing on Alibaba +- Name: Installing on Alibaba Cloud by using Assisted Installer Dir: installing_alibaba Distros: openshift-origin,openshift-enterprise Topics: - - Name: Preparing to install on Alibaba Cloud - File: preparing-to-install-on-alibaba - - Name: Creating the required Alibaba Cloud resources - File: manually-creating-alibaba-ram - - Name: Installing a cluster quickly on Alibaba Cloud - File: installing-alibaba-default - - Name: Installing a cluster on Alibaba Cloud with customizations - File: installing-alibaba-customizations - - Name: Installing a cluster on Alibaba Cloud with network customizations - File: installing-alibaba-network-customizations - - Name: Installing a cluster on Alibaba Cloud into an existing VPC - File: installing-alibaba-vpc - - Name: Installation configuration parameters for Alibaba Cloud - File: installation-config-parameters-alibaba - Name: Uninstalling a cluster on Alibaba Cloud File: uninstall-cluster-alibaba - Name: Installing on AWS diff --git a/authentication/managing_cloud_provider_credentials/cco-mode-manual.adoc b/authentication/managing_cloud_provider_credentials/cco-mode-manual.adoc index 0956fb09ae75..a9f8965c9cd9 100644 --- a/authentication/managing_cloud_provider_credentials/cco-mode-manual.adoc +++ b/authentication/managing_cloud_provider_credentials/cco-mode-manual.adoc @@ -6,7 +6,7 @@ include::_attributes/common-attributes.adoc[] toc::[] -Manual mode is supported for Alibaba Cloud, Amazon Web Services (AWS), global Microsoft Azure, Microsoft Azure Stack Hub, Google Cloud Platform (GCP), {ibm-cloud-name}, and Nutanix. +Manual mode is supported for Amazon Web Services (AWS), global Microsoft Azure, Microsoft Azure Stack Hub, Google Cloud Platform (GCP), {ibm-cloud-name}, and Nutanix. [id="manual-mode-classic_{context}"] == User-managed credentials @@ -26,7 +26,6 @@ An AWS, global Azure, or GCP cluster that uses manual mode might be configured t [id="additional-resources_cco-mode-manual"] == Additional resources -* xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[Manually creating RAM resources for Alibaba Cloud] * xref:../../installing/installing_aws/ipi/installing-aws-customizations.adoc#manually-create-iam_installing-aws-customizations[Manually creating long-term credentials for AWS] * xref:../../installing/installing_azure/installing-azure-customizations.adoc#manually-create-iam_installing-azure-customizations[Manually creating long-term credentials for Azure] * xref:../../installing/installing_gcp/installing-gcp-customizations.adoc#manually-create-iam_installing-gcp-customizations[Manually creating long-term credentials for GCP] diff --git a/installing/installing-fips.adoc b/installing/installing-fips.adoc index c5ced1c8b3a8..69b9a36464d4 100644 --- a/installing/installing-fips.adoc +++ b/installing/installing-fips.adoc @@ -87,7 +87,6 @@ To enable FIPS mode for your cluster, you must run the installation program from ==== * xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[Amazon Web Services] -* xref:../installing/installing_alibaba/installing-alibaba-customizations.adoc#installing-alibaba-customizations[Alibaba Cloud] * xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-customizations[Microsoft Azure] * xref:../installing/installing_bare_metal/installing-bare-metal.adoc#installing-bare-metal[Bare metal] * xref:../installing/installing_gcp/installing-gcp-customizations.adoc#installing-gcp-customizations[Google Cloud Platform] diff --git a/installing/installing-preparing.adoc b/installing/installing-preparing.adoc index 877c7672782f..43b80aca9def 100644 --- a/installing/installing-preparing.adoc +++ b/installing/installing-preparing.adoc @@ -17,7 +17,6 @@ Before you install an {product-title} cluster, you need to select the best insta If you want to install and manage {product-title} yourself, you can install it on the following platforms: -* Alibaba Cloud * Amazon Web Services (AWS) on 64-bit x86 instances ifndef::openshift-origin[] * Amazon Web Services (AWS) on 64-bit ARM instances @@ -54,9 +53,9 @@ Because you need to provision machines as part of the {product-title} cluster in Because the operating system is integral to {product-title}, it is easier to let the installation program for {product-title} stand up all of the infrastructure. These are called _installer provisioned infrastructure_ installations. In this type of installation, you can provide some existing infrastructure to the cluster, but the installation program deploys all of the machines that your cluster initially needs. -You can deploy an installer-provisioned infrastructure cluster without specifying any customizations to the cluster or its underlying machines to xref:../installing/installing_alibaba/installing-alibaba-default.adoc#installing-alibaba-default[Alibaba Cloud], xref:../installing/installing_aws/ipi/installing-aws-default.adoc#installing-aws-default[AWS], xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[Azure], xref:../installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc#installing-azure-stack-hub-default[Azure Stack Hub], xref:../installing/installing_gcp/installing-gcp-default.adoc#installing-gcp-default[GCP], xref:../installing/installing_nutanix/installing-nutanix-installer-provisioned.adoc#installing-nutanix-installer-provisioned[Nutanix]. +You can deploy an installer-provisioned infrastructure cluster without specifying any customizations to the cluster or its underlying machines to xref:../installing/installing_aws/ipi/installing-aws-default.adoc#installing-aws-default[AWS], xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[Azure], xref:../installing/installing_azure_stack_hub/installing-azure-stack-hub-default.adoc#installing-azure-stack-hub-default[Azure Stack Hub], xref:../installing/installing_gcp/installing-gcp-default.adoc#installing-gcp-default[GCP], xref:../installing/installing_nutanix/installing-nutanix-installer-provisioned.adoc#installing-nutanix-installer-provisioned[Nutanix]. -If you need to perform basic configuration for your installer-provisioned infrastructure cluster, such as the instance type for the cluster machines, you can customize an installation for xref:../installing/installing_alibaba/installing-alibaba-customizations.adoc#installing-alibaba-customizations[Alibaba Cloud], xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[AWS], xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-customizations[Azure], xref:../installing/installing_gcp/installing-gcp-customizations.adoc#installing-gcp-customizations[GCP], xref:../installing/installing_nutanix/installing-nutanix-installer-provisioned.adoc#installing-nutanix-installer-provisioned[Nutanix]. +If you need to perform basic configuration for your installer-provisioned infrastructure cluster, such as the instance type for the cluster machines, you can customize an installation for xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[AWS], xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-customizations[Azure], xref:../installing/installing_gcp/installing-gcp-customizations.adoc#installing-gcp-customizations[GCP], xref:../installing/installing_nutanix/installing-nutanix-installer-provisioned.adoc#installing-nutanix-installer-provisioned[Nutanix]. For installer-provisioned infrastructure installations, you can use an existing xref:../installing/installing_aws/ipi/installing-aws-vpc.adoc#installing-aws-vpc[VPC in AWS], xref:../installing/installing_azure/installing-azure-vnet.adoc#installing-azure-vnet[vNet in Azure], or xref:../installing/installing_gcp/installing-gcp-vpc.adoc#installing-gcp-vpc[VPC in GCP]. You can also reuse part of your networking infrastructure so that your cluster in xref:../installing/installing_aws/ipi/installing-aws-network-customizations.adoc#installing-aws-network-customizations[AWS], xref:../installing/installing_azure/installing-azure-network-customizations.adoc#installing-azure-network-customizations[Azure], xref:../installing/installing_gcp/installing-gcp-network-customizations.adoc#installing-gcp-network-customizations[GCP] can coexist with existing IP address allocations in your environment and integrate with existing MTU and VXLAN configurations. If you have existing accounts and credentials on these clouds, you can re-use them, but you might need to modify the accounts to have the required permissions to install {product-title} clusters on them. @@ -131,10 +130,9 @@ Not all installation options are supported for all platforms, as shown in the fo //This table is for all flavors of OpenShift, except OKD. A separate table is required because OKD does not support multiple AWS architecture types. Trying to maintain one table using conditions, while convenient, is very fragile and prone to publishing errors. ifndef::openshift-origin[] |=== -||Alibaba |AWS (64-bit x86) |AWS (64-bit ARM) |Azure (64-bit x86) |Azure (64-bit ARM)|Azure Stack Hub |GCP (64-bit x86) |GCP (64-bit ARM) |Nutanix |{rh-openstack} |Bare metal (64-bit x86) |Bare metal (64-bit ARM) |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-power-name} |{ibm-power-server-name} +||AWS (64-bit x86) |AWS (64-bit ARM) |Azure (64-bit x86) |Azure (64-bit ARM)|Azure Stack Hub |GCP (64-bit x86) |GCP (64-bit ARM) |Nutanix |{rh-openstack} |Bare metal (64-bit x86) |Bare metal (64-bit ARM) |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-power-name} |{ibm-power-server-name} |Default -|xref:../installing/installing_alibaba/installing-alibaba-default.adoc#installing-alibaba-default[✓] |xref:../installing/installing_aws/ipi/installing-aws-default.adoc#installing-aws-default[✓] |xref:../installing/installing_aws/ipi/installing-aws-default.adoc#installing-aws-default[✓] |xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[✓] @@ -153,7 +151,6 @@ ifndef::openshift-origin[] | |Custom -|xref:../installing/installing_alibaba/installing-alibaba-customizations.adoc#installing-alibaba-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[✓] |xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-customizations[✓] @@ -173,7 +170,6 @@ ifndef::openshift-origin[] |Network customization -|xref:../installing/installing_alibaba/installing-alibaba-network-customizations.adoc#installing-alibaba-network-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-network-customizations.adoc#installing-aws-network-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-network-customizations.adoc#installing-aws-network-customizations[✓] |xref:../installing/installing_azure/installing-azure-network-customizations.adoc#installing-azure-network-customizations[✓] @@ -192,7 +188,6 @@ ifndef::openshift-origin[] | |Restricted network -| |xref:../installing/installing_aws/ipi/installing-restricted-networks-aws-installer-provisioned.adoc#installing-restricted-networks-aws-installer-provisioned[✓] |xref:../installing/installing_aws/ipi/installing-restricted-networks-aws-installer-provisioned.adoc#installing-restricted-networks-aws-installer-provisioned[✓] |xref:../installing/installing_azure/installing-restricted-networks-azure-installer-provisioned.adoc#installing-restricted-networks-azure-installer-provisioned[✓] @@ -211,7 +206,6 @@ ifndef::openshift-origin[] |xref:../installing/installing_ibm_powervs/installing-restricted-networks-ibm-power-vs.adoc#installing-restricted-networks-ibm-power-vs[✓] |Private clusters -| |xref:../installing/installing_aws/ipi/installing-aws-private.adoc#installing-aws-private[✓] |xref:../installing/installing_aws/ipi/installing-aws-private.adoc#installing-aws-private[✓] |xref:../installing/installing_azure/installing-azure-private.adoc#installing-azure-private[✓] @@ -230,7 +224,6 @@ ifndef::openshift-origin[] |xref:../installing/installing_ibm_powervs/installing-ibm-power-vs-private-cluster.adoc#installing-ibm-power-vs-private-cluster[✓] |Existing virtual private networks -| |xref:../installing/installing_aws/ipi/installing-aws-vpc.adoc#installing-aws-vpc[✓] |xref:../installing/installing_aws/ipi/installing-aws-vpc.adoc#installing-aws-vpc[✓] |xref:../installing/installing_azure/installing-azure-vnet.adoc#installing-azure-vnet[✓] @@ -249,7 +242,6 @@ ifndef::openshift-origin[] |xref:../installing/installing_ibm_powervs/installing-ibm-powervs-vpc.adoc#installing-ibm-powervs-vpc[✓] |Government regions -| |xref:../installing/installing_aws/ipi/installing-aws-government-region.adoc#installing-aws-government-region[✓] | |xref:../installing/installing_azure/installing-azure-government-region.adoc#installing-azure-government-region[✓] @@ -268,7 +260,6 @@ ifndef::openshift-origin[] | |Secret regions -| |xref:../installing/installing_aws/ipi/installing-aws-secret-region.adoc#installing-aws-secret-region[✓] | | @@ -287,7 +278,6 @@ ifndef::openshift-origin[] | |China regions -| |xref:../installing/installing_aws/ipi/installing-aws-china.adoc#installing-aws-china-region[✓] | | @@ -310,11 +300,10 @@ endif::openshift-origin[] //This table is for OKD only. A separate table is required because OKD does not support multiple AWS architecture types. Trying to maintain one table using conditions, while convenient, is very fragile and prone to publishing errors. ifdef::openshift-origin[] |=== -||Alibaba |AWS |Azure |Azure Stack Hub |GCP |Nutanix |{rh-openstack} |Bare metal |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-power-name} +||AWS |Azure |Azure Stack Hub |GCP |Nutanix |{rh-openstack} |Bare metal |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-power-name} |Default -|xref:../installing/installing_alibaba/installing-alibaba-default.adoc#installing-alibaba-default[✓] |xref:../installing/installing_aws/ipi/installing-aws-default.adoc#installing-aws-default[✓] |xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[✓] |xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[✓] @@ -328,7 +317,6 @@ ifdef::openshift-origin[] | |Custom -|xref:../installing/installing_alibaba/installing-alibaba-customizations.adoc#installing-alibaba-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-customizations.adoc#installing-aws-customizations[✓] |xref:../installing/installing_azure/installing-azure-customizations.adoc#installing-azure-customizations[✓] |xref:../installing/installing_azure/installing-azure-default.adoc#installing-azure-default[✓] @@ -342,7 +330,6 @@ ifdef::openshift-origin[] | |Network customization -|xref:../installing/installing_alibaba/installing-alibaba-network-customizations.adoc#installing-alibaba-network-customizations[✓] |xref:../installing/installing_aws/ipi/installing-aws-network-customizations.adoc#installing-aws-network-customizations[✓] |xref:../installing/installing_azure/installing-azure-network-customizations.adoc#installing-azure-network-customizations[✓] |xref:../installing/installing_azure_stack_hub/installing-azure-stack-hub-network-customizations.adoc#installing-azure-stack-hub-network-customizations[✓] @@ -356,7 +343,6 @@ ifdef::openshift-origin[] | |Restricted network -| |xref:../installing/installing_aws/ipi/installing-restricted-networks-aws-installer-provisioned.adoc#installing-restricted-networks-aws-installer-provisioned[✓] | | @@ -370,7 +356,6 @@ ifdef::openshift-origin[] | |Private clusters -| |xref:../installing/installing_aws/ipi/installing-aws-private.adoc#installing-aws-private[✓] |xref:../installing/installing_azure/installing-azure-private.adoc#installing-azure-private[✓] | @@ -384,7 +369,6 @@ ifdef::openshift-origin[] | |Existing virtual private networks -| |xref:../installing/installing_aws/ipi/installing-aws-vpc.adoc#installing-aws-vpc[✓] |xref:../installing/installing_azure/installing-azure-vnet.adoc#installing-azure-vnet[✓] | @@ -398,7 +382,6 @@ ifdef::openshift-origin[] | |Government regions -| |xref:../installing/installing_aws/ipi/installing-aws-government-region.adoc#installing-aws-government-region[✓] |xref:../installing/installing_azure/installing-azure-government-region.adoc#installing-azure-government-region[✓] | @@ -412,7 +395,6 @@ ifdef::openshift-origin[] | |Secret regions -| |xref:../installing/installing_aws/ipi/installing-aws-secret-region.adoc#installing-aws-secret-region[✓] | | @@ -426,7 +408,6 @@ ifdef::openshift-origin[] | |China regions -| |xref:../installing/installing_aws/ipi/installing-aws-china.adoc#installing-aws-china-region[✓] | | @@ -445,11 +426,10 @@ endif::openshift-origin[] //This table is for all flavors of OpenShift, except OKD. A separate table is required because OKD does not support multiple AWS architecture types. Trying to maintain one table using conditions, while convenient, is very fragile and prone to publishing errors. ifndef::openshift-origin[] |=== -||Alibaba |AWS (64-bit x86) |AWS (64-bit ARM) |Azure (64-bit x86) |Azure (64-bit ARM) |Azure Stack Hub |GCP (64-bit x86) |GCP (64-bit ARM) |Nutanix |{rh-openstack} |Bare metal (64-bit x86) |Bare metal (64-bit ARM) |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-z-name} with {op-system-base} KVM |{ibm-power-name} |Platform agnostic +||AWS (64-bit x86) |AWS (64-bit ARM) |Azure (64-bit x86) |Azure (64-bit ARM) |Azure Stack Hub |GCP (64-bit x86) |GCP (64-bit ARM) |Nutanix |{rh-openstack} |Bare metal (64-bit x86) |Bare metal (64-bit ARM) |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-z-name} with {op-system-base} KVM |{ibm-power-name} |Platform agnostic |Custom -| |xref:../installing/installing_aws/upi/installing-aws-user-infra.adoc#installing-aws-user-infra[✓] |xref:../installing/installing_aws/upi/installing-aws-user-infra.adoc#installing-aws-user-infra[✓] |xref:../installing/installing_azure/installing-azure-user-infra.adoc#installing-azure-user-infra[✓] @@ -479,7 +459,6 @@ ifndef::openshift-origin[] | | | -| |xref:../installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc#installing-bare-metal-network-customizations[✓] |xref:../installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc#installing-bare-metal-network-customizations[✓] |xref:../installing/installing_vsphere/upi/installing-vsphere-network-customizations.adoc#installing-vsphere-network-customizations[✓] @@ -490,7 +469,6 @@ ifndef::openshift-origin[] | |Restricted network -| |xref:../installing/installing_aws/upi/installing-restricted-networks-aws.adoc#installing-restricted-networks-aws[✓] |xref:../installing/installing_aws/upi/installing-restricted-networks-aws.adoc#installing-restricted-networks-aws[✓] | @@ -515,7 +493,6 @@ ifndef::openshift-origin[] | | | -| |xref:../installing/installing_gcp/installing-gcp-user-infra-vpc.adoc#installing-gcp-user-infra-vpc[✓] |xref:../installing/installing_gcp/installing-gcp-user-infra-vpc.adoc#installing-gcp-user-infra-vpc[✓] | @@ -535,11 +512,10 @@ endif::openshift-origin[] //This table is for OKD only. A separate table is required because OKD does not support multiple AWS architecture types. Trying to maintain one table using conditions, while convenient, is very fragile and prone to publishing errors. ifdef::openshift-origin[] |=== -||Alibaba |AWS |Azure |Azure Stack Hub |GCP |Nutanix |{rh-openstack}|Bare metal |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-z-name} with {op-system-base} KVM |{ibm-power-name} |Platform agnostic +||AWS |Azure |Azure Stack Hub |GCP |Nutanix |{rh-openstack}|Bare metal |vSphere |{ibm-cloud-name} |{ibm-z-name} |{ibm-z-name} with {op-system-base} KVM |{ibm-power-name} |Platform agnostic |Custom -| |xref:../installing/installing_aws/upi/installing-aws-user-infra.adoc#installing-aws-user-infra[✓] |xref:../installing/installing_azure/installing-azure-user-infra.adoc#installing-azure-user-infra[✓] |xref:../installing/installing_azure_stack_hub/installing-azure-stack-hub-user-infra.adoc#installing-azure-stack-hub-user-infra[✓] @@ -562,7 +538,6 @@ ifdef::openshift-origin[] | | | -| |xref:../installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc#installing-bare-metal-network-customizations[✓] |xref:../installing/installing_vsphere/upi/installing-vsphere-network-customizations.adoc#installing-vsphere-network-customizations[✓] | @@ -572,7 +547,6 @@ ifdef::openshift-origin[] | |Restricted network -| |xref:../installing/installing_aws/upi/installing-restricted-networks-aws.adoc#installing-restricted-networks-aws[✓] | | @@ -591,7 +565,6 @@ ifdef::openshift-origin[] | | | -| |xref:../installing/installing_gcp/installing-gcp-user-infra-vpc.adoc#installing-gcp-user-infra-vpc[✓] | | diff --git a/installing/installing_alibaba/installation-config-parameters-alibaba.adoc b/installing/installing_alibaba/installation-config-parameters-alibaba.adoc deleted file mode 100644 index 98d3191343fc..000000000000 --- a/installing/installing_alibaba/installation-config-parameters-alibaba.adoc +++ /dev/null @@ -1,12 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installation-config-parameters-alibaba"] -= Installation configuration parameters for Alibaba Cloud -include::_attributes/common-attributes.adoc[] -:context: installation-config-parameters-alibaba -:platform: Alibaba Cloud - -toc::[] - -Before you deploy an {product-title} cluster on Alibaba Cloud, you provide parameters to customize your cluster and the platform that hosts it. When you create the `install-config.yaml` file, you provide values for the required parameters through the command line. You can then modify the `install-config.yaml` file to customize your cluster further. - -include::modules/installation-configuration-parameters.adoc[leveloffset=+1] diff --git a/installing/installing_alibaba/installing-alibaba-customizations.adoc b/installing/installing_alibaba/installing-alibaba-customizations.adoc deleted file mode 100644 index de22f4b83f93..000000000000 --- a/installing/installing_alibaba/installing-alibaba-customizations.adoc +++ /dev/null @@ -1,72 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installing-alibaba-customizations"] -= Installing a cluster on Alibaba Cloud with customizations -include::_attributes/common-attributes.adoc[] -:context: installing-alibaba-customizations - -toc::[] - -In {product-title} version {product-version}, you can install a customized cluster on infrastructure that the installation program provisions on Alibaba Cloud. To customize the installation, you modify parameters in the `install-config.yaml` file before you install the cluster. - -[NOTE] -==== -The scope of the {product-title} installation configurations is intentionally narrow. It is designed for simplicity and ensured success. You can complete many more {product-title} configuration tasks after an installation completes. -==== - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -[id="prerequisites_installing-alibaba-customizations"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. -* You xref:../../installing/installing_alibaba/preparing-to-install-on-alibaba.adoc#installation-alibaba-dns_preparing-to-install-on-alibaba[registered your domain]. -* If you use a firewall, you xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured it to allow the sites] that your cluster requires access to. -* If the cloud Resource Access Management (RAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the `kube-system` namespace, you can xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[manually create and maintain Resource Access Management (RAM) credentials]. - -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -include::modules/ssh-agent-using.adoc[leveloffset=+1] - -include::modules/installation-obtaining-installer.adoc[leveloffset=+1] - -include::modules/installation-initializing.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../../installing/installing_alibaba/installation-config-parameters-alibaba.adoc#installation-config-parameters-alibaba[Installation configuration parameters for Alibaba Cloud] - -include::modules/manually-creating-alibaba-manifests.adoc[leveloffset=+2] - -include::modules/cco-ccoctl-creating-at-once.adoc[leveloffset=+2] - -include::modules/installation-alibaba-config-yaml.adoc[leveloffset=+2] - -include::modules/installation-configure-proxy.adoc[leveloffset=+2] - -include::modules/installation-launching-installer.adoc[leveloffset=+1] - -include::modules/cli-installing-cli.adoc[leveloffset=+1] - -include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] - -include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] - -include::modules/cluster-telemetry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* See xref:../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service. -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console. - -[id="next-steps_installing-alibaba-customizations"] -== Next steps - -* xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. -* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. -* If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -//Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_alibaba/installing-alibaba-default.adoc b/installing/installing_alibaba/installing-alibaba-default.adoc deleted file mode 100644 index ce90fcd9e96d..000000000000 --- a/installing/installing_alibaba/installing-alibaba-default.adoc +++ /dev/null @@ -1,60 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installing-alibaba-default"] -= Installing a cluster quickly on Alibaba Cloud -include::_attributes/common-attributes.adoc[] -:context: installing-alibaba-default - -toc::[] - -In {product-title} version {product-version}, you can install a cluster on -Alibaba Cloud that uses the default configuration options. - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -[id="prerequisites_installing-alibaba-default"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. -* You xref:../../installing/installing_alibaba/preparing-to-install-on-alibaba.adoc#installation-alibaba-dns_preparing-to-install-on-alibaba[registered your domain]. -* If you use a firewall, you xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured it to allow the sites] that your cluster requires access to. -* You have xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[created the required Alibaba Cloud resources]. -* If the cloud Resource Access Management (RAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the kube-system namespace, you can xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[manually create and maintain Resource Access Management (RAM) credentials]. - -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -include::modules/ssh-agent-using.adoc[leveloffset=+1] - -include::modules/installation-obtaining-installer.adoc[leveloffset=+1] - -include::modules/installation-initializing.adoc[leveloffset=+1] - -include::modules/manually-creating-alibaba-manifests.adoc[leveloffset=+1] - -include::modules/cco-ccoctl-creating-at-once.adoc[leveloffset=+1] - -include::modules/installation-launching-installer.adoc[leveloffset=+1] - -include::modules/cli-installing-cli.adoc[leveloffset=+1] - -include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] - -include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] - -include::modules/cluster-telemetry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console. -* See xref:../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service - -[id="next-steps_installing-alibaba-default"] -== Next steps - -* xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. -* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. -* If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -//Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials] diff --git a/installing/installing_alibaba/installing-alibaba-network-customizations.adoc b/installing/installing_alibaba/installing-alibaba-network-customizations.adoc deleted file mode 100644 index b8bb74a2a730..000000000000 --- a/installing/installing_alibaba/installing-alibaba-network-customizations.adoc +++ /dev/null @@ -1,82 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installing-alibaba-network-customizations"] -= Installing a cluster on Alibaba Cloud with network customizations -include::_attributes/common-attributes.adoc[] -:context: installing-alibaba-network-customizations - -toc::[] - -In {product-title} {product-version}, you can install a cluster on Alibaba Cloud with customized network configuration options. By customizing your network configuration, your cluster can coexist with existing IP address allocations in your environment and integrate with existing MTU and -VXLAN configurations. - -You must set most of the network configuration parameters during installation, and you can modify only `kubeProxy` configuration parameters in a running cluster. - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -[id="prerequisites_installing-alibaba-network-customizations"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. -* You xref:../../installing/installing_alibaba/preparing-to-install-on-alibaba.adoc#installation-alibaba-dns_preparing-to-install-on-alibaba[registered your domain]. -* If you use a firewall, you xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured it to allow the sites] that your cluster requires access to. -* If the cloud Resource Access Management (RAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the `kube-system` namespace, you can xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[manually create and maintain Resource Access Management (RAM) credentials]. - -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -include::modules/ssh-agent-using.adoc[leveloffset=+1] - -include::modules/installation-obtaining-installer.adoc[leveloffset=+1] - -//Networking-specific customization module -include::modules/nw-network-config.adoc[leveloffset=+1] - -include::modules/installation-initializing.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../../installing/installing_alibaba/installation-config-parameters-alibaba.adoc#installation-config-parameters-alibaba[Installation configuration parameters for Alibaba Cloud] - -include::modules/manually-creating-alibaba-manifests.adoc[leveloffset=+2] - -include::modules/cco-ccoctl-creating-at-once.adoc[leveloffset=+2] - -include::modules/installation-alibaba-config-yaml.adoc[leveloffset=+2] - -include::modules/installation-configure-proxy.adoc[leveloffset=+2] - -//Networking-specific customization module -include::modules/nw-operator-cr.adoc[leveloffset=+1] - -//Networking-specific customization module -include::modules/nw-modifying-operator-install-config.adoc[leveloffset=+1] - -//Networking-specific customization module -include::modules/configuring-hybrid-ovnkubernetes.adoc[leveloffset=+1] - -include::modules/installation-launching-installer.adoc[leveloffset=+1] - -include::modules/cli-installing-cli.adoc[leveloffset=+1] - -include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] - -include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] - -include::modules/cluster-telemetry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* See xref:../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service. -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console. - -[id="next-steps_installing-alibaba-network-customizations"] -== Next steps - -* xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validate an installation]. -* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. -* If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -//Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_alibaba/installing-alibaba-vpc.adoc b/installing/installing_alibaba/installing-alibaba-vpc.adoc deleted file mode 100644 index 9bb799304cc1..000000000000 --- a/installing/installing_alibaba/installing-alibaba-vpc.adoc +++ /dev/null @@ -1,73 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="installing-alibaba-vpc"] -= Installing a cluster on Alibaba Cloud into an existing VPC -include::_attributes/common-attributes.adoc[] -:context: installing-alibaba-vpc - -toc::[] - -In {product-title} version {product-version}, you can install a cluster into an existing Alibaba Virtual Private Cloud (VPC) on Alibaba Cloud Services. The installation program provisions the required infrastructure, which can then be customized. To customize the VPC installation, modify the parameters in the 'install-config.yaml' file before you install the cluster. - -[NOTE] -==== -The scope of the {product-title} installation configurations is intentionally narrow. It is designed for simplicity and ensured success. You can complete many more {product-title} configuration tasks after an installation completes. -==== - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -[id="prerequisites_installing-alibaba-vpc"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. -* You xref:../../installing/installing_alibaba/preparing-to-install-on-alibaba.adoc#installation-alibaba-dns_preparing-to-install-on-alibaba[registered your domain]. -* If you use a firewall, you xref:../../installing/install_config/configuring-firewall.adoc#configuring-firewall[configured it to allow the sites] that your cluster requires access to. -* If the cloud Resource Access Management (RAM) APIs are not accessible in your environment, or if you do not want to store an administrator-level credential secret in the `kube-system` namespace, you can xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[manually create and maintain Resource Access Management (RAM) credentials]. - -include::modules/installation-custom-alibaba-vpc.adoc[leveloffset=+1] - -include::modules/cluster-entitlements.adoc[leveloffset=+1] - -include::modules/ssh-agent-using.adoc[leveloffset=+1] - -include::modules/installation-obtaining-installer.adoc[leveloffset=+1] - -include::modules/installation-initializing.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources -* xref:../../installing/installing_alibaba/installation-config-parameters-alibaba.adoc#installation-config-parameters-alibaba[Installation configuration parameters for Alibaba Cloud] - -include::modules/installation-alibaba-config-yaml.adoc[leveloffset=+2] - -include::modules/manually-creating-alibaba-manifests.adoc[leveloffset=+2] - -include::modules/cco-ccoctl-configuring.adoc[leveloffset=+2] - -include::modules/cco-ccoctl-creating-at-once.adoc[leveloffset=+2] - -include::modules/installation-launching-installer.adoc[leveloffset=+1] - -include::modules/cli-installing-cli.adoc[leveloffset=+1] - -include::modules/cli-logging-in-kubeadmin.adoc[leveloffset=+1] - -include::modules/logging-in-by-using-the-web-console.adoc[leveloffset=+1] - -include::modules/cluster-telemetry.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* See xref:../../support/remote_health_monitoring/about-remote-health-monitoring.adoc#about-remote-health-monitoring[About remote health monitoring] for more information about the Telemetry service. -* See xref:../../web_console/web-console.adoc#web-console[Accessing the web console] for more details about accessing and understanding the {product-title} web console - -[id="next-steps_installing-alibaba-vpc"] -== Next steps - -* xref:../../installing/validating-an-installation.adoc#validating-an-installation[Validating an installation]. -* xref:../../post_installation_configuration/cluster-tasks.adoc#available_cluster_customizations[Customize your cluster]. -* If necessary, you can xref:../../support/remote_health_monitoring/opting-out-of-remote-health-reporting.adoc#opting-out-remote-health-reporting_opting-out-remote-health-reporting[opt out of remote health reporting]. -//Given that manual mode is required to install on Alibaba Cloud, I do not believe this xref is necessary. -//* If necessary, you can xref:../../post_installation_configuration/changing-cloud-credentials-configuration.adoc#manually-removing-cloud-creds_changing-cloud-credentials-configuration[remove cloud provider credentials]. diff --git a/installing/installing_alibaba/manually-creating-alibaba-ram.adoc b/installing/installing_alibaba/manually-creating-alibaba-ram.adoc deleted file mode 100644 index a2c28e3f6bc8..000000000000 --- a/installing/installing_alibaba/manually-creating-alibaba-ram.adoc +++ /dev/null @@ -1,34 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="manually-creating-alibaba-ram"] -= Creating the required Alibaba Cloud resources -include::_attributes/common-attributes.adoc[] -:context: manually-creating-alibaba-ram - -toc::[] - -Before you install {product-title}, you must use the Alibaba Cloud console to create a Resource Access Management (RAM) user that has sufficient permissions to install {product-title} into your Alibaba Cloud. This user must also have permissions to create new RAM users. You can also configure and use the `ccoctl` tool to create new credentials for the {product-title} components with the permissions that they require. - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -//Task part 1: Manually creating the required RAM user -include::modules/manually-creating-alibaba-ram-user.adoc[leveloffset=+1] - -//Task part 2: Configuring the Cloud Credential Operator utility -include::modules/cco-ccoctl-configuring.adoc[leveloffset=+1] -[role="_additional-resources"] -.Additional resources -* xref:../../updating/preparing_for_updates/preparing-manual-creds-update.adoc#preparing-manual-creds-update[Preparing to update a cluster with manually maintained credentials] - -//Task part 3: Creating Alibaba resources with a single command -// modules/cco-ccoctl-creating-at-once.adoc[leveloffset=+1] - -[id="next-steps_manually-creating-alibaba-ram"] -== Next steps - -* Install a cluster on Alibaba Cloud infrastructure that is provisioned by the {product-title} installation program, by using one of the following methods: - -** **xref:../../installing/installing_alibaba/installing-alibaba-default.adoc#installing-alibaba-default[Installing a cluster quickly on Alibaba Cloud]**: You can install a cluster quickly by using the default configuration options. - -** **xref:../../installing/installing_alibaba/installing-alibaba-customizations.adoc#installing-alibaba-customizations[Installing a customized cluster on Alibaba Cloud]**: The installation program allows for some customization to be applied at the installation stage. Many other customization options are available xref:../../post_installation_configuration/cluster-tasks.adoc#post-install-cluster-tasks[post-installation]. - diff --git a/installing/installing_alibaba/preparing-to-install-on-alibaba.adoc b/installing/installing_alibaba/preparing-to-install-on-alibaba.adoc deleted file mode 100644 index f38489249b90..000000000000 --- a/installing/installing_alibaba/preparing-to-install-on-alibaba.adoc +++ /dev/null @@ -1,35 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="preparing-to-install-on-alibaba"] -= Preparing to install on Alibaba Cloud -include::_attributes/common-attributes.adoc[] -:context: preparing-to-install-on-alibaba - -toc::[] - -:FeatureName: Alibaba Cloud on {product-title} -include::snippets/technology-preview.adoc[] - -[id="prerequisites_preparing-to-install-on-alibaba"] -== Prerequisites - -* You reviewed details about the xref:../../architecture/architecture-installation.adoc#architecture-installation[{product-title} installation and update] processes. -* You read the documentation on xref:../../installing/installing-preparing.adoc#installing-preparing[selecting a cluster installation method and preparing it for users]. - -[id="requirements-for-installing-ocp-on-alibaba"] -== Requirements for installing {product-title} on Alibaba Cloud - -Before installing {product-title} on Alibaba Cloud, you must configure and register your domain, create a Resource Access Management (RAM) user for the installation, and review the supported Alibaba Cloud data center regions and zones for the installation. - -include::modules/installation-alibaba-dns.adoc[leveloffset=+1] - -// include modules/installation-alibaba-limits.adoc[leveloffset=+1] - -// include modules/installation-alibaba-ram-user.adoc[leveloffset=+1] - -include::modules/installation-alibaba-regions.adoc[leveloffset=+1] - -[id="next-steps_preparing-to-install-on-alibaba"] -== Next steps - -* xref:../../installing/installing_alibaba/manually-creating-alibaba-ram.adoc#manually-creating-alibaba-ram[Create the required Alibaba Cloud resources]. - diff --git a/installing/installing_vsphere/installing-vsphere-assisted-installer.adoc b/installing/installing_vsphere/installing-vsphere-assisted-installer.adoc index 09bcc9c374cd..ce5606915f42 100644 --- a/installing/installing_vsphere/installing-vsphere-assisted-installer.adoc +++ b/installing/installing_vsphere/installing-vsphere-assisted-installer.adoc @@ -8,11 +8,7 @@ toc::[] You can install {product-title} on on-premise hardware or on-premise VMs by using the {ai-full}. Installing {product-title} by using the {ai-full} supports `x86_64`, `AArch64`, `ppc64le`, and `s390x` CPU architectures. -The {ai-full} is a user-friendly installation solution offered on the Red{nbsp}Hat Hybrid Cloud Console. The {ai-full} supports the various deployment platforms with a focus on the following infrastructures: - -* Bare metal -* Nutanix -* vSphere +The {ai-full} is a user-friendly installation solution offered on the Red{nbsp}Hat Hybrid Cloud Console. [role="_additional-resources"] [id="additional-resources_installing-vsphere-assisted-installer"] diff --git a/modules/cco-ccoctl-configuring.adoc b/modules/cco-ccoctl-configuring.adoc index 3486210eeeab..ffa080090adf 100644 --- a/modules/cco-ccoctl-configuring.adoc +++ b/modules/cco-ccoctl-configuring.adoc @@ -7,7 +7,6 @@ //Platforms that must use `ccoctl` and update content // * installing/installing_ibm_cloud_public/configuring-iam-ibm-cloud.adoc // * installing/installing_ibm_powervs/preparing-to-install-on-ibm-power-vs.doc -// * installing/installing_alibaba/manually-creating-alibaba-ram.adoc // * installing/installing_nutanix/preparing-to-install-on-nutanix.adoc // // AWS assemblies: @@ -49,9 +48,6 @@ endif::[] ifeval::["{context}" == "configuring-iam-ibm-cloud"] :ibm-cloud: endif::[] -ifeval::["{context}" == "manually-creating-alibaba-ram"] -:alibabacloud: -endif::[] ifeval::["{context}" == "preparing-to-install-on-nutanix"] :nutanix: endif::[] @@ -133,11 +129,6 @@ endif::[] ifndef::update[= Configuring the Cloud Credential Operator utility] ifdef::update[= Configuring the Cloud Credential Operator utility for a cluster update] -//This applies only to Alibaba Cloud. -ifdef::alibabacloud[] -To assign RAM users and policies that provide long-term RAM AccessKeys (AKs) for each in-cluster component, extract and prepare the Cloud Credential Operator (CCO) utility (`ccoctl`) binary. -endif::alibabacloud[] - //Nutanix-only intro because it needs context in its install procedure. ifdef::nutanix[] The Cloud Credential Operator (CCO) manages cloud provider credentials as Kubernetes custom resource definitions (CRDs). To install a cluster on Nutanix, you must set the CCO to `manual` mode as part of the installation process. @@ -396,7 +387,6 @@ Usage: ccoctl [command] Available Commands: - alibabacloud Manage credentials objects for alibaba cloud aws Manage credentials objects for AWS cloud azure Manage credentials objects for Azure gcp Manage credentials objects for Google cloud @@ -422,9 +412,6 @@ endif::[] ifeval::["{context}" == "configuring-iam-ibm-cloud"] :!ibm-cloud: endif::[] -ifeval::["{context}" == "manually-creating-alibaba-ram"] -:!alibabacloud: -endif::[] ifeval::["{context}" == "preparing-to-install-on-nutanix"] :!nutanix: endif::[] diff --git a/modules/cco-ccoctl-creating-at-once.adoc b/modules/cco-ccoctl-creating-at-once.adoc index 1e8830f99820..294fbb8b7924 100644 --- a/modules/cco-ccoctl-creating-at-once.adoc +++ b/modules/cco-ccoctl-creating-at-once.adoc @@ -1,10 +1,5 @@ // Module included in the following assemblies: // -// Platforms that must use `ccoctl` -// * installing/installing_alibaba/manually-creating-alibaba-ram.adoc -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc -// // AWS assemblies: // * installing/installing_aws/installing-aws-customizations.adoc // * installing/installing_aws/installing-aws-network-customizations.adoc @@ -32,17 +27,6 @@ // * installing/installing_azure/installing-azure-vnet.adoc // * installing/installing_azure/installing-restricted-networks-azure-installer-provisioned.adoc -//Platforms that must use `ccoctl` -ifeval::["{context}" == "installing-alibaba-default"] -:alibabacloud-default: -endif::[] -ifeval::["{context}" == "installing-alibaba-customizations"] -:alibabacloud-customizations: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:alibabacloud-vpc: -endif::[] - //AWS install assemblies ifeval::["{context}" == "installing-aws-customizations"] :aws-sts: @@ -132,12 +116,6 @@ ifdef::azure-workload-id[] You can use the `ccoctl azure create-all` command to automate the creation of Azure resources. endif::azure-workload-id[] -ifdef::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] -[id="cco-ccoctl-creating-at-once_{context}"] -= Creating credentials for {product-title} components with the ccoctl tool - -You can use the {product-title} Cloud Credential Operator (CCO) utility to automate the creation of Alibaba Cloud RAM users and policies for each in-cluster component. -endif::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] [NOTE] ==== @@ -149,10 +127,7 @@ By default, `ccoctl` creates objects in the directory in which the commands are You must have: * Extracted and prepared the `ccoctl` binary. -ifdef::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] -* Created a RAM user with sufficient permission to create the {product-title} cluster. -* Added the AccessKeyID (`access_key_id`) and AccessKeySecret (`access_key_secret`) of that RAM user into the link:https://www.alibabacloud.com/help/en/doc-detail/311667.htm#h2-sls-mfm-3p3[`~/.alibabacloud/credentials` file] on your local computer. -endif::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] + ifdef::azure-workload-id[] * Access to your Microsoft Azure account by using the Azure CLI. endif::azure-workload-id[] @@ -267,77 +242,6 @@ To see additional optional parameters and explanations of how to use them, run t ==== endif::azure-workload-id[] -ifdef::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] -. Use the `ccoctl` tool to process all `CredentialsRequest` objects by running the following command: - -.. Run the following command to use the tool: -+ -[source,terminal] ----- -$ ccoctl alibabacloud create-ram-users \ - --name \// <1> - --region= \// <2> - --credentials-requests-dir= \// <3> - --output-dir= <4> ----- -<1> Specify the name used to tag any cloud resources that are created for tracking. -<2> Specify the Alibaba Cloud region in which cloud resources will be created. -<3> Specify the directory containing the files for the component `CredentialsRequest` objects. -<4> Specify the directory where the generated component credentials secrets will be placed. -+ -[NOTE] -==== -If your cluster uses Technology Preview features that are enabled by the `TechPreviewNoUpgrade` feature set, you must include the `--enable-tech-preview` parameter. -==== -+ -.Example output -[source,text] ----- -2022/02/11 16:18:26 Created RAM User: user1-alicloud-openshift-machine-api-alibabacloud-credentials -2022/02/11 16:18:27 Ready for creating new ram policy user1-alicloud-openshift-machine-api-alibabacloud-credentials-policy-policy -2022/02/11 16:18:27 RAM policy user1-alicloud-openshift-machine-api-alibabacloud-credentials-policy-policy has created -2022/02/11 16:18:28 Policy user1-alicloud-openshift-machine-api-alibabacloud-credentials-policy-policy has attached on user user1-alicloud-openshift-machine-api-alibabacloud-credentials -2022/02/11 16:18:29 Created access keys for RAM User: user1-alicloud-openshift-machine-api-alibabacloud-credentials -2022/02/11 16:18:29 Saved credentials configuration to: user1-alicloud/manifests/openshift-machine-api-alibabacloud-credentials-credentials.yaml -... ----- -+ -[NOTE] -==== -A RAM user can have up to two AccessKeys at the same time. If you run `ccoctl alibabacloud create-ram-users` more than twice, the previously generated manifests secret becomes stale and you must reapply the newly generated secrets. -==== - -.. Verify that the {product-title} secrets are created: -+ -[source,terminal] ----- -$ ls /manifests ----- -+ -.Example output -[source,text] ----- -openshift-cluster-csi-drivers-alibaba-disk-credentials-credentials.yaml -openshift-image-registry-installer-cloud-credentials-credentials.yaml -openshift-ingress-operator-cloud-credentials-credentials.yaml -openshift-machine-api-alibabacloud-credentials-credentials.yaml ----- -+ -You can verify that the RAM users and policies are created by querying Alibaba Cloud. For more information, refer to Alibaba Cloud documentation on listing RAM users and policies. - -. Copy the generated credential files to the target manifests directory: -+ -[source,terminal] ----- -$ cp .//manifests/*credentials.yaml ./dir>/manifests/ ----- -+ -where: - -``:: Specifies the directory created by the `ccoctl alibabacloud create-ram-users` command. -``:: Specifies the directory in which the installation program creates files. -endif::alibabacloud-default,alibabacloud-customizations,alibabacloud-vpc[] - ifdef::aws-sts,google-cloud-platform,azure-workload-id[] .Verification @@ -403,17 +307,6 @@ openshift-machine-api-azure-cloud-credentials-credentials.yaml You can verify that the Microsoft Entra ID service accounts are created by querying Azure. For more information, refer to Azure documentation on listing Entra ID service accounts. endif::azure-workload-id[] -//Platforms that must use `ccoctl` -ifeval::["{context}" == "installing-alibaba-default"] -:!alibabacloud-default: -endif::[] -ifeval::["{context}" == "installing-alibaba-customizations"] -:!alibabacloud-customizations: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:!alibabacloud-vpc: -endif::[] - //AWS install assemblies ifeval::["{context}" == "installing-aws-customizations"] :!aws-sts: diff --git a/modules/cli-installing-cli.adoc b/modules/cli-installing-cli.adoc index 298fd2849465..404a62c15f65 100644 --- a/modules/cli-installing-cli.adoc +++ b/modules/cli-installing-cli.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * cli_reference/openshift_cli/getting-started.adoc // * installing/installing_aws/installing-aws-user-infra.adoc // * installing/installing_aws/installing-aws-customizations.adoc diff --git a/modules/cli-logging-in-kubeadmin.adoc b/modules/cli-logging-in-kubeadmin.adoc index dbbd52bb17f5..48dc8a5d72e1 100644 --- a/modules/cli-logging-in-kubeadmin.adoc +++ b/modules/cli-logging-in-kubeadmin.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-user-infra.adoc // * installing/installing_aws/installing-aws-customizations.adoc // * installing/installing_aws/installing-aws-default.adoc diff --git a/modules/cluster-entitlements.adoc b/modules/cluster-entitlements.adoc index f65b82856040..168beee1bc39 100644 --- a/modules/cluster-entitlements.adoc +++ b/modules/cluster-entitlements.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc // * installing/installing_bare_metal/installing-bare-metal.adoc // * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc diff --git a/modules/cluster-telemetry.adoc b/modules/cluster-telemetry.adoc index af569170ac1e..392f608078d4 100644 --- a/modules/cluster-telemetry.adoc +++ b/modules/cluster-telemetry.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_bare_metal/installing-bare-metal-network-customizations.adoc // * installing/installing_bare_metal/installing-bare-metal.adoc // * installing/installing_bare_metal/installing-restricted-networks-bare-metal.adoc diff --git a/modules/installation-alibaba-config-yaml.adoc b/modules/installation-alibaba-config-yaml.adoc deleted file mode 100644 index b39ca28f060f..000000000000 --- a/modules/installation-alibaba-config-yaml.adoc +++ /dev/null @@ -1,67 +0,0 @@ -// Module included in the following assemblies: -// -// installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-customizations.adoc - -:_mod-docs-content-type: REFERENCE -[id="installation-alibaba-config-yaml_{context}"] -= Sample customized install-config.yaml file for Alibaba Cloud - -You can customize the installation configuration file (`install-config.yaml`) to specify more details about -your cluster's platform or modify the values of the required -parameters. - -[source,yaml] ----- -apiVersion: v1 -baseDomain: alicloud-dev.devcluster.openshift.com -credentialsMode: Manual -compute: -- architecture: amd64 - hyperthreading: Enabled - name: worker - platform: {} - replicas: 3 -controlPlane: - architecture: amd64 - hyperthreading: Enabled - name: master - platform: {} - replicas: 3 -metadata: - creationTimestamp: null - name: test-cluster <1> - networking: - clusterNetwork: - - cidr: 10.128.0.0/14 - hostPrefix: 23 - machineNetwork: - - cidr: 10.0.0.0/16 - networkType: OVNKubernetes <2> - serviceNetwork: - - 172.30.0.0/16 -platform: - alibabacloud: - defaultMachinePlatform: <3> - instanceType: ecs.g6.xlarge - systemDiskCategory: cloud_efficiency - systemDiskSize: 200 - region: ap-southeast-1 <4> - resourceGroupID: rg-acfnw6j3hyai <5> - vpcID: vpc-0xifdjerdibmaqvtjob2b <8> - vswitchIDs: <8> - - vsw-0xi8ycgwc8wv5rhviwdq5 - - vsw-0xiy6v3z2tedv009b4pz2 -publish: External -pullSecret: '{"auths": {"cloud.openshift.com": {"auth": ... }' <6> -sshKey: | - ssh-rsa AAAA... <7> ----- -<1> Required. The installation program prompts you for a cluster name. -<2> The cluster network plugin to install. The default value `OVNKubernetes` is the only supported value. -<3> Optional. Specify parameters for machine pools that do not define their own platform configuration. -<4> Required. The installation program prompts you for the region to deploy the cluster to. -<5> Optional. Specify an existing resource group where the cluster should be installed. -<6> Required. The installation program prompts you for the pull secret. -<7> Optional. The installation program prompts you for the SSH key value that you use to access the machines in your cluster. -<8> Optional. These are example vswitchID values. diff --git a/modules/installation-alibaba-dns.adoc b/modules/installation-alibaba-dns.adoc deleted file mode 100644 index 6a9de87bad7d..000000000000 --- a/modules/installation-alibaba-dns.adoc +++ /dev/null @@ -1,37 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/installing_alibaba/installing-alibaba-account.adoc - -:_mod-docs-content-type: PROCEDURE -[id="installation-alibaba-dns_{context}"] -= Registering and Configuring Alibaba Cloud Domain - -To install {product-title}, the Alibaba Cloud account you use must have a dedicated public hosted zone in your account. This zone must be authoritative for the domain. This service provides cluster DNS resolution and name lookup for external connections to the cluster. - -.Procedure - -. Identify your domain, or subdomain, and registrar. You can transfer an existing domain and registrar or obtain a new one through Alibaba Cloud or another source. -+ -[NOTE] -==== -If you purchase a new domain through Alibaba Cloud, it takes time for the relevant DNS changes to propagate. For more information about purchasing domains through Alibaba Cloud, see link:https://www.alibabacloud.com/domain[Alibaba Cloud domains]. -==== - -. If you are using an existing domain and registrar, migrate its DNS to Alibaba Cloud. See link:https://www.alibabacloud.com/help/en/doc-detail/42479.htm[Domain name transfer] -in the Alibaba Cloud documentation. - -. Configure DNS for your domain. This includes: -* link:https://partners-intl.aliyun.com/help/en/doc-detail/54068.htm?spm=a2c63.p38356.0.0.427d2054k5gZOr#task-1830383[Registering a generic domain name]. -* link:https://partners-intl.aliyun.com/help/en/doc-detail/108953.htm?spm=a2c63.p38356.0.0.3c62433fjUrdZG#section-qyn-s41-ygb[Completing real-name verification for your domain name]. -* link:https://account.alibabacloud.com/login/login.htm[Applying for an Internet Content Provider (ICP) filing]. -* link:https://www.alibabacloud.com/product/dns/pricing?spm=a3c0i.23458820.2359477120.2.36ca7d3fe0b5KL[Enabling domain name resolution]. -+ -Use an appropriate root domain, such as `openshiftcorp.com`, or subdomain, such as `clusters.openshiftcorp.com`. - -. If you are using a subdomain, follow the procedures of your company to add its delegation records to the parent domain. - -//// -.Question - -Can Alibaba provide a link(s) to their doc on how to complete each task under step 3 in their doc? Could not find content in their help. -//// diff --git a/modules/installation-alibaba-regions.adoc b/modules/installation-alibaba-regions.adoc deleted file mode 100644 index 99134ab62dba..000000000000 --- a/modules/installation-alibaba-regions.adoc +++ /dev/null @@ -1,15 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/installing_alibaba/installing-alibaba-account.adoc - -:_mod-docs-content-type: REFERENCE -[id="installation-alibaba-regions_{context}"] -= Supported Alibaba regions - -You can deploy an {product-title} cluster to the regions listed in the link:https://www.alibabacloud.com/help/en/doc-detail/188196.htm[Alibaba _Regions and zones_ documentation]. - -//// -Answer from Gaurav Singh (PM) - -All of the regions (in mainland china and outside mainland china ) listed in this doc https://www.alibabacloud.com/help/doc-detail/188196.htm[Alibaba doc] will be shown as option to the customer to deploy openshift . We might need to test all of them. -//// diff --git a/modules/installation-configuration-parameters.adoc b/modules/installation-configuration-parameters.adoc index b5982abe8608..a38f9de2c1f7 100644 --- a/modules/installation-configuration-parameters.adoc +++ b/modules/installation-configuration-parameters.adoc @@ -7,7 +7,6 @@ // * installing/installing_azure_stack_hub/installation-config-parameters-ash.adoc // * installing/installing_bare_metal/installation-config-parameters-bare-metal.adoc // * installing/installing_ibm_cloud_public/installation-config-parameters-ibm-cloud-vps.adoc -// * installing/installing_alibaba/installation-config-parameters-alibaba.adoc // * installing/installing_ibm_powervs/installation-config-parameters-ibm-power-vs.adoc // * installing/installing_nutanix/installation-config-parameters-nutanix.adoc // * installing/installing_openstack/installation-config-parameters-openstack.adoc @@ -36,9 +35,6 @@ endif::[] ifeval::["{context}" == "installation-config-parameters-ibm-cloud-vpc"] :ibm-cloud: endif::[] -ifeval::["{context}" == "installation-config-parameters-alibaba"] -:alibaba-cloud: -endif::[] ifeval::["{context}" == "installation-config-parameters-ibm-power-vs"] :ibm-power-vs: endif::[] @@ -125,7 +121,7 @@ endif::osp[] |platform: ifndef::agent[] -|The configuration for the specific platform upon which to perform the installation: `alibabacloud`, `aws`, `baremetal`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}`. For additional information about `platform.` parameters, consult the table for your specific platform that follows. +|The configuration for the specific platform upon which to perform the installation: `aws`, `baremetal`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}`. For additional information about `platform.` parameters, consult the table for your specific platform that follows. endif::agent[] ifdef::agent[] |The configuration for the specific platform upon which to perform the installation: `baremetal`, `external`, `none`, or `vsphere`. @@ -528,7 +524,7 @@ ifdef::ibm-power-vs[] Example usage, `compute.platform.powervs.sysType`. endif::ibm-power-vs[] ifndef::agent[] -|`alibabacloud`, `aws`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}` +|`aws`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}` endif::agent[] ifdef::agent[] |`baremetal`, `vsphere`, or `{}` @@ -622,7 +618,7 @@ ifdef::ibm-power-vs[] Example usage, `controlPlane.platform.powervs.processors`. endif::ibm-power-vs[] ifndef::agent[] -|`alibabacloud`, `aws`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}` +|`aws`, `azure`, `gcp`, `ibmcloud`, `nutanix`, `openstack`, `powervs`, `vsphere`, or `{}` endif::agent[] ifdef::agent[] |`baremetal`, `vsphere`, or `{}` @@ -3106,171 +3102,6 @@ configuring user-defined routing. |==== endif::ash[] -ifdef::alibaba-cloud[] -//From: https://github.com/openshift/installer/blob/master/data/data/install.openshift.io_installconfigs.yaml#L20; https://github.com/openshift/openshift-docs/pull/40651/files#r792388476 - -[id="installation-configuration-parameters-additional-alibaba_{context}"] -== Additional Alibaba Cloud configuration parameters - -Additional Alibaba Cloud configuration parameters are described in the following table. The `alibabacloud` parameters are the configuration used when installing on Alibaba Cloud. The `defaultMachinePlatform` parameters are the default configuration used when installing on Alibaba Cloud for machine pools that do not define their own platform configuration. - -These parameters apply to both compute machines and control plane machines where specified. - -[NOTE] -==== -If defined, the parameters `compute.platform.alibabacloud` and `controlPlane.platform.alibabacloud` will overwrite `platform.alibabacloud.defaultMachinePlatform` settings for compute machines and control plane machines respectively. -==== - -.Optional {alibaba} parameters -[cols=".^2l,.^3,.^5a",options="header"] -|==== -|Parameter|Description|Values - -|compute: - platform: - alibabacloud: - imageID: -|The imageID used to create the ECS instance. ImageID must belong to the same region as the cluster. -|String. - -|compute: - platform: - alibabacloud: - instanceType: -|InstanceType defines the ECS instance type. Example: `ecs.g6.large` -|String. - -|compute: - platform: - alibabacloud: - systemDiskCategory: -|Defines the category of the system disk. Examples: `cloud_efficiency`,`cloud_essd` -|String. - -|compute: - platform: - alibabacloud: - systemDisksize: -|Defines the size of the system disk in gibibytes (GiB). -|Integer. - -|compute: - platform: - alibabacloud: - zones: -|The list of availability zones that can be used. Examples: `cn-hangzhou-h`, `cn-hangzhou-j` -|String list. - -|controlPlane: - platform: - alibabacloud: - imageID: -|The imageID used to create the ECS instance. ImageID must belong to the same region as the cluster. -|String. - -|controlPlane: - platform: - alibabacloud: - instanceType: -|InstanceType defines the ECS instance type. Example: `ecs.g6.xlarge` -|String. - -|controlPlane: - platform: - alibabacloud: - systemDiskCategory: -|Defines the category of the system disk. Examples: `cloud_efficiency`,`cloud_essd` -|String. - -|controlPlane: - platform: - alibabacloud: - systemDisksize: -|Defines the size of the system disk in gibibytes (GiB). -|Integer. - -|controlPlane: - platform: - alibabacloud: - zones: -|The list of availability zones that can be used. Examples: `cn-hangzhou-h`, `cn-hangzhou-j` -|String list. - -|platform: - alibabacloud: - region: -|Required. The Alibaba Cloud region where the cluster will be created. -|String. - -|platform: - alibabacloud: - resourceGroupID: -|The ID of an already existing resource group where the cluster will be installed. If empty, the installation program will create a new resource group for the cluster. -|String. - -|platform: - alibabacloud: - tags: -|Additional keys and values to apply to all Alibaba Cloud resources created for the cluster. -|Object. - -|platform: - alibabacloud: - vpcID: -|The ID of an already existing VPC where the cluster should be installed. If empty, the installation program will create a new VPC for the cluster. -|String. - -|platform: - alibabacloud: - vswitchIDs: -|The ID list of already existing VSwitches where cluster resources will be created. The existing VSwitches can only be used when also using existing VPC. If empty, the installation program will create new VSwitches for the cluster. -|String list. - -|platform: - alibabacloud: - defaultMachinePlatform: - imageID: -|For both compute machines and control plane machines, the image ID that should be used to create ECS instance. If set, the image ID should belong to the same region as the cluster. -|String. - -|platform: - alibabacloud: - defaultMachinePlatform: - instanceType: -|For both compute machines and control plane machines, the ECS instance type used to create the ECS instance. Example: `ecs.g6.xlarge` -|String. - -|platform: - alibabacloud: - defaultMachinePlatform: - systemDiskCategory: -|For both compute machines and control plane machines, the category of the system disk. Examples: `cloud_efficiency`, `cloud_essd`. -|String, for example "", `cloud_efficiency`, `cloud_essd`. - -|platform: - alibabacloud: - defaultMachinePlatform: - systemDiskSize: -|For both compute machines and control plane machines, the size of the system disk in gibibytes (GiB). The minimum is `120`. -|Integer. - -|platform: - alibabacloud: - defaultMachinePlatform: - zones: -|For both compute machines and control plane machines, the list of availability zones that can be used. Examples: `cn-hangzhou-h`, `cn-hangzhou-j` -|String list. - -|platform: - alibabacloud: - privateZoneID: -|The ID of an existing private zone into which to add DNS records for the cluster's internal API. An existing private zone can only be used when also using existing VPC. The private zone must be associated with the VPC containing the subnets. Leave the private zone unset to have the installation program create the private zone on your behalf. -|String. - -|==== - -endif::alibaba-cloud[] - ifdef::nutanix[] [id="installation-configuration-parameters-additional-nutanix_{context}"] == Additional Nutanix configuration parameters @@ -3547,9 +3378,6 @@ endif::[] ifeval::["{context}" == "installation-config-parameters-ibm-cloud-vpc"] :!ibm-cloud: endif::[] -ifeval::["{context}" == "installation-config-parameters-alibaba"] -:!alibaba-cloud: -endif::[] ifeval::["{context}" == "installation-config-parameters-ibm-power-vs"] :!ibm-power-vs: endif::[] diff --git a/modules/installation-configure-proxy.adoc b/modules/installation-configure-proxy.adoc index 8747934acc96..09fd00ccb7f2 100644 --- a/modules/installation-configure-proxy.adoc +++ b/modules/installation-configure-proxy.adoc @@ -1,6 +1,5 @@ // Module included in the following assemblies: // -// installing/installing_alibaba/installing-alibaba-network-customizations.adoc // * installing/installing_aws/installing_aws-customizations.adoc // * installing/installing_aws/installing_aws-network-customizations.adoc // * installing/installing_aws/installing_aws-private.adoc diff --git a/modules/installation-custom-alibaba-vpc.adoc b/modules/installation-custom-alibaba-vpc.adoc deleted file mode 100644 index 0be217cb89d4..000000000000 --- a/modules/installation-custom-alibaba-vpc.adoc +++ /dev/null @@ -1,52 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/installing_alibaba/installing-alibaba-vpc.adoc - -:_mod-docs-content-type: CONCEPT -[id="installation-custom-alibaba-vpc_{context}"] -= Using a custom VPC - -In {product-title} {product-version}, you can deploy a cluster into existing subnets in an existing Virtual Private Cloud (VPC) in the Alibaba Cloud Platform. By deploying {product-title} into an existing Alibaba VPC, you can avoid limit constraints in new accounts and more easily adhere to your organization's operational constraints. If you cannot obtain the infrastructure creation permissions that are required to create the VPC yourself, use this installation option. You must configure networking using vSwitches. - -[id="installation-custom-alibaba-vpc-requirements_{context}"] -== Requirements for using your VPC - -The union of the VPC CIDR block and the machine network CIDR must be non-empty. The vSwitches must be within the machine network. - -The installation program does not create the following components: - -* VPC -* vSwitches -* Route table -* NAT gateway - -include::snippets/custom-dns-server.adoc[] - -[id="installation-custom-alibaba-vpc-validation_{context}"] -== VPC validation - -To ensure that the vSwitches you provide are suitable, the installation program confirms the following data: - -* All the vSwitches that you specify must exist. -* You have provided one or more vSwitches for control plane machines and compute machines. -* The vSwitches' CIDRs belong to the machine CIDR that you specified. - -[id="installation-about-custom-alibaba-permissions_{context}"] -== Division of permissions - -Some individuals can create different resources in your cloud than others. For example, you might be able to create application-specific items, like instances, buckets, and load balancers, but not networking-related components, such as VPCs or vSwitches. - -[id="installation-custom-alibaba-vpc-isolation_{context}"] -== Isolation between clusters - -If you deploy {product-title} into an existing network, the isolation of cluster services is reduced in the following ways: - -* You can install multiple {product-title} clusters in the same VPC. - -* ICMP ingress is allowed to the entire network. - -* TCP 22 ingress (SSH) is allowed to the entire network. - -* Control plane TCP 6443 ingress (Kubernetes API) is allowed to the entire network. - -* Control plane TCP 22623 ingress (MCS) is allowed to the entire network. diff --git a/modules/installation-initializing.adoc b/modules/installation-initializing.adoc index 5c7d6ad05883..0d70a507e0a0 100644 --- a/modules/installation-initializing.adoc +++ b/modules/installation-initializing.adoc @@ -1,9 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_aws/installing-alibaba-default.adoc -// * installing/installing_aws/installing-alibaba-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_aws/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-customizations.adoc // * installing/installing_aws/installing-aws-network-customizations.adoc // * installing/installing_aws/installing-aws-vpc.adoc @@ -44,15 +40,6 @@ // Consider also adding the installation-configuration-parameters.adoc module. //YOU MUST SET AN IFEVAL FOR EACH NEW MODULE -ifeval::["{context}" == "installing-alibaba-default"] -:alibabacloud-default: -endif::[] -ifeval::["{context}" == "installing-alibaba-customizations"] -:alibabacloud-custom: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:alibabacloud-vpc: -endif::[] ifeval::["{context}" == "installing-aws-customizations"] :aws: :three-node-cluster: @@ -183,9 +170,6 @@ endif::[] = Creating the installation configuration file You can customize the {product-title} cluster you install on -ifdef::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] -Alibaba Cloud. -endif::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] ifdef::aws[] Amazon Web Services (AWS). endif::aws[] @@ -279,12 +263,6 @@ endif::ibm-power-vs[] ==== For production {product-title} clusters on which you want to perform installation debugging or disaster recovery, specify an SSH key that your `ssh-agent` process uses. ==== -ifdef::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] -... Select *alibabacloud* as the platform to target. -... Select the region to deploy the cluster to. -... Select the base domain to deploy the cluster to. The base domain corresponds to the public DNS zone that you created for your cluster. -... Provide a descriptive name for your cluster. -endif::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] ifdef::aws[] ... Select *AWS* as the platform to target. ... If you do not have an Amazon Web Services (AWS) profile stored on your computer, enter the AWS @@ -386,7 +364,6 @@ The installation program connects to Prism Central. ... Enter the base domain. This base domain must be the same one that you configured in the DNS records. endif::nutanix[] ifndef::osp[] -ifndef::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] ... Enter a descriptive name for your cluster. ifdef::azure[] + @@ -404,7 +381,6 @@ ifdef::vsphere,nutanix[] The cluster name you enter must match the cluster name you specified when configuring the DNS records. endif::vsphere,nutanix[] -endif::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] endif::osp[] ifdef::osp[] ... Enter a name for your cluster. The name must be 14 or fewer characters long. @@ -419,9 +395,9 @@ ifdef::aws-outposts[] You will find more information about how to change these values below. endif::aws-outposts[] -ifndef::restricted,alibabacloud-default,alibabacloud-custom,alibabacloud-vpc,nutanix,aws-outposts[] +ifndef::restricted,nutanix,aws-outposts[] . Modify the `install-config.yaml` file. You can find more information about the available parameters in the "Installation configuration parameters" section. -endif::restricted,alibabacloud-default,alibabacloud-custom,alibabacloud-vpc,nutanix,aws-outposts[] +endif::restricted,nutanix,aws-outposts[] ifdef::three-node-cluster[] + [NOTE] @@ -430,28 +406,6 @@ If you are installing a three-node cluster, be sure to set the `compute.replicas ==== endif::three-node-cluster[] -ifdef::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] -. Installing the cluster into Alibaba Cloud requires that the Cloud Credential Operator (CCO) operate in manual mode. Modify the `install-config.yaml` file to set the `credentialsMode` parameter to `Manual`: -+ -.Example install-config.yaml configuration file with `credentialsMode` set to `Manual` -[source,yaml] ----- -apiVersion: v1 -baseDomain: cluster1.example.com -credentialsMode: Manual <1> -compute: -- architecture: amd64 - hyperthreading: Enabled - ... ----- -<1> Add this line to set the `credentialsMode` to `Manual`. -endif::alibabacloud-default,alibabacloud-custom,alibabacloud-vpc[] - -ifdef::alibabacloud-custom,alibabacloud-vpc[] -. Modify the `install-config.yaml` file. You can find more information about the available parameters in the "Installation configuration parameters" section. -endif::alibabacloud-custom,alibabacloud-vpc[] - - ifdef::osp+restricted[] . In the `install-config.yaml` file, set the value of `platform.openstack.clusterOSImage` to the image location or name. For example: + @@ -679,15 +633,6 @@ endif::azure[] ifdef::osp-user[You now have the file `install-config.yaml` in the directory that you specified.] -ifeval::["{context}" == "installing-alibaba-default"] -:!alibabacloud-default: -endif::[] -ifeval::["{context}" == "installing-alibaba-customizations"] -:!alibabacloud-custom: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:!alibabacloud-vpc: -endif::[] ifeval::["{context}" == "installing-aws-customizations"] :!aws: :!three-node-cluster: diff --git a/modules/installation-launching-installer.adoc b/modules/installation-launching-installer.adoc index 1bf1c5c68d07..b74127ce6dfb 100644 --- a/modules/installation-launching-installer.adoc +++ b/modules/installation-launching-installer.adoc @@ -1,9 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-default.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-customizations.adoc // * installing/installing_aws/installing-aws-default.adoc // * installing/installing_aws/installing-aws-government-region.adoc @@ -50,22 +46,6 @@ // If you use this module in any other assembly, you must update the ifeval // statements. -ifeval::["{context}" == "installing-alibaba-customizations"] -:custom-config: -:single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-default"] -:custom-config: -:single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-network-customizations"] -:custom-config: -:single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:custom-config: -:single-step: -endif::[] ifeval::["{context}" == "installing-aws-private"] :custom-config: :aws: @@ -555,22 +535,6 @@ INFO Time elapsed: 36m22s * It is recommended that you use Ignition config files within 12 hours after they are generated because the 24-hour certificate rotates from 16 to 22 hours after the cluster is installed. By using the Ignition config files within 12 hours, you can avoid installation failure if the certificate update runs during installation. ==== -ifeval::["{context}" == "installing-alibaba-customizations"] -:!custom-config: -:!single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-default"] -:!custom-config: -:!single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-network-customizations"] -:!custom-config: -:!single-step: -endif::[] -ifeval::["{context}" == "installing-alibaba-vpc"] -:!custom-config: -:!single-step: -endif::[] ifeval::["{context}" == "installing-aws-private"] :!custom-config: :!aws: diff --git a/modules/installation-obtaining-installer.adoc b/modules/installation-obtaining-installer.adoc index 45ff48c57699..05d7b1539ba6 100644 --- a/modules/installation-obtaining-installer.adoc +++ b/modules/installation-obtaining-installer.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-user-infra.adoc // * installing/installing_aws/installing-aws-customizations.adoc // * installing/installing_aws/installing-aws-default.adoc diff --git a/modules/logging-in-by-using-the-web-console.adoc b/modules/logging-in-by-using-the-web-console.adoc index e92587dcec52..2449e1b4a02d 100644 --- a/modules/logging-in-by-using-the-web-console.adoc +++ b/modules/logging-in-by-using-the-web-console.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-china.adoc. // * installing/installing_aws/installing-aws-secret-region.adoc // *installing/validating-an-installation.adoc diff --git a/modules/manually-creating-alibaba-manifests.adoc b/modules/manually-creating-alibaba-manifests.adoc deleted file mode 100644 index ff53ae53c69a..000000000000 --- a/modules/manually-creating-alibaba-manifests.adoc +++ /dev/null @@ -1,24 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/installing_alibaba/installing-alibaba-default.adoc -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc - -:_mod-docs-content-type: PROCEDURE -[id="manually-creating-alibaba-manifests_{context}"] -= Generating the required installation manifests - -You must generate the Kubernetes manifest and Ignition config files that the cluster needs to configure the machines. - -.Procedure - -. Generate the manifests by running the following command from the directory that contains the installation program: -+ -[source,terminal] ----- -$ openshift-install create manifests --dir ----- -+ -where: - -``:: Specifies the directory in which the installation program creates files. diff --git a/modules/manually-creating-alibaba-ram-user.adoc b/modules/manually-creating-alibaba-ram-user.adoc deleted file mode 100644 index 881c889c1a6c..000000000000 --- a/modules/manually-creating-alibaba-ram-user.adoc +++ /dev/null @@ -1,247 +0,0 @@ -// Module included in the following assemblies: -// -// * installing/installing_alibaba/manually-creating-alibaba-ram.adoc - -:_mod-docs-content-type: PROCEDURE -[id="manually-creating-alibaba-ram-user_{context}"] -= Creating the required RAM user - -// https://github.com/openshift/cloud-credential-operator/pull/412/files#diff-2480a11ca4927139d6eaa9883946b6f4cb38358cd98def8c57dd73e9319dbc9cR232 - -You must have a Alibaba Cloud Resource Access Management (RAM) user for the installation that has sufficient privileges. You can use the Alibaba Cloud Resource Access Management console to create a new user or modify an existing user. Later, you create credentials in {product-title} based on this user's permissions. - -When you configure the RAM user, be sure to consider the following requirements: - -* The user must have an Alibaba Cloud AccessKey ID and AccessKey secret pair. - -** For a new user, you can select `Open API Access` for the Access Mode when creating the user. This mode generates the required AccessKey pair. -** For an existing user, you can add an AccessKey pair or you can link:https://www.alibabacloud.com/help/en/doc-detail/53045.htm[obtain the AccessKey pair] for that user. -+ -[NOTE] -==== -When created, the AccessKey secret is displayed only once. You must immediately save the AccessKey pair because the AccessKey pair is required for API calls. -==== - -* Add the AccessKey ID and secret to the link:https://www.alibabacloud.com/help/en/doc-detail/311667.htm#h2-sls-mfm-3p3[`~/.alibabacloud/credentials` file] on your local computer. Alibaba Cloud automatically creates this file when you log in to the console. The Cloud Credential Operator (CCO) utility, ccoutil, uses these credentials when processing `Credential Request` objects. -+ -For example: -+ -[source,terminal] ----- -[default] # Default client -type = access_key # Certification type: access_key -access_key_id = LTAI5t8cefXKmt # Key <1> -access_key_secret = wYx56mszAN4Uunfh # Secret ----- -<1> Add your AccessKeyID and AccessKeySecret here. - -* The RAM user must have the `AdministratorAccess` policy to ensure that the account has sufficient permission to create the {product-title} cluster. This policy grants permissions to manage all Alibaba Cloud resources. -+ -When you attach the `AdministratorAccess` policy to a RAM user, you grant that user full access to all Alibaba Cloud services and resources. If you do not want to create a user with full access, create a custom policy with the following actions that you can add to your RAM user for installation. These actions are sufficient to install {product-title}. -+ -[TIP] -==== -You can copy and paste the following JSON code into the Alibaba Cloud console to create a custom poicy. For information on creating custom policies, see link:https://www.alibabacloud.com/help/en/doc-detail/93733.html[Create a custom policy] in the Alibaba Cloud documentation. -==== -+ -.Example custom policy JSON file -[%collapsible] -==== -[source,json] ----- -{ - "Version": "1", - "Statement": [ - { - "Action": [ - "tag:ListTagResources", - "tag:UntagResources" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "vpc:DescribeVpcs", - "vpc:DeleteVpc", - "vpc:DescribeVSwitches", - "vpc:DeleteVSwitch", - "vpc:DescribeEipAddresses", - "vpc:DescribeNatGateways", - "vpc:ReleaseEipAddress", - "vpc:DeleteNatGateway", - "vpc:DescribeSnatTableEntries", - "vpc:CreateSnatEntry", - "vpc:AssociateEipAddress", - "vpc:ListTagResources", - "vpc:TagResources", - "vpc:DescribeVSwitchAttributes", - "vpc:CreateVSwitch", - "vpc:CreateNatGateway", - "vpc:DescribeRouteTableList", - "vpc:CreateVpc", - "vpc:AllocateEipAddress", - "vpc:ListEnhanhcedNatGatewayAvailableZones" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "ecs:ModifyInstanceAttribute", - "ecs:DescribeSecurityGroups", - "ecs:DeleteSecurityGroup", - "ecs:DescribeSecurityGroupReferences", - "ecs:DescribeSecurityGroupAttribute", - "ecs:RevokeSecurityGroup", - "ecs:DescribeInstances", - "ecs:DeleteInstances", - "ecs:DescribeNetworkInterfaces", - "ecs:DescribeInstanceRamRole", - "ecs:DescribeUserData", - "ecs:DescribeDisks", - "ecs:ListTagResources", - "ecs:AuthorizeSecurityGroup", - "ecs:RunInstances", - "ecs:TagResources", - "ecs:ModifySecurityGroupPolicy", - "ecs:CreateSecurityGroup", - "ecs:DescribeAvailableResource", - "ecs:DescribeRegions", - "ecs:AttachInstanceRamRole" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "pvtz:DescribeRegions", - "pvtz:DescribeZones", - "pvtz:DeleteZone", - "pvtz:DeleteZoneRecord", - "pvtz:BindZoneVpc", - "pvtz:DescribeZoneRecords", - "pvtz:AddZoneRecord", - "pvtz:SetZoneRecordStatus", - "pvtz:DescribeZoneInfo", - "pvtz:DescribeSyncEcsHostTask", - "pvtz:AddZone" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "slb:DescribeLoadBalancers", - "slb:SetLoadBalancerDeleteProtection", - "slb:DeleteLoadBalancer", - "slb:SetLoadBalancerModificationProtection", - "slb:DescribeLoadBalancerAttribute", - "slb:AddBackendServers", - "slb:DescribeLoadBalancerTCPListenerAttribute", - "slb:SetLoadBalancerTCPListenerAttribute", - "slb:StartLoadBalancerListener", - "slb:CreateLoadBalancerTCPListener", - "slb:ListTagResources", - "slb:TagResources", - "slb:CreateLoadBalancer" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "ram:ListResourceGroups", - "ram:DeleteResourceGroup", - "ram:ListPolicyAttachments", - "ram:DetachPolicy", - "ram:GetResourceGroup", - "ram:CreateResourceGroup", - "ram:DeleteRole", - "ram:GetPolicy", - "ram:DeletePolicy", - "ram:ListPoliciesForRole", - "ram:CreateRole", - "ram:AttachPolicyToRole", - "ram:GetRole", - "ram:CreatePolicy", - "ram:CreateUser", - "ram:DetachPolicyFromRole", - "ram:CreatePolicyVersion", - "ram:DetachPolicyFromUser", - "ram:ListPoliciesForUser", - "ram:AttachPolicyToUser", - "ram:CreateUser", - "ram:GetUser", - "ram:DeleteUser", - "ram:CreateAccessKey", - "ram:ListAccessKeys", - "ram:DeleteAccessKey", - "ram:ListUsers", - "ram:ListPolicyVersions" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "oss:DeleteBucket", - "oss:DeleteBucketTagging", - "oss:GetBucketTagging", - "oss:GetBucketCors", - "oss:GetBucketPolicy", - "oss:GetBucketLifecycle", - "oss:GetBucketReferer", - "oss:GetBucketTransferAcceleration", - "oss:GetBucketLog", - "oss:GetBucketWebSite", - "oss:GetBucketInfo", - "oss:PutBucketTagging", - "oss:PutBucket", - "oss:OpenOssService", - "oss:ListBuckets", - "oss:GetService", - "oss:PutBucketACL", - "oss:GetBucketLogging", - "oss:ListObjects", - "oss:GetObject", - "oss:PutObject", - "oss:DeleteObject" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": [ - "alidns:DescribeDomainRecords", - "alidns:DeleteDomainRecord", - "alidns:DescribeDomains", - "alidns:DescribeDomainRecordInfo", - "alidns:AddDomainRecord", - "alidns:SetDomainRecordStatus" - ], - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": "bssapi:CreateInstance", - "Resource": "*", - "Effect": "Allow" - }, - { - "Action": "ram:PassRole", - "Resource": "*", - "Effect": "Allow", - "Condition": { - "StringEquals": { - "acs:Service": "ecs.aliyuncs.com" - } - } - } - ] -} ----- -==== - -For more information about creating a RAM user and granting permissions, see link:https://www.alibabacloud.com/help/en/doc-detail/93720.htm[Create a RAM user] and link:https://www.alibabacloud.com/help/en/doc-detail/116146.htm[Grant permissions to a RAM user] in the Alibaba Cloud documentation. - diff --git a/modules/ssh-agent-using.adoc b/modules/ssh-agent-using.adoc index a255c0b4860d..85ed59ec033a 100644 --- a/modules/ssh-agent-using.adoc +++ b/modules/ssh-agent-using.adoc @@ -1,7 +1,5 @@ // Module included in the following assemblies: // -// * installing/installing_alibaba/installing-alibaba-network-customizations.adoc -// * installing/installing_alibaba/installing-alibaba-vpc.adoc // * installing/installing_aws/installing-aws-user-infra.adoc // * installing/installing_aws/installing-aws-china.adoc // * installing/installing_aws/installing-aws-customizations.adoc diff --git a/snippets/custom-dns-server.adoc b/snippets/custom-dns-server.adoc index dbf46f6ff394..273de3e758f4 100644 --- a/snippets/custom-dns-server.adoc +++ b/snippets/custom-dns-server.adoc @@ -3,7 +3,6 @@ // * modules/installation-custom-aws-vpc.adoc // * modules/installation-about-custom-azure-vnet.adoc // * modules/installation-custom-gcp-vpc.adoc -// * modules/installation-custom-alibaba-vpc.adoc // * modules/installation-ibm-power-vs.adoc :_mod-docs-content-type: SNIPPET diff --git a/welcome/index.adoc b/welcome/index.adoc index 2129cc646e60..20ef7f585a1a 100644 --- a/welcome/index.adoc +++ b/welcome/index.adoc @@ -72,15 +72,13 @@ Explore the following {product-title} installation tasks: - **xref:../installing/index.adoc#ocp-installation-overview[{product-title} installation overview]**: Depending on the platform, you can install {product-title} on installer-provisioned or user-provisioned infrastructure. The {product-title} installation program provides the flexibility to deploy {product-title} on a range of different platforms. -- **xref:../installing/installing_alibaba/preparing-to-install-on-alibaba.adoc#preparing-to-install-on-alibaba[Install a cluster on Alibaba]**: On Alibaba Cloud, you can install {product-title} on installer-provisioned infrastructure. This is currently a Technology Preview feature only. - - **xref:../installing/installing_aws/preparing-to-install-on-aws.adoc#preparing-to-install-on-aws[Install a cluster on AWS]**: On AWS, you can install {product-title} on installer-provisioned infrastructure or user-provisioned infrastructure. - **xref:../installing/installing_azure/preparing-to-install-on-azure.adoc#preparing-to-install-on-azure[Install a cluster on Azure]**: On Microsoft Azure, you can install {product-title} on installer-provisioned infrastructure or user-provisioned infrastructure. - **xref:../installing/installing_azure_stack_hub/preparing-to-install-on-azure-stack-hub.adoc#preparing-to-install-on-azure-stack-hub[Install a cluster on Azure Stack Hub]**: On Microsoft Azure Stack Hub, you can install {product-title} on installer-provisioned infrastructure or user-provisioned infrastructure. -- **xref:../installing/installing_on_prem_assisted/installing-on-prem-assisted.html#using-the-assisted-installer_installing-on-prem-assisted[Installing {product-title} with the Assisted Installer]**: The Assisted Installer is an installation solution that is provided on the Red Hat {hybrid-console}. The Assisted Installer supports installing an {product-title} cluster on many platforms, but with a focus on bare metal, Nutanix, and {vmw-full} infrastructures. +- **xref:../installing/installing_on_prem_assisted/installing-on-prem-assisted.html#using-the-assisted-installer_installing-on-prem-assisted[Installing {product-title} with the Assisted Installer]**: The Assisted Installer is an installation solution that is provided on the Red Hat {hybrid-console}. The Assisted Installer supports installing an {product-title} cluster on multiple platforms. - **xref:../installing/installing_with_agent_based_installer/installing-with-agent-based-installer.html#installing-ocp-agent_installing-with-agent-based-installer[Installing {product-title} with the Agent-based Installer]**: You can use the Agent-based Installer to generate a bootable ISO image that contains the Assisted discovery agent, the Assisted Service, and all the other information required to deploy an {product-title} cluster. The Agent-based Installer leverages the advantages of the Assisted Installer in a disconnected environment From dc7fc04a85c4ff313440c15c9d8319633f2311c0 Mon Sep 17 00:00:00 2001 From: Aidan Reilly <74046732+aireilly@users.noreply.github.com> Date: Thu, 30 May 2024 11:43:54 +0100 Subject: [PATCH 206/339] Updates for PolicyGenerator and deprecated PolicyGenTemplate Updates for Max David's comments Adding merge comparison Reorg for clarity Updates for David --- _attributes/common-attributes.adoc | 2 +- _topic_maps/_topic_map.yml | 30 ++- .../cnf-talm-for-cluster-upgrades.adoc | 16 +- .../policygenerator_for_ztp/_attributes | 1 + edge_computing/policygenerator_for_ztp/images | 1 + .../policygenerator_for_ztp/modules | 1 + .../policygenerator_for_ztp/snippets | 1 + .../ztp-advanced-policygenerator-config.adoc | 129 +++++++++++++ ...ing-managed-clusters-policygenerator.adoc} | 36 +++- ...ztp-talm-updating-managed-policies-pg.adoc | 70 +++++++ .../policygentemplate_for_ztp/_attributes | 1 + .../policygentemplate_for_ztp/images | 1 + .../policygentemplate_for_ztp/modules | 1 + .../policygentemplate_for_ztp/snippets | 1 + .../ztp-advanced-policy-config.adoc | 125 +++++++++++++ ...configuring-managed-clusters-policies.adoc | 74 ++++++++ .../ztp-talm-updating-managed-policies.adoc | 74 ++++++++ .../ztp-advanced-policy-config.adoc | 124 ------------- ...-deploying-far-edge-clusters-at-scale.adoc | 11 +- .../ztp-deploying-far-edge-sites.adoc | 11 +- edge_computing/ztp-manual-install.adoc | 11 +- .../ztp-preparing-the-hub-cluster.adoc | 13 +- .../ztp-sno-additional-worker-node.adoc | 7 +- .../ztp-talm-updating-managed-policies.adoc | 64 ------- edge_computing/ztp-updating-gitops.adoc | 11 +- .../ztp-using-hub-cluster-templates.adoc | 40 ++++ microshift_welcome/index.adoc | 2 +- modules/builds-using-build-volumes.adoc | 7 + ...-aware-lifecycle-manager-blocking-crs.adoc | 15 +- ...logy-aware-lifecycle-manager-policies.adoc | 4 +- ...alling-amq-interconnect-messaging-bus.adoc | 2 - ...are-lifecycle-manager-backup-recovery.adoc | 7 +- ...cle-manager-creating-custom-resources.adoc | 6 +- ...-manager-operator-and-platform-update.adoc | 2 +- ...ycle-manager-operator-troubleshooting.adoc | 50 ++--- ...are-lifecycle-manager-operator-update.adoc | 90 ++------- ...gy-aware-lifecycle-manager-pao-update.adoc | 25 ++- ...are-lifecycle-manager-platform-update.adoc | 73 ++------ ...fecycle-manager-preparing-for-updates.adoc | 9 +- ...are-lifecycle-manager-troubleshooting.adoc | 2 +- .../ztp-add-local-reg-for-sno-duprofile.adoc | 5 +- .../ztp-adding-new-content-to-gitops-ztp.adoc | 104 ++--------- ...-pgt-and-rhacm-pg-patching-strategies.adoc | 49 +++++ modules/ztp-configuring-cluster-policies.adoc | 4 +- .../ztp-configuring-disk-partitioning.adoc | 3 +- .../ztp-configuring-hwevents-using-pgt.adoc | 36 ++-- ...figuring-pgt-compliance-eval-timeouts.adoc | 49 +++-- .../ztp-configuring-pgt-image-registry.adoc | 11 +- .../ztp-configuring-ptp-fast-events-amqp.adoc | 74 ++++---- modules/ztp-configuring-ptp-fast-events.adoc | 50 ++--- ...tp-creating-a-validator-inform-policy.adoc | 42 ++--- modules/ztp-creating-hwevents-amqp.adoc | 53 +++--- ...-customizing-a-managed-site-using-pgt.adoc | 38 ++-- ...inition-of-done-for-ztp-installations.adoc | 2 +- ...loying-additional-changes-to-clusters.adoc | 3 +- ...tp-enabling-workload-partitioning-sno.adoc | 2 +- .../ztp-example-hub-template-functions.adoc | 3 +- ...ating-install-and-config-crs-manually.adoc | 23 +-- ...monitoring-policy-deployment-progress.adoc | 2 +- modules/ztp-pgt-config-best-practices.adoc | 8 +- modules/ztp-policygentemplates-for-ran.adoc | 43 +++-- modules/ztp-precaching-troubleshooting.adoc | 4 +- modules/ztp-precaching-ztp-config.adoc | 3 +- ...-preparing-for-the-gitops-ztp-upgrade.adoc | 4 +- ...ztp-preparing-the-hub-cluster-for-ztp.adoc | 2 +- ...paring-the-ztp-git-repository-ver-ind.adoc | 19 +- .../ztp-preparing-the-ztp-git-repository.adoc | 33 ++-- modules/ztp-provisioning-lvm-storage.adoc | 68 +++---- ...emoving-content-from-managed-clusters.adoc | 20 +- modules/ztp-removing-obsolete-content.adoc | 8 +- ...equired-changes-to-the-git-repository.adoc | 27 +-- ...tp-restarting-policies-reconciliation.adoc | 2 +- modules/ztp-site-cleanup.adoc | 6 +- .../ztp-sno-siteconfig-config-reference.adoc | 7 +- ...in-pgt-crs-with-hub-cluster-templates.adoc | 116 +++--------- ...configmap-changes-to-existing-pgt-crs.adoc | 8 +- modules/ztp-talo-integration.adoc | 4 +- modules/ztp-the-policygentemplate.adoc | 171 +++--------------- ...eshooting-ztp-gitops-installation-crs.adoc | 2 +- ...bleshooting-ztp-gitops-supermicro-tls.adoc | 2 +- ...gt-to-configure-high-performance-mode.adoc | 27 ++- ...ing-pgt-to-configure-performance-mode.adoc | 27 ++- ...ng-pgt-to-configure-power-saving-mode.adoc | 35 ++-- ...p-using-pgt-to-configure-power-states.adoc | 9 +- ...ing-pgt-to-maximize-power-saving-mode.adoc | 31 ++-- .../ztp-using-pgt-to-update-source-crs.adoc | 50 ++--- ...tp-using-rhacm-hub-cluster-templates.adoc} | 16 +- ...eneration-of-configuration-policy-crs.adoc | 24 +-- .../ztp-worker-node-applying-du-profile.adoc | 12 +- ...er-node-daemon-selector-compatibility.adoc | 4 +- .../ztp-worker-node-preparing-policies.adoc | 97 ++-------- ...ycle-manager-operator-troubleshooting.adoc | 33 ++++ ...are-lifecycle-manager-operator-update.adoc | 48 +++++ ...gy-aware-lifecycle-manager-pao-update.yaml | 7 + ...are-lifecycle-manager-platform-update.adoc | 66 +++++++ snippets/pg-group-du-sno-config-policy.yaml | 42 +++++ ...are-lifecycle-manager-operator-update.adoc | 51 ++++++ .../pg-using-ztp-to-update-source-crs.yaml | 13 ++ ...ontent-to-gitops-ztp-folder-structure.adoc | 20 ++ ...-ztp-adding-new-content-to-gitops-ztp.adoc | 99 ++++++++++ ...ing-hwevents-using-pgt-hardware-event.adoc | 11 ++ snippets/pg-ztp-configuring-hwevents.yaml | 4 + ...guring-ptp-fast-events-amqp-transport.yaml | 13 ++ ...-ztp-configuring-ptp-fast-events-amqp.yaml | 4 + ...-configuring-ptp-fast-events-linuxptp.adoc | 135 ++++++++++++++ .../pg-ztp-configuring-ptp-fast-events.yaml | 13 ++ snippets/pg-ztp-creating-hwevents-amqp.yaml | 8 + ...example-single-node-cluster-validator.adoc | 41 +++++ ...-ztp-provisioning-lvm-storage-cluster.adoc | 16 ++ .../pg-ztp-provisioning-lvm-storage-sub.yaml | 3 + snippets/pg-ztp-provisioning-lvm-storage.adoc | 14 ++ ...ing-nics-in-pgt-hub-cluster-templates.yaml | 101 +++++++++++ snippets/pg-ztp-the-policygenerator.adoc | 76 ++++++++ ...pg-to-configure-high-performance-mode.yaml | 7 + ...sing-pg-to-configure-performance-mode.yaml | 7 + ...ing-pg-to-configure-power-saving-mode.adoc | 17 ++ ...sing-pg-to-maximize-power-saving-mode.adoc | 14 ++ ...pg-ztp-worker-node-preparing-policies.adoc | 100 ++++++++++ ...ycle-manager-operator-troubleshooting.adoc | 35 ++++ ...are-lifecycle-manager-operator-update.adoc | 32 ++++ ...gy-aware-lifecycle-manager-pao-update.yaml | 9 + ...are-lifecycle-manager-platform-update.adoc | 48 +++++ snippets/pgt-deprecation-notice.adoc | 8 + snippets/pgt-group-du-sno-config-policy.yaml | 54 ++++++ ...are-lifecycle-manager-operator-update.adoc | 32 ++++ .../pgt-using-ztp-to-update-source-crs.yaml | 15 ++ ...ontent-to-gitops-ztp-folder-structure.adoc | 20 ++ ...-ztp-adding-new-content-to-gitops-ztp.adoc | 63 +++++++ ...ing-hwevents-using-pgt-hardware-event.adoc | 11 ++ ...gt-ztp-configuring-hwevents-using-pgt.yaml | 7 + ...guring-ptp-fast-events-amqp-transport.yaml | 7 + ...-ztp-configuring-ptp-fast-events-amqp.yaml | 7 + ...-configuring-ptp-fast-events-linuxptp.adoc | 23 +++ .../pgt-ztp-configuring-ptp-fast-events.yaml | 7 + snippets/pgt-ztp-creating-hwevents-amqp.yaml | 14 ++ ...example-single-node-cluster-validator.adoc | 27 +++ ...-ztp-provisioning-lvm-storage-cluster.adoc | 14 ++ .../pgt-ztp-provisioning-lvm-storage-sub.yaml | 6 + .../pgt-ztp-provisioning-lvm-storage.adoc | 13 ++ snippets/pgt-ztp-the-policygentemplate.adoc | 64 +++++++ ...gt-to-configure-high-performance-mode.yaml | 10 + ...ing-pgt-to-configure-performance-mode.yaml | 10 + ...ng-pgt-to-configure-power-saving-mode.adoc | 19 ++ ...ing-pgt-to-maximize-power-saving-mode.adoc | 14 ++ ...gt-ztp-worker-node-preparing-policies.adoc | 80 ++++++++ snippets/ptp-amq-interconnect-eol.adoc | 1 + ...creating-hwevents-amqp-hardware-event.adoc | 10 + ...ing-nics-in-pgt-hub-cluster-templates.yaml | 80 ++++++++ snippets/ztp-the-policygenerator-single.yaml | 152 ++++++++++++++++ .../ztp-the-policygentemplate-single.yaml | 20 ++ 150 files changed, 3163 insertions(+), 1304 deletions(-) create mode 120000 edge_computing/policygenerator_for_ztp/_attributes create mode 120000 edge_computing/policygenerator_for_ztp/images create mode 120000 edge_computing/policygenerator_for_ztp/modules create mode 120000 edge_computing/policygenerator_for_ztp/snippets create mode 100644 edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc rename edge_computing/{ztp-configuring-managed-clusters-policies.adoc => policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc} (50%) create mode 100644 edge_computing/policygenerator_for_ztp/ztp-talm-updating-managed-policies-pg.adoc create mode 120000 edge_computing/policygentemplate_for_ztp/_attributes create mode 120000 edge_computing/policygentemplate_for_ztp/images create mode 120000 edge_computing/policygentemplate_for_ztp/modules create mode 120000 edge_computing/policygentemplate_for_ztp/snippets create mode 100644 edge_computing/policygentemplate_for_ztp/ztp-advanced-policy-config.adoc create mode 100644 edge_computing/policygentemplate_for_ztp/ztp-configuring-managed-clusters-policies.adoc create mode 100644 edge_computing/policygentemplate_for_ztp/ztp-talm-updating-managed-policies.adoc delete mode 100644 edge_computing/ztp-advanced-policy-config.adoc delete mode 100644 edge_computing/ztp-talm-updating-managed-policies.adoc create mode 100644 edge_computing/ztp-using-hub-cluster-templates.adoc create mode 100644 modules/ztp-comparing-pgt-and-rhacm-pg-patching-strategies.adoc rename modules/{ztp-using-hub-cluster-templates.adoc => ztp-using-rhacm-hub-cluster-templates.adoc} (79%) create mode 100644 snippets/pg-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc create mode 100644 snippets/pg-cnf-topology-aware-lifecycle-manager-operator-update.adoc create mode 100644 snippets/pg-cnf-topology-aware-lifecycle-manager-pao-update.yaml create mode 100644 snippets/pg-cnf-topology-aware-lifecycle-manager-platform-update.adoc create mode 100644 snippets/pg-group-du-sno-config-policy.yaml create mode 100644 snippets/pg-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc create mode 100644 snippets/pg-using-ztp-to-update-source-crs.yaml create mode 100644 snippets/pg-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc create mode 100644 snippets/pg-ztp-adding-new-content-to-gitops-ztp.adoc create mode 100644 snippets/pg-ztp-configuring-hwevents-using-pgt-hardware-event.adoc create mode 100644 snippets/pg-ztp-configuring-hwevents.yaml create mode 100644 snippets/pg-ztp-configuring-ptp-fast-events-amqp-transport.yaml create mode 100644 snippets/pg-ztp-configuring-ptp-fast-events-amqp.yaml create mode 100644 snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc create mode 100644 snippets/pg-ztp-configuring-ptp-fast-events.yaml create mode 100644 snippets/pg-ztp-creating-hwevents-amqp.yaml create mode 100644 snippets/pg-ztp-example-single-node-cluster-validator.adoc create mode 100644 snippets/pg-ztp-provisioning-lvm-storage-cluster.adoc create mode 100644 snippets/pg-ztp-provisioning-lvm-storage-sub.yaml create mode 100644 snippets/pg-ztp-provisioning-lvm-storage.adoc create mode 100644 snippets/pg-ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml create mode 100644 snippets/pg-ztp-the-policygenerator.adoc create mode 100644 snippets/pg-ztp-using-pg-to-configure-high-performance-mode.yaml create mode 100644 snippets/pg-ztp-using-pg-to-configure-performance-mode.yaml create mode 100644 snippets/pg-ztp-using-pg-to-configure-power-saving-mode.adoc create mode 100644 snippets/pg-ztp-using-pg-to-maximize-power-saving-mode.adoc create mode 100644 snippets/pg-ztp-worker-node-preparing-policies.adoc create mode 100644 snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc create mode 100644 snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-update.adoc create mode 100644 snippets/pgt-cnf-topology-aware-lifecycle-manager-pao-update.yaml create mode 100644 snippets/pgt-cnf-topology-aware-lifecycle-manager-platform-update.adoc create mode 100644 snippets/pgt-deprecation-notice.adoc create mode 100644 snippets/pgt-group-du-sno-config-policy.yaml create mode 100644 snippets/pgt-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc create mode 100644 snippets/pgt-using-ztp-to-update-source-crs.yaml create mode 100644 snippets/pgt-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc create mode 100644 snippets/pgt-ztp-adding-new-content-to-gitops-ztp.adoc create mode 100644 snippets/pgt-ztp-configuring-hwevents-using-pgt-hardware-event.adoc create mode 100644 snippets/pgt-ztp-configuring-hwevents-using-pgt.yaml create mode 100644 snippets/pgt-ztp-configuring-ptp-fast-events-amqp-transport.yaml create mode 100644 snippets/pgt-ztp-configuring-ptp-fast-events-amqp.yaml create mode 100644 snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc create mode 100644 snippets/pgt-ztp-configuring-ptp-fast-events.yaml create mode 100644 snippets/pgt-ztp-creating-hwevents-amqp.yaml create mode 100644 snippets/pgt-ztp-example-single-node-cluster-validator.adoc create mode 100644 snippets/pgt-ztp-provisioning-lvm-storage-cluster.adoc create mode 100644 snippets/pgt-ztp-provisioning-lvm-storage-sub.yaml create mode 100644 snippets/pgt-ztp-provisioning-lvm-storage.adoc create mode 100644 snippets/pgt-ztp-the-policygentemplate.adoc create mode 100644 snippets/pgt-ztp-using-pgt-to-configure-high-performance-mode.yaml create mode 100644 snippets/pgt-ztp-using-pgt-to-configure-performance-mode.yaml create mode 100644 snippets/pgt-ztp-using-pgt-to-configure-power-saving-mode.adoc create mode 100644 snippets/pgt-ztp-using-pgt-to-maximize-power-saving-mode.adoc create mode 100644 snippets/pgt-ztp-worker-node-preparing-policies.adoc create mode 100644 snippets/ztp-creating-hwevents-amqp-hardware-event.adoc create mode 100644 snippets/ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml create mode 100644 snippets/ztp-the-policygenerator-single.yaml create mode 100644 snippets/ztp-the-policygentemplate-single.yaml diff --git a/_attributes/common-attributes.adoc b/_attributes/common-attributes.adoc index 054a1e5b3ba8..cac86a5414d5 100644 --- a/_attributes/common-attributes.adoc +++ b/_attributes/common-attributes.adoc @@ -46,7 +46,7 @@ endif::[] :rh-storage: OpenShift Data Foundation :rh-rhacm-first: Red Hat Advanced Cluster Management (RHACM) :rh-rhacm: RHACM -:rh-rhacm-version: 2.9 +:rh-rhacm-version: 2.10 :sandboxed-containers-first: OpenShift sandboxed containers :sandboxed-containers-operator: OpenShift sandboxed containers Operator :sandboxed-containers-version: 1.5 diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 29b9368fdc8f..742c5821a414 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -3034,9 +3034,7 @@ Topics: File: ztp-updating-gitops - Name: Installing managed clusters with RHACM and SiteConfig resources File: ztp-deploying-far-edge-sites -- Name: Configuring managed clusters with policies and PolicyGenTemplate resources - File: ztp-configuring-managed-clusters-policies -- Name: Manually installing a single-node OpenShift cluster with ZTP +- Name: Manually installing a single-node OpenShift cluster with GitOps ZTP File: ztp-manual-install - Name: Recommended single-node OpenShift cluster configuration for vDU application workloads File: ztp-reference-cluster-configuration-for-vdu @@ -3044,12 +3042,30 @@ Topics: File: ztp-vdu-validating-cluster-tuning - Name: Advanced managed cluster configuration with SiteConfig resources File: ztp-advanced-install-ztp -- Name: Advanced managed cluster configuration with PolicyGenTemplate resources - File: ztp-advanced-policy-config +- Name: Managing cluster polices with PolicyGenerator resources + Dir: policygenerator_for_ztp + Distros: openshift-origin,openshift-enterprise + Topics: + - Name: Configuring managed cluster policies by using PolicyGenerator resources + File: ztp-configuring-managed-clusters-policygenerator + - Name: Advanced managed cluster configuration with PolicyGenerator resources + File: ztp-advanced-policygenerator-config + - Name: Updating managed clusters in a disconnected environment with PolicyGenerator resources and TALM + File: ztp-talm-updating-managed-policies-pg +- Name: Managing cluster polices with PolicyGenTemplate resources + Dir: policygentemplate_for_ztp + Distros: openshift-origin,openshift-enterprise + Topics: + - Name: Configuring managed cluster policies by using PolicyGenTemplate resources + File: ztp-configuring-managed-clusters-policies + - Name: Advanced managed cluster configuration with PolicyGenTemplate resources + File: ztp-advanced-policy-config + - Name: Updating managed clusters in a disconnected environment with PolicyGenTemplate resources and TALM + File: ztp-talm-updating-managed-policies +- Name: Using hub templates in PolicyGenerator or PolicyGenTemplate CRs + File: ztp-using-hub-cluster-templates - Name: Updating managed clusters with the Topology Aware Lifecycle Manager File: cnf-talm-for-cluster-upgrades -- Name: Updating managed clusters in a disconnected environment with the Topology Aware Lifecycle Manager - File: ztp-talm-updating-managed-policies - Name: Expanding single-node OpenShift clusters with GitOps ZTP File: ztp-sno-additional-worker-node - Name: Pre-caching images for single-node OpenShift deployments diff --git a/edge_computing/cnf-talm-for-cluster-upgrades.adoc b/edge_computing/cnf-talm-for-cluster-upgrades.adoc index 107dad139be7..9193a96ef027 100644 --- a/edge_computing/cnf-talm-for-cluster-upgrades.adoc +++ b/edge_computing/cnf-talm-for-cluster-upgrades.adoc @@ -8,12 +8,18 @@ toc::[] You can use the {cgu-operator-first} to manage the software lifecycle of multiple clusters. {cgu-operator} uses {rh-rhacm-first} policies to perform changes on the target clusters. -:FeatureName: {cgu-operator-full} +:Featurename: Using PolicyGenerator resources with {ztp} +include::snippets/technology-preview.adoc[] include::modules/cnf-about-topology-aware-lifecycle-manager-config.adoc[leveloffset=+1] include::modules/cnf-about-topology-aware-lifecycle-manager-policies.adoc[leveloffset=+1] +[role="_additional-resources"] +.Additional resources + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-the-policygentemplate_ztp-configuring-managed-clusters-policygenerator[About the PolicyGenerator CRD] + include::modules/cnf-topology-aware-lifecycle-manager-installation-web-console.adoc[leveloffset=+1] include::modules/cnf-topology-aware-lifecycle-manager-installation-cli.adoc[leveloffset=+1] @@ -27,7 +33,7 @@ include::modules/cnf-topology-aware-lifecycle-manager-policies-concept.adoc[leve [role="_additional-resources"] .Additional resources -For more information about the `PolicyGenTemplate` CRD, see xref:../edge_computing/ztp-configuring-managed-clusters-policies.adoc#ztp-the-policygentemplate_ztp-configuring-managed-clusters-policies[About the PolicyGenTemplate CRD]. +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-the-policygentemplate_ztp-configuring-managed-clusters-policygenerator[About the PolicyGenerator CRD] include::modules/cnf-topology-aware-lifecycle-manager-about-subscription-crs.adoc[leveloffset=+2] @@ -50,8 +56,8 @@ include::modules/cnf-topology-aware-lifecycle-manager-troubleshooting.adoc[level [role="_additional-resources"] .Additional resources -* For information about troubleshooting, see xref:../support/troubleshooting/troubleshooting-operator-issues.adoc#troubleshooting-operator-issues[OpenShift Container Platform Troubleshooting Operator Issues]. +* xref:../support/troubleshooting/troubleshooting-operator-issues.adoc#troubleshooting-operator-issues[{product-title} Troubleshooting Operator Issues] -* For more information about using {cgu-operator-full} in the ZTP workflow, see xref:../edge_computing/ztp-talm-updating-managed-policies.adoc#ztp-topology-aware-lifecycle-manager[Updating managed policies with {cgu-operator-full}]. +* xref:../edge_computing/policygenerator_for_ztp/ztp-talm-updating-managed-policies-pg.adoc#ztp-topology-aware-lifecycle-manager[Updating managed policies with {cgu-operator-full}] -* For more information about the `PolicyGenTemplate` CRD, see xref:../edge_computing/ztp-configuring-managed-clusters-policies.adoc#ztp-the-policygentemplate_ztp-configuring-managed-clusters-policies[About the PolicyGenTemplate CRD] +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-the-policygentemplate_ztp-configuring-managed-clusters-policygenerator[About the PolicyGenerator CRD] diff --git a/edge_computing/policygenerator_for_ztp/_attributes b/edge_computing/policygenerator_for_ztp/_attributes new file mode 120000 index 000000000000..20cc1dcb77bf --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/_attributes @@ -0,0 +1 @@ +../../_attributes/ \ No newline at end of file diff --git a/edge_computing/policygenerator_for_ztp/images b/edge_computing/policygenerator_for_ztp/images new file mode 120000 index 000000000000..847b03ed0541 --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/edge_computing/policygenerator_for_ztp/modules b/edge_computing/policygenerator_for_ztp/modules new file mode 120000 index 000000000000..36719b9de743 --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/modules @@ -0,0 +1 @@ +../../modules/ \ No newline at end of file diff --git a/edge_computing/policygenerator_for_ztp/snippets b/edge_computing/policygenerator_for_ztp/snippets new file mode 120000 index 000000000000..5a3f5add140e --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/snippets @@ -0,0 +1 @@ +../../snippets/ \ No newline at end of file diff --git a/edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc b/edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc new file mode 100644 index 000000000000..bfba8214cea2 --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc @@ -0,0 +1,129 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-advanced-policygenerator-config"] += Advanced managed cluster configuration with PolicyGenerator resources +include::_attributes/common-attributes.adoc[] +:context: ztp-advanced-policygenerator-config +:policy-gen-cr: PolicyGenerator +:policy-prefix: acm- +:rangen-yaml-path: policies.manifests +:argocd-folder: out/argocd/example/acmpolicygenerator/ + +toc::[] + +You can use `{policy-gen-cr}` CRs to deploy custom functionality in your managed clusters. + +:Featurename: Using PolicyGenerator resources with {ztp} +include::snippets/technology-preview.adoc[] + +[NOTE] +==== +For more information about `PolicyGenerator` resources, see the {rh-rhacm} link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html/governance/integrate-third-party-policy-controllers#policy-generator[Policy Generator] documentation. +==== + +include::modules/ztp-deploying-additional-changes-to-clusters.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-advanced-install-ztp.adoc#ztp-customizing-the-install-extra-manifests_ztp-advanced-install-ztp[Customizing extra installation manifests in the {ztp} pipeline] + +include::modules/ztp-using-pgt-to-update-source-crs.adoc[leveloffset=+1] + +include::modules/ztp-adding-new-content-to-gitops-ztp.adoc[leveloffset=+1] + +include::modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc[leveloffset=+1] + +include::modules/ztp-creating-a-validator-inform-policy.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}] + +include::modules/ztp-using-pgt-to-configure-power-states.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#configuring-workload-hints_cnf-low-latency-perf-profile[Configuring node power consumption and realtime processing with workload hints] + +include::modules/ztp-using-pgt-to-configure-performance-mode.adoc[leveloffset=+2] + +include::modules/ztp-using-pgt-to-configure-high-performance-mode.adoc[leveloffset=+2] + +include::modules/ztp-using-pgt-to-configure-power-saving-mode.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes that run colocated high and low priority workloads] + +* xref:../../edge_computing/ztp-reference-cluster-configuration-for-vdu.adoc#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] + +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] + +include::modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc[leveloffset=+2] + +include::modules/ztp-provisioning-lvm-storage.adoc[leveloffset=+1] + +[id="ztp-advanced-policy-config-ptp_{context}"] +== Configuring PTP events with {policy-gen-cr} CRs + +You can use the {ztp} pipeline to configure PTP events that use HTTP or AMQP transport. + +include::snippets/ptp-amq-interconnect-eol.adoc[] + +include::modules/ztp-configuring-ptp-fast-events.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc#ztp-using-pgt-to-update-source-crs_ztp-advanced-policygenerator-config[Using {policy-gen-cr} CRs to override source CRs content] + +include::modules/ztp-configuring-ptp-fast-events-amqp.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../networking/ptp/using-ptp-events.adoc#cnf-installing-amq-interconnect-messaging-bus_using-ptp-events[Installing the AMQ messaging bus] + +* xref:../../registry/index.adoc#registry-overview[{product-registry} overview] + +[id="ztp-advanced-policy-config-bare-metal_{context}"] +== Configuring bare-metal events with {policy-gen-cr} CRs + +You can use the {ztp} pipeline to configure bare-metal events that use HTTP or AMQP transport. + +include::snippets/ptp-amq-interconnect-eol.adoc[] + +include::modules/ztp-configuring-hwevents-using-pgt.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/using-rfhe.adoc#nw-rfhe-installing-operator-cli_using-rfhe[Installing the {redfish-operator} using the CLI] + +* xref:../../scalability_and_performance/using-rfhe.adoc#nw-rfhe-creating-hardware-event_using-rfhe[Creating the bare-metal event and Secret CRs] + +include::modules/ztp-creating-hwevents-amqp.adoc[leveloffset=+2] + +include::modules/ztp-add-local-reg-for-sno-duprofile.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../registry/index.adoc#registry-overview[{product-title} registry overview] + +include::modules/ztp-configuring-disk-partitioning.adoc[leveloffset=+2] + +include::modules/ztp-configuring-pgt-image-registry.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../registry/accessing-the-registry.adoc#accessing-the-registry[Accessing the registry] + +:!policy-gen-cr: +:!policy-prefix: +:!rangen-yaml-path: +:!argocd-folder: diff --git a/edge_computing/ztp-configuring-managed-clusters-policies.adoc b/edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc similarity index 50% rename from edge_computing/ztp-configuring-managed-clusters-policies.adoc rename to edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc index e52160f22384..eab3f613d171 100644 --- a/edge_computing/ztp-configuring-managed-clusters-policies.adoc +++ b/edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc @@ -1,12 +1,27 @@ :_mod-docs-content-type: ASSEMBLY -[id="ztp-configuring-managed-clusters-policies"] -= Configuring managed clusters with policies and PolicyGenTemplate resources +[id="ztp-configuring-managed-clusters-policygenerator"] += Configuring managed cluster policies by using PolicyGenerator resources include::_attributes/common-attributes.adoc[] -:context: ztp-configuring-managed-clusters-policies +:context: ztp-configuring-managed-clusters-policygenerator +:policy-gen-cr: PolicyGenerator +:policy-prefix: acm- +:argocd-folder: out/argocd/example/acmpolicygenerator/ +:placement-rule-cr: Placement +:binding-field: policyDefaults.placement.labelSelector toc::[] -Applied policy custom resources (CRs) configure the managed clusters that you provision. You can customize how {rh-rhacm-first} uses `PolicyGenTemplate` CRs to generate the applied policy CRs. +Applied `Policy` custom resources (CRs) configure the managed clusters that you provision. You can customize how {rh-rhacm-first} uses `{policy-gen-cr}` CRs to generate the applied `Policy` CRs. + +:Featurename: Using PolicyGenerator resources with {ztp} +include::snippets/technology-preview.adoc[] + +[NOTE] +==== +For more information about `PolicyGenerator` resources, see the {rh-rhacm} link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html/governance/integrate-third-party-policy-controllers#policy-generator[Policy Generator] documentation. +==== + +include::modules/ztp-comparing-pgt-and-rhacm-pg-patching-strategies.adoc[leveloffset=+1] include::modules/ztp-the-policygentemplate.adoc[leveloffset=+1] @@ -29,15 +44,14 @@ include::modules/ztp-policygentemplates-for-ran.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] include::modules/ztp-customizing-a-managed-site-using-pgt.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* xref:../edge_computing/ztp-advanced-policy-config.adoc#ztp-creating-a-validator-inform-policy_ztp-advanced-policy-config[Signalling ZTP cluster deployment completion with validator inform policies] - +* xref:../../edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc#ztp-creating-a-validator-inform-policy_ztp-advanced-policy-config[Signalling {ztp} cluster deployment completion with validator inform policies] include::modules/ztp-monitoring-policy-deployment-progress.adoc[leveloffset=+1] @@ -48,8 +62,14 @@ include::modules/ztp-restarting-policies-reconciliation.adoc[leveloffset=+1] [role="_additional-resources"] .Additional resources -* For information about using {cgu-operator-first} to construct your own `ClusterGroupUpgrade` CR, see xref:../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-about-cgu-crs_cnf-topology-aware-lifecycle-manager[About the ClusterGroupUpgrade CR]. +* For information about using {cgu-operator-first} to construct your own `ClusterGroupUpgrade` CR, see xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-about-cgu-crs_cnf-topology-aware-lifecycle-manager[About the ClusterGroupUpgrade CR]. include::modules/ztp-removing-content-from-managed-clusters.adoc[leveloffset=+1] include::modules/ztp-definition-of-done-for-ztp-installations.adoc[leveloffset=+1] + +:!policy-gen-cr: +:!policy-prefix: +:!argocd-folder: +:!placement-rule-cr: +:!binding-field: diff --git a/edge_computing/policygenerator_for_ztp/ztp-talm-updating-managed-policies-pg.adoc b/edge_computing/policygenerator_for_ztp/ztp-talm-updating-managed-policies-pg.adoc new file mode 100644 index 000000000000..a8c66bf742f3 --- /dev/null +++ b/edge_computing/policygenerator_for_ztp/ztp-talm-updating-managed-policies-pg.adoc @@ -0,0 +1,70 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-topology-aware-lifecycle-manager-pg"] += Updating managed clusters in a disconnected environment with PolicyGenerator resources and TALM +include::_attributes/common-attributes.adoc[] +:context: ztp-talm-pg +:policy-gen-cr: PolicyGenerator +:policy-prefix: acm- +:rangen-yaml-path: policies.manifests + +toc::[] +You can use the {cgu-operator-first} to manage the software lifecycle of managed clusters that you have deployed using {ztp-first} and {cgu-operator-first}. +{cgu-operator} uses {rh-rhacm-first} {policy-gen-cr} policies to manage and control changes applied to target clusters. + +:Featurename: Using PolicyGenerator resources with {ztp} +include::snippets/technology-preview.adoc[] + +[role="_additional-resources"] +.Additional resources + +* For more information about the {cgu-operator-full}, see xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#cnf-about-topology-aware-lifecycle-manager-config_cnf-topology-aware-lifecycle-manager[About the {cgu-operator-full}]. + +include::modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For more information about how to update {ztp-first}, see xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}]. + +* For more information about how to mirror an {product-title} image repository, see xref:../../installing/disconnected_install/installing-mirroring-installation-images.adoc#installation-mirror-repository_installing-mirroring-installation-images[Mirroring the {product-title} image repository]. + +* For more information about how to mirror Operator catalogs for disconnected clusters, see xref:../../installing/disconnected_install/installing-mirroring-installation-images.adoc#olm-mirror-catalog_installing-mirroring-installation-images[Mirroring Operator catalogs for use with disconnected clusters]. + +* For more information about how to prepare the disconnected environment and mirroring the desired image repository, see xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-hub-cluster[Preparing the disconnected environment]. + +* For more information about update channels and releases, see xref:../../updating/understanding_updates/understanding-update-channels-release.adoc#understanding-update-channels-releases[Understanding update channels and releases]. + +include::modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For more information about mirroring the images in a disconnected environment, see xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-acm-adding-images-to-mirror-registry_ztp-preparing-the-hub-cluster[Preparing the disconnected environment]. + +include::modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For more information about updating {ztp}, see xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}]. + +include::modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-precache-user-spec-images.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* For more information about the {cgu-operator} precaching workflow, see xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-precache-feature-concept_cnf-topology-aware-lifecycle-manager[Using the container image precache feature]. + +include::modules/cnf-topology-aware-lifecycle-manager-autocreate-cgu-cr-ztp.adoc[leveloffset=+1] + +:!policy-gen-cr: +:!policy-prefix: +:!rangen-yaml-path: diff --git a/edge_computing/policygentemplate_for_ztp/_attributes b/edge_computing/policygentemplate_for_ztp/_attributes new file mode 120000 index 000000000000..20cc1dcb77bf --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/_attributes @@ -0,0 +1 @@ +../../_attributes/ \ No newline at end of file diff --git a/edge_computing/policygentemplate_for_ztp/images b/edge_computing/policygentemplate_for_ztp/images new file mode 120000 index 000000000000..847b03ed0541 --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/edge_computing/policygentemplate_for_ztp/modules b/edge_computing/policygentemplate_for_ztp/modules new file mode 120000 index 000000000000..36719b9de743 --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/modules @@ -0,0 +1 @@ +../../modules/ \ No newline at end of file diff --git a/edge_computing/policygentemplate_for_ztp/snippets b/edge_computing/policygentemplate_for_ztp/snippets new file mode 120000 index 000000000000..5a3f5add140e --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/snippets @@ -0,0 +1 @@ +../../snippets/ \ No newline at end of file diff --git a/edge_computing/policygentemplate_for_ztp/ztp-advanced-policy-config.adoc b/edge_computing/policygentemplate_for_ztp/ztp-advanced-policy-config.adoc new file mode 100644 index 000000000000..b4b1f10e61e7 --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/ztp-advanced-policy-config.adoc @@ -0,0 +1,125 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-advanced-policy-config"] += Advanced managed cluster configuration with PolicyGenTemplate resources +include::_attributes/common-attributes.adoc[] +:context: ztp-advanced-policy-config +:policy-gen-cr: PolicyGenTemplate +:policy-prefix: +:rangen-yaml-path: spec.sourceFiles +:argocd-folder: out/argocd/example/policygentemplates/ + +toc::[] + +You can use `{policy-gen-cr}` CRs to deploy custom functionality in your managed clusters. + +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +include::modules/ztp-deploying-additional-changes-to-clusters.adoc[leveloffset=+1] + +include::modules/ztp-using-pgt-to-update-source-crs.adoc[leveloffset=+1] + +include::modules/ztp-adding-new-content-to-gitops-ztp.adoc[leveloffset=+1] + +include::modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc[leveloffset=+1] + +include::modules/ztp-creating-a-validator-inform-policy.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}] + +include::modules/ztp-using-pgt-to-configure-power-states.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#configuring-workload-hints_cnf-low-latency-perf-profile[Configuring node power consumption and realtime processing with workload hints] + +include::modules/ztp-using-pgt-to-configure-performance-mode.adoc[leveloffset=+2] + +include::modules/ztp-using-pgt-to-configure-high-performance-mode.adoc[leveloffset=+2] + +include::modules/ztp-using-pgt-to-configure-power-saving-mode.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes that run colocated high and low priority workloads] + +* xref:../../edge_computing/ztp-reference-cluster-configuration-for-vdu.adoc#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] + +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] + +include::modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc[leveloffset=+2] + +include::modules/ztp-provisioning-lvm-storage.adoc[leveloffset=+1] + +[id="ztp-advanced-policy-config-ptp_{context}"] +== Configuring PTP events with PolicyGenTemplate CRs + +You can use the {ztp} pipeline to configure PTP events that use HTTP or AMQP transport. + +include::snippets/ptp-amq-interconnect-eol.adoc[] + +include::modules/ztp-configuring-ptp-fast-events.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygentemplate_for_ztp/ztp-advanced-policy-config.adoc#ztp-using-pgt-to-update-source-crs_ztp-advanced-policy-config[Using PolicyGenTemplate CRs to override source CRs content] + +include::modules/ztp-configuring-ptp-fast-events-amqp.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../networking/ptp/using-ptp-events.adoc#cnf-installing-amq-interconnect-messaging-bus_using-ptp-events[Installing the AMQ messaging bus] + +* xref:../../registry/index.adoc#registry-overview[{product-registry} overview] + +[id="ztp-advanced-policy-config-bare-metal_{context}"] +== Configuring bare-metal events with PolicyGenTemplate CRs + +You can use the {ztp} pipeline to configure bare-metal events that use HTTP or AMQP transport. + +include::snippets/ptp-amq-interconnect-eol.adoc[] + +include::modules/ztp-configuring-hwevents-using-pgt.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../scalability_and_performance/using-rfhe.adoc#nw-rfhe-installing-operator-cli_using-rfhe[Installing the {redfish-operator} using the CLI] + +* xref:../../scalability_and_performance/using-rfhe.adoc#nw-rfhe-creating-hardware-event_using-rfhe[Creating the bare-metal event and Secret CRs] + +include::modules/ztp-creating-hwevents-amqp.adoc[leveloffset=+2] + +include::modules/ztp-add-local-reg-for-sno-duprofile.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../registry/index.adoc#registry-overview[{product-title} registry overview] + +include::modules/ztp-configuring-disk-partitioning.adoc[leveloffset=+2] + +include::modules/ztp-configuring-pgt-image-registry.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../registry/accessing-the-registry.adoc#accessing-the-registry[Accessing the registry] + +:!policy-gen-cr: +:!policy-prefix: +:!rangen-yaml-path: +:!argocd-folder: diff --git a/edge_computing/policygentemplate_for_ztp/ztp-configuring-managed-clusters-policies.adoc b/edge_computing/policygentemplate_for_ztp/ztp-configuring-managed-clusters-policies.adoc new file mode 100644 index 000000000000..52af15ba607a --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/ztp-configuring-managed-clusters-policies.adoc @@ -0,0 +1,74 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-configuring-managed-clusters-policies"] += Configuring managed cluster policies by using PolicyGenTemplate resources +include::_attributes/common-attributes.adoc[] +:context: ztp-configuring-managed-clusters-policies +:policy-gen-cr: PolicyGenTemplate +:policy-prefix: +:argocd-folder: out/argocd/example/policygentemplates +:placement-rule-cr: PlacementRule +:binding-field: spec.bindingRules + +toc::[] + +Applied `Policy` custom resources (CRs) configure the managed clusters that you provision. You can customize how {rh-rhacm-first} uses `{policy-gen-cr}` CRs to generate the applied `Policy` CRs. + +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +include::modules/ztp-the-policygentemplate.adoc[leveloffset=+1] + +include::modules/ztp-pgt-config-best-practices.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For recommendations about scaling clusters with {rh-rhacm}, see link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.6/html/install/installing#performance-and-scalability[Performance and scalability]. + +[NOTE] +==== +When managing large numbers of spoke clusters on the hub cluster, minimize the number of policies to reduce resource consumption. + +Grouping multiple configuration CRs into a single or limited number of policies is one way to reduce the overall number of policies on the hub cluster. When using the common, group, and site hierarchy of policies for managing site configuration, it is especially important to combine site-specific configurations into a single policy. +==== + +include::modules/ztp-policygentemplates-for-ran.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] + +include::modules/ztp-customizing-a-managed-site-using-pgt.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc#ztp-creating-a-validator-inform-policy_ztp-advanced-policy-config[Signalling {ztp} cluster deployment completion with validator inform policies] + +include::modules/ztp-monitoring-policy-deployment-progress.adoc[leveloffset=+1] + +include::modules/ztp-validating-the-generation-of-configuration-policy-crs.adoc[leveloffset=+1] + +include::modules/ztp-restarting-policies-reconciliation.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* For information about using {cgu-operator-first} to construct your own `ClusterGroupUpgrade` CR, see xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-about-cgu-crs_cnf-topology-aware-lifecycle-manager[About the ClusterGroupUpgrade CR]. + +include::modules/ztp-removing-content-from-managed-clusters.adoc[leveloffset=+1] + +include::modules/ztp-definition-of-done-for-ztp-installations.adoc[leveloffset=+1] + +:!policy-gen-cr: +:!policy-prefix: +:!argocd-folder: +:!placement-rule-cr: +:!binding-field: diff --git a/edge_computing/policygentemplate_for_ztp/ztp-talm-updating-managed-policies.adoc b/edge_computing/policygentemplate_for_ztp/ztp-talm-updating-managed-policies.adoc new file mode 100644 index 000000000000..6b9309e3c458 --- /dev/null +++ b/edge_computing/policygentemplate_for_ztp/ztp-talm-updating-managed-policies.adoc @@ -0,0 +1,74 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-topology-aware-lifecycle-manager"] += Updating managed clusters in a disconnected environment with PolicyGenTemplate resources and TALM +include::_attributes/common-attributes.adoc[] +:context: ztp-talm +:policy-gen-cr: PolicyGenTemplate +:policy-prefix: +:rangen-yaml-path: spec.sourceFiles + +toc::[] + +You can use the {cgu-operator-first} to manage the software lifecycle of managed clusters that you have deployed by using {ztp-first} and {cgu-operator-first}. +{cgu-operator} uses {rh-rhacm-first} {policy-gen-cr} policies to manage and control changes applied to target clusters. + +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +* xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#cnf-about-topology-aware-lifecycle-manager-config_cnf-topology-aware-lifecycle-manager[About the {cgu-operator-full}] + +include::modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}] + +* xref:../../installing/disconnected_install/installing-mirroring-installation-images.adoc#installation-mirror-repository_installing-mirroring-installation-images[Mirroring the {product-title} image repository] + +* xref:../../installing/disconnected_install/installing-mirroring-installation-images.adoc#olm-mirror-catalog_installing-mirroring-installation-images[Mirroring Operator catalogs for use with disconnected clusters] + +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-hub-cluster[Preparing the disconnected environment] + +* xref:../../updating/understanding_updates/understanding-update-channels-release.adoc#understanding-update-channels-releases[Understanding update channels and releases] + +include::modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-acm-adding-images-to-mirror-registry_ztp-preparing-the-hub-cluster[Preparing the disconnected environment] + +include::modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}] + +include::modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-precache-user-spec-images.adoc[leveloffset=+1] + +include::modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc[leveloffset=+2] + +[role="_additional-resources"] +.Additional resources + +* xref:../../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-precache-feature-concept_cnf-topology-aware-lifecycle-manager[Using the container image precache feature] + +include::modules/cnf-topology-aware-lifecycle-manager-autocreate-cgu-cr-ztp.adoc[leveloffset=+1] + +:!policy-gen-cr: +:!policy-prefix: +:!rangen-yaml-path: diff --git a/edge_computing/ztp-advanced-policy-config.adoc b/edge_computing/ztp-advanced-policy-config.adoc deleted file mode 100644 index 8a41c0707c96..000000000000 --- a/edge_computing/ztp-advanced-policy-config.adoc +++ /dev/null @@ -1,124 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="ztp-advanced-policy-config"] -= Advanced managed cluster configuration with PolicyGenTemplate resources -include::_attributes/common-attributes.adoc[] -:context: ztp-advanced-policy-config - -toc::[] - -You can use `PolicyGenTemplate` CRs to deploy custom functionality in your managed clusters. - -include::modules/ztp-deploying-additional-changes-to-clusters.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* xref:../edge_computing/ztp-advanced-install-ztp.adoc#ztp-customizing-the-install-extra-manifests_ztp-advanced-install-ztp[Customizing extra installation manifests in the {ztp} pipeline] - -include::modules/ztp-using-pgt-to-update-source-crs.adoc[leveloffset=+1] - -include::modules/ztp-adding-new-content-to-gitops-ztp.adoc[leveloffset=+1] - -include::modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc[leveloffset=+1] - -include::modules/ztp-creating-a-validator-inform-policy.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* xref:../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}] - -include::modules/ztp-using-pgt-to-configure-power-states.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* xref:../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#configuring-workload-hints_cnf-low-latency-perf-profile[Configuring node power consumption and realtime processing with workload hints] - -include::modules/ztp-using-pgt-to-configure-performance-mode.adoc[leveloffset=+2] - -include::modules/ztp-using-pgt-to-configure-high-performance-mode.adoc[leveloffset=+2] - -include::modules/ztp-using-pgt-to-configure-power-saving-mode.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../scalability_and_performance/low_latency_tuning/cnf-tuning-low-latency-nodes-with-perf-profile.adoc#cnf-configuring-power-saving-for-nodes_cnf-low-latency-perf-profile[Configuring power saving for nodes that run colocated high and low priority workloads] - -* xref:../edge_computing/ztp-reference-cluster-configuration-for-vdu.adoc#ztp-du-configuring-host-firmware-requirements_sno-configure-for-vdu[Configuring host firmware for low latency and high performance] - -* xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} site configuration repository] - -include::modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc[leveloffset=+2] - -include::modules/ztp-provisioning-lvm-storage.adoc[leveloffset=+1] - -[id="ztp-advanced-policy-config-ptp_{context}"] -== Configuring PTP events with PolicyGenTemplate CRs - -You can use the {ztp} pipeline to configure PTP events that use HTTP or AMQP transport. - -include::snippets/ptp-amq-interconnect-eol.adoc[] - -include::modules/ztp-configuring-ptp-fast-events.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../edge_computing/ztp-advanced-policy-config.adoc#ztp-using-pgt-to-update-source-crs_ztp-advanced-policy-config[Using PolicyGenTemplate CRs to override source CRs content] - -include::modules/ztp-configuring-ptp-fast-events-amqp.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../networking/ptp/using-ptp-events.adoc#cnf-installing-amq-interconnect-messaging-bus_using-ptp-events[Installing the AMQ messaging bus] -* For more information about container image registries, see xref:../registry/index.adoc#registry-overview[{product-registry} overview]. - -[id="ztp-advanced-policy-config-bare-metal_{context}"] -== Configuring bare-metal events with PolicyGenTemplate CRs - -You can use the {ztp} pipeline to configure bare-metal events that use HTTP or AMQP transport. - -include::snippets/ptp-amq-interconnect-eol.adoc[] - -include::modules/ztp-configuring-hwevents-using-pgt.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../scalability_and_performance/using-rfhe.adoc#nw-rfhe-installing-operator-cli_using-rfhe[Installing the {redfish-operator} using the CLI] - -* xref:../scalability_and_performance/using-rfhe.adoc#nw-rfhe-creating-hardware-event_using-rfhe[Creating the bare-metal event and Secret CRs] - -include::modules/ztp-creating-hwevents-amqp.adoc[leveloffset=+2] - -include::modules/ztp-add-local-reg-for-sno-duprofile.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* xref:../registry/index.adoc#registry-overview[{product-title} registry overview]. - -include::modules/ztp-configuring-disk-partitioning.adoc[leveloffset=+2] - -include::modules/ztp-configuring-pgt-image-registry.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* xref:../registry/accessing-the-registry.adoc#accessing-the-registry[Accessing the registry] - -include::modules/ztp-using-hub-cluster-templates.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html-single/governance/index#hub-templates[{rh-rhacm} support for hub cluster templates in configuration policies] - -include::modules/ztp-example-hub-template-functions.adoc[leveloffset=+2] - -include::modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc[leveloffset=+2] - -include::modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc[leveloffset=+2] diff --git a/edge_computing/ztp-deploying-far-edge-clusters-at-scale.adoc b/edge_computing/ztp-deploying-far-edge-clusters-at-scale.adoc index 1d6dfe112e60..706fc291add5 100644 --- a/edge_computing/ztp-deploying-far-edge-clusters-at-scale.adoc +++ b/edge_computing/ztp-deploying-far-edge-clusters-at-scale.adoc @@ -3,6 +3,7 @@ = Challenges of the network far edge include::_attributes/common-attributes.adoc[] :context: ztp-deploying-far-edge-clusters-at-scale +:policy-gen-cr: PolicyGenerator toc::[] @@ -16,7 +17,15 @@ include::modules/ztp-creating-ztp-crs-for-multiple-managed-clusters.adoc[levelof include::modules/ztp-configuring-cluster-policies.adoc[leveloffset=+1] +include::snippets/pgt-deprecation-notice.adoc[] + [role="_additional-resources"] .Additional resources -* For more information about extracting the reference `SiteConfig` and `PolicyGenTemplate` CRs from the `ztp-site-generate` container image, see xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the ZTP Git repository]. +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +* xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-ztp-git-repository_ztp-preparing-the-hub-cluster[Preparing the {ztp} Git repository] + +:!policy-gen-cr: diff --git a/edge_computing/ztp-deploying-far-edge-sites.adoc b/edge_computing/ztp-deploying-far-edge-sites.adoc index ae20f984a9bb..7d02a0385ed2 100644 --- a/edge_computing/ztp-deploying-far-edge-sites.adoc +++ b/edge_computing/ztp-deploying-far-edge-sites.adoc @@ -8,6 +8,15 @@ toc::[] You can provision {product-title} clusters at scale with {rh-rhacm-first} using the assisted service and the GitOps plugin policy generator with core-reduction technology enabled. The {ztp-first} pipeline performs the cluster installations. {ztp} can be used in a disconnected environment. +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + include::modules/ztp-talo-integration.adoc[leveloffset=+1] include::modules/ztp-ztp-building-blocks.adoc[leveloffset=+1] @@ -41,7 +50,7 @@ include::modules/ztp-sno-siteconfig-config-reference.adoc[leveloffset=+2] * xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-configuring-hub-cluster-with-argocd_ztp-preparing-the-hub-cluster[Configuring the hub cluster with ArgoCD] -* xref:../edge_computing/ztp-advanced-policy-config.adoc#ztp-creating-a-validator-inform-policy_ztp-advanced-policy-config[Signalling ZTP cluster deployment completion with validator inform policies] +* xref:../edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc#ztp-creating-a-validator-inform-policy_ztp-advanced-policy-config[Signalling {ztp} cluster deployment completion with validator inform policies] * xref:../edge_computing/ztp-manual-install.adoc#ztp-creating-the-site-secrets_ztp-manual-install[Creating the managed bare-metal host secrets] diff --git a/edge_computing/ztp-manual-install.adoc b/edge_computing/ztp-manual-install.adoc index e78d675a99b2..e686f8dd3c5f 100644 --- a/edge_computing/ztp-manual-install.adoc +++ b/edge_computing/ztp-manual-install.adoc @@ -1,8 +1,10 @@ :_mod-docs-content-type: ASSEMBLY [id="ztp-manual-install"] -= Manually installing a {sno} cluster with ZTP += Manually installing a {sno} cluster with {ztp} include::_attributes/common-attributes.adoc[] :context: ztp-manual-install +:policy-gen-cr: PolicyGenerator +:policy-prefix: acm- toc::[] @@ -42,12 +44,15 @@ include::modules/ztp-manually-install-a-single-managed-cluster.adoc[leveloffset= * xref:../edge_computing/ztp-reference-cluster-configuration-for-vdu.adoc#ztp-managed-cluster-network-prereqs_sno-configure-for-vdu[Connectivity prerequisites for managed cluster networks] -* xref:../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#lvms-preface-sno-ran_logical-volume-manager-storage[Deploying LVM Storage on single-node OpenShift clusters] +* xref:../storage/persistent_storage/persistent_storage_local/persistent-storage-using-lvms.adoc#lvms-preface-sno-ran_logical-volume-manager-storage[Deploying LVM Storage on {sno} clusters] -* xref:../edge_computing/ztp-advanced-policy-config.adoc#ztp-provisioning-lvm-storage_ztp-advanced-policy-config[Configuring LVM Storage using PolicyGenTemplate CRs] +* xref:../edge_computing/policygenerator_for_ztp/ztp-advanced-policygenerator-config.adoc#ztp-provisioning-lvm-storage_ztp-advanced-policy-config[Configuring {lvms} using {policy-gen-cr} CRs] include::modules/ztp-checking-the-managed-cluster-status.adoc[leveloffset=+1] include::modules/ztp-troubleshooting-the-managed-cluster.adoc[leveloffset=+1] include::modules/ztp-installation-crs.adoc[leveloffset=+1] + +:!policy-gen-cr: +:!policy-prefix: diff --git a/edge_computing/ztp-preparing-the-hub-cluster.adoc b/edge_computing/ztp-preparing-the-hub-cluster.adoc index 1674ae386c3a..ae27b2f852e1 100644 --- a/edge_computing/ztp-preparing-the-hub-cluster.adoc +++ b/edge_computing/ztp-preparing-the-hub-cluster.adoc @@ -1,6 +1,6 @@ :_mod-docs-content-type: ASSEMBLY [id="ztp-preparing-the-hub-cluster"] -= Preparing the hub cluster for ZTP += Preparing the hub cluster for {ztp} include::_attributes/common-attributes.adoc[] :context: ztp-preparing-the-hub-cluster @@ -52,4 +52,13 @@ include::modules/ztp-preparing-the-hub-cluster-for-ztp.adoc[leveloffset=+1] include::modules/ztp-preparing-the-ztp-git-repository.adoc[leveloffset=+1] -include::modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc[leveloffset=+2] +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +include::modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc[leveloffset=+1] diff --git a/edge_computing/ztp-sno-additional-worker-node.adoc b/edge_computing/ztp-sno-additional-worker-node.adoc index 27e0839e0598..e795be90ea74 100644 --- a/edge_computing/ztp-sno-additional-worker-node.adoc +++ b/edge_computing/ztp-sno-additional-worker-node.adoc @@ -1,4 +1,3 @@ -:_mod-docs-content-type: ASSEMBLY [id="ztp-sno-additional-worker-node"] = Expanding {sno} clusters with {ztp} include::_attributes/common-attributes.adoc[] @@ -36,6 +35,12 @@ include::modules/ztp-worker-node-daemon-selector-compatibility.adoc[leveloffset= include::modules/ztp-worker-node-node-selector-compatibility.adoc[leveloffset=+1] +:policy-gen-cr: PolicyGenerator +include::modules/ztp-worker-node-preparing-policies.adoc[leveloffset=+1] + +:policy-gen-cr: PolicyGenTemplate include::modules/ztp-worker-node-preparing-policies.adoc[leveloffset=+1] include::modules/ztp-adding-worker-nodes.adoc[leveloffset=+1] + +:!policy-gen-cr: diff --git a/edge_computing/ztp-talm-updating-managed-policies.adoc b/edge_computing/ztp-talm-updating-managed-policies.adoc deleted file mode 100644 index 1058b61673c8..000000000000 --- a/edge_computing/ztp-talm-updating-managed-policies.adoc +++ /dev/null @@ -1,64 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -[id="ztp-topology-aware-lifecycle-manager"] -= Updating managed clusters in a disconnected environment with the {cgu-operator-full} -include::_attributes/common-attributes.adoc[] -:context: ztp-talm - -toc::[] - -You can use the {cgu-operator-first} to manage the software lifecycle of {product-title} managed clusters. {cgu-operator} uses {rh-rhacm-first} policies to perform changes on the target clusters. - -:FeatureName: The Topology Aware Lifecycle Manager - -[role="_additional-resources"] -.Additional resources - -* For more information about the {cgu-operator-full}, see xref:../edge_computing/cnf-talm-for-cluster-upgrades.adoc#cnf-about-topology-aware-lifecycle-manager-config_cnf-topology-aware-lifecycle-manager[About the {cgu-operator-full}]. - -include::modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc[leveloffset=+1] - -[role="_additional-resources"] -.Additional resources - -* For more information about how to update {ztp-first}, see xref:../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}]. - -* For more information about how to mirror an {product-title} image repository, see xref:../installing/disconnected_install/installing-mirroring-installation-images.adoc#installation-mirror-repository_installing-mirroring-installation-images[Mirroring the {product-title} image repository]. - -* For more information about how to mirror Operator catalogs for disconnected clusters, see xref:../installing/disconnected_install/installing-mirroring-installation-images.adoc#olm-mirror-catalog_installing-mirroring-installation-images[Mirroring Operator catalogs for use with disconnected clusters]. - -* For more information about how to prepare the disconnected environment and mirroring the desired image repository, see xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-preparing-the-hub-cluster[Preparing the disconnected environment]. - -* For more information about update channels and releases, see xref:../updating/understanding_updates/understanding-update-channels-release.adoc#understanding-update-channels-releases[Understanding update channels and releases]. - -include::modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* For more information about mirroring the images in a disconnected environment, see xref:../edge_computing/ztp-preparing-the-hub-cluster.adoc#ztp-acm-adding-images-to-mirror-registry_ztp-preparing-the-hub-cluster[Preparing the disconnected environment]. - -include::modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* For more information about updating {ztp}, see xref:../edge_computing/ztp-updating-gitops.adoc#ztp-updating-gitops[Upgrading {ztp}]. - -* xref:../edge_computing/ztp-talm-updating-managed-policies.adoc#cnf-topology-aware-lifecycle-manager-operator-troubleshooting_ztp-talm[Troubleshooting missed Operator updates due to out-of-date policy compliance states]. - -include::modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc[leveloffset=+3] - -include::modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc[leveloffset=+2] - -include::modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc[leveloffset=+2] - -include::modules/cnf-topology-aware-lifecycle-manager-precache-user-spec-images.adoc[leveloffset=+2] - -include::modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc[leveloffset=+2] - -[role="_additional-resources"] -.Additional resources - -* For more information about the {cgu-operator} precaching workflow, see xref:../edge_computing/cnf-talm-for-cluster-upgrades.adoc#talo-precache-feature-concept_cnf-topology-aware-lifecycle-manager[Using the container image precache feature]. - -include::modules/cnf-topology-aware-lifecycle-manager-autocreate-cgu-cr-ztp.adoc[leveloffset=+1] diff --git a/edge_computing/ztp-updating-gitops.adoc b/edge_computing/ztp-updating-gitops.adoc index 04e62409ec1f..5f1091e355f5 100644 --- a/edge_computing/ztp-updating-gitops.adoc +++ b/edge_computing/ztp-updating-gitops.adoc @@ -13,6 +13,15 @@ You can update the {ztp-first} infrastructure independently from the hub cluster You can update the {gitops-title} Operator when new versions become available. When updating the {ztp} plugin, review the updated files in the reference configuration and ensure that the changes meet your requirements. ==== +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + include::modules/ztp-updating-gitops-ztp.adoc[leveloffset=+1] include::modules/ztp-preparing-for-the-gitops-ztp-upgrade.adoc[leveloffset=+1] @@ -32,4 +41,4 @@ include::modules/ztp-roll-out-the-configuration-changes.adoc[leveloffset=+1] * For information about the {cgu-operator-first}, see xref:../edge_computing/cnf-talm-for-cluster-upgrades.adoc#cnf-about-topology-aware-lifecycle-manager-config_cnf-topology-aware-lifecycle-manager[About the {cgu-operator-full} configuration]. -* For information about creating `ClusterGroupUpgrade` CRs, see xref:../edge_computing/ztp-talm-updating-managed-policies.adoc#talo-precache-autocreated-cgu-for-ztp_ztp-talm[About the auto-created ClusterGroupUpgrade CR for ZTP]. +* For information about creating `ClusterGroupUpgrade` CRs, see xref:../edge_computing/policygentemplate_for_ztp/ztp-talm-updating-managed-policies.adoc#talo-precache-autocreated-cgu-for-ztp_ztp-talm[About the auto-created ClusterGroupUpgrade CR for {ztp}]. diff --git a/edge_computing/ztp-using-hub-cluster-templates.adoc b/edge_computing/ztp-using-hub-cluster-templates.adoc new file mode 100644 index 000000000000..b4057d5d02b3 --- /dev/null +++ b/edge_computing/ztp-using-hub-cluster-templates.adoc @@ -0,0 +1,40 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ztp-using-hub-cluster-templates-pgt"] += Using hub templates in PolicyGenerator or PolicyGenTemplate CRs +include::_attributes/common-attributes.adoc[] +:context: hub-cluster-templates-pgt + +toc::[] + +{cgu-operator-full} supports partial {rh-rhacm-first} hub cluster template functions in configuration policies used with {ztp-first}. + +Hub-side cluster templates allow you to define configuration policies that can be dynamically customized to the target clusters. +This reduces the need to create separate policies for many clusters with similiar configurations but with different values. + +[IMPORTANT] +==== +Policy templates are restricted to the same namespace as the namespace where the policy is defined. +This means you must create the objects referenced in the hub template in the same namespace where the policy is created. +==== + +include::snippets/pgt-deprecation-notice.adoc[] + +[role="_additional-resources"] +.Additional resources + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-configuring-managed-clusters-policygenerator[Configuring managed cluster policies by using PolicyGenerator resources] + +* xref:../edge_computing/policygenerator_for_ztp/ztp-configuring-managed-clusters-policygenerator.adoc#ztp-comparing-pgt-and-rhacm-pg-patching-strategies_ztp-configuring-managed-clusters-policygenerator[Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching] + +include::modules/ztp-using-rhacm-hub-cluster-templates.adoc[leveloffset=+1] + +[role="_additional-resources"] +.Additional resources + +* link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html-single/governance/index#hub-templates[{rh-rhacm} support for hub cluster templates in configuration policies] + +include::modules/ztp-example-hub-template-functions.adoc[leveloffset=+1] + +include::modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc[leveloffset=+1] + +include::modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc[leveloffset=+1] diff --git a/microshift_welcome/index.adoc b/microshift_welcome/index.adoc index 593c9171412d..332f9e839ce6 100644 --- a/microshift_welcome/index.adoc +++ b/microshift_welcome/index.adoc @@ -22,4 +22,4 @@ For related information, use the following links: * link:https://access.redhat.com/documentation/en-us/red_hat_device_edge/4/html/overview/device-edge-overview[Red Hat Device Edge overview] * link:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/composing_installing_and_managing_rhel_for_edge_images/index[RHEL for Edge documentation] -* link:https://docs.openshift.com/container-platform/latest/welcome/index.html[OpenShift Container Platform documentation] \ No newline at end of file +* link:https://docs.openshift.com/container-platform/latest/welcome/index.html[OpenShift Container Platform documentation] diff --git a/modules/builds-using-build-volumes.adoc b/modules/builds-using-build-volumes.adoc index 9a6dbc32b5ae..28d685cea154 100644 --- a/modules/builds-using-build-volumes.adoc +++ b/modules/builds-using-build-volumes.adoc @@ -1,3 +1,7 @@ +// Module included in the following assemblies: +// +// * cicd/builds/build-strategies.adoc + ifeval::["{context}" == "build-strategies-docker"] :dockerstrategy: endif::[] @@ -68,6 +72,9 @@ ifndef::openshift-dedicated,openshift-rosa[] <5> Required. The driver that provides the ephemeral CSI volume. <6> Required. This value must be set to `true`. Provides a read-only volume. <7> Optional. The volume attributes of the ephemeral CSI volume. Consult the CSI driver's documentation for supported attribute keys and values. + +:FeatureName: Shared Resource CSI Driver +include::snippets/technology-preview.adoc[] endif::openshift-dedicated,openshift-rosa[] -- diff --git a/modules/cnf-about-topology-aware-lifecycle-manager-blocking-crs.adoc b/modules/cnf-about-topology-aware-lifecycle-manager-blocking-crs.adoc index 8f103c858f19..f7a7341ea1e6 100644 --- a/modules/cnf-about-topology-aware-lifecycle-manager-blocking-crs.adoc +++ b/modules/cnf-about-topology-aware-lifecycle-manager-blocking-crs.adoc @@ -23,6 +23,7 @@ One `ClusterGroupUpgrade` CR can have multiple blocking CRs. In this case, all t . Save the content of the `ClusterGroupUpgrade` CRs in the `cgu-a.yaml`, `cgu-b.yaml`, and `cgu-c.yaml` files. + +-- [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -74,7 +75,7 @@ status: - - spoke2 ---- <1> Defines the blocking CRs. The `cgu-a` update cannot start until `cgu-c` is complete. -+ + [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -129,7 +130,7 @@ status: status: {} ---- <1> The `cgu-b` update cannot start until `cgu-a` is complete. -+ + [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -174,6 +175,7 @@ status: status: {} ---- <1> The `cgu-c` update does not have any blocking CRs. {cgu-operator} starts the `cgu-c` update when the `enable` field is set to `true`. +-- . Create the `ClusterGroupUpgrade` CRs by running the following command for each relevant CR: + @@ -192,8 +194,8 @@ $ oc --namespace=default patch clustergroupupgrade.ran.openshift.io/ \ + The following examples show `ClusterGroupUpgrade` CRs where the `enable` field is set to `true`: + +-- .Example for `cgu-a` with blocking CRs -+ [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -247,9 +249,8 @@ status: status: {} ---- <1> Shows the list of blocking CRs. -+ + .Example for `cgu-b` with blocking CRs -+ [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -305,9 +306,8 @@ status: status: {} ---- <1> Shows the list of blocking CRs. -+ + .Example for `cgu-c` with blocking CRs -+ [source,yaml] ---- apiVersion: ran.openshift.io/v1alpha1 @@ -355,3 +355,4 @@ status: spoke6: 0 ---- <1> The `cgu-c` update does not have any blocking CRs. +-- diff --git a/modules/cnf-about-topology-aware-lifecycle-manager-policies.adoc b/modules/cnf-about-topology-aware-lifecycle-manager-policies.adoc index 2ee82dce5507..406bd6133248 100644 --- a/modules/cnf-about-topology-aware-lifecycle-manager-policies.adoc +++ b/modules/cnf-about-topology-aware-lifecycle-manager-policies.adoc @@ -12,10 +12,8 @@ The {cgu-operator-first} uses {rh-rhacm} policies for cluster updates. Supported use cases include the following: * Manual user creation of policy CRs -* Automatically generated policies from the `PolicyGenTemplate` custom resource definition (CRD) +* Automatically generated policies from the `PolicyGenerator` or `PolicyGentemplate` custom resource definition (CRD) For policies that update an Operator subscription with manual approval, {cgu-operator} provides additional functionality that approves the installation of the updated Operator. For more information about managed policies, see link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html-single/governance/index#policy-overview[Policy Overview] in the {rh-rhacm} documentation. - -For more information about the `PolicyGenTemplate` CRD, see the "About the PolicyGenTemplate CRD" section in "Configuring managed clusters with policies and PolicyGenTemplate resources". diff --git a/modules/cnf-installing-amq-interconnect-messaging-bus.adoc b/modules/cnf-installing-amq-interconnect-messaging-bus.adoc index 5279cb2c5ef5..21e7ce0a61c4 100644 --- a/modules/cnf-installing-amq-interconnect-messaging-bus.adoc +++ b/modules/cnf-installing-amq-interconnect-messaging-bus.adoc @@ -8,12 +8,10 @@ To pass PTP fast event notifications between publisher and subscriber on a node, you can install and configure an AMQ messaging bus to run locally on the node. To use AMQ messaging, you must install the AMQ Interconnect Operator. - include::snippets/ptp-amq-interconnect-eol.adoc[] .Prerequisites -* Install the {product-title} CLI (`oc`). * Log in as a user with `cluster-admin` privileges. diff --git a/modules/cnf-topology-aware-lifecycle-manager-backup-recovery.adoc b/modules/cnf-topology-aware-lifecycle-manager-backup-recovery.adoc index ceb398af8306..623a75a0e0b1 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-backup-recovery.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-backup-recovery.adoc @@ -42,8 +42,10 @@ $ oc delete cgu/du-upgrade-4918 -n ztp-group-du-sno ---- $ ostree admin status ---- -.Example outputs + +-- +.Example outputs + [source,terminal] ---- [root@lab-test-spoke2-node-0 core]# ostree admin status @@ -53,7 +55,7 @@ $ ostree admin status origin refspec: c038a8f08458bbed83a77ece033ad3c55597e3f64edad66ea12fda18cbdceaf9 ---- <1> The current deployment is pinned. A platform OS deployment rollback is not necessary. -+ + [source,terminal] ---- [root@lab-test-spoke2-node-0 core]# ostree admin status @@ -67,6 +69,7 @@ rhcos ad8f159f9dc4ea7e773fd9604c9a16be0fe9b266ae800ac8470f63abc39b52ca.0 (rollba ---- <1> This platform OS deployment is marked for rollback. <2> The previous deployment is pinned and can be rolled back. +-- . To trigger a rollback of the platform OS deployment, run the following command: + diff --git a/modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc b/modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc index 77f1217030a6..abb8867997ad 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-creating-custom-resources.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="talm-prechache-user-specified-images-preparing-crs_{context}"] -== Creating the custom resources for pre-caching += Creating the custom resources for pre-caching You must create the `PreCachingConfig` CR before or concurrently with the `ClusterGroupUpgrade` CR. @@ -26,7 +26,7 @@ spec: - quay.io/exampleconfig/applicationN@sha256:4fe1334adfafadsf987123adfffdaf1243340adfafdedga0991234afdadfsa09 ---- <1> The `namespace` must be accessible to the hub cluster. -<2> It is recommended to set the minimum disk space required field to ensure that there is sufficient storage space for the pre-cached images. +<2> It is recommended to set the minimum disk space required field to ensure that there is sufficient storage space for the pre-cached images. . Create a `ClusterGroupUpgrade` CR with the `preCaching` field set to `true` and specify the `PreCachingConfig` CR created in the previous step: + @@ -225,4 +225,4 @@ $ chroot /host/ [source,terminal] ---- $ sudo podman images | grep ----- \ No newline at end of file +---- diff --git a/modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc b/modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc index 8c94a5069707..a85a08158798 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-operator-and-platform-update.adoc @@ -18,7 +18,7 @@ You can perform a platform and an Operator update at the same time. .Procedure -. Create the `PolicyGenTemplate` CR for the updates by following the steps described in the "Performing a platform update" and "Performing an Operator update" sections. +. Create the `{policy-gen-cr}` CR for the updates by following the steps described in the "Performing a platform update" and "Performing an Operator update" sections. . Apply the prep work for the platform and the Operator update. diff --git a/modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc b/modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc index a90d9986083a..036c41a136f9 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc @@ -3,53 +3,25 @@ // * scalability_and_performance/ztp_far_edge/ztp-talm-updating-managed-policies.adoc :_mod-docs-content-type: PROCEDURE -[id="cnf-topology-aware-lifecycle-manager-operator-troubleshooting_{context}"] -= Troubleshooting missed Operator updates due to out-of-date policy compliance states +[id="cnf-topology-aware-lifecycle-manager-operator-troubleshooting-{policy-gen-cr}_{context}"] += Troubleshooting missed Operator updates with {policy-gen-cr} CRs In some scenarios, {cgu-operator-first} might miss Operator updates due to an out-of-date policy compliance state. After a catalog source update, it takes time for the Operator Lifecycle Manager (OLM) to update the subscription status. The status of the subscription policy might continue to show as compliant while {cgu-operator} decides whether remediation is needed. As a result, the Operator specified in the subscription policy does not get upgraded. -To avoid this scenario, add another catalog source configuration to the `PolicyGenTemplate` and specify this configuration in the subscription for any Operators that require an update. +To avoid this scenario, add another catalog source configuration to the `{policy-gen-cr}` and specify this configuration in the subscription for any Operators that require an update. .Procedure -. Add a catalog source configuration in the `PolicyGenTemplate` resource: +. Add a catalog source configuration in the `{policy-gen-cr}` resource: + -[source,yaml] ----- -- fileName: DefaultCatsrc.yaml - remediationAction: inform - policyName: "operator-catsrc-policy" - metadata: - name: redhat-operators - spec: - displayName: Red Hat Operators Catalog - image: registry.example.com:5000/olm/redhat-operators:v{product-version} - updateStrategy: - registryPoll: - interval: 1h - status: - connectionState: - lastObservedState: READY -- fileName: DefaultCatsrc.yaml - remediationAction: inform - policyName: "operator-catsrc-policy" - metadata: - name: redhat-operators-v2 <1> - spec: - displayName: Red Hat Operators Catalog v2 <2> - image: registry.example.com:5000/olredhat-operators: <3> - updateStrategy: - registryPoll: - interval: 1h - status: - connectionState: - lastObservedState: READY ----- -<1> Update the name for the new configuration. -<2> Update the display name for the new configuration. -<3> Update the index image URL. This `fileName.spec.image` field overrides any configuration in the `DefaultCatsrc.yaml` file. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc[] +endif::[] . Update the `Subscription` resource to point to the new configuration for Operators that require an update: + @@ -65,4 +37,4 @@ spec: source: redhat-operators-v2 <1> # ... ---- -<1> Enter the name of the additional catalog source configuration that you defined in the `PolicyGenTemplate` resource. +<1> Enter the name of the additional catalog source configuration that you defined in the `{policy-gen-cr}` resource. diff --git a/modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc b/modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc index 9d12b206c77f..85b1b0929320 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-operator-update.adoc @@ -3,8 +3,8 @@ // * scalability_and_performance/ztp_far_edge/ztp-talm-updating-managed-policies.adoc :_mod-docs-content-type: PROCEDURE -[id="talo-operator-update_{context}"] -= Performing an Operator update +[id="talo-operator-update-{policy-gen-cr}_{context}"] += Performing an Operator update with {policy-gen-cr} CRs You can perform an Operator update with the {cgu-operator}. @@ -19,40 +19,15 @@ You can perform an Operator update with the {cgu-operator}. .Procedure -. Update the `PolicyGenTemplate` CR for the Operator update. -.. Update the `du-upgrade` `PolicyGenTemplate` CR with the following additional contents in the `du-upgrade.yaml` file: +. Update the `{policy-gen-cr}` CR for the Operator update. +.. Update the `du-upgrade` `{policy-gen-cr}` CR with the following additional contents in the `du-upgrade.yaml` file: + -[source,yaml,subs="attributes+"] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "du-upgrade" - namespace: "ztp-group-du-sno" -spec: - bindingRules: - group-du-sno: "" - mcp: "master" - remediationAction: inform - sourceFiles: - - fileName: DefaultCatsrc.yaml - remediationAction: inform - policyName: "operator-catsrc-policy" - metadata: - name: redhat-operators - spec: - displayName: Red Hat Operators Catalog - image: registry.example.com:5000/olm/redhat-operators:v{product-version} <1> - updateStrategy: <2> - registryPoll: - interval: 1h - status: - connectionState: - lastObservedState: READY <3> ----- -<1> The index image URL contains the desired Operator images. If the index images are always pushed to the same image name and tag, this change is not needed. -<2> Set how frequently the Operator Lifecycle Manager (OLM) polls the index image for new Operator versions with the `registryPoll.interval` field. This change is not needed if a new index image tag is always pushed for y-stream and z-stream Operator updates. The `registryPoll.interval` field can be set to a shorter interval to expedite the update, however shorter intervals increase computational load. To counteract this, you can restore `registryPoll.interval` to the default value once the update is complete. -<3> Last observed state of the catalog connection. The `READY` value ensures that the `CatalogSource` policy is ready, indicating that the index pod is pulled and is running. This way, {cgu-operator} upgrades the Operators based on up-to-date policy compliance states. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-update.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-cnf-topology-aware-lifecycle-manager-operator-update.adoc[] +endif::[] .. This update generates one policy, `du-upgrade-operator-catsrc-policy`, to update the `redhat-operators` catalog source with the new index images that contain the desired Operators images. + @@ -66,46 +41,21 @@ If you want to use the image pre-caching for Operators and there are Operators f + For example, the desired SRIOV-FEC Operator is available in the `certified-operators` catalog source. To update the catalog source and the Operator subscription, add the following contents to generate two policies, `du-upgrade-fec-catsrc-policy` and `du-upgrade-subscriptions-fec-policy`: + -[source,yaml] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "du-upgrade" - namespace: "ztp-group-du-sno" -spec: - bindingRules: - group-du-sno: "" - mcp: "master" - remediationAction: inform - sourceFiles: - … - - fileName: DefaultCatsrc.yaml - remediationAction: inform - policyName: "fec-catsrc-policy" - metadata: - name: certified-operators - spec: - displayName: Intel SRIOV-FEC Operator - image: registry.example.com:5000/olm/far-edge-sriov-fec:v4.10 - updateStrategy: - registryPoll: - interval: 10m - - fileName: AcceleratorsSubscription.yaml - policyName: "subscriptions-fec-policy" - spec: - channel: "stable" - source: certified-operators ----- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc[] +endif::[] -.. Remove the specified subscriptions channels in the common `PolicyGenTemplate` CR, if they exist. The default subscriptions channels from the {ztp} image are used for the update. +.. Remove the specified subscriptions channels in the common `{policy-gen-cr}` CR, if they exist. The default subscriptions channels from the {ztp} image are used for the update. + [NOTE] ==== -The default channel for the Operators applied through {ztp} {product-version} is `stable`, except for the `performance-addon-operator`. As of {product-title} 4.11, the `performance-addon-operator` functionality was moved to the `node-tuning-operator`. For the 4.10 release, the default channel for PAO is `v4.10`. You can also specify the default channels in the common `PolicyGenTemplate` CR. +The default channel for the Operators applied through {ztp} {product-version} is `stable`, except for the `performance-addon-operator`. As of {product-title} 4.11, the `performance-addon-operator` functionality was moved to the `node-tuning-operator`. For the 4.10 release, the default channel for PAO is `v4.10`. You can also specify the default channels in the common `{policy-gen-cr}` CR. ==== -.. Push the `PolicyGenTemplate` CRs updates to the {ztp} Git repository. +.. Push the `{policy-gen-cr}` CRs updates to the {ztp} Git repository. + ArgoCD pulls the changes from the Git repository and generates the policies on the hub cluster. @@ -152,7 +102,7 @@ $ oc get policies -A | grep -E "catsrc-policy" ---- . Create the `ClusterGroupUpgrade` CR for the Operator update with the `spec.enable` field set to `false`. -.. Save the content of the Operator update `ClusterGroupUpgrade` CR with the `du-upgrade-operator-catsrc-policy` policy and the subscription policies created from the common `PolicyGenTemplate` and the target clusters to the `cgu-operator-upgrade.yml` file, as shown in the following example: +.. Save the content of the Operator update `ClusterGroupUpgrade` CR with the `du-upgrade-operator-catsrc-policy` policy and the subscription policies created from the common `{policy-gen-cr}` and the target clusters to the `cgu-operator-upgrade.yml` file, as shown in the following example: + [source,yaml] ---- diff --git a/modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc b/modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc index 99542d1c4276..c02ad67f6ac7 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-pao-update.adoc @@ -3,8 +3,8 @@ // * scalability_and_performance/ztp_far_edge/ztp-talm-updating-managed-policies.adoc :_mod-docs-content-type: PROCEDURE -[id="talm-pao-update_{context}"] -= Removing Performance Addon Operator subscriptions from deployed clusters +[id="talm-pao-update-{policy-gen-cr}_{context}"] += Removing Performance Addon Operator subscriptions from deployed clusters with {policy-gen-cr} CRs In earlier versions of {product-title}, the Performance Addon Operator provided automatic, low latency performance tuning for applications. In {product-title} 4.11 or later, these functions are part of the Node Tuning Operator. @@ -15,7 +15,7 @@ Do not install the Performance Addon Operator on clusters running {product-title You need to remove any policies that create Performance Addon Operator subscriptions to prevent a re-installation of the Operator. ==== -The reference DU profile includes the Performance Addon Operator in the `PolicyGenTemplate` CR `common-ranGen.yaml`. To remove the subscription from deployed managed clusters, you must update `common-ranGen.yaml`. +The reference DU profile includes the Performance Addon Operator in the `{policy-gen-cr}` CR `{policy-prefix}common-ranGen.yaml`. To remove the subscription from deployed managed clusters, you must update `{policy-prefix}common-ranGen.yaml`. [NOTE] ==== @@ -32,19 +32,16 @@ If you install Performance Addon Operator 4.10.3-5 or later on {product-title} 4 .Procedure -. Change the `complianceType` to `mustnothave` for the Performance Addon Operator namespace, Operator group, and subscription in the `common-ranGen.yaml` file. +. Change the `complianceType` to `mustnothave` for the Performance Addon Operator namespace, Operator group, and subscription in the `{policy-prefix}common-ranGen.yaml` file. + [source,yaml] ---- - - fileName: PaoSubscriptionNS.yaml - policyName: "subscriptions-policy" - complianceType: mustnothave - - fileName: PaoSubscriptionOperGroup.yaml - policyName: "subscriptions-policy" - complianceType: mustnothave - - fileName: PaoSubscription.yaml - policyName: "subscriptions-policy" - complianceType: mustnothave +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-cnf-topology-aware-lifecycle-manager-pao-update.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-cnf-topology-aware-lifecycle-manager-pao-update.yaml[] +endif::[] ---- . Merge the changes with your custom site repository and wait for the ArgoCD application to synchronize the change to the hub cluster. The status of the `common-subscriptions-policy` policy changes to `Non-Compliant`. @@ -58,6 +55,6 @@ If you install Performance Addon Operator 4.10.3-5 or later on {product-title} 4 $ oc get policy -n ztp-common common-subscriptions-policy ---- -. Delete the Performance Addon Operator namespace, Operator group and subscription CRs from `.spec.sourceFiles` in the `common-ranGen.yaml` file. +. Delete the Performance Addon Operator namespace, Operator group and subscription CRs from `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file. . Merge the changes with your custom site repository and wait for the ArgoCD application to synchronize the change to the hub cluster. The policy remains compliant. diff --git a/modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc b/modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc index 5e1363a8cc6d..69d1fb80e0fe 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-platform-update.adoc @@ -3,8 +3,8 @@ // * scalability_and_performance/ztp_far_edge/ztp-talm-updating-managed-policies.adoc :_mod-docs-content-type: PROCEDURE -[id="talo-platform-update_{context}"] -= Performing a platform update +[id="talo-platform-update-{policy-gen-cr}_{context}"] += Performing a platform update with {policy-gen-cr} CRs You can perform a platform update with the {cgu-operator}. @@ -19,66 +19,27 @@ You can perform a platform update with the {cgu-operator}. .Procedure -. Create a `PolicyGenTemplate` CR for the platform update: -.. Save the following contents of the `PolicyGenTemplate` CR in the `du-upgrade.yaml` file. -+ -.Example of `PolicyGenTemplate` for platform update -+ -[source,yaml,subs="attributes+"] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "du-upgrade" - namespace: "ztp-group-du-sno" -spec: - bindingRules: - group-du-sno: "" - mcp: "master" - remediationAction: inform - sourceFiles: - - fileName: ImageSignature.yaml <1> - policyName: "platform-upgrade-prep" - binaryData: - ${DIGEST_ALGO}-${DIGEST_ENCODED}: ${SIGNATURE_BASE64} <2> - - fileName: DisconnectedICSP.yaml - policyName: "platform-upgrade-prep" - metadata: - name: disconnected-internal-icsp-for-ocp - spec: - repositoryDigestMirrors: <3> - - mirrors: - - quay-intern.example.com/ocp4/openshift-release-dev - source: quay.io/openshift-release-dev/ocp-release - - mirrors: - - quay-intern.example.com/ocp4/openshift-release-dev - source: quay.io/openshift-release-dev/ocp-v4.0-art-dev - - fileName: ClusterVersion.yaml <4> - policyName: "platform-upgrade" - metadata: - name: version - spec: - channel: "stable-{product-version}" - upstream: http://upgrade.example.com/images/upgrade-graph_stable-{product-version} - desiredUpdate: - version: {product-version}.4 - status: - history: - - version: {product-version}.4 - state: "Completed" ----- -<1> The `ConfigMap` CR contains the signature of the desired release image to update to. -<2> Shows the image signature of the desired {product-title} release. Get the signature from the `checksum-${OCP_RELEASE_NUMBER}.yaml` file you saved when following the procedures in the "Setting up the environment" section. -<3> Shows the mirror repository that contains the desired {product-title} image. Get the mirrors from the `imageContentSources.yaml` file that you saved when following the procedures in the "Setting up the environment" section. -<4> Shows the `ClusterVersion` CR to trigger the update. The `channel`, `upstream`, and `desiredVersion` fields are all required for image pre-caching. +. Create a `{policy-gen-cr}` CR for the platform update: + +.. Save the following `{policy-gen-cr}` CR in the `du-upgrade.yaml` file: + -The `PolicyGenTemplate` CR generates two policies: +-- +.Example of `{policy-gen-cr}` for platform update +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-cnf-topology-aware-lifecycle-manager-platform-update.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-cnf-topology-aware-lifecycle-manager-platform-update.adoc[] +endif::[] + +The `{policy-gen-cr}` CR generates two policies: * The `du-upgrade-platform-upgrade-prep` policy does the preparation work for the platform update. It creates the `ConfigMap` CR for the desired release image signature, creates the image content source of the mirrored release image repository, and updates the cluster version with the desired update channel and the update graph reachable by the managed cluster in the disconnected environment. * The `du-upgrade-platform-upgrade` policy is used to perform platform upgrade. +-- -.. Add the `du-upgrade.yaml` file contents to the `kustomization.yaml` file located in the {ztp} Git repository for the `PolicyGenTemplate` CRs and push the changes to the Git repository. +.. Add the `du-upgrade.yaml` file contents to the `kustomization.yaml` file located in the {ztp} Git repository for the `{policy-gen-cr}` CRs and push the changes to the Git repository. + ArgoCD pulls the changes from the Git repository and generates the policies on the hub cluster. diff --git a/modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc b/modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc index 0218ab047d88..aeff0af2703c 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-preparing-for-updates.adoc @@ -3,13 +3,8 @@ // * scalability_and_performance/ztp_far_edge/ztp-talm-updating-managed-policies.adoc :_mod-docs-content-type: PROCEDURE -[id="talo-platform-prepare-end-to-end_{context}"] -= Updating clusters in a disconnected environment - -You can upgrade managed clusters and Operators for managed clusters that you have deployed using {ztp-first} and {cgu-operator-first}. - [id="talo-platform-prepare-for-update-env-setup_{context}"] -== Setting up the environment += Setting up the disconnected environment {cgu-operator} can perform both platform and Operator updates. @@ -31,7 +26,7 @@ imageContentSources: source: quay.io/openshift-release-dev/ocp-v4.0-art-dev ---- -. Save the image signature of the desired platform image that was mirrored. You must add the image signature to the `PolicyGenTemplate` CR for platform updates. To get the image signature, perform the following steps: +. Save the image signature of the desired platform image that was mirrored. You must add the image signature to the `{policy-gen-cr}` CR for platform updates. To get the image signature, perform the following steps: .. Specify the desired {product-title} tag by running the following command: + diff --git a/modules/cnf-topology-aware-lifecycle-manager-troubleshooting.adoc b/modules/cnf-topology-aware-lifecycle-manager-troubleshooting.adoc index 6b92cba9f0af..4a4d8d5848fb 100644 --- a/modules/cnf-topology-aware-lifecycle-manager-troubleshooting.adoc +++ b/modules/cnf-topology-aware-lifecycle-manager-troubleshooting.adoc @@ -425,7 +425,7 @@ Resolution:: Create and apply a new `ClusterGroupUpdate` CR with the same specif Issue:: If there are no policies for the managed cluster when the cluster becomes `Ready`, a `ClusterGroupUpgrade` CR with no policies is auto-created. Upon completion of the `ClusterGroupUpgrade` CR, the managed cluster is labeled as `ztp-done`. -If the `PolicyGenTemplate` CRs were not pushed to the Git repository within the required time after `SiteConfig` resources were pushed, this might result in no policies being available for the target cluster when the cluster became `Ready`. +If the `PolicyGenerator` or `PolicyGenTemplate` CRs were not pushed to the Git repository within the required time after `SiteConfig` resources were pushed, this might result in no policies being available for the target cluster when the cluster became `Ready`. Resolution:: Verify that the policies you want to apply are available on the hub cluster, then create a `ClusterGroupUpgrade` CR with the required policies. diff --git a/modules/ztp-add-local-reg-for-sno-duprofile.adoc b/modules/ztp-add-local-reg-for-sno-duprofile.adoc index eb2655a04568..0e654d61c23c 100644 --- a/modules/ztp-add-local-reg-for-sno-duprofile.adoc +++ b/modules/ztp-add-local-reg-for-sno-duprofile.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: CONCEPT [id="ztp-add-local-reg-for-sno-duprofile_{context}"] @@ -11,7 +12,7 @@ Long download times are unavoidable during initial deployment. Over time, there is a risk that CRI-O will erase the `/var/lib/containers/storage` directory in the case of an unexpected shutdown. To address long image download times, you can create a local image registry on remote managed clusters using {ztp-first}. This is useful in Edge computing scenarios where clusters are deployed at the far edge of the network. -Before you can set up the local image registry with {ztp}, you need to configure disk partitioning in the `SiteConfig` CR that you use to install the remote managed cluster. After installation, you configure the local image registry using a `PolicyGenTemplate` CR. Then, the {ztp} pipeline creates Persistent Volume (PV) and Persistent Volume Claim (PVC) CRs and patches the `imageregistry` configuration. +Before you can set up the local image registry with {ztp}, you need to configure disk partitioning in the `SiteConfig` CR that you use to install the remote managed cluster. After installation, you configure the local image registry using a `{policy-gen-cr}` CR. Then, the {ztp} pipeline creates Persistent Volume (PV) and Persistent Volume Claim (PVC) CRs and patches the `imageregistry` configuration. [NOTE] ==== diff --git a/modules/ztp-adding-new-content-to-gitops-ztp.adoc b/modules/ztp-adding-new-content-to-gitops-ztp.adoc index ae45bb61cf21..5a38dbb6a2d3 100644 --- a/modules/ztp-adding-new-content-to-gitops-ztp.adoc +++ b/modules/ztp-adding-new-content-to-gitops-ztp.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE @@ -11,98 +12,29 @@ Perform the following procedure to add new content to the {ztp} pipeline. .Procedure -. Create a subdirectory named `source-crs` in the directory that contains the `kustomization.yaml` file for the `PolicyGenTemplate` custom resource (CR). +. Create a subdirectory named `source-crs` in the directory that contains the `kustomization.yaml` file for the `{policy-gen-cr}` custom resource (CR). . Add your user-provided CRs to the `source-crs` subdirectory, as shown in the following example: + -[source,text] ----- -example -└── policygentemplates - ├── dev.yaml - ├── kustomization.yaml - ├── mec-edge-sno1.yaml - ├── sno.yaml - └── source-crs <1> - ├── PaoCatalogSource.yaml - ├── PaoSubscription.yaml - ├── custom-crs - | ├── apiserver-config.yaml - | └── disable-nic-lldp.yaml - └── elasticsearch - ├── ElasticsearchNS.yaml - └── ElasticsearchOperatorGroup.yaml ----- -<1> The `source-crs` subdirectory must be in the same directory as the `kustomization.yaml` file. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc[] +endif::[] -. Update the required `PolicyGenTemplate` CRs to include references to the content you added in the `source-crs/custom-crs` and `source-crs/elasticsearch` directories. For example: +. Update the required `{policy-gen-cr}` CRs to include references to the content you added in the `source-crs/custom-crs` and `source-crs/elasticsearch` directories. For example: + -[source,yaml] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "group-dev" - namespace: "ztp-clusters" -spec: - bindingRules: - dev: "true" - mcp: "master" - sourceFiles: - # These policies/CRs come from the internal container Image - #Cluster Logging - - fileName: ClusterLogNS.yaml - remediationAction: inform - policyName: "group-dev-cluster-log-ns" - - fileName: ClusterLogOperGroup.yaml - remediationAction: inform - policyName: "group-dev-cluster-log-operator-group" - - fileName: ClusterLogSubscription.yaml - remediationAction: inform - policyName: "group-dev-cluster-log-sub" - #Local Storage Operator - - fileName: StorageNS.yaml - remediationAction: inform - policyName: "group-dev-lso-ns" - - fileName: StorageOperGroup.yaml - remediationAction: inform - policyName: "group-dev-lso-operator-group" - - fileName: StorageSubscription.yaml - remediationAction: inform - policyName: "group-dev-lso-sub" - #These are custom local polices that come from the source-crs directory in the git repo - # Performance Addon Operator - - fileName: PaoSubscriptionNS.yaml - remediationAction: inform - policyName: "group-dev-pao-ns" - - fileName: PaoSubscriptionCatalogSource.yaml - remediationAction: inform - policyName: "group-dev-pao-cat-source" - spec: - image: - - fileName: PaoSubscription.yaml - remediationAction: inform - policyName: "group-dev-pao-sub" - #Elasticsearch Operator - - fileName: elasticsearch/ElasticsearchNS.yaml <1> - remediationAction: inform - policyName: "group-dev-elasticsearch-ns" - - fileName: elasticsearch/ElasticsearchOperatorGroup.yaml - remediationAction: inform - policyName: "group-dev-elasticsearch-operator-group" - #Custom Resources - - fileName: custom-crs/apiserver-config.yaml <1> - remediationAction: inform - policyName: "group-dev-apiserver-config" - - fileName: custom-crs/disable-nic-lldp.yaml - remediationAction: inform - policyName: "group-dev-disable-nic-lldp" ----- -<1> Set `fileName` to include the relative path to the file from the `/source-crs` parent directory. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-adding-new-content-to-gitops-ztp.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-adding-new-content-to-gitops-ztp.adoc[] +endif::[] -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository that is monitored by the GitOps ZTP Argo CD policies application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository that is monitored by the GitOps ZTP Argo CD policies application. -. Update the `ClusterGroupUpgrade` CR to include the changed `PolicyGenTemplate` and save it as `cgu-test.yaml`. The following example shows a generated `cgu-test.yaml` file. +. Update the `ClusterGroupUpgrade` CR to include the changed `{policy-gen-cr}` and save it as `cgu-test.yaml`. The following example shows a generated `cgu-test.yaml` file. + [source,yaml] ---- diff --git a/modules/ztp-comparing-pgt-and-rhacm-pg-patching-strategies.adoc b/modules/ztp-comparing-pgt-and-rhacm-pg-patching-strategies.adoc new file mode 100644 index 000000000000..ca0d0ea9d048 --- /dev/null +++ b/modules/ztp-comparing-pgt-and-rhacm-pg-patching-strategies.adoc @@ -0,0 +1,49 @@ +// Module included in the following assemblies: +// +// * edge_computing/ztp-configuring-managed-clusters-policygenerator.adoc + +:_mod-docs-content-type: CONCEPT +[id="ztp-comparing-pgt-and-rhacm-pg-patching-strategies_{context}"] += Comparing {rh-rhacm} PolicyGenerator and PolicyGenTemplate resource patching + +`PolicyGenerator` custom resources (CRs) and `PolicyGenTemplate` CRs can be used in {ztp} to generate {rh-rhacm} policies for managed clusters. + +There are advantages to using `PolicyGenerator` CRs over `PolicyGenTemplate` CRs when it comes to patching {product-title} resources with {ztp}. +Using the {rh-rhacm} `PolicyGenerator` API provides a generic way of patching resources which is not possible with `PolicyGenTemplate` resources. + +The `PolicyGenerator` API is a part of the link:https://open-cluster-management.io/[Open Cluster Management] standard, while the `PolicyGenTemplate` API is not. +A comparison of `PolicyGenerator` and `PolicyGenTemplate` resource patching and placement strategies are described in the following table. + +include::snippets/pgt-deprecation-notice.adoc[] + +.Comparison of {rh-rhacm} PolicyGenerator and PolicyGenTemplate patching +[cols="1,2", width="90%", options="header"] +|==== +|PolicyGenerator patching +|PolicyGenTemplate patching + +|Uses Kustomize strategic merges for merging resources. +For more information see link:https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/[Declarative Management of Kubernetes Objects Using Kustomize]. +|Works by replacing variables with their values as defined by the patch. +This is less flexible than Kustomize merge strategies. + +|Supports `ManagedClusterSet` and `Binding` resources. +|Does not support `ManagedClusterSet` and `Binding` resources. + +|Relies only on patching, no embedded variable substitution is required. +|Overwrites variable values defined in the patch. + +|Does not support merging lists in merge patches. +Replacing a list in a merge patch is supported. +|Merging and replacing lists is supported in a limited fashion - you can only merge one object in the list. + +|Does not currently support the link:https://spec.openapis.org/oas/latest.html[OpenAPI specification] for resource patching. +This means that additional directives are required in the patch to merge content that does not follow a schema, for example `PtpConfig` resources. +|Works by replacing fields and values with values as defined by the patch. + +|Requires additional directives, for example, `$patch: replace` in the patch to merge content that does not follow a schema. +|Substitutes fields and values defined in the source CR with values defined in the patch, for example `$name`. + +|Can patch the `Name` and `Namespace` fields defined in the reference source CR, but only if the CR file has a single object. +|Can patch the `Name` and `Namespace` fields defined in the reference source CR. +|==== diff --git a/modules/ztp-configuring-cluster-policies.adoc b/modules/ztp-configuring-cluster-policies.adoc index a91bd57f3d3e..b0c8066ec802 100644 --- a/modules/ztp-configuring-cluster-policies.adoc +++ b/modules/ztp-configuring-cluster-policies.adoc @@ -42,10 +42,10 @@ The following recommended structuring of policies combines configuration CRs to |Description |Common -|A policy that exists in the common category is applied to all clusters in the fleet. Use common `PolicyGenTemplate` CRs to apply common installation settings across all cluster types. +|A policy that exists in the common category is applied to all clusters in the fleet. Use common `{policy-gen-cr}` CRs to apply common installation settings across all cluster types. |Groups -|A policy that exists in the groups category is applied to a group of clusters in the fleet. Use group `PolicyGenTemplate` CRs to manage specific aspects of single-node, three-node, and standard cluster installations. Cluster groups can also follow geographic region, hardware variant, etc. +|A policy that exists in the groups category is applied to a group of clusters in the fleet. Use group `{policy-gen-cr}` CRs to manage specific aspects of single-node, three-node, and standard cluster installations. Cluster groups can also follow geographic region, hardware variant, etc. |Sites |A policy that exists in the sites category is applied to a specific cluster site. Any cluster diff --git a/modules/ztp-configuring-disk-partitioning.adoc b/modules/ztp-configuring-disk-partitioning.adoc index 393093aac738..37ec8f24cab3 100644 --- a/modules/ztp-configuring-disk-partitioning.adoc +++ b/modules/ztp-configuring-disk-partitioning.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-configuring-disk-partitioning_{context}"] diff --git a/modules/ztp-configuring-hwevents-using-pgt.adoc b/modules/ztp-configuring-hwevents-using-pgt.adoc index 558e9d6cd455..8802884f51e6 100644 --- a/modules/ztp-configuring-hwevents-using-pgt.adoc +++ b/modules/ztp-configuring-hwevents-using-pgt.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-creating-hwevents_{context}"] @@ -18,31 +19,26 @@ You can configure bare-metal events that use HTTP transport on managed clusters .Procedure -. Configure the {redfish-operator} Operator by adding the following YAML to `spec.sourceFiles` in the `common-ranGen.yaml` file: +. Configure the {redfish-operator} Operator by adding the following YAML to `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file: + [source,yaml] ---- -# Bare Metal Event Relay operator -- fileName: BareMetalEventRelaySubscriptionNS.yaml - policyName: "subscriptions-policy" -- fileName: BareMetalEventRelaySubscriptionOperGroup.yaml - policyName: "subscriptions-policy" -- fileName: BareMetalEventRelaySubscription.yaml - policyName: "subscriptions-policy" +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-hwevents-using-pgt.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-hwevents.yaml[] +endif::[] ---- -. Add the `HardwareEvent` CR to `spec.sourceFiles` in your specific group configuration file, for example, in the `group-du-sno-ranGen.yaml` file: +. Add the `HardwareEvent` CR to `{rangen-yaml-path}` in your specific group configuration file, for example, in the `{policy-prefix}group-du-sno-ranGen.yaml` file: + -[source,yaml] ----- -- fileName: HardwareEvent.yaml <1> - policyName: "config-policy" - spec: - nodeSelector: {} - transportHost: "http://hw-event-publisher-service.openshift-bare-metal-events.svc.cluster.local:9043" - logLevel: "info" ----- -<1> Each baseboard management controller (BMC) requires a single `HardwareEvent` CR only. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-hwevents-using-pgt-hardware-event.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-hwevents-using-pgt-hardware-event.adoc[] +endif::[] + [NOTE] ==== diff --git a/modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc b/modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc index 48493e707d97..b5b485199325 100644 --- a/modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc +++ b/modules/ztp-configuring-pgt-compliance-eval-timeouts.adoc @@ -1,14 +1,15 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-configuring-pgt-compliance-eval-timeouts_{context}"] -= Configuring policy compliance evaluation timeouts for PolicyGenTemplate CRs += Configuring policy compliance evaluation timeouts for {policy-gen-cr} CRs Use {rh-rhacm-first} installed on a hub cluster to monitor and report on whether your managed clusters are compliant with applied policies. {rh-rhacm} uses policy templates to apply predefined policy controllers and policies. Policy controllers are Kubernetes custom resource definition (CRD) instances. -You can override the default policy evaluation intervals with `PolicyGenTemplate` custom resources (CRs). You configure duration settings that define how long a `ConfigurationPolicy` CR can be in a state of policy compliance or non-compliance before {rh-rhacm} re-evaluates the applied cluster policies. +You can override the default policy evaluation intervals with `{policy-gen-cr}` custom resources (CRs). You configure duration settings that define how long a `ConfigurationPolicy` CR can be in a state of policy compliance or non-compliance before {rh-rhacm} re-evaluates the applied cluster policies. The {ztp-first} policy generator generates `ConfigurationPolicy` CR policies with pre-defined policy evaluation intervals. The default value for the `noncompliant` state is 10 seconds. The default value for the `compliant` state is 10 minutes. To disable the evaluation interval, set the value to `never`. @@ -22,30 +23,56 @@ The {ztp-first} policy generator generates `ConfigurationPolicy` CR policies wit .Procedure -. To configure the evaluation interval for all policies in a `PolicyGenTemplate` CR, add `evaluationInterval` to the `spec` field, and then set the appropriate `compliant` and `noncompliant` values. For example: +. To configure the evaluation interval for all policies in a `{policy-gen-cr}` CR, set appropriate `compliant` and `noncompliant` values for the `evaluationInterval` field. +For example: + [source,yaml] ---- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] spec: evaluationInterval: compliant: 30m noncompliant: 20s +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +policyDefaults: + evaluationInterval: + compliant: 30m + noncompliant: 45s +endif::[] ---- ++ +[NOTE] +==== +You can also set `compliant` and `noncompliant` fields to `never` to stop evaluating the policy after it reaches particular compliance state. +==== -. To configure the evaluation interval for the `spec.sourceFiles` object in a `PolicyGenTemplate` CR, add `evaluationInterval` to the `sourceFiles` field, for example: +. To configure the evaluation interval for an individual policy object in a `{policy-gen-cr}` CR, add the `evaluationInterval` field and set appropriate values. +For example: + [source,yaml] ---- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] spec: sourceFiles: - - fileName: SriovSubscription.yaml - policyName: "sriov-sub-policy" - evaluationInterval: - compliant: never - noncompliant: 10s + - fileName: SriovSubscription.yaml + policyName: "sriov-sub-policy" + evaluationInterval: + compliant: never + noncompliant: 10s +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +policies: + - name: "sriov-sub-policy" + manifests: + - path: "SriovSubscription.yaml" + evaluationInterval: + compliant: never + noncompliant: 10s +endif::[] ---- -. Commit the `PolicyGenTemplate` CRs files in the Git repository and push your changes. +. Commit the `{policy-gen-cr}` CRs files in the Git repository and push your changes. .Verification diff --git a/modules/ztp-configuring-pgt-image-registry.adoc b/modules/ztp-configuring-pgt-image-registry.adoc index d92ebe02c749..1c8315413070 100644 --- a/modules/ztp-configuring-pgt-image-registry.adoc +++ b/modules/ztp-configuring-pgt-image-registry.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-configuring-pgt-image-registry_{context}"] -= Configuring the image registry using PolicyGenTemplate CRs += Configuring the image registry using {policy-gen-cr} CRs -Use `PolicyGenTemplate` (PGT) CRs to apply the CRs required to configure the image registry and patch the `imageregistry` configuration. +Use `{policy-gen-cr}` (PGT) CRs to apply the CRs required to configure the image registry and patch the `imageregistry` configuration. .Prerequisites @@ -20,7 +21,7 @@ Use `PolicyGenTemplate` (PGT) CRs to apply the CRs required to configure the ima .Procedure -. Configure the storage class, persistent volume claim, persistent volume, and image registry configuration in the appropriate `PolicyGenTemplate` CR. For example, to configure an individual site, add the following YAML to the file `example-sno-site.yaml`: +. Configure the storage class, persistent volume claim, persistent volume, and image registry configuration in the appropriate `{policy-gen-cr}` CR. For example, to configure an individual site, add the following YAML to the file `{policy-prefix}example-sno-site.yaml`: + [source,yaml] ---- @@ -74,7 +75,7 @@ sourceFiles: Do not set `complianceType: mustonlyhave` for the `- fileName: ImageRegistryConfig.yaml` configuration. This can cause the registry pod deployment to fail. ==== -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} ArgoCD application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} ArgoCD application. .Verification diff --git a/modules/ztp-configuring-ptp-fast-events-amqp.adoc b/modules/ztp-configuring-ptp-fast-events-amqp.adoc index 3bd83aacd6fb..3b448edcb3ea 100644 --- a/modules/ztp-configuring-ptp-fast-events-amqp.adoc +++ b/modules/ztp-configuring-ptp-fast-events-amqp.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-configuring-ptp-fast-events-amqp_{context}"] @@ -20,67 +21,54 @@ include::snippets/ptp-amq-interconnect-eol.adoc[leveloffset=+1] .Procedure -. Add the following YAML into `.spec.sourceFiles` in the `common-ranGen.yaml` file to configure the AMQP Operator: +. Add the following YAML into `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file to configure the AMQP Operator: + [source,yaml] ---- -#AMQ interconnect operator for fast events -- fileName: AmqSubscriptionNS.yaml - policyName: "subscriptions-policy" -- fileName: AmqSubscriptionOperGroup.yaml - policyName: "subscriptions-policy" -- fileName: AmqSubscription.yaml - policyName: "subscriptions-policy" +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-ptp-fast-events-amqp.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-ptp-fast-events-amqp.yaml[] +endif::[] ---- -. Apply the following `PolicyGenTemplate` changes to `group-du-3node-ranGen.yaml`, `group-du-sno-ranGen.yaml`, or `group-du-standard-ranGen.yaml` files according to your requirements: +. Apply the following `{policy-gen-cr}` changes to `{policy-prefix}group-du-3node-ranGen.yaml`, `{policy-prefix}group-du-sno-ranGen.yaml`, or `{policy-prefix}group-du-standard-ranGen.yaml` files according to your requirements: -.. In `.sourceFiles`, add the `PtpOperatorConfig` CR file that configures the AMQ transport host to the `config-policy`: +.. In `{rangen-yaml-path}`, add the `PtpOperatorConfig` CR file that configures the AMQ transport host to the `config-policy`: + [source,yaml] ---- -- fileName: PtpOperatorConfigForEvent.yaml - policyName: "config-policy" - spec: - daemonNodeSelector: {} - ptpEventConfig: - enableEventPublisher: true - transportHost: "amqp://amq-router.amq-router.svc.cluster.local" +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-ptp-fast-events-amqp-transport.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-ptp-fast-events-amqp-transport.yaml[] +endif::[] ---- -.. Configure the `linuxptp` and `phc2sys` for the PTP clock type and interface. For example, add the following stanza into `.sourceFiles`: +.. Configure the `linuxptp` and `phc2sys` for the PTP clock type and interface. For example, add the following YAML into `{rangen-yaml-path}`: + -[source,yaml] ----- -- fileName: PtpConfigSlave.yaml <1> - policyName: "config-policy" - metadata: - name: "du-ptp-slave" - spec: - profile: - - name: "slave" - interface: "ens5f1" <2> - ptp4lOpts: "-2 -s --summary_interval -4" <3> - phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16" <4> - ptpClockThreshold: <5> - holdOverTimeout: 30 #secs - maxOffsetThreshold: 100 #nano secs - minOffsetThreshold: -100 #nano secs ----- -<1> Can be one `PtpConfigMaster.yaml`, `PtpConfigSlave.yaml`, or `PtpConfigSlaveCvl.yaml` depending on your requirements. `PtpConfigSlaveCvl.yaml` configures `linuxptp` services for an Intel E810 Columbiaville NIC. For configurations based on `group-du-sno-ranGen.yaml` or `group-du-3node-ranGen.yaml`, use `PtpConfigSlave.yaml`. -<2> Device specific interface name. -<3> You must append the `--summary_interval -4` value to `ptp4lOpts` in `.spec.sourceFiles.spec.profile` to enable PTP fast events. -<4> Required `phc2sysOpts` values. `-m` prints messages to `stdout`. The `linuxptp-daemon` `DaemonSet` parses the logs and generates Prometheus metrics. -<5> Optional. If the `ptpClockThreshold` stanza is not present, default values are used for the `ptpClockThreshold` fields. The stanza shows default `ptpClockThreshold` values. The `ptpClockThreshold` values configure how long after the PTP master clock is disconnected before PTP events are triggered. `holdOverTimeout` is the time value in seconds before the PTP clock event state changes to `FREERUN` when the PTP master clock is disconnected. The `maxOffsetThreshold` and `minOffsetThreshold` settings configure offset values in nanoseconds that compare against the values for `CLOCK_REALTIME` (`phc2sys`) or master offset (`ptp4l`). When the `ptp4l` or `phc2sys` offset value is outside this range, the PTP clock state is set to `FREERUN`. When the offset value is within this range, the PTP clock state is set to `LOCKED`. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc[] +endif::[] -. Apply the following `PolicyGenTemplate` changes to your specific site YAML files, for example, `example-sno-site.yaml`: +. Apply the following `{policy-gen-cr}` changes to your specific site YAML files, for example, `{policy-prefix}example-sno-site.yaml`: -.. In `.sourceFiles`, add the `Interconnect` CR file that configures the AMQ router to the `config-policy`: +.. In `{rangen-yaml-path}`, add the `Interconnect` CR file that configures the AMQ router to the `config-policy`: + [source,yaml] ---- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] - fileName: AmqInstance.yaml policyName: "config-policy" +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +- path: source-crs/AmqInstance.yaml +endif::[] ---- . Merge any other required changes and files with your custom site repository. diff --git a/modules/ztp-configuring-ptp-fast-events.adoc b/modules/ztp-configuring-ptp-fast-events.adoc index 50178d0c175b..5fadbe04fab9 100644 --- a/modules/ztp-configuring-ptp-fast-events.adoc +++ b/modules/ztp-configuring-ptp-fast-events.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-configuring-ptp-fast-events_{context}"] @@ -18,19 +19,18 @@ You can configure PTP events that use HTTP transport on managed clusters that yo .Procedure -. Apply the following `PolicyGenTemplate` changes to `group-du-3node-ranGen.yaml`, `group-du-sno-ranGen.yaml`, or `group-du-standard-ranGen.yaml` files according to your requirements: +. Apply the following `{policy-gen-cr}` changes to `{policy-prefix}group-du-3node-ranGen.yaml`, `{policy-prefix}group-du-sno-ranGen.yaml`, or `{policy-prefix}group-du-standard-ranGen.yaml` files according to your requirements: -.. In `.sourceFiles`, add the `PtpOperatorConfig` CR file that configures the transport host: +.. In `{rangen-yaml-path}`, add the `PtpOperatorConfig` CR file that configures the transport host: + [source,yaml] ---- -- fileName: PtpOperatorConfigForEvent.yaml - policyName: "config-policy" - spec: - daemonNodeSelector: {} - ptpEventConfig: - enableEventPublisher: true - transportHost: http://ptp-event-publisher-service-NODE_NAME.openshift-ptp.svc.cluster.local:9043 +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-ptp-fast-events.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-ptp-fast-events.yaml[] +endif::[] ---- + [NOTE] @@ -38,30 +38,14 @@ You can configure PTP events that use HTTP transport on managed clusters that yo In {product-title} 4.13 or later, you do not need to set the `transportHost` field in the `PtpOperatorConfig` resource when you use HTTP transport with PTP events. ==== -.. Configure the `linuxptp` and `phc2sys` for the PTP clock type and interface. For example, add the following stanza into `.sourceFiles`: +.. Configure the `linuxptp` and `phc2sys` for the PTP clock type and interface. For example, add the following YAML into `{rangen-yaml-path}`: + -[source,yaml] ----- -- fileName: PtpConfigSlave.yaml <1> - policyName: "config-policy" - metadata: - name: "du-ptp-slave" - spec: - profile: - - name: "slave" - interface: "ens5f1" <2> - ptp4lOpts: "-2 -s --summary_interval -4" <3> - phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16" <4> - ptpClockThreshold: <5> - holdOverTimeout: 30 #secs - maxOffsetThreshold: 100 #nano secs - minOffsetThreshold: -100 #nano secs ----- -<1> Can be one of `PtpConfigMaster.yaml`, `PtpConfigSlave.yaml`, or `PtpConfigSlaveCvl.yaml` depending on your requirements. `PtpConfigSlaveCvl.yaml` configures `linuxptp` services for an Intel E810 Columbiaville NIC. For configurations based on `group-du-sno-ranGen.yaml` or `group-du-3node-ranGen.yaml`, use `PtpConfigSlave.yaml`. -<2> Device specific interface name. -<3> You must append the `--summary_interval -4` value to `ptp4lOpts` in `.spec.sourceFiles.spec.profile` to enable PTP fast events. -<4> Required `phc2sysOpts` values. `-m` prints messages to `stdout`. The `linuxptp-daemon` `DaemonSet` parses the logs and generates Prometheus metrics. -<5> Optional. If the `ptpClockThreshold` stanza is not present, default values are used for the `ptpClockThreshold` fields. The stanza shows default `ptpClockThreshold` values. The `ptpClockThreshold` values configure how long after the PTP master clock is disconnected before PTP events are triggered. `holdOverTimeout` is the time value in seconds before the PTP clock event state changes to `FREERUN` when the PTP master clock is disconnected. The `maxOffsetThreshold` and `minOffsetThreshold` settings configure offset values in nanoseconds that compare against the values for `CLOCK_REALTIME` (`phc2sys`) or master offset (`ptp4l`). When the `ptp4l` or `phc2sys` offset value is outside this range, the PTP clock state is set to `FREERUN`. When the offset value is within this range, the PTP clock state is set to `LOCKED`. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc[] +endif::[] . Merge any other required changes and files with your custom site repository. diff --git a/modules/ztp-creating-a-validator-inform-policy.adoc b/modules/ztp-creating-a-validator-inform-policy.adoc index f9f63004f464..07cfe9270257 100644 --- a/modules/ztp-creating-a-validator-inform-policy.adoc +++ b/modules/ztp-creating-a-validator-inform-policy.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-creating-a-validator-inform-policy_{context}"] @@ -10,35 +11,14 @@ Create a validator inform policy that signals when the {ztp-first} installation .Procedure -. Create a standalone `PolicyGenTemplate` custom resource (CR) that contains the source file -`validatorCRs/informDuValidator.yaml`. You only need one standalone `PolicyGenTemplate` CR for each cluster type. For example, this CR applies a validator inform policy for {sno} clusters: +. Create a standalone `{policy-gen-cr}` custom resource (CR) that contains the source file +`validatorCRs/informDuValidator.yaml`. You only need one standalone `{policy-gen-cr}` CR for each cluster type. For example, this CR applies a validator inform policy for {sno} clusters: + -.Example single-node cluster validator inform policy CR (group-du-sno-validator-ranGen.yaml) -[source,yaml] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "group-du-sno-validator" <1> - namespace: "ztp-group" <2> -spec: - bindingRules: - group-du-sno: "" <3> - bindingExcludedRules: - ztp-done: "" <4> - mcp: "master" <5> - sourceFiles: - - fileName: validatorCRs/informDuValidator.yaml - remediationAction: inform <6> - policyName: "du-policy" <7> ----- -<1> The name of `PolicyGenTemplates` object. This name is also used as part of the names -for the `placementBinding`, `placementRule`, and `policy` that are created in the requested `namespace`. -<2> This value should match the `namespace` used in the group `PolicyGenTemplates`. -<3> The `group-du-*` label defined in `bindingRules` must exist in the `SiteConfig` files. -<4> The label defined in `bindingExcludedRules` must be`ztp-done:`. The `ztp-done` label is used in coordination with the {cgu-operator-full}. -<5> `mcp` defines the `MachineConfigPool` object that is used in the source file `validatorCRs/informDuValidator.yaml`. It should be `master` for single node and three-node cluster deployments and `worker` for standard cluster deployments. -<6> Optional. The default value is `inform`. -<7> This value is used as part of the name for the generated {rh-rhacm} policy. The generated validator policy for the single node example is `group-du-sno-validator-du-policy`. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-example-single-node-cluster-validator.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-example-single-node-cluster-validator.adoc[] +endif::[] -. Commit the `PolicyGenTemplate` CR file in your Git repository and push the changes. +. Commit the `{policy-gen-cr}` CR file in your Git repository and push the changes. diff --git a/modules/ztp-creating-hwevents-amqp.adoc b/modules/ztp-creating-hwevents-amqp.adoc index 34e5fcccb787..47e4f6f15d25 100644 --- a/modules/ztp-creating-hwevents-amqp.adoc +++ b/modules/ztp-creating-hwevents-amqp.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-creating-hwevents-amqp_{context}"] @@ -20,54 +21,46 @@ include::snippets/ptp-amq-interconnect-eol.adoc[] .Procedure -. To configure the AMQ Interconnect Operator and the {redfish-operator} Operator, add the following YAML to `spec.sourceFiles` in the `common-ranGen.yaml` file: +. To configure the AMQ Interconnect Operator and the {redfish-operator} Operator, add the following YAML to `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file: + [source,yaml] ---- -# AMQ interconnect operator for fast events -- fileName: AmqSubscriptionNS.yaml - policyName: "subscriptions-policy" -- fileName: AmqSubscriptionOperGroup.yaml - policyName: "subscriptions-policy" -- fileName: AmqSubscription.yaml - policyName: "subscriptions-policy" -# Bare Metal Event Rely operator -- fileName: BareMetalEventRelaySubscriptionNS.yaml - policyName: "subscriptions-policy" -- fileName: BareMetalEventRelaySubscriptionOperGroup.yaml - policyName: "subscriptions-policy" -- fileName: BareMetalEventRelaySubscription.yaml - policyName: "subscriptions-policy" +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-creating-hwevents-amqp.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-creating-hwevents-amqp.yaml[] +endif::[] ---- -. Add the `Interconnect` CR to `.spec.sourceFiles` in the site configuration file, for example, the `example-sno-site.yaml` file: +. Add the `Interconnect` CR to `{rangen-yaml-path}` in the site configuration file, for example, the `{policy-prefix}example-sno-site.yaml` file: + [source,yaml] ---- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] - fileName: AmqInstance.yaml policyName: "config-policy" +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +- path: source-crs/AmqInstance.yaml +endif::[] ---- -. Add the `HardwareEvent` CR to `spec.sourceFiles` in your specific group configuration file, for example, in the `group-du-sno-ranGen.yaml` file: +. Add the `HardwareEvent` CR to `{rangen-yaml-path}` in your specific group configuration file, for example, in the `{policy-prefix}group-du-sno-ranGen.yaml` file: + -[source,yaml] ----- -- fileName: HardwareEvent.yaml - policyName: "config-policy" - spec: - nodeSelector: {} - transportHost: "amqp://..svc.cluster.local" <1> - logLevel: "info" ----- -<1> The `transportHost` URL is composed of the existing AMQ Interconnect CR `name` and `namespace`. For example, in `transportHost: "amqp://amq-router.amq-router.svc.cluster.local"`, the AMQ Interconnect `name` and `namespace` are both set to `amq-router`. - +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/ztp-creating-hwevents-amqp-hardware-event.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/ztp-creating-hwevents-amqp-hardware-event.adoc[] +endif::[] + [NOTE] ==== Each baseboard management controller (BMC) requires a single `HardwareEvent` resource only. ==== -. Commit the `PolicyGenTemplate` change in Git, and then push the changes to your site configuration repository to deploy bare-metal events monitoring to new sites using {ztp}. +. Commit the `{policy-gen-cr}` change in Git, and then push the changes to your site configuration repository to deploy bare-metal events monitoring to new sites using {ztp}. . Create the Redfish Secret by running the following command: + diff --git a/modules/ztp-customizing-a-managed-site-using-pgt.adoc b/modules/ztp-customizing-a-managed-site-using-pgt.adoc index 42be665b2801..6fcc9738c59d 100644 --- a/modules/ztp-customizing-a-managed-site-using-pgt.adoc +++ b/modules/ztp-customizing-a-managed-site-using-pgt.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="ztp-customizing-a-managed-site-using-pgt_{context}"] -= Customizing a managed cluster with PolicyGenTemplate CRs += Customizing a managed cluster with {policy-gen-cr} CRs Use the following procedure to customize the policies that get applied to the managed cluster that you provision using the {ztp-first} pipeline. @@ -20,49 +20,49 @@ Use the following procedure to customize the policies that get applied to the ma .Procedure -. Create a `PolicyGenTemplate` CR for site-specific configuration CRs. +. Create a `{policy-gen-cr}` CR for site-specific configuration CRs. -.. Choose the appropriate example for your CR from the `out/argocd/example/policygentemplates` folder, for example, `example-sno-site.yaml` or `example-multinode-site.yaml`. +.. Choose the appropriate example for your CR from the `{argocd-folder}` folder, for example, `{policy-prefix}example-sno-site.yaml` or `{policy-prefix}example-multinode-site.yaml`. -.. Change the `bindingRules` field in the example file to match the site-specific label included in the `SiteConfig` CR. In the example `SiteConfig` file, the site-specific label is `sites: example-sno`. +.. Change the `{binding-field}` field in the example file to match the site-specific label included in the `SiteConfig` CR. In the example `SiteConfig` file, the site-specific label is `sites: example-sno`. + [NOTE] ==== -Ensure that the labels defined in your `PolicyGenTemplate` `bindingRules` field correspond to the labels that are defined in the related managed clusters `SiteConfig` CR. +Ensure that the labels defined in your `{policy-gen-cr}` `{binding-field}` field correspond to the labels that are defined in the related managed clusters `SiteConfig` CR. ==== .. Change the content in the example file to match the desired configuration. -. Optional: Create a `PolicyGenTemplate` CR for any common configuration CRs that apply to the entire fleet of clusters. +. Optional: Create a `{policy-gen-cr}` CR for any common configuration CRs that apply to the entire fleet of clusters. -.. Select the appropriate example for your CR from the `out/argocd/example/policygentemplates` folder, for example, `common-ranGen.yaml`. +.. Select the appropriate example for your CR from the `{argocd-folder}` folder, for example, `{policy-prefix}common-ranGen.yaml`. -.. Change the content in the example file to match the desired configuration. +.. Change the content in the example file to match the required configuration. -. Optional: Create a `PolicyGenTemplate` CR for any group configuration CRs that apply to the certain groups of clusters in the fleet. +. Optional: Create a `{policy-gen-cr}` CR for any group configuration CRs that apply to the certain groups of clusters in the fleet. + -Ensure that the content of the overlaid spec files matches your desired end state. As a reference, the out/source-crs directory contains the full list of source-crs available to be included and overlaid by your PolicyGenTemplate templates. +Ensure that the content of the overlaid spec files matches your required end state. As a reference, the `out/source-crs` directory contains the full list of source-crs available to be included and overlaid by your {policy-gen-cr} templates. + [NOTE] ==== -Depending on the specific requirements of your clusters, you might need more than a single group policy per cluster type, especially considering that the example group policies each have a single PerformancePolicy.yaml file that can only be shared across a set of clusters if those clusters consist of identical hardware configurations. +Depending on the specific requirements of your clusters, you might need more than a single group policy per cluster type, especially considering that the example group policies each have a single `PerformancePolicy.yaml` file that can only be shared across a set of clusters if those clusters consist of identical hardware configurations. ==== -.. Select the appropriate example for your CR from the `out/argocd/example/policygentemplates` folder, for example, `group-du-sno-ranGen.yaml`. +.. Select the appropriate example for your CR from the `{argocd-folder}` folder, for example, `{policy-prefix}group-du-sno-ranGen.yaml`. -.. Change the content in the example file to match the desired configuration. +.. Change the content in the example file to match the required configuration. -. Optional. Create a validator inform policy `PolicyGenTemplate` CR to signal when the {ztp} installation and configuration of the deployed cluster is complete. For more information, see "Creating a validator inform policy". +. Optional. Create a validator inform policy `{policy-gen-cr}` CR to signal when the {ztp} installation and configuration of the deployed cluster is complete. For more information, see "Creating a validator inform policy". -. Define all the policy namespaces in a YAML file similar to the example `out/argocd/example/policygentemplates/ns.yaml` file. +. Define all the policy namespaces in a YAML file similar to the example `{argocd-folder}/ns.yaml` file. + [IMPORTANT] ==== -Do not include the `Namespace` CR in the same file with the `PolicyGenTemplate` CR. +Do not include the `Namespace` CR in the same file with the `{policy-gen-cr}` CR. ==== -. Add the `PolicyGenTemplate` CRs and `Namespace` CR to the `kustomization.yaml` file in the generators section, similar to the example shown in `out/argocd/example/policygentemplates/kustomization.yaml`. +. Add the `{policy-gen-cr}` CRs and `Namespace` CR to the `kustomization.yaml` file in the generators section, similar to the example shown in `{argocd-folder}kustomization.yaml`. -. Commit the `PolicyGenTemplate` CRs, `Namespace` CR, and associated `kustomization.yaml` file in your Git repository and push the changes. +. Commit the `{policy-gen-cr}` CRs, `Namespace` CR, and associated `kustomization.yaml` file in your Git repository and push the changes. + -The ArgoCD pipeline detects the changes and begins the managed cluster deployment. You can push the changes to the `SiteConfig` CR and the `PolicyGenTemplate` CR simultaneously. +The ArgoCD pipeline detects the changes and begins the managed cluster deployment. You can push the changes to the `SiteConfig` CR and the `{policy-gen-cr}` CR simultaneously. diff --git a/modules/ztp-definition-of-done-for-ztp-installations.adoc b/modules/ztp-definition-of-done-for-ztp-installations.adoc index dbdde7eabe93..66bd999712f1 100644 --- a/modules/ztp-definition-of-done-for-ztp-installations.adoc +++ b/modules/ztp-definition-of-done-for-ztp-installations.adoc @@ -17,7 +17,7 @@ The cluster configuration phase is shown by a `ztp-running` label applied the `M {ztp} done:: Cluster installation and configuration is complete in the {ztp} done phase. This is shown by the removal of the `ztp-running` label and addition of the `ztp-done` label to the `ManagedCluster` CR. The `ztp-done` label shows that the configuration has been applied and the baseline DU configuration has completed cluster tuning. + -The transition to the {ztp} done state is conditional on the compliant state of a {rh-rhacm-first} validator inform policy. This policy captures the existing criteria for a completed installation and validates that it moves to a compliant state only when {ztp} provisioning of the managed cluster is complete. +The change to the {ztp} done state is conditional on the compliant state of a {rh-rhacm-first} validator inform policy. This policy captures the existing criteria for a completed installation and validates that it moves to a compliant state only when {ztp} provisioning of the managed cluster is complete. + The validator inform policy ensures the configuration of the cluster is fully applied and Operators have completed their initialization. The policy validates the following: + diff --git a/modules/ztp-deploying-additional-changes-to-clusters.adoc b/modules/ztp-deploying-additional-changes-to-clusters.adoc index b4e7b44f5638..3908123cc621 100644 --- a/modules/ztp-deploying-additional-changes-to-clusters.adoc +++ b/modules/ztp-deploying-additional-changes-to-clusters.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: CONCEPT [id="ztp-deploying-additional-changes-to-clusters_{context}"] diff --git a/modules/ztp-enabling-workload-partitioning-sno.adoc b/modules/ztp-enabling-workload-partitioning-sno.adoc index 1bf2c73c93b5..1776ac5c889d 100644 --- a/modules/ztp-enabling-workload-partitioning-sno.adoc +++ b/modules/ztp-enabling-workload-partitioning-sno.adoc @@ -17,7 +17,7 @@ Both of these steps happen at different points during cluster provisioning. ==== Configuring workload partitioning by using the `cpuPartitioningMode` field in the `SiteConfig` CR is a Tech Preview feature in {product-title} 4.13. -Alternatively, you can specify cluster management CPU resources with the `cpuset` field of the `SiteConfig` custom resource (CR) and the `reserved` field of the group `PolicyGenTemplate` CR. +Alternatively, you can specify cluster management CPU resources with the `cpuset` field of the `SiteConfig` custom resource (CR) and the `reserved` field of the group `PolicyGenerator` or `PolicyGentemplate` CR. The {ztp} pipeline uses these values to populate the required fields in the workload partitioning `MachineConfig` CR (`cpuset`) and the `PerformanceProfile` CR (`reserved`) that configure the {sno} cluster. This method is a General Availability feature in {product-title} 4.14. ==== diff --git a/modules/ztp-example-hub-template-functions.adoc b/modules/ztp-example-hub-template-functions.adoc index 614040dde5a1..c7001a03d65b 100644 --- a/modules/ztp-example-hub-template-functions.adoc +++ b/modules/ztp-example-hub-template-functions.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: REFERENCE [id="ztp-example-hub-template-functions_{context}"] diff --git a/modules/ztp-generating-install-and-config-crs-manually.adoc b/modules/ztp-generating-install-and-config-crs-manually.adoc index eb75510924d8..fed72f454cf2 100644 --- a/modules/ztp-generating-install-and-config-crs-manually.adoc +++ b/modules/ztp-generating-install-and-config-crs-manually.adoc @@ -6,7 +6,7 @@ [id="ztp-generating-install-and-config-crs-manually_{context}"] = Generating {ztp} installation and configuration CRs manually -Use the `generator` entrypoint for the `ztp-site-generate` container to generate the site installation and configuration custom resource (CRs) for a cluster based on `SiteConfig` and `PolicyGenTemplate` CRs. +Use the `generator` entrypoint for the `ztp-site-generate` container to generate the site installation and configuration custom resource (CRs) for a cluster based on `SiteConfig` and `{policy-gen-cr}` CRs. .Prerequisites @@ -30,7 +30,7 @@ $ mkdir -p ./out $ podman run --log-driver=none --rm registry.redhat.io/openshift4/ztp-site-generate-rhel8:v{product-version} extract /home/ztp --tar | tar x -C ./out ---- + -The `./out` directory has the reference `PolicyGenTemplate` and `SiteConfig` CRs in the `out/argocd/example/` folder. +The `./out` directory has the reference `{policy-gen-cr}` and `SiteConfig` CRs in the `out/argocd/example/` folder. + .Example output [source,terminal] @@ -38,11 +38,12 @@ The `./out` directory has the reference `PolicyGenTemplate` and `SiteConfig` CRs out └── argocd └── example - ├── policygentemplates - │ ├── common-ranGen.yaml - │ ├── example-sno-site.yaml - │ ├── group-du-sno-ranGen.yaml - │ ├── group-du-sno-validator-ranGen.yaml + ├── acmpolicygenerator + │ ├── {policy-prefix}common-ranGen.yaml + │ ├── {policy-prefix}example-sno-site.yaml + │ ├── {policy-prefix}group-du-sno-ranGen.yaml + │ ├── {policy-prefix}group-du-sno-validator-ranGen.yaml + │ ├── ... │ ├── kustomization.yaml │ └── ns.yaml └── siteconfig @@ -124,7 +125,7 @@ site-machineconfig └── site-1-sno_machineconfig_predefined-extra-manifests-worker.yaml ---- -. Generate and export the Day 2 configuration CRs using the reference `PolicyGenTemplate` CRs from the previous step. Run the following commands: +. Generate and export the Day 2 configuration CRs using the reference `{policy-gen-cr}` CRs from the previous step. Run the following commands: .. Create an output folder for the Day 2 CRs: + @@ -137,10 +138,10 @@ $ mkdir -p ./ref + [source,terminal,subs="attributes+"] ---- -$ podman run -it --rm -v `pwd`/out/argocd/example/policygentemplates:/resources:Z -v `pwd`/ref:/output:Z,U registry.redhat.io/openshift4/ztp-site-generate-rhel8:v{product-version} generator config -N . /output +$ podman run -it --rm -v `pwd`/out/argocd/example/acmpolicygenerator:/resources:Z -v `pwd`/ref:/output:Z,U registry.redhat.io/openshift4/ztp-site-generate-rhel8:v{product-version} generator config -N . /output ---- + -The command generates example group and site-specific `PolicyGenTemplate` CRs for {sno}, three-node clusters, and standard clusters in the `./ref` folder. +The command generates example group and site-specific `{policy-gen-cr}` CRs for {sno}, three-node clusters, and standard clusters in the `./ref` folder. + .Example output [source,terminal] @@ -188,4 +189,4 @@ Labels: beta.kubernetes.io/arch=amd64 node-role.kubernetes.io/worker= node.openshift.io/os_id=rhcos ---- -<1> The custom label is applied to the node. \ No newline at end of file +<1> The custom label is applied to the node. diff --git a/modules/ztp-monitoring-policy-deployment-progress.adoc b/modules/ztp-monitoring-policy-deployment-progress.adoc index 66ef343ce4de..e4d5324d5b51 100644 --- a/modules/ztp-monitoring-policy-deployment-progress.adoc +++ b/modules/ztp-monitoring-policy-deployment-progress.adoc @@ -6,7 +6,7 @@ [id="ztp-monitoring-policy-deployment-progress_{context}"] = Monitoring managed cluster policy deployment progress -The ArgoCD pipeline uses `PolicyGenTemplate` CRs in Git to generate the {rh-rhacm} policies and then sync them to the hub cluster. You can monitor the progress of the managed cluster policy synchronization after the assisted service installs {product-title} on the managed cluster. +The ArgoCD pipeline uses `{policy-gen-cr}` CRs in Git to generate the {rh-rhacm} policies and then sync them to the hub cluster. You can monitor the progress of the managed cluster policy synchronization after the assisted service installs {product-title} on the managed cluster. .Prerequisites diff --git a/modules/ztp-pgt-config-best-practices.adoc b/modules/ztp-pgt-config-best-practices.adoc index 831a6c786dc7..d4ddeedcebbe 100644 --- a/modules/ztp-pgt-config-best-practices.adoc +++ b/modules/ztp-pgt-config-best-practices.adoc @@ -4,14 +4,14 @@ :_module-type: CONCEPT [id="ztp-pgt-config-best-practices_{context}"] -= Recommendations when customizing PolicyGenTemplate CRs += Recommendations when customizing {policy-gen-cr} CRs -Consider the following best practices when customizing site configuration `PolicyGenTemplate` custom resources (CRs): +Consider the following best practices when customizing site configuration `{policy-gen-cr}` custom resources (CRs): -* Use as few policies as are necessary. Using fewer policies requires less resources. Each additional policy creates overhead for the hub cluster and the deployed managed cluster. CRs are combined into policies based on the `policyName` field in the `PolicyGenTemplate` CR. CRs in the same `PolicyGenTemplate` which have the same value for `policyName` are managed under a single policy. +* Use as few policies as are necessary. Using fewer policies requires less resources. Each additional policy creates increased CPU load for the hub cluster and the deployed managed cluster. CRs are combined into policies based on the `policyName` field in the `{policy-gen-cr}` CR. CRs in the same `{policy-gen-cr}` which have the same value for `policyName` are managed under a single policy. * In disconnected environments, use a single catalog source for all Operators by configuring the registry as a single index containing all Operators. Each additional `CatalogSource` CR on the managed clusters increases CPU usage. * `MachineConfig` CRs should be included as `extraManifests` in the `SiteConfig` CR so that they are applied during installation. This can reduce the overall time taken until the cluster is ready to deploy applications. -* `PolicyGenTemplates` should override the channel field to explicitly identify the desired version. This ensures that changes in the source CR during upgrades does not update the generated subscription. +* `{policy-gen-cr}` CRs should override the channel field to explicitly identify the desired version. This ensures that changes in the source CR during upgrades does not update the generated subscription. diff --git a/modules/ztp-policygentemplates-for-ran.adoc b/modules/ztp-policygentemplates-for-ran.adoc index e3921f5e5272..8acea32b2a0c 100644 --- a/modules/ztp-policygentemplates-for-ran.adoc +++ b/modules/ztp-policygentemplates-for-ran.adoc @@ -4,48 +4,51 @@ :_module-type: CONCEPT [id="ztp-policygentemplates-for-ran_{context}"] -= PolicyGenTemplate CRs for RAN deployments += {policy-gen-cr} CRs for RAN deployments -Use `PolicyGenTemplate` (PGT) custom resources (CRs) to customize the configuration applied to the cluster by using the {ztp-first} pipeline. The PGT CR allows you to generate one or more policies to manage the set of configuration CRs on your fleet of clusters. The PGT identifies the set of managed CRs, bundles them into policies, builds the policy wrapping around those CRs, and associates the policies with clusters by using label binding rules. +Use `{policy-gen-cr}` custom resources (CRs) to customize the configuration applied to the cluster by using the {ztp-first} pipeline. The `{policy-gen-cr}` CR allows you to generate one or more policies to manage the set of configuration CRs on your fleet of clusters. The `{policy-gen-cr}` CR identifies the set of managed CRs, bundles them into policies, builds the policy wrapping around those CRs, and associates the policies with clusters by using label binding rules. -The reference configuration, obtained from the {ztp} container, is designed to provide a set of critical features and node tuning settings that ensure the cluster can support the stringent performance and resource utilization constraints typical of RAN (Radio Access Network) Distributed Unit (DU) applications. Changes or omissions from the baseline configuration can affect feature availability, performance, and resource utilization. Use the reference `PolicyGenTemplate` CRs as the basis to create a hierarchy of configuration files tailored to your specific site requirements. +The reference configuration, obtained from the {ztp} container, is designed to provide a set of critical features and node tuning settings that ensure the cluster can support the stringent performance and resource utilization constraints typical of RAN (Radio Access Network) Distributed Unit (DU) applications. Changes or omissions from the baseline configuration can affect feature availability, performance, and resource utilization. Use the reference `{policy-gen-cr}` CRs as the basis to create a hierarchy of configuration files tailored to your specific site requirements. -The baseline `PolicyGenTemplate` CRs that are defined for RAN DU cluster configuration can be extracted from the {ztp} `ztp-site-generate` container. See "Preparing the {ztp} site configuration repository" for further details. +The baseline `{policy-gen-cr}` CRs that are defined for RAN DU cluster configuration can be extracted from the {ztp} `ztp-site-generate` container. See "Preparing the {ztp} site configuration repository" for further details. -The `PolicyGenTemplate` CRs can be found in the `./out/argocd/example/policygentemplates` folder. The reference architecture has common, group, and site-specific configuration CRs. Each `PolicyGenTemplate` CR refers to other CRs that can be found in the `./out/source-crs` folder. +The `{policy-gen-cr}` CRs can be found in the `./{argocd-folder}` folder. The reference architecture has common, group, and site-specific configuration CRs. Each `{policy-gen-cr}` CR refers to other CRs that can be found in the `./out/source-crs` folder. -The `PolicyGenTemplate` CRs relevant to RAN cluster configuration are described below. Variants are provided for the group `PolicyGenTemplate` CRs to account for differences in single-node, three-node compact, and standard cluster configurations. Similarly, site-specific configuration variants are provided for single-node clusters and multi-node (compact or standard) clusters. Use the group and site-specific configuration variants that are relevant for your deployment. +The `{policy-gen-cr}` CRs relevant to RAN cluster configuration are described below. Variants are provided for the group `{policy-gen-cr}` CRs to account for differences in single-node, three-node compact, and standard cluster configurations. Similarly, site-specific configuration variants are provided for single-node clusters and multi-node (compact or standard) clusters. Use the group and site-specific configuration variants that are relevant for your deployment. -.PolicyGenTemplate CRs for RAN deployments +.{policy-gen-cr} CRs for RAN deployments [cols=2*, options="header"] |==== -|PolicyGenTemplate CR +|{policy-gen-cr} CR |Description -|`example-multinode-site.yaml` +|`{policy-prefix}example-multinode-site.yaml` |Contains a set of CRs that get applied to multi-node clusters. These CRs configure SR-IOV features typical for RAN installations. -|`example-sno-site.yaml` +|`{policy-prefix}example-sno-site.yaml` |Contains a set of CRs that get applied to {sno} clusters. These CRs configure SR-IOV features typical for RAN installations. -|`common-ranGen.yaml` +|`{policy-prefix}common-mno-ranGen.yaml` +|Contains a set of common RAN policy configuration that get applied to multi-node clusters. + +|`{policy-prefix}common-ranGen.yaml` |Contains a set of common RAN CRs that get applied to all clusters. These CRs subscribe to a set of operators providing cluster features typical for RAN as well as baseline cluster tuning. -|`group-du-3node-ranGen.yaml` +|`{policy-prefix}group-du-3node-ranGen.yaml` |Contains the RAN policies for three-node clusters only. -|`group-du-sno-ranGen.yaml` +|`{policy-prefix}group-du-sno-ranGen.yaml` |Contains the RAN policies for single-node clusters only. -|`group-du-standard-ranGen.yaml` +|`{policy-prefix}group-du-standard-ranGen.yaml` |Contains the RAN policies for standard three control-plane clusters. -|`group-du-3node-validator-ranGen.yaml` -|`PolicyGenTemplate` CR used to generate the various policies required for three-node clusters. +|`{policy-prefix}group-du-3node-validator-ranGen.yaml` +|`{policy-gen-cr}` CR used to generate the various policies required for three-node clusters. -|`group-du-standard-validator-ranGen.yaml` -|`PolicyGenTemplate` CR used to generate the various policies required for standard clusters. +|`{policy-prefix}group-du-standard-validator-ranGen.yaml` +|`{policy-gen-cr}` CR used to generate the various policies required for standard clusters. -|`group-du-sno-validator-ranGen.yaml` -|`PolicyGenTemplate` CR used to generate the various policies required for {sno} clusters. +|`{policy-prefix}group-du-sno-validator-ranGen.yaml` +|`{policy-gen-cr}` CR used to generate the various policies required for {sno} clusters. |==== diff --git a/modules/ztp-precaching-troubleshooting.adoc b/modules/ztp-precaching-troubleshooting.adoc index 76cc73a375d3..21f95d28640b 100644 --- a/modules/ztp-precaching-troubleshooting.adoc +++ b/modules/ztp-precaching-troubleshooting.adoc @@ -4,9 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="ztp-pre-staging-troubleshooting_{context}"] -= Troubleshooting - -== Rendered catalog is invalid += Troubleshooting a "Rendered catalog is invalid" error When you download images by using a local or disconnected registry, you might see the `The rendered catalog is invalid` error. This means that you are missing certificates of the new registry you want to pull content from. diff --git a/modules/ztp-precaching-ztp-config.adoc b/modules/ztp-precaching-ztp-config.adoc index 5e47734f9e1e..c86f84b24e61 100644 --- a/modules/ztp-precaching-ztp-config.adoc +++ b/modules/ztp-precaching-ztp-config.adoc @@ -227,6 +227,5 @@ To extract all the images before the {product-title} installation, you must exec ==== `extract-ocp.sh`:: The `extract-ocp.sh` script extracts and loads the required images from the disk partition to the local container storage. -When the script finishes successfully, you can use the images locally. -When you upload the `SiteConfig` and the optional `PolicyGenTemplates` custom resources (CRs) to the Git repo, which Argo CD is monitoring, you can start the {ztp} workflow by syncing the CRs with the hub cluster. +When you commit the `SiteConfig` and optional `PolicyGenerator` or `PolicyGenTemplate` custom resources (CRs) to the Git repo that Argo CD is monitoring, you can start the {ztp} workflow by syncing the CRs with the hub cluster. diff --git a/modules/ztp-preparing-for-the-gitops-ztp-upgrade.adoc b/modules/ztp-preparing-for-the-gitops-ztp-upgrade.adoc index 75a85025db40..5d69146b2a36 100644 --- a/modules/ztp-preparing-for-the-gitops-ztp-upgrade.adoc +++ b/modules/ztp-preparing-for-the-gitops-ztp-upgrade.adoc @@ -27,9 +27,9 @@ $ podman run --log-driver=none --rm registry.redhat.io/openshift4/ztp-site-gener The `/update` directory contains the following subdirectories: + * `update/extra-manifest`: contains the source CR files that the `SiteConfig` CR uses to generate the extra manifest `configMap`. -* `update/source-crs`: contains the source CR files that the `PolicyGenTemplate` CR uses to generate the {rh-rhacm-first} policies. +* `update/source-crs`: contains the source CR files that the `PolicyGenerator` or `PolicyGentemplate` CR uses to generate the {rh-rhacm-first} policies. * `update/argocd/deployment`: contains patches and YAML files to apply on the hub cluster for use in the next step of this procedure. -* `update/argocd/example`: contains example `SiteConfig` and `PolicyGenTemplate` files that represent the recommended configuration. +* `update/argocd/example`: contains example `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` files that represent the recommended configuration. . Update the `clusters-app.yaml` and `policies-app.yaml` files to reflect the name of your applications and the URL, branch, and path for your Git repository. + diff --git a/modules/ztp-preparing-the-hub-cluster-for-ztp.adoc b/modules/ztp-preparing-the-hub-cluster-for-ztp.adoc index 4ced482d7e9d..c604e1bd641e 100644 --- a/modules/ztp-preparing-the-hub-cluster-for-ztp.adoc +++ b/modules/ztp-preparing-the-hub-cluster-for-ztp.adoc @@ -37,7 +37,7 @@ You can configure the hub cluster with a set of ArgoCD applications that generat *** The `targetRevision` indicates which Git repository branch to monitor. -*** `path` specifies the path to the `SiteConfig` and `PolicyGenTemplate` CRs, respectively. +*** `path` specifies the path to the `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` CRs, respectively. [start=2] include::snippets/ztp-patch-argocd-hub-cluster.adoc[] diff --git a/modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc b/modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc index 7dc154c00f5c..9aacf70fb696 100644 --- a/modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc +++ b/modules/ztp-preparing-the-ztp-git-repository-ver-ind.adoc @@ -9,11 +9,22 @@ You can use {ztp} to manage source custom resources (CRs) for managed clusters that are running different versions of {product-title}. This means that the version of {product-title} running on the hub cluster can be independent of the version running on the managed clusters. +[NOTE] +==== +The following procedure assumes you are using `PolicyGenerator` resources instead of `PolicyGentemplate` resources for cluster policies management. +==== + +.Prerequisites + +* You have installed the OpenShift CLI (`oc`). + +* You have logged in as a user with `cluster-admin` privileges. + .Procedure -. Create a directory structure with separate paths for the `SiteConfig` and `PolicyGenTemplate` CRs. +. Create a directory structure with separate paths for the `SiteConfig` and `PolicyGenerator` CRs. -. Within the `PolicyGenTemplate` directory, create a directory for each {product-title} version you want to make available. +. Within the `PolicyGenerator` directory, create a directory for each {product-title} version you want to make available. For each version, create the following resources: * `kustomization.yaml` file that explicitly includes the files in that directory * `source-crs` directory to contain reference CR configuration files from the `ztp-site-generate` container @@ -26,7 +37,7 @@ The following example describes a structure using user-provided manifests and CR + [source,text] ---- -├── policygentemplates +├── acmpolicygenerator │ ├── kustomization.yaml <1> │ ├── version_4.13 <2> │ │ ├── common-ranGen.yaml @@ -63,7 +74,7 @@ The following example describes a structure using user-provided manifests and CR ---- <1> Create a top-level `kustomization` YAML file. -<2> Create the version-specific directories within the custom `/policygentemplates` directory. +<2> Create the version-specific directories within the custom `/acmpolicygenerator` directory. <3> Create a `kustomization.yaml` file for each version. <4> Create a `source-crs` directory for each version to contain reference CRs from the `ztp-site-generate` container. <5> Create the `reference-crs` directory for policy CRs that are extracted from the ZTP container. diff --git a/modules/ztp-preparing-the-ztp-git-repository.adoc b/modules/ztp-preparing-the-ztp-git-repository.adoc index fa594dc35198..0b01ba6a5b76 100644 --- a/modules/ztp-preparing-the-ztp-git-repository.adoc +++ b/modules/ztp-preparing-the-ztp-git-repository.adoc @@ -16,12 +16,12 @@ Before you can use the {ztp-first} pipeline, you need to prepare the Git reposit .Procedure -. Create a directory structure with separate paths for the `SiteConfig` and `PolicyGenTemplate` CRs. +. Create a directory structure with separate paths for the `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` CRs. + [NOTE] ==== -Keep `SiteConfig` and `PolicyGenTemplate` CRs in separate directories. -Both the `SiteConfig` and `PolicyGenTemplate` directories must contain a `kustomization.yaml` file that explicitly includes the files in that directory. +Keep `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` CRs in separate directories. +Both the `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` directories must contain a `kustomization.yaml` file that explicitly includes the files in that directory. ==== . Export the `argocd` directory from the `ztp-site-generate` container image using the following commands: @@ -41,16 +41,14 @@ $ mkdir -p ./out $ podman run --log-driver=none --rm registry.redhat.io/openshift4/ztp-site-generate-rhel8:v{product-version} extract /home/ztp --tar | tar x -C ./out ---- - . Check that the `out` directory contains the following subdirectories: + * `out/extra-manifest` contains the source CR files that `SiteConfig` uses to generate extra manifest `configMap`. -* `out/source-crs` contains the source CR files that `PolicyGenTemplate` uses to generate the {rh-rhacm-first} policies. +* `out/source-crs` contains the source CR files that `PolicyGenerator` uses to generate the {rh-rhacm-first} policies. * `out/argocd/deployment` contains patches and YAML files to apply on the hub cluster for use in the next step of this procedure. -* `out/argocd/example` contains the examples for `SiteConfig` and `PolicyGenTemplate` files that represent the recommended configuration. - +* `out/argocd/example` contains the examples for `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` files that represent the recommended configuration. -. Copy the `out/source-crs` folder and contents to the `PolicyGentemplate` directory. +. Copy the `out/source-crs` folder and contents to the `PolicyGenerator` or `PolicyGentemplate` directory. . The out/extra-manifests directory contains the reference manifests for a RAN DU cluster. Copy the `out/extra-manifests` directory into the `SiteConfig` folder. @@ -62,24 +60,29 @@ For example: [source,text] ---- example/ - ├── policygentemplates + ├── acmpolicygenerator + │ ├── kustomization.yaml + │ └── source-crs/ + ├── policygentemplates <1> │ ├── kustomization.yaml │ └── source-crs/ └── siteconfig ├── extra-manifests └── kustomization.yaml ---- +<1> Using `PolicyGenTemplate` CRs to manage and deploy polices to manage clusters will be deprecated in a future {product-title} release. +Equivalent and improved functionality is available by using {rh-rhacm-first} and `PolicyGenerator` CRs. . Commit the directory structure and the `kustomization.yaml` files and push to your Git repository. The initial push to Git should include the `kustomization.yaml` files. You can use the directory structure under `out/argocd/example` as a reference for the structure and content of your Git repository. -That structure includes `SiteConfig` and `PolicyGenTemplate` reference CRs for single-node, three-node, and standard clusters. +That structure includes `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` reference CRs for single-node, three-node, and standard clusters. Remove references to cluster types that you are not using. For all cluster types, you must: -* Add the `source-crs` subdirectory to the `policygentemplate` directory. +* Add the `source-crs` subdirectory to the `acmpolicygenerator` or `policygentemplates` directory. * Add the `extra-manifests` directory to the `siteconfig` directory. The following example describes a set of CRs for a network of single-node clusters: @@ -87,10 +90,10 @@ The following example describes a set of CRs for a network of single-node cluste [source,text] ---- example/ - ├── policygentemplates - │ ├── common-ranGen.yaml - │ ├── example-sno-site.yaml - │ ├── group-du-sno-ranGen.yaml + ├── acmpolicygenerator + │ ├── acm-common-ranGen.yaml + │ ├── acm-example-sno-site.yaml + │ ├── acm-group-du-sno-ranGen.yaml │ ├── group-du-sno-validator-ranGen.yaml │ ├── kustomization.yaml │ ├── source-crs/ diff --git a/modules/ztp-provisioning-lvm-storage.adoc b/modules/ztp-provisioning-lvm-storage.adoc index 56b5d14e622e..b0c4dbccb3ac 100644 --- a/modules/ztp-provisioning-lvm-storage.adoc +++ b/modules/ztp-provisioning-lvm-storage.adoc @@ -1,10 +1,11 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-provisioning-lvm-storage_{context}"] -= Configuring {lvms} using PolicyGenTemplate CRs += Configuring {lvms} using {policy-gen-cr} CRs You can configure {lvms-first} for managed clusters that you deploy with {ztp-first}. @@ -25,57 +26,46 @@ Use the Local Storage Operator for persistent storage that uses local volumes in .Procedure -. To configure {lvms} for new managed clusters, add the following YAML to `spec.sourceFiles` in the `common-ranGen.yaml` file: +. To configure {lvms} for new managed clusters, add the following YAML to `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file: + -[source,yaml,subs="attributes+"] ----- -- fileName: StorageLVMOSubscriptionNS.yaml - policyName: subscription-policies -- fileName: StorageLVMOSubscriptionOperGroup.yaml - policyName: subscription-policies -- fileName: StorageLVMOSubscription.yaml - spec: - name: lvms-operator - channel: stable-{product-version} - policyName: subscription-policies ----- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-provisioning-lvm-storage.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-provisioning-lvm-storage.adoc[] +endif::[] + [NOTE] ==== The Storage LVMO subscription is deprecated. In future releases of {product-title}, the storage LVMO subscription will not be available. Instead, you must use the Storage LVMS subscription. -In {product-title} {product-version}, you can use the Storage LVMS subscription instead of the LVMO subscription. The LVMS subscription does not require manual overrides in the `common-ranGen.yaml` file. Add the following YAML to `spec.sourceFiles` in the `common-ranGen.yaml` file to use the Storage LVMS subscription: +In {product-title} {product-version}, you can use the Storage LVMS subscription instead of the LVMO subscription. The LVMS subscription does not require manual overrides in the `{policy-prefix}common-ranGen.yaml` file. Add the following YAML to `{rangen-yaml-path}` in the `{policy-prefix}common-ranGen.yaml` file to use the Storage LVMS subscription: [source,yaml] ---- -- fileName: StorageLVMSubscriptionNS.yaml - policyName: subscription-policies -- fileName: StorageLVMSubscriptionOperGroup.yaml - policyName: subscription-policies -- fileName: StorageLVMSubscription.yaml - policyName: subscription-policies +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-provisioning-lvm-storage-sub.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-provisioning-lvm-storage-sub.yaml[] +endif::[] ---- - ==== -. Add the `LVMCluster` CR to `spec.sourceFiles` in your specific group or individual site configuration file. For example, in the `group-du-sno-ranGen.yaml` file, add the following: +. Add the `LVMCluster` CR to `{rangen-yaml-path}` in your specific group or individual site configuration file. For example, in the `{policy-prefix}group-du-sno-ranGen.yaml` file, add the following: + -[source,yaml] ----- -- fileName: StorageLVMCluster.yaml - policyName: "lvms-config" <1> - spec: - storage: - deviceClasses: - - name: vg1 - thinPoolConfig: - name: thin-pool-1 - sizePercent: 90 - overprovisionRatio: 10 ----- -<1> This example configuration creates a volume group (`vg1`) with all the available devices, except the disk where {product-title} is installed. +-- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-provisioning-lvm-storage-cluster.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-provisioning-lvm-storage-cluster.adoc[] +endif::[] + +This example configuration creates a volume group (`vg1`) with all the available devices, except the disk where {product-title} is installed. A thin-pool logical volume is also created. +-- . Merge any other required changes and files with your custom site repository. -. Commit the `PolicyGenTemplate` changes in Git, and then push the changes to your site configuration repository to deploy {lvms} to new sites using {ztp}. +. Commit the `{policy-gen-cr}` changes in Git, and then push the changes to your site configuration repository to deploy {lvms} to new sites using {ztp}. diff --git a/modules/ztp-removing-content-from-managed-clusters.adoc b/modules/ztp-removing-content-from-managed-clusters.adoc index b1c2da749cbf..519b006ad0a2 100644 --- a/modules/ztp-removing-content-from-managed-clusters.adoc +++ b/modules/ztp-removing-content-from-managed-clusters.adoc @@ -8,7 +8,7 @@ You can remove content from a custom resource (CR) that is deployed in a managed cluster through a policy. -By default, all `Policy` CRs created from a `PolicyGenTemplate` CR have the `complianceType` field set to `musthave`. +By default, all `Policy` CRs created from a `{policy-gen-cr}` CR have the `complianceType` field set to `musthave`. A `musthave` policy without the removed content is still compliant because the CR on the managed cluster has all the specified content. With this configuration, when you remove content from a CR, {cgu-operator} removes the content from the policy but the content is not removed from the CR on the managed cluster. @@ -45,16 +45,28 @@ spec: enableOperatorWebhook: true ---- -. Change the `complianceType` of the affected policies to `mustonlyhave` in the `group-du-sno-ranGen.yaml` file. +. Change the `complianceType` of the affected policies to `mustonlyhave` in the `{policy-prefix}group-du-sno-ranGen.yaml` file. + .Example YAML [source,yaml] ---- -# ... +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] - fileName: SriovOperatorConfig.yaml policyName: "config-policy" complianceType: mustonlyhave +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +# ... +policyDefaults: + complianceType: "mustonlyhave" # ... +policies: + - name: config-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "" + manifests: + - path: source-crs/SriovOperatorConfig.yaml +endif::[] ---- . Create a `ClusterGroupUpdates` CR and specify the clusters that must receive the CR changes:: @@ -124,4 +136,4 @@ $ oc get ---- + -If there are no results, the CR is removed from the managed cluster. \ No newline at end of file +If there are no results, the CR is removed from the managed cluster. diff --git a/modules/ztp-removing-obsolete-content.adoc b/modules/ztp-removing-obsolete-content.adoc index 4c37b6707b9d..654eb3e34c87 100644 --- a/modules/ztp-removing-obsolete-content.adoc +++ b/modules/ztp-removing-obsolete-content.adoc @@ -6,7 +6,7 @@ [id="ztp-removing-obsolete-content_{context}"] = Removing obsolete content from the {ztp} pipeline -If a change to the `PolicyGenTemplate` configuration results in obsolete policies, for example, if you rename policies, use the following procedure to remove the obsolete policies. +If a change to the `PolicyGenerator` or `PolicyGentemplate` configuration results in obsolete policies, for example, if you rename policies, use the following procedure to remove the obsolete policies. .Prerequisites @@ -16,18 +16,18 @@ If a change to the `PolicyGenTemplate` configuration results in obsolete policie .Procedure -. Remove the affected `PolicyGenTemplate` files from the Git repository, commit and push to the remote repository. +. Remove the affected `PolicyGenerator` or `PolicyGentemplate` files from the Git repository, commit and push to the remote repository. . Wait for the changes to synchronize through the application and the affected policies to be removed from the hub cluster. -. Add the updated `PolicyGenTemplate` files back to the Git repository, and then commit and push to the remote repository. +. Add the updated `PolicyGenerator` or `PolicyGentemplate` files back to the Git repository, and then commit and push to the remote repository. + [NOTE] ==== Removing {ztp-first} policies from the Git repository, and as a result also removing them from the hub cluster, does not affect the configuration of the managed cluster. The policy and CRs managed by that policy remains in place on the managed cluster. ==== -. Optional: As an alternative, after making changes to `PolicyGenTemplate` CRs that result in obsolete policies, you can remove these policies from the hub cluster manually. You can delete policies from the {rh-rhacm} console using the *Governance* tab or by running the following command: +. Optional: As an alternative, after making changes to `PolicyGenerator` or `PolicyGentemplate` CRs that result in obsolete policies, you can remove these policies from the hub cluster manually. You can delete policies from the {rh-rhacm} console using the *Governance* tab or by running the following command: + [source,terminal] ---- diff --git a/modules/ztp-required-changes-to-the-git-repository.adoc b/modules/ztp-required-changes-to-the-git-repository.adoc index ceafb63998db..451214d7f3b0 100644 --- a/modules/ztp-required-changes-to-the-git-repository.adoc +++ b/modules/ztp-required-changes-to-the-git-repository.adoc @@ -8,17 +8,22 @@ When upgrading the `ztp-site-generate` container from an earlier release of {ztp-first} to 4.10 or later, there are additional requirements for the contents of the Git repository. Existing content in the repository must be updated to reflect these changes. -* Make required changes to `PolicyGenTemplate` files: +[NOTE] +==== +The following procedure assumes you are using `PolicyGenerator` resources instead of `PolicyGentemplate` resources for cluster policies management. +==== + +* Make required changes to `PolicyGenerator` files: + -All `PolicyGenTemplate` files must be created in a `Namespace` prefixed with `ztp`. This ensures that the {ztp} application is able to manage the policy CRs generated by {ztp} without conflicting with the way {rh-rhacm-first} manages the policies internally. +All `PolicyGenerator` files must be created in a `Namespace` prefixed with `ztp`. This ensures that the {ztp} application is able to manage the policy CRs generated by {ztp} without conflicting with the way {rh-rhacm-first} manages the policies internally. * Add the `kustomization.yaml` file to the repository: + -All `SiteConfig` and `PolicyGenTemplate` CRs must be included in a `kustomization.yaml` file under their respective directory trees. For example: +All `SiteConfig` and `PolicyGenerator` CRs must be included in a `kustomization.yaml` file under their respective directory trees. For example: + [source,terminal] ---- -├── policygentemplates +├── acmpolicygenerator │ ├── site1-ns.yaml │ ├── site1.yaml │ ├── site2-ns.yaml @@ -36,10 +41,10 @@ All `SiteConfig` and `PolicyGenTemplate` CRs must be included in a `kustomizatio + [NOTE] ==== -The files listed in the `generator` sections must contain either `SiteConfig` or `PolicyGenTemplate` CRs only. If your existing YAML files contain other CRs, for example, `Namespace`, these other CRs must be pulled out into separate files and listed in the `resources` section. +The files listed in the `generator` sections must contain either `SiteConfig` or `{policy-gen-cr}` CRs only. If your existing YAML files contain other CRs, for example, `Namespace`, these other CRs must be pulled out into separate files and listed in the `resources` section. ==== + -The `PolicyGenTemplate` kustomization file must contain all `PolicyGenTemplate` YAML files in the `generator` section and `Namespace` CRs in the `resources` section. For example: +The `PolicyGenerator` kustomization file must contain all `PolicyGenerator` YAML files in the `generator` section and `Namespace` CRs in the `resources` section. For example: + [source,yaml] ---- @@ -47,14 +52,14 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization generators: -- common-ranGen.yaml -- group-du-sno-ranGen.yaml +- acm-common-ranGen.yaml +- acm-group-du-sno-ranGen.yaml - site1.yaml - site2.yaml resources: - common-ns.yaml -- group-du-sno-ranGen-ns.yaml +- acm-group-du-sno-ranGen-ns.yaml - site1-ns.yaml - site2-ns.yaml ---- @@ -77,11 +82,11 @@ In {product-title} 4.10 and later, the `pre-sync.yaml` and `post-sync.yaml` file + [NOTE] ==== -There is a set of `pre-sync.yaml` and `post-sync.yaml` files under both the `SiteConfig` and `PolicyGenTemplate` trees. +There is a set of `pre-sync.yaml` and `post-sync.yaml` files under both the `SiteConfig` and `{policy-gen-cr}` trees. ==== * Review and incorporate recommended changes + Each release may include additional recommended changes to the configuration applied to deployed clusters. Typically these changes result in lower CPU use by the OpenShift platform, additional features, or improved tuning of the platform. + -Review the reference `SiteConfig` and `PolicyGenTemplate` CRs applicable to the types of cluster in your network. These examples can be found in the `argocd/example` directory extracted from the {ztp} container. +Review the reference `SiteConfig` and `PolicyGenerator` CRs applicable to the types of cluster in your network. These examples can be found in the `argocd/example` directory extracted from the {ztp} container. diff --git a/modules/ztp-restarting-policies-reconciliation.adoc b/modules/ztp-restarting-policies-reconciliation.adoc index bf041b2ad7af..5cbc3faa45b4 100644 --- a/modules/ztp-restarting-policies-reconciliation.adoc +++ b/modules/ztp-restarting-policies-reconciliation.adoc @@ -36,6 +36,6 @@ $ oc get clustergroupupgrades -n ztp-install $CLUSTER -o jsonpath='{.status.cond $ oc delete clustergroupupgrades -n ztp-install $CLUSTER ---- -Note that when the `ClusterGroupUpgrade` CR completes with status `UpgradeCompleted` and the managed cluster has the label `ztp-done` applied, you can make additional configuration changes using `PolicyGenTemplate`. Deleting the existing `ClusterGroupUpgrade` CR will not make the {cgu-operator} generate a new CR. +Note that when the `ClusterGroupUpgrade` CR completes with status `UpgradeCompleted` and the managed cluster has the label `ztp-done` applied, you can make additional configuration changes by using `{policy-gen-cr}`. Deleting the existing `ClusterGroupUpgrade` CR will not make the {cgu-operator} generate a new CR. At this point, {ztp} has completed its interaction with the cluster and any further interactions should be treated as an update and a new `ClusterGroupUpgrade` CR created for remediation of the policies. diff --git a/modules/ztp-site-cleanup.adoc b/modules/ztp-site-cleanup.adoc index 3008d64a123a..f25a990d9fd8 100644 --- a/modules/ztp-site-cleanup.adoc +++ b/modules/ztp-site-cleanup.adoc @@ -16,10 +16,10 @@ You can remove a managed site and the associated installation and configuration .Procedure -. Remove a site and the associated CRs by removing the associated `SiteConfig` and `PolicyGenTemplate` files from the `kustomization.yaml` file. +. Remove a site and the associated CRs by removing the associated `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` files from the `kustomization.yaml` file. + When you run the {ztp} pipeline again, the generated CRs are removed. -. Optional: If you want to permanently remove a site, you should also remove the `SiteConfig` and site-specific `PolicyGenTemplate` files from the Git repository. +. Optional: If you want to permanently remove a site, you should also remove the `SiteConfig` and site-specific `PolicyGenerator` or `PolicyGentemplate` files from the Git repository. -. Optional: If you want to remove a site temporarily, for example when redeploying a site, you can leave the `SiteConfig` and site-specific `PolicyGenTemplate` CRs in the Git repository. +. Optional: If you want to remove a site temporarily, for example when redeploying a site, you can leave the `SiteConfig` and site-specific `PolicyGenerator` or `PolicyGentemplate` CRs in the Git repository. diff --git a/modules/ztp-sno-siteconfig-config-reference.adoc b/modules/ztp-sno-siteconfig-config-reference.adoc index c7f403ca5ba0..ba459f2cf519 100644 --- a/modules/ztp-sno-siteconfig-config-reference.adoc +++ b/modules/ztp-sno-siteconfig-config-reference.adoc @@ -40,8 +40,11 @@ Adding additional components back into the system might require additional reser |Specifies the cluster image set used to deploy an individual cluster. If defined, it overrides the `spec.clusterImageSetNameRef` at site level. |`spec.clusters.clusterLabels` -|Configure cluster labels to correspond to the `bindingRules` field in the `PolicyGenTemplate` CRs that you define. -For example, `policygentemplates/common-ranGen.yaml` applies to all clusters with `common: true` set, `policygentemplates/group-du-sno-ranGen.yaml` applies to all clusters with `group-du-sno: ""` set. +|Configure cluster labels to correspond to the binding rules in the `PolicyGenerator` or `PolicyGentemplate` CRs that you define. +`PolicyGenerator` CRs use the `policyDefaults.placement.labelSelector` field. +`PolicyGentemplate` CRs use the `spec.bindingRules` field. + +For example, `acmpolicygenerator/acm-common-ranGen.yaml` applies to all clusters with `common: true` set, `acmpolicygenerator/acm-group-du-sno-ranGen.yaml` applies to all clusters with `group-du-sno: ""` set. |`spec.clusters.crTemplates.KlusterletAddonConfig` |Optional. Set `KlusterletAddonConfig` to `KlusterletAddonConfigOverride.yaml to override the default `KlusterletAddonConfig` that is created for the cluster. diff --git a/modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc b/modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc index ec4e6831aa3f..54fed2d18044 100644 --- a/modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc +++ b/modules/ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates.adoc @@ -4,16 +4,16 @@ :_mod-docs-content-type: PROCEDURE [id="ztp-specifying-nics-in-pgt-crs-with-hub-cluster-templates_{context}"] -= Specifying group and site configuration in group PolicyGenTemplate CRs with hub templates += Specifying group and site configurations in group PolicyGenerator or PolicyGentemplate CRs You can manage the configuration of fleets of clusters with `ConfigMap` CRs by using hub templates to populate the group and site values in the generated policies that get applied to the managed clusters. -Using hub templates in site `PolicyGenTemplate` (PGT) CRs means that you do not need to create a `PolicyGenTemplate` CR for each site. +Using hub templates in site `PolicyGenerator` or `PolicyGentemplate` CRs means that you do not need to create a policy CR for each site. You can group the clusters in a fleet in various categories, depending on the use case, for example hardware type or region. Each cluster should have a label corresponding to the group or groups that the cluster is in. -If you manage the configuration values for each group in different `ConfigMap` CRs, then you require only one group `PolicyGenTemplate` CR to apply the changes to all the clusters in the group by using hub templates. +If you manage the configuration values for each group in different `ConfigMap` CRs, then you require only one group policy CR to apply the changes to all the clusters in the group by using hub templates. -The following example shows you how to use three `ConfigMap` CRs and one group `PolicyGenTemplate` CR to apply both site and group configuration to clusters grouped by hardware type and region. +The following example shows you how to use three `ConfigMap` CRs and one `PolicyGenerator` CR to apply both site and group configuration to clusters grouped by hardware type and region. [NOTE] ==== @@ -91,7 +91,7 @@ data: + [NOTE] ==== -Each `ConfigMap` CR must be in the same namespace as the policy to be generated from the group `PolicyGenTemplate` CR. +Each `ConfigMap` CR must be in the same namespace as the policy to be generated from the group `PolicyGenerator` CR. ==== . Commit the `ConfigMap` CRs in Git, and then push to the Git repository being monitored by the Argo CD application. @@ -104,109 +104,43 @@ The following command applies to a single cluster named `du-sno-1-zone-1` and th $ oc patch managedclusters.cluster.open-cluster-management.io/du-sno-1-zone-1 --type merge -p '{"metadata":{"labels":{"hardware-type": "hardware-type-1", "group-du-sno-zone": "zone-1"}}}' ---- -. Create a group `PolicyGenTemplate` CR that uses hub templates to obtain the required data from the `ConfigMap` objects. +. Depending on your requirements, Create a group `PolicyGenerator` or `PolicyGentemplate` CR that uses hub templates to obtain the required data from the `ConfigMap` objects: ++ +-- +.. Create a group `PolicyGenerator` CR. +This example `PolicyGenerator` CR configures logging, VLAN IDs, NICs and Performance Profile for the clusters that match the labels listed the under `policyDefaults.placement` field: ++ +[source,yaml] +---- +include::snippets/pg-ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml[] +---- + +.. Create a group `PolicyGenTemplate` CR. This example `PolicyGenTemplate` CR configures logging, VLAN IDs, NICs and Performance Profile for the clusters that match the labels listed under `spec.bindingRules`: + [source,yaml] ---- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: group-du-sno-pgt - namespace: ztp-group -spec: - bindingRules: - # These policies will correspond to all clusters with these labels - group-du-sno-zone: "zone-1" - hardware-type: "hardware-type-1" - mcp: "master" - sourceFiles: - - fileName: ClusterLogForwarder.yaml # wave 10 - policyName: "group-du-sno-cfg-policy" - spec: - outputs: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-outputs" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' - pipelines: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-pipelines" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' - - - fileName: PerformanceProfile.yaml # wave 10 - policyName: "group-du-sno-cfg-policy" - metadata: - name: openshift-node-performance-profile - spec: - additionalKernelArgs: - - rcupdate.rcu_normal_after_boot=0 - - vfio_pci.enable_sriov=1 - - vfio_pci.disable_idle_d3=1 - - efi=runtime - cpu: - isolated: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-isolated" (index .ManagedClusterLabels "hardware-type")) hub}}' - reserved: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-reserved" (index .ManagedClusterLabels "hardware-type")) hub}}' - hugepages: - defaultHugepagesSize: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-default" (index .ManagedClusterLabels "hardware-type")) hub}}' - pages: - - size: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-size" (index .ManagedClusterLabels "hardware-type")) hub}}' - count: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-count" (index .ManagedClusterLabels "hardware-type")) | toInt hub}}' - realTimeKernel: - enabled: true - - - fileName: SriovNetwork.yaml # wave 100 - policyName: "group-du-sno-sriov-policy" - metadata: - name: sriov-nw-du-fh - spec: - resourceName: du_fh - vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-1" .ManagedClusterName) | toInt hub}}' - - - fileName: SriovNetworkNodePolicy.yaml # wave 100 - policyName: "group-du-sno-sriov-policy" - metadata: - name: sriov-nnp-du-fh - spec: - deviceType: netdevice - isRdma: false - nicSelector: - pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-1" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' - numVfs: 8 - priority: 10 - resourceName: du_fh - - - fileName: SriovNetwork.yaml # wave 100 - policyName: "group-du-sno-sriov-policy" - metadata: - name: sriov-nw-du-mh - spec: - resourceName: du_mh - vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-2" .ManagedClusterName) | toInt hub}}' - - - fileName: SriovNetworkNodePolicy.yaml # wave 100 - policyName: "group-du-sno-sriov-policy" - metadata: - name: sriov-nw-du-fh - spec: - deviceType: netdevice - isRdma: false - nicSelector: - pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-2" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' - numVfs: 8 - priority: 10 - resourceName: du_fh +include::snippets/ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml[] ---- +-- + + [NOTE] ==== -To retrieve site-specific configuration values, use the `.ManagedClusterName` field. +To retrieve site-specific configuration values, use the `.ManagedClusterName` field. This is a template context value set to the name of the target managed cluster. -To retrieve group-specific configuration, use the `.ManagedClusterLabels` field. +To retrieve group-specific configuration, use the `.ManagedClusterLabels` field. This is a template context value set to the value of the managed cluster's labels. ==== -. Commit the site `PolicyGenTemplate` CR in Git and push to the Git repository that is monitored by the ArgoCD application. +. Commit the site `PolicyGenerator` or `PolicyGentemplate` CR in Git and push to the Git repository that is monitored by the ArgoCD application. + [NOTE] ==== Subsequent changes to the referenced `ConfigMap` CR are not automatically synced to the applied policies. -You need to manually sync the new `ConfigMap` changes to update existing `PolicyGenTemplate` CRs. See "Syncing new ConfigMap changes to existing PolicyGenTemplate CRs". +You need to manually sync the new `ConfigMap` changes to update existing `PolicyGenerator` CRs. See "Syncing new ConfigMap changes to existing PolicyGenerator or PolicyGenTemplate CRs". -You can use the same `PolicyGenTemplate` CR for multiple clusters. +You can use the same `PolicyGenerator` or `PolicyGentemplate` CR for multiple clusters. If there is a configuration change, then the only modifications you need to make are to the `ConfigMap` objects that hold the configuration for each cluster and the labels of the managed clusters. ==== diff --git a/modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc b/modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc index 88ea45d380a5..b1791df016c1 100644 --- a/modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc +++ b/modules/ztp-syncing-new-configmap-changes-to-existing-pgt-crs.adoc @@ -1,10 +1,10 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-using-hub-cluster-templates.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-syncing-new-configmap-changes-to-existing-pgt-crs_{context}"] -= Syncing new ConfigMap changes to existing PolicyGenTemplate CRs += Syncing new ConfigMap changes to existing PolicyGenerator or PolicyGentemplate CRs .Prerequisites @@ -12,7 +12,7 @@ * You have logged in to the hub cluster as a user with `cluster-admin` privileges. -* You have created a `PolicyGenTemplate` CR that pulls information from a `ConfigMap` CR using hub cluster templates. +* You have created a `PolicyGenerator` or `PolicyGentemplate` CR that pulls information from a `ConfigMap` CR using hub cluster templates. .Procedure @@ -20,7 +20,7 @@ . To sync the contents of the updated `ConfigMap` CR to the deployed policy, do either of the following: -.. Option 1: Delete the existing policy. ArgoCD uses the `PolicyGenTemplate` CR to immediately recreate the deleted policy. For example, run the following command: +.. Option 1: Delete the existing policy. ArgoCD uses the `PolicyGenerator` or `PolicyGentemplate` CR to immediately recreate the deleted policy. For example, run the following command: + [source,terminal] ---- diff --git a/modules/ztp-talo-integration.adoc b/modules/ztp-talo-integration.adoc index 05ba8bcb5de6..f5c3fcb74822 100644 --- a/modules/ztp-talo-integration.adoc +++ b/modules/ztp-talo-integration.adoc @@ -25,11 +25,11 @@ To automate the initial configuration of newly deployed clusters, {cgu-operator} The automatic creation of an enabled `ClusterGroupUpgrade` ensures that initial zero-touch deployment of clusters proceeds without the need for user intervention. Additionally, the automatic creation of a `ClusterGroupUpgrade` CR for any `ManagedCluster` without the `ztp-done` label allows a failed {ztp} installation to be restarted by simply deleting the `ClusterGroupUpgrade` CR for the cluster. Waves:: -Each policy generated from a `PolicyGenTemplate` CR includes a `ztp-deploy-wave` annotation. This annotation is based on the same annotation from each CR which is included in that policy. The wave annotation is used to order the policies in the auto-generated `ClusterGroupUpgrade` CR. The wave annotation is not used other than for the auto-generated `ClusterGroupUpgrade` CR. +Each policy generated from a `PolicyGenerator` or `PolicyGentemplate` CR includes a `ztp-deploy-wave` annotation. This annotation is based on the same annotation from each CR which is included in that policy. The wave annotation is used to order the policies in the auto-generated `ClusterGroupUpgrade` CR. The wave annotation is not used other than for the auto-generated `ClusterGroupUpgrade` CR. + [NOTE] ==== -All CRs in the same policy must have the same setting for the `ztp-deploy-wave` annotation. The default value of this annotation for each CR can be overridden in the `PolicyGenTemplate`. The wave annotation in the source CR is used for determining and setting the policy wave annotation. This annotation is removed from each built CR which is included in the generated policy at runtime. +All CRs in the same policy must have the same setting for the `ztp-deploy-wave` annotation. The default value of this annotation for each CR can be overridden in the `PolicyGenerator` or `PolicyGentemplate`. The wave annotation in the source CR is used for determining and setting the policy wave annotation. This annotation is removed from each built CR which is included in the generated policy at runtime. ==== + The {cgu-operator} applies the configuration policies in the order specified by the wave annotations. The {cgu-operator} waits for each policy to be compliant before moving to the next policy. It is important to ensure that the wave annotation for each CR takes into account any prerequisites for those CRs to be applied to the cluster. For example, an Operator must be installed before or concurrently with the configuration for the Operator. Similarly, the `CatalogSource` for an Operator must be installed in a wave before or concurrently with the Operator Subscription. The default wave value for each CR takes these prerequisites into account. diff --git a/modules/ztp-the-policygentemplate.adoc b/modules/ztp-the-policygentemplate.adoc index d16c4838849b..a1e141a1d93a 100644 --- a/modules/ztp-the-policygentemplate.adoc +++ b/modules/ztp-the-policygentemplate.adoc @@ -4,106 +4,30 @@ :_mod-docs-content-type: REFERENCE [id="ztp-the-policygentemplate_{context}"] -= About the PolicyGenTemplate CRD += About the {policy-gen-cr} CRD -The `PolicyGenTemplate` custom resource definition (CRD) tells the `PolicyGen` policy generator what custom resources (CRs) to include in the cluster configuration, how to combine the CRs into the generated policies, and what items in those CRs need to be updated with overlay content. +The `{policy-gen-cr}` custom resource definition (CRD) tells the `PolicyGen` policy generator what custom resources (CRs) to include in the cluster configuration, how to combine the CRs into the generated policies, and what items in those CRs need to be updated with overlay content. -The following example shows a `PolicyGenTemplate` CR (`common-du-ranGen.yaml`) extracted from the `ztp-site-generate` reference container. The `common-du-ranGen.yaml` file defines two {rh-rhacm-first} policies. The polices manage a collection of configuration CRs, one for each unique value of `policyName` in the CR. `common-du-ranGen.yaml` creates a single placement binding and a placement rule to bind the policies to clusters based on the labels listed in the `bindingRules` section. +The following example shows a `{policy-gen-cr}` CR (`{policy-prefix}common-du-ranGen.yaml`) extracted from the `ztp-site-generate` reference container. The `{policy-prefix}common-du-ranGen.yaml` file defines two {rh-rhacm-first} policies. The polices manage a collection of configuration CRs, one for each unique value of `policyName` in the CR. `{policy-prefix}common-du-ranGen.yaml` creates a single placement binding and a placement rule to bind the policies to clusters based on the labels listed in the `{binding-field}` section. -.Example PolicyGenTemplate CR - common-du-ranGen.yaml -[source,yaml] ----- ---- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "common" - namespace: "ztp-common" -spec: - bindingRules: - common: "true" <1> - sourceFiles: <2> - - fileName: SriovSubscription.yaml - policyName: "subscriptions-policy" - - fileName: SriovSubscriptionNS.yaml - policyName: "subscriptions-policy" - - fileName: SriovSubscriptionOperGroup.yaml - policyName: "subscriptions-policy" - - fileName: SriovOperatorStatus.yaml - policyName: "subscriptions-policy" - - fileName: PtpSubscription.yaml - policyName: "subscriptions-policy" - - fileName: PtpSubscriptionNS.yaml - policyName: "subscriptions-policy" - - fileName: PtpSubscriptionOperGroup.yaml - policyName: "subscriptions-policy" - - fileName: PtpOperatorStatus.yaml - policyName: "subscriptions-policy" - - fileName: ClusterLogNS.yaml - policyName: "subscriptions-policy" - - fileName: ClusterLogOperGroup.yaml - policyName: "subscriptions-policy" - - fileName: ClusterLogSubscription.yaml - policyName: "subscriptions-policy" - - fileName: ClusterLogOperatorStatus.yaml - policyName: "subscriptions-policy" - - fileName: StorageNS.yaml - policyName: "subscriptions-policy" - - fileName: StorageOperGroup.yaml - policyName: "subscriptions-policy" - - fileName: StorageSubscription.yaml - policyName: "subscriptions-policy" - - fileName: StorageOperatorStatus.yaml - policyName: "subscriptions-policy" - - fileName: ReduceMonitoringFootprint.yaml - policyName: "config-policy" - - fileName: OperatorHub.yaml <3> - policyName: "config-policy" - - fileName: DefaultCatsrc.yaml <4> - policyName: "config-policy" <5> - metadata: - name: redhat-operators - spec: - displayName: disconnected-redhat-operators - image: registry.example.com:5000/disconnected-redhat-operators/disconnected-redhat-operator-index:v4.9 - - fileName: DisconnectedICSP.yaml - policyName: "config-policy" - spec: - repositoryDigestMirrors: - - mirrors: - - registry.example.com:5000 - source: registry.redhat.io ----- -<1> `common: "true"` applies the policies to all clusters with this label. -<2> Files listed under `sourceFiles` create the Operator policies for installed clusters. -<3> `OperatorHub.yaml` configures the OperatorHub for the disconnected registry. -<4> `DefaultCatsrc.yaml` configures the catalog source for the disconnected registry. -<5> `policyName: "config-policy"` configures Operator subscriptions. The `OperatorHub` CR disables the default and this CR replaces `redhat-operators` with a `CatalogSource` CR that points to the disconnected registry. +.Example {policy-gen-cr} CR - {policy-prefix}common-ranGen.yaml +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-the-policygentemplate.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-the-policygenerator.adoc[] +endif::[] -A `PolicyGenTemplate` CR can be constructed with any number of included CRs. Apply the following example CR in the hub cluster to generate a policy containing a single CR: +A `{policy-gen-cr}` CR can be constructed with any number of included CRs. Apply the following example CR in the hub cluster to generate a policy containing a single CR: [source,yaml] ---- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "group-du-sno" - namespace: "ztp-group" -spec: - bindingRules: - group-du-sno: "" - mcp: "master" - sourceFiles: - - fileName: PtpConfigSlave.yaml - policyName: "config-policy" - metadata: - name: "du-ptp-slave" - spec: - profile: - - name: "slave" - interface: "ens5f0" - ptp4lOpts: "-2 -s --summary_interval -4" - phc2sysOpts: "-a -r -n 24" +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/ztp-the-policygentemplate-single.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/ztp-the-policygenerator-single.yaml[] +endif::[] ---- Using the source file `PtpConfigSlave.yaml` as an example, the file defines a `PtpConfig` CR. The generated policy for the `PtpConfigSlave` example is named `group-du-sno-config-policy`. The `PtpConfig` CR defined in the generated `group-du-sno-config-policy` is named `du-ptp-slave`. The `spec` defined in `PtpConfigSlave.yaml` is placed under `du-ptp-slave` along with the other `spec` items defined under the source file. @@ -112,59 +36,10 @@ The following example shows the `group-du-sno-config-policy` CR: [source,yaml] ---- -apiVersion: policy.open-cluster-management.io/v1 -kind: Policy -metadata: - name: group-du-ptp-config-policy - namespace: groups-sub - annotations: - policy.open-cluster-management.io/categories: CM Configuration Management - policy.open-cluster-management.io/controls: CM-2 Baseline Configuration - policy.open-cluster-management.io/standards: NIST SP 800-53 -spec: - remediationAction: inform - disabled: false - policy-templates: - - objectDefinition: - apiVersion: policy.open-cluster-management.io/v1 - kind: ConfigurationPolicy - metadata: - name: group-du-ptp-config-policy-config - spec: - remediationAction: inform - severity: low - namespaceselector: - exclude: - - kube-* - include: - - '*' - object-templates: - - complianceType: musthave - objectDefinition: - apiVersion: ptp.openshift.io/v1 - kind: PtpConfig - metadata: - name: du-ptp-slave - namespace: openshift-ptp - spec: - recommend: - - match: - - nodeLabel: node-role.kubernetes.io/worker-du - priority: 4 - profile: slave - profile: - - interface: ens5f0 - name: slave - phc2sysOpts: -a -r -n 24 - ptp4lConf: | - [global] - # - # Default Data Set - # - twoStepFlag 1 - slaveOnly 0 - priority1 128 - priority2 128 - domainNumber 24 - ..... +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-group-du-sno-config-policy.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-group-du-sno-config-policy.yaml[] +endif::[] ---- diff --git a/modules/ztp-troubleshooting-ztp-gitops-installation-crs.adoc b/modules/ztp-troubleshooting-ztp-gitops-installation-crs.adoc index 5c2a8f1511ba..729631cde561 100644 --- a/modules/ztp-troubleshooting-ztp-gitops-installation-crs.adoc +++ b/modules/ztp-troubleshooting-ztp-gitops-installation-crs.adoc @@ -6,7 +6,7 @@ [id="ztp-troubleshooting-ztp-gitops-installation-crs_{context}"] = Troubleshooting {ztp} by validating the installation CRs -The ArgoCD pipeline uses the `SiteConfig` and `PolicyGenTemplate` custom resources (CRs) to generate the cluster configuration CRs and {rh-rhacm-first} policies. Use the following steps to troubleshoot issues that might occur during this process. +The ArgoCD pipeline uses the `SiteConfig` and `PolicyGenerator` or `PolicyGentemplate` custom resources (CRs) to generate the cluster configuration CRs and {rh-rhacm-first} policies. Use the following steps to troubleshoot issues that might occur during this process. .Prerequisites diff --git a/modules/ztp-troubleshooting-ztp-gitops-supermicro-tls.adoc b/modules/ztp-troubleshooting-ztp-gitops-supermicro-tls.adoc index 557dc2c771a8..b06e5e3d8cab 100644 --- a/modules/ztp-troubleshooting-ztp-gitops-supermicro-tls.adoc +++ b/modules/ztp-troubleshooting-ztp-gitops-supermicro-tls.adoc @@ -4,7 +4,7 @@ :_mod-docs-content-type: PROCEDURE [id="ztp-troubleshooting-ztp-gitops-supermicro-tls_{context}"] -= Troubleshooting {ztp} virtual media booting on Supermicro servers += Troubleshooting {ztp} virtual media booting on SuperMicro servers SuperMicro X11 servers do not support virtual media installations when the image is served using the `https` protocol. As a result, {sno} deployments for this environment fail to boot on the target node. To avoid this issue, log in to the hub cluster and disable Transport Layer Security (TLS) in the `Provisioning` resource. This ensures the image is not served with TLS even though the image address uses the `https` scheme. diff --git a/modules/ztp-using-pgt-to-configure-high-performance-mode.adoc b/modules/ztp-using-pgt-to-configure-high-performance-mode.adoc index 3342f3148c2c..04cd3f2cb7c6 100644 --- a/modules/ztp-using-pgt-to-configure-high-performance-mode.adoc +++ b/modules/ztp-using-pgt-to-configure-high-performance-mode.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-using-pgt-to-configure-high-performance-mode_{context}"] -= Configuring high-performance mode using PolicyGenTemplate CRs += Configuring high-performance mode using {policy-gen-cr} CRs -Follow this example to set high performance mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `PolicyGenTemplate` CR in the `group-du-sno-ranGen.yaml`. +Follow this example to set high performance mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `{policy-gen-cr}` CR in the `{policy-prefix}group-du-sno-ranGen.yaml`. High performance mode provides ultra low latency at the highest power consumption. @@ -16,20 +17,16 @@ High performance mode provides ultra low latency at the highest power consumptio .Procedure -. Update the `PolicyGenTemplate` entry for `PerformanceProfile` in the `group-du-sno-ranGen.yaml` reference file in `out/argocd/example/policygentemplates` as follows to set high-performance mode. +. Update the `{policy-gen-cr}` entry for `PerformanceProfile` in the `{policy-prefix}group-du-sno-ranGen.yaml` reference file in `{argocd-folder}` as follows to set high-performance mode. + [source,yaml] ---- -- fileName: PerformanceProfile.yaml - policyName: "config-policy" - metadata: - [...] - spec: - [...] - workloadHints: - realTime: true - highPowerConsumption: true - perPodPowerManagement: false +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-using-pgt-to-configure-high-performance-mode.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-using-pg-to-configure-high-performance-mode.yaml[] +endif::[] ---- -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. diff --git a/modules/ztp-using-pgt-to-configure-performance-mode.adoc b/modules/ztp-using-pgt-to-configure-performance-mode.adoc index 00f2c942c99e..c0892bec5791 100644 --- a/modules/ztp-using-pgt-to-configure-performance-mode.adoc +++ b/modules/ztp-using-pgt-to-configure-performance-mode.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-using-pgt-to-configure-performance-mode_{context}"] -= Configuring performance mode using PolicyGenTemplate CRs += Configuring performance mode using {policy-gen-cr} CRs -Follow this example to set performance mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `PolicyGenTemplate` CR in the `group-du-sno-ranGen.yaml`. +Follow this example to set performance mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `{policy-gen-cr}` CR in the `{policy-prefix}group-du-sno-ranGen.yaml`. Performance mode provides low latency at a relatively high power consumption. @@ -16,20 +17,16 @@ Performance mode provides low latency at a relatively high power consumption. .Procedure -. Update the `PolicyGenTemplate` entry for `PerformanceProfile` in the `group-du-sno-ranGen.yaml` reference file in `out/argocd/example/policygentemplates` as follows to set performance mode. +. Update the `{policy-gen-cr}` entry for `PerformanceProfile` in the `{policy-prefix}group-du-sno-ranGen.yaml` reference file in `{argocd-folder}/` as follows to set performance mode. + [source,yaml] ---- -- fileName: PerformanceProfile.yaml - policyName: "config-policy" - metadata: - [...] - spec: - [...] - workloadHints: - realTime: true - highPowerConsumption: false - perPodPowerManagement: false +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-using-pgt-to-configure-performance-mode.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-using-pg-to-configure-performance-mode.yaml[] +endif::[] ---- -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. diff --git a/modules/ztp-using-pgt-to-configure-power-saving-mode.adoc b/modules/ztp-using-pgt-to-configure-power-saving-mode.adoc index a0f5b070c89d..7a369db7f0ab 100644 --- a/modules/ztp-using-pgt-to-configure-power-saving-mode.adoc +++ b/modules/ztp-using-pgt-to-configure-power-saving-mode.adoc @@ -1,12 +1,13 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-using-pgt-to-configure-power-saving-mode_{context}"] -= Configuring power saving mode using PolicyGenTemplate CRs += Configuring power saving mode using {policy-gen-cr} CRs -Follow this example to set power saving mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `PolicyGenTemplate` CR in the `group-du-sno-ranGen.yaml`. +Follow this example to set power saving mode by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `{policy-gen-cr}` CR in the `{policy-prefix}group-du-sno-ranGen.yaml`. The power saving mode balances reduced power consumption with increased latency. @@ -16,28 +17,16 @@ The power saving mode balances reduced power consumption with increased latency. .Procedure -. Update the `PolicyGenTemplate` entry for `PerformanceProfile` in the `group-du-sno-ranGen.yaml` reference file in `out/argocd/example/policygentemplates` as follows to configure power saving mode. It is recommended to configure the CPU governor for the power saving mode through the additional kernel arguments object. +. Update the `{policy-gen-cr}` entry for `PerformanceProfile` in the `{policy-prefix}group-du-sno-ranGen.yaml` reference file in `{argocd-folder}` as follows to configure power saving mode. It is recommended to configure the CPU governor for the power saving mode through the additional kernel arguments object. + -[source,yaml] ----- -- fileName: PerformanceProfile.yaml - policyName: "config-policy" - metadata: - [...] - spec: - [...] - workloadHints: - realTime: true - highPowerConsumption: false - perPodPowerManagement: true - [...] - additionalKernelArgs: - - [...] - - "cpufreq.default_governor=schedutil" <1> ----- -<1> The `schedutil` governor is recommended, however, other governors that can be used include `ondemand` and `powersave`. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-using-pgt-to-configure-power-saving-mode.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-using-pg-to-configure-power-saving-mode.adoc[] +endif::[] -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. .Verification diff --git a/modules/ztp-using-pgt-to-configure-power-states.adoc b/modules/ztp-using-pgt-to-configure-power-states.adoc index b01b8eba290d..1e7c17fab30a 100644 --- a/modules/ztp-using-pgt-to-configure-power-states.adoc +++ b/modules/ztp-using-pgt-to-configure-power-states.adoc @@ -1,11 +1,12 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: CONCEPT [id="ztp-using-pgt-to-configure-power-saving-states_{context}"] -= Configuring power states using PolicyGenTemplates CRs += Configuring power states using {policy-gen-cr} CRs For low latency and high-performance edge deployments, it is necessary to disable or limit C-states and P-states. With this configuration, the CPU runs at a constant frequency, which is typically the maximum turbo frequency. This ensures that the CPU is always running at its maximum speed, which results in high performance and low latency. @@ -20,9 +21,9 @@ Workloads can be classified as critical or non-critical, with critical workloads The default configuration is for a low latency, performance mode. -`PolicyGenTemplate` custom resources (CRs) allow you to overlay additional configuration details onto the base source CRs provided with the GitOps plugin in the `ztp-site-generate` container. +`{policy-gen-cr}` custom resources (CRs) allow you to overlay additional configuration details onto the base source CRs provided with the GitOps plugin in the `ztp-site-generate` container. -Configure the power states by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `PolicyGenTemplate` CR in the `group-du-sno-ranGen.yaml`. +Configure the power states by updating the `workloadHints` fields in the generated `PerformanceProfile` CR for the reference configuration, based on the `{policy-gen-cr}` CR in the `{policy-prefix}group-du-sno-ranGen.yaml`. The following common prerequisites apply to configuring all three power states. diff --git a/modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc b/modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc index c608944c2008..1959aece0aac 100644 --- a/modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc +++ b/modules/ztp-using-pgt-to-maximize-power-saving-mode.adoc @@ -1,6 +1,7 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-using-pgt-to-maximize-power-savings-mode_{context}"] @@ -9,34 +10,26 @@ Limiting the maximum CPU frequency is recommended to achieve maximum power savings. Enabling C-states on the non-critical workload CPUs without restricting the maximum CPU frequency negates much of the power savings by boosting the frequency of the critical CPUs. -Maximize power savings by updating the `sysfs` plugin fields, setting an appropriate value for `max_perf_pct` in the `TunedPerformancePatch` CR for the reference configuration. This example based on the `group-du-sno-ranGen.yaml` describes the procedure to follow to restrict the maximum CPU frequency. +Maximize power savings by updating the `sysfs` plugin fields, setting an appropriate value for `max_perf_pct` in the `TunedPerformancePatch` CR for the reference configuration. This example based on the `{policy-prefix}group-du-sno-ranGen.yaml` describes the procedure to follow to restrict the maximum CPU frequency. .Prerequisites -* You have configured power savings mode as described in "Using PolicyGenTemplate CRs to configure power savings mode". +* You have configured power savings mode as described in "Using {policy-gen-cr} CRs to configure power savings mode". .Procedure -. Update the `PolicyGenTemplate` entry for `TunedPerformancePatch` in the `group-du-sno-ranGen.yaml` reference file in `out/argocd/example/policygentemplates`. To maximize power savings, add `max_perf_pct` as shown in the following example: +. Update the `{policy-gen-cr}` entry for `TunedPerformancePatch` in the `{policy-prefix}group-du-sno-ranGen.yaml` reference file in `{argocd-folder}`. To maximize power savings, add `max_perf_pct` as shown in the following example: + -[source,yaml] ----- -- fileName: TunedPerformancePatch.yaml - policyName: "config-policy" - spec: - profile: - - name: performance-patch - data: | - [...] - [sysfs] - /sys/devices/system/cpu/intel_pstate/max_perf_pct= <1> ----- -+ -<1> The `max_perf_pct` controls the maximum frequency the `cpufreq` driver is allowed to set as a percentage of the maximum supported CPU frequency. This value applies to all CPUs. You can check the maximum supported frequency in `/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq`. As a starting point, you can use a percentage that caps all CPUs at the `All Cores Turbo` frequency. The `All Cores Turbo` frequency is the frequency that all cores will run at when the cores are all fully occupied. +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-using-pgt-to-maximize-power-saving-mode.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-using-pg-to-maximize-power-saving-mode.adoc[] +endif::[] + [NOTE] ==== To maximize power savings, set a lower value. Setting a lower value for `max_perf_pct` limits the maximum CPU frequency, thereby reducing power consumption, but also potentially impacting performance. Experiment with different values and monitor the system's performance and power consumption to find the optimal setting for your use-case. ==== -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} Argo CD application. diff --git a/modules/ztp-using-pgt-to-update-source-crs.adoc b/modules/ztp-using-pgt-to-update-source-crs.adoc index 33f8ffdc80f7..539752827360 100644 --- a/modules/ztp-using-pgt-to-update-source-crs.adoc +++ b/modules/ztp-using-pgt-to-update-source-crs.adoc @@ -1,14 +1,15 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_module-type: PROCEDURE [id="ztp-using-pgt-to-update-source-crs_{context}"] -= Using PolicyGenTemplate CRs to override source CRs content += Using {policy-gen-cr} CRs to override source CRs content -`PolicyGenTemplate` custom resources (CRs) allow you to overlay additional configuration details on top of the base source CRs provided with the GitOps plugin in the `ztp-site-generate` container. You can think of `PolicyGenTemplate` CRs as a logical merge or patch to the base CR. Use `PolicyGenTemplate` CRs to update a single field of the base CR, or overlay the entire contents of the base CR. You can update values and insert fields that are not in the base CR. +`{policy-gen-cr}` custom resources (CRs) allow you to overlay additional configuration details on top of the base source CRs provided with the GitOps plugin in the `ztp-site-generate` container. You can think of `{policy-gen-cr}` CRs as a logical merge or patch to the base CR. Use `{policy-gen-cr}` CRs to update a single field of the base CR, or overlay the entire contents of the base CR. You can update values and insert fields that are not in the base CR. -The following example procedure describes how to update fields in the generated `PerformanceProfile` CR for the reference configuration based on the `PolicyGenTemplate` CR in the `group-du-sno-ranGen.yaml` file. Use the procedure as a basis for modifying other parts of the `PolicyGenTemplate` based on your requirements. +The following example procedure describes how to update fields in the generated `PerformanceProfile` CR for the reference configuration based on the `{policy-gen-cr}` CR in the `{policy-prefix}group-du-sno-ranGen.yaml` file. Use the procedure as a basis for modifying other parts of the `{policy-gen-cr}` based on your requirements. .Prerequisites @@ -16,7 +17,7 @@ The following example procedure describes how to update fields in the generated .Procedure -. Review the baseline source CR for existing content. You can review the source CRs listed in the reference `PolicyGenTemplate` CRs by extracting them from the {ztp-first} container. +. Review the baseline source CR for existing content. You can review the source CRs listed in the reference `{policy-gen-cr}` CRs by extracting them from the {ztp-first} container. .. Create an `/out` folder: + @@ -69,37 +70,26 @@ spec: + [NOTE] ==== -Any fields in the source CR which contain `$...` are removed from the generated CR if they are not provided in the `PolicyGenTemplate` CR. +Any fields in the source CR which contain `$...` are removed from the generated CR if they are not provided in the `{policy-gen-cr}` CR. ==== -. Update the `PolicyGenTemplate` entry for `PerformanceProfile` in the `group-du-sno-ranGen.yaml` reference file. The following example `PolicyGenTemplate` CR stanza supplies appropriate CPU specifications, sets the `hugepages` configuration, and adds a new field that sets `globallyDisableIrqLoadBalancing` to false. +. Update the `{policy-gen-cr}` entry for `PerformanceProfile` in the `{policy-prefix}group-du-sno-ranGen.yaml` reference file. The following example `{policy-gen-cr}` CR stanza supplies appropriate CPU specifications, sets the `hugepages` configuration, and adds a new field that sets `globallyDisableIrqLoadBalancing` to false. + [source,yaml] ---- -- fileName: PerformanceProfile.yaml - policyName: "config-policy" - metadata: - name: openshift-node-performance-profile - spec: - cpu: - # These must be tailored for the specific hardware platform - isolated: "2-19,22-39" - reserved: "0-1,20-21" - hugepages: - defaultHugepagesSize: 1G - pages: - - size: 1G - count: 10 - globallyDisableIrqLoadBalancing: false +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-using-ztp-to-update-source-crs.yaml[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-using-ztp-to-update-source-crs.yaml[] +endif::[] ---- -. Commit the `PolicyGenTemplate` change in Git, and then push to the Git repository being monitored by the {ztp} argo CD application. - - +. Commit the `{policy-gen-cr}` change in Git, and then push to the Git repository being monitored by the {ztp} argo CD application. ++ .Example output - -The {ztp} application generates an {rh-rhacm} policy that contains the generated `PerformanceProfile` CR. The contents of that CR are derived by merging the `metadata` and `spec` contents from the `PerformanceProfile` entry in the `PolicyGenTemplate` onto the source CR. The resulting CR has the following content: - +The {ztp} application generates an {rh-rhacm} policy that contains the generated `PerformanceProfile` CR. The contents of that CR are derived by merging the `metadata` and `spec` contents from the `PerformanceProfile` entry in the `{policy-gen-cr}` onto the source CR. The resulting CR has the following content: ++ [source,yaml] ---- --- @@ -134,9 +124,9 @@ spec: [NOTE] ==== -In the `/source-crs` folder that you extract from the `ztp-site-generate` container, the `$` syntax is not used for template substitution as implied by the syntax. Rather, if the `policyGen` tool sees the `$` prefix for a string and you do not specify a value for that field in the related `PolicyGenTemplate` CR, the field is omitted from the output CR entirely. +In the `/source-crs` folder that you extract from the `ztp-site-generate` container, the `$` syntax is not used for template substitution as implied by the syntax. Rather, if the `policyGen` tool sees the `$` prefix for a string and you do not specify a value for that field in the related `{policy-gen-cr}` CR, the field is omitted from the output CR entirely. -An exception to this is the `$mcp` variable in `/source-crs` YAML files that is substituted with the specified value for `mcp` from the `PolicyGenTemplate` CR. For example, in `example/policygentemplates/group-du-standard-ranGen.yaml`, the value for `mcp` is `worker`: +An exception to this is the `$mcp` variable in `/source-crs` YAML files that is substituted with the specified value for `mcp` from the `{policy-gen-cr}` CR. For example, in `example/policygentemplates/{policy-prefix}group-du-standard-ranGen.yaml`, the value for `mcp` is `worker`: [source,yaml] ---- diff --git a/modules/ztp-using-hub-cluster-templates.adoc b/modules/ztp-using-rhacm-hub-cluster-templates.adoc similarity index 79% rename from modules/ztp-using-hub-cluster-templates.adoc rename to modules/ztp-using-rhacm-hub-cluster-templates.adoc index ca34dbcaf466..8b6375d5929c 100644 --- a/modules/ztp-using-hub-cluster-templates.adoc +++ b/modules/ztp-using-rhacm-hub-cluster-templates.adoc @@ -1,22 +1,14 @@ // Module included in the following assemblies: // -// * scalability_and_performance/ztp_far_edge/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policy-config.adoc +// * edge_computing/ztp-advanced-policygenerator-config.adoc :_mod-docs-content-type: CONCEPT -[id="ztp-using-hub-cluster-templates_{context}"] -= Using hub templates in PolicyGenTemplate CRs +[id="ztp-using-rhacm-hub-cluster-templates_{context}"] += Using {rh-rhacm} hub cluster templates in configuration policies {cgu-operator-full} supports partial {rh-rhacm-first} hub cluster template functions in configuration policies used with {ztp-first}. -Hub-side cluster templates allow you to define configuration policies that can be dynamically customized to the target clusters. -This reduces the need to create separate policies for many clusters with similiar configurations but with different values. - -[IMPORTANT] -==== -Policy templates are restricted to the same namespace as the namespace where the policy is defined. -This means that you must create the objects referenced in the hub template in the same namespace where the policy is created. -==== - The following supported hub template functions are available for use in {ztp} with {cgu-operator}: * link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.6/html-single/governance/index#fromConfigmap-func[`fromConfigmap`] returns the value of the provided data key in the named `ConfigMap` resource. diff --git a/modules/ztp-validating-the-generation-of-configuration-policy-crs.adoc b/modules/ztp-validating-the-generation-of-configuration-policy-crs.adoc index e347474018a3..ddd2fb87570f 100644 --- a/modules/ztp-validating-the-generation-of-configuration-policy-crs.adoc +++ b/modules/ztp-validating-the-generation-of-configuration-policy-crs.adoc @@ -6,7 +6,7 @@ [id="ztp-validating-the-generation-of-configuration-policy-crs_{context}"] = Validating the generation of configuration policy CRs -Policy custom resources (CRs) are generated in the same namespace as the `PolicyGenTemplate` from which they are created. The same troubleshooting flow applies to all policy CRs generated from a `PolicyGenTemplate` regardless of whether they are `ztp-common`, `ztp-group`, or `ztp-site` based, as shown using the following commands: +`Policy` custom resources (CRs) are generated in the same namespace as the `{policy-gen-cr}` from which they are created. The same troubleshooting flow applies to all policy CRs generated from a `{policy-gen-cr}` regardless of whether they are `ztp-common`, `ztp-group`, or `ztp-site` based, as shown using the following commands: [source,terminal] ---- @@ -31,7 +31,7 @@ If the policies failed synchronization, use the following troubleshooting steps. $ oc describe -n openshift-gitops application policies ---- -. Check for `Status: Conditions:` to show the error logs. For example, setting an invalid `sourceFile→fileName:` generates the error shown below: +. Check for `Status: Conditions:` to show the error logs. For example, setting an invalid `sourceFile` entry to `fileName:` generates the error shown below: + [source,text] ---- @@ -74,37 +74,37 @@ NAME REMEDIATION ACTION COMPLIANCE STA ztp-common.common-config-policy inform Compliant 13d ztp-common.common-subscriptions-policy inform Compliant 13d ztp-group.group-du-sno-config-policy inform Compliant 13d -Ztp-group.group-du-sno-validator-du-policy inform Compliant 13d +ztp-group.group-du-sno-validator-du-policy inform Compliant 13d ztp-site.example-sno-config-policy inform Compliant 13d ---- + -{rh-rhacm} copies all applicable policies into the cluster namespace. The copied policy names have the format: `.-`. +{rh-rhacm} copies all applicable policies into the cluster namespace. The copied policy names have the format: `<{policy-gen-cr}.Namespace>.<{policy-gen-cr}.Name>-`. -. Check the placement rule for any policies not copied to the cluster namespace. The `matchSelector` in the `PlacementRule` for those policies should match labels on the `ManagedCluster` object: +. Check the placement rule for any policies not copied to the cluster namespace. The `matchSelector` in the `{placement-rule-cr}` for those policies should match labels on the `ManagedCluster` object: + -[source,terminal] +[source,terminal,subs="attributes+"] ---- -$ oc get placementrule -n $NS +$ oc get {placement-rule-cr} -n $NS ---- -. Note the `PlacementRule` name appropriate for the missing policy, common, group, or site, using the following command: +. Note the `{placement-rule-cr}` name appropriate for the missing policy, common, group, or site, using the following command: + -[source,terminal] +[source,terminal,subs="attributes+"] ---- -$ oc get placementrule -n $NS -o yaml +$ oc get {placement-rule-cr} -n $NS -o yaml ---- + * The status-decisions should include your cluster name. * The key-value pair of the `matchSelector` in the spec must match the labels on your managed cluster. -. Check the labels on the `ManagedCluster` object using the following command: +. Check the labels on the `ManagedCluster` object by using the following command: + [source,terminal] ---- $ oc get ManagedCluster $CLUSTER -o jsonpath='{.metadata.labels}' | jq ---- -. Check to see which policies are compliant using the following command: +. Check to see what policies are compliant by using the following command: + [source,terminal] ---- diff --git a/modules/ztp-worker-node-applying-du-profile.adoc b/modules/ztp-worker-node-applying-du-profile.adoc index 825f4bc032b9..a12446e2c923 100644 --- a/modules/ztp-worker-node-applying-du-profile.adoc +++ b/modules/ztp-worker-node-applying-du-profile.adoc @@ -4,12 +4,20 @@ :_mod-docs-content-type: CONCEPT [id="ztp-additional-worker-apply-du-profile_{context}"] -= Applying profiles to the worker node += Applying profiles to the worker node with PolicyGenerator or PolicyGenTemplate resources You can configure the additional worker node with a DU profile. -You can apply a RAN distributed unit (DU) profile to the worker node cluster using the {ztp-first} common, group, and site-specific `PolicyGenTemplate` resources. The {ztp} pipeline that is linked to the ArgoCD `policies` application includes the following CRs that you can find in the `out/argocd/example/policygentemplates` folder when you extract the `ztp-site-generate` container: +You can apply a RAN distributed unit (DU) profile to the worker node cluster using the {ztp-first} common, group, and site-specific `PolicyGenerator` or `PolicyGenTemplate` resources. The {ztp} pipeline that is linked to the ArgoCD `policies` application includes the following CRs that you can find in the relevant `out/argocd/example` folder when you extract the `ztp-site-generate` container: +/acmpolicygenerator resources:: +* `acm-common-ranGen.yaml` +* `acm-group-du-sno-ranGen.yaml` +* `acm-example-sno-site.yaml` +* `ns.yaml` +* `kustomization.yaml` + +/policygentemplates resources:: * `common-ranGen.yaml` * `group-du-sno-ranGen.yaml` * `example-sno-site.yaml` diff --git a/modules/ztp-worker-node-daemon-selector-compatibility.adoc b/modules/ztp-worker-node-daemon-selector-compatibility.adoc index f0afdc0d15ea..4e0a53898395 100644 --- a/modules/ztp-worker-node-daemon-selector-compatibility.adoc +++ b/modules/ztp-worker-node-daemon-selector-compatibility.adoc @@ -4,9 +4,9 @@ :_mod-docs-content-type: PROCEDURE [id="ztp-additional-worker-daemon-selector-comp_{context}"] -= (Optional) Ensuring PTP and SR-IOV daemon selector compatibility += Ensuring PTP and SR-IOV daemon selector compatibility -If the DU profile was deployed using the {ztp-first} plugin version 4.11 or earlier, the PTP and SR-IOV Operators might be configured to place the daemons only on nodes labelled as `master`. This configuration prevents the PTP and SR-IOV daemons from operating on the worker node. If the PTP and SR-IOV daemon node selectors are incorrectly configured on your system, you must change the daemons before proceeding with the worker DU profile configuration. +If the DU profile was deployed using the {ztp-first} plugin version 4.11 or earlier, the PTP and SR-IOV Operators might be configured to place the daemons only on nodes labeled as `master`. This configuration prevents the PTP and SR-IOV daemons from operating on the worker node. If the PTP and SR-IOV daemon node selectors are incorrectly configured on your system, you must change the daemons before proceeding with the worker DU profile configuration. .Procedure diff --git a/modules/ztp-worker-node-preparing-policies.adoc b/modules/ztp-worker-node-preparing-policies.adoc index 3e5902a82a46..370023462b98 100644 --- a/modules/ztp-worker-node-preparing-policies.adoc +++ b/modules/ztp-worker-node-preparing-policies.adoc @@ -3,98 +3,25 @@ // * scalability_and_performance/ztp_far_edge/ztp-sno-additional-worker-node.adoc :_mod-docs-content-type: PROCEDURE -[id="ztp-additional-worker-policies_{context}"] -= Using PolicyGenTemplate CRs to apply worker node policies to worker nodes -include::../_attributes/common-attributes.adoc[] +[id="ztp-additional-worker-policies-{policy-gen-cr}_{context}"] += Using {policy-gen-cr} CRs to apply worker node policies to worker nodes -You can create policies for worker nodes. +You can create policies for worker nodes using `{policy-gen-cr}` CRs. .Procedure -. Create the following policy template: +. Create the following `{policy-gen-cr}` CR: + -[source,yaml] ----- -apiVersion: ran.openshift.io/v1 -kind: PolicyGenTemplate -metadata: - name: "example-sno-workers" - namespace: "example-sno" -spec: - bindingRules: - sites: "example-sno" <1> - mcp: "worker" <2> - sourceFiles: - - fileName: MachineConfigGeneric.yaml <3> - policyName: "config-policy" - metadata: - labels: - machineconfiguration.openshift.io/role: worker - name: enable-workload-partitioning - spec: - config: - storage: - files: - - contents: - source: data:text/plain;charset=utf-8;base64,W2NyaW8ucnVudGltZS53b3JrbG9hZHMubWFuYWdlbWVudF0KYWN0aXZhdGlvbl9hbm5vdGF0aW9uID0gInRhcmdldC53b3JrbG9hZC5vcGVuc2hpZnQuaW8vbWFuYWdlbWVudCIKYW5ub3RhdGlvbl9wcmVmaXggPSAicmVzb3VyY2VzLndvcmtsb2FkLm9wZW5zaGlmdC5pbyIKcmVzb3VyY2VzID0geyAiY3B1c2hhcmVzIiA9IDAsICJjcHVzZXQiID0gIjAtMyIgfQo= - mode: 420 - overwrite: true - path: /etc/crio/crio.conf.d/01-workload-partitioning - user: - name: root - - contents: - source: data:text/plain;charset=utf-8;base64,ewogICJtYW5hZ2VtZW50IjogewogICAgImNwdXNldCI6ICIwLTMiCiAgfQp9Cg== - mode: 420 - overwrite: true - path: /etc/kubernetes/openshift-workload-pinning - user: - name: root - - fileName: PerformanceProfile.yaml - policyName: "config-policy" - metadata: - name: openshift-worker-node-performance-profile - spec: - cpu: <4> - isolated: "4-47" - reserved: "0-3" - hugepages: - defaultHugepagesSize: 1G - pages: - - size: 1G - count: 32 - realTimeKernel: - enabled: true - - fileName: TunedPerformancePatch.yaml - policyName: "config-policy" - metadata: - name: performance-patch-worker - spec: - profile: - - name: performance-patch-worker - data: | - [main] - summary=Configuration changes profile inherited from performance created tuned - include=openshift-node-performance-openshift-worker-node-performance-profile - [bootloader] - cmdline_crash=nohz_full=4-47 <5> - [sysctl] - kernel.timer_migration=1 - [scheduler] - group.ice-ptp=0:f:10:*:ice-ptp.* - [service] - service.stalld=start,enable - service.chronyd=stop,disable - recommend: - - profile: performance-patch-worker ----- -<1> The policies are applied to all clusters with this label. -<2> The `MCP` field must be set to `worker`. -<3> This generic `MachineConfig` CR is used to configure workload partitioning on the worker node. -<4> The `cpu.isolated` and `cpu.reserved` fields must be configured for each particular hardware platform. -<5> The `cmdline_crash` CPU set must match the `cpu.isolated` set in the `PerformanceProfile` section. +-- +ifeval::["{policy-gen-cr}" == "PolicyGenTemplate"] +include::snippets/pgt-ztp-worker-node-preparing-policies.adoc[] +endif::[] +ifeval::["{policy-gen-cr}" == "PolicyGenerator"] +include::snippets/pg-ztp-worker-node-preparing-policies.adoc[] +endif::[] -+ A generic `MachineConfig` CR is used to configure workload partitioning on the worker node. You can generate the content of `crio` and `kubelet` configuration files. +-- . Add the created policy template to the Git repository monitored by the ArgoCD `policies` application. diff --git a/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc b/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc new file mode 100644 index 000000000000..d05e85c49b4d --- /dev/null +++ b/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc @@ -0,0 +1,33 @@ +[source,yaml] +---- +manifests: +- path: source-crs/DefaultCatsrc.yaml + patches: + - metadata: + name: redhat-operators + spec: + displayName: Red Hat Operators Catalog + image: registry.example.com:5000/olm/redhat-operators:v{product-version} + updateStrategy: + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY +- path: source-crs/DefaultCatsrc.yaml + patches: + - metadata: + name: redhat-operators-v2 <1> + spec: + displayName: Red Hat Operators Catalog v2 <2> + image: registry.example.com:5000/olredhat-operators: <3> + updateStrategy: + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY +---- +<1> Update the name for the new configuration. +<2> Update the display name for the new configuration. +<3> Update the index image URL. This `policies.manifests.patches.spec.image` field overrides any configuration in the `DefaultCatsrc.yaml` file. diff --git a/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-update.adoc b/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-update.adoc new file mode 100644 index 000000000000..5154ed1c01b7 --- /dev/null +++ b/snippets/pg-cnf-topology-aware-lifecycle-manager-operator-update.adoc @@ -0,0 +1,48 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: du-upgrade +placementBindingDefaults: + name: du-upgrade-placement-binding +policyDefaults: + namespace: ztp-group-du-sno + placement: + labelSelector: + matchExpressions: + - key: group-du-sno + operator: Exists + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: du-upgrade-operator-catsrc-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/DefaultCatsrc.yaml + patches: + - metadata: + name: redhat-operators + spec: + displayName: Red Hat Operators Catalog + image: registry.example.com:5000/olm/redhat-operators:v{product-version} <1> + updateStrategy: <2> + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY <3> +---- +<1> Contains the required Operator images. If the index images are always pushed to the same image name and tag, this change is not needed. +<2> Sets how frequently the Operator Lifecycle Manager (OLM) polls the index image for new Operator versions with the `registryPoll.interval` field. This change is not needed if a new index image tag is always pushed for y-stream and z-stream Operator updates. The `registryPoll.interval` field can be set to a shorter interval to expedite the update, however shorter intervals increase computational load. To counteract this, you can restore `registryPoll.interval` to the default value once the update is complete. +<3> Displays the observed state of the catalog connection. The `READY` value ensures that the `CatalogSource` policy is ready, indicating that the index pod is pulled and is running. This way, {cgu-operator} upgrades the Operators based on up-to-date policy compliance states. diff --git a/snippets/pg-cnf-topology-aware-lifecycle-manager-pao-update.yaml b/snippets/pg-cnf-topology-aware-lifecycle-manager-pao-update.yaml new file mode 100644 index 000000000000..df38008fdb39 --- /dev/null +++ b/snippets/pg-cnf-topology-aware-lifecycle-manager-pao-update.yaml @@ -0,0 +1,7 @@ +- name: group-du-sno-pg-subscriptions-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/PaoSubscriptionNS.yaml + - path: source-crs/PaoSubscriptionOperGroup.yaml + - path: source-crs/PaoSubscription.yaml \ No newline at end of file diff --git a/snippets/pg-cnf-topology-aware-lifecycle-manager-platform-update.adoc b/snippets/pg-cnf-topology-aware-lifecycle-manager-platform-update.adoc new file mode 100644 index 000000000000..cb07a97e7207 --- /dev/null +++ b/snippets/pg-cnf-topology-aware-lifecycle-manager-platform-update.adoc @@ -0,0 +1,66 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: du-upgrade +placementBindingDefaults: + name: du-upgrade-placement-binding +policyDefaults: + namespace: ztp-group-du-sno + placement: + labelSelector: + matchExpressions: + - key: group-du-sno + operator: Exists + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: du-upgrade-platform-upgrade + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "100" + manifests: + - path: source-crs/ClusterVersion.yaml <1> + patches: + - metadata: + name: version + spec: + channel: stable-{product-version} + desiredUpdate: + version: {product-version}.4 + upstream: http://upgrade.example.com/images/upgrade-graph_stable-{product-version} + status: + history: + - state: Completed + version: {product-version}.4 + - name: du-upgrade-platform-upgrade-prep + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/ImageSignature.yaml <2> + - path: source-crs/DisconnectedICSP.yaml + patches: + - metadata: + name: disconnected-internal-icsp-for-ocp + spec: + repositoryDigestMirrors: <3> + - mirrors: + - quay-intern.example.com/ocp4/openshift-release-dev + source: quay.io/openshift-release-dev/ocp-release + - mirrors: + - quay-intern.example.com/ocp4/openshift-release-dev + source: quay.io/openshift-release-dev/ocp-v4.0-art-dev +---- +<1> Shows the `ClusterVersion` CR to trigger the update. The `channel`, `upstream`, and `desiredVersion` fields are all required for image pre-caching. +<2> `ImageSignature.yaml` contains the image signature of the required release image. The image signature is used to verify the image before applying the platform update. +<3> Shows the mirror repository that contains the required {product-title} image. Get the mirrors from the `imageContentSources.yaml` file that you saved when following the procedures in the "Setting up the environment" section. + diff --git a/snippets/pg-group-du-sno-config-policy.yaml b/snippets/pg-group-du-sno-config-policy.yaml new file mode 100644 index 000000000000..db03631e73ab --- /dev/null +++ b/snippets/pg-group-du-sno-config-policy.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: du-upgrade +placementBindingDefaults: + name: du-upgrade-placement-binding +policyDefaults: + namespace: ztp-group-du-sno + placement: + labelSelector: + matchExpressions: + - key: group-du-sno + operator: Exists + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: du-upgrade-operator-catsrc-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/DefaultCatsrc.yaml + patches: + - metadata: + name: redhat-operators + spec: + displayName: Red Hat Operators Catalog + image: registry.example.com:5000/olm/redhat-operators:v4.14 + updateStrategy: + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY diff --git a/snippets/pg-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc b/snippets/pg-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc new file mode 100644 index 000000000000..bb09d4e08933 --- /dev/null +++ b/snippets/pg-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc @@ -0,0 +1,51 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: du-upgrade +placementBindingDefaults: + name: du-upgrade-placement-binding +policyDefaults: + namespace: ztp-group-du-sno + placement: + labelSelector: + matchExpressions: + - key: group-du-sno + operator: Exists + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: du-upgrade-fec-catsrc-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/DefaultCatsrc.yaml + patches: + - metadata: + name: certified-operators + spec: + displayName: Intel SRIOV-FEC Operator + image: registry.example.com:5000/olm/far-edge-sriov-fec:v4.10 + updateStrategy: + registryPoll: + interval: 10m + - name: du-upgrade-subscriptions-fec-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/AcceleratorsSubscription.yaml + patches: + - spec: + channel: stable + source: certified-operators +---- diff --git a/snippets/pg-using-ztp-to-update-source-crs.yaml b/snippets/pg-using-ztp-to-update-source-crs.yaml new file mode 100644 index 000000000000..cc23f89dfc41 --- /dev/null +++ b/snippets/pg-using-ztp-to-update-source-crs.yaml @@ -0,0 +1,13 @@ +- path: source-crs/PerformanceProfile.yaml + patches: + - spec: + # These must be tailored for the specific hardware platform + cpu: + isolated: "2-19,22-39" + reserved: "0-1,20-21" + hugepages: + defaultHugepagesSize: 1G + pages: + - size: 1G + count: 10 + globallyDisableIrqLoadBalancing: false diff --git a/snippets/pg-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc b/snippets/pg-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc new file mode 100644 index 000000000000..da3df80a080b --- /dev/null +++ b/snippets/pg-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc @@ -0,0 +1,20 @@ +:_mod-docs-content-type: SNIPPET +[source,terminal] +---- +example +└── acmpolicygenerator + ├── dev.yaml + ├── kustomization.yaml + ├── mec-edge-sno1.yaml + ├── sno.yaml + └── source-crs <1> + ├── PaoCatalogSource.yaml + ├── PaoSubscription.yaml + ├── custom-crs + | ├── apiserver-config.yaml + | └── disable-nic-lldp.yaml + └── elasticsearch + ├── ElasticsearchNS.yaml + └── ElasticsearchOperatorGroup.yaml +---- +<1> The `source-crs` subdirectory must be in the same directory as the `kustomization.yaml` file. diff --git a/snippets/pg-ztp-adding-new-content-to-gitops-ztp.adoc b/snippets/pg-ztp-adding-new-content-to-gitops-ztp.adoc new file mode 100644 index 000000000000..7dd94da67b88 --- /dev/null +++ b/snippets/pg-ztp-adding-new-content-to-gitops-ztp.adoc @@ -0,0 +1,99 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: group-dev +placementBindingDefaults: + name: group-dev-placement-binding +policyDefaults: + namespace: ztp-clusters + placement: + labelSelector: + matchExpressions: + - key: dev + operator: In + values: + - "true" + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: group-dev-group-dev-cluster-log-ns + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/ClusterLogNS.yaml + - name: group-dev-group-dev-cluster-log-operator-group + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/ClusterLogOperGroup.yaml + - name: group-dev-group-dev-cluster-log-sub + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/ClusterLogSubscription.yaml + - name: group-dev-group-dev-lso-ns + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/StorageNS.yaml + - name: group-dev-group-dev-lso-operator-group + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/StorageOperGroup.yaml + - name: group-dev-group-dev-lso-sub + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/StorageSubscription.yaml + - name: group-dev-group-dev-pao-cat-source + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/PaoSubscriptionCatalogSource.yaml + patches: + - spec: + image: + - name: group-dev-group-dev-pao-ns + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/PaoSubscriptionNS.yaml + - name: group-dev-group-dev-pao-sub + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/PaoSubscription.yaml + - name: group-dev-group-dev-elasticsearch-ns + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: elasticsearch/ElasticsearchNS.yaml <1> + - name: group-dev-group-dev-elasticsearch-operator-group + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: elasticsearch/ElasticsearchOperatorGroup.yaml + - name: group-dev-group-dev-apiserver-config + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: custom-crs/apiserver-config.yaml <1> + - name: group-dev-group-dev-disable-nic-lldp + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: custom-crs/disable-nic-lldp.yaml +---- +<1> Set `policies.manifests.path` to include the relative path to the file from the `/source-crs` parent directory. diff --git a/snippets/pg-ztp-configuring-hwevents-using-pgt-hardware-event.adoc b/snippets/pg-ztp-configuring-hwevents-using-pgt-hardware-event.adoc new file mode 100644 index 000000000000..3357dd558705 --- /dev/null +++ b/snippets/pg-ztp-configuring-hwevents-using-pgt-hardware-event.adoc @@ -0,0 +1,11 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- path: source-crs/HardwareEvent.yaml <1> + patches: + - spec: + logLevel: debug + nodeSelector: {} + transportHost: http://hw-event-publisher-service.openshift-bare-metal-events.svc.cluster.local:9043 +---- +<1> Each baseboard management controller (BMC) requires a single `HardwareEvent` CR only. diff --git a/snippets/pg-ztp-configuring-hwevents.yaml b/snippets/pg-ztp-configuring-hwevents.yaml new file mode 100644 index 000000000000..531daddd6015 --- /dev/null +++ b/snippets/pg-ztp-configuring-hwevents.yaml @@ -0,0 +1,4 @@ +# Bare Metal Event Relay Operator +- path: source-crs/BareMetalEventRelaySubscriptionNS.yaml +- path: source-crs/BareMetalEventRelaySubscriptionOperGroup.yaml +- path: source-crs/BareMetalEventRelaySubscription.yaml \ No newline at end of file diff --git a/snippets/pg-ztp-configuring-ptp-fast-events-amqp-transport.yaml b/snippets/pg-ztp-configuring-ptp-fast-events-amqp-transport.yaml new file mode 100644 index 000000000000..ff0ecff6664c --- /dev/null +++ b/snippets/pg-ztp-configuring-ptp-fast-events-amqp-transport.yaml @@ -0,0 +1,13 @@ +- path: source-crs/PtpOperatorConfigForEvent.yaml + patches: + - metadata: + name: default + namespace: openshift-ptp + annotations: + ran.openshift.io/ztp-deploy-wave: "10" + spec: + daemonNodeSelector: + node-role.kubernetes.io/$mcp: "" + ptpEventConfig: + enableEventPublisher: true + transportHost: "amqp://amq-router.amq-router.svc.cluster.local" diff --git a/snippets/pg-ztp-configuring-ptp-fast-events-amqp.yaml b/snippets/pg-ztp-configuring-ptp-fast-events-amqp.yaml new file mode 100644 index 000000000000..7e2bbd00c113 --- /dev/null +++ b/snippets/pg-ztp-configuring-ptp-fast-events-amqp.yaml @@ -0,0 +1,4 @@ +#AMQ Interconnect Operator for fast events +- path: source-crs/AmqSubscriptionNS.yaml +- path: source-crs/AmqSubscriptionOperGroup.yaml +- path: source-crs/AmqSubscription.yaml \ No newline at end of file diff --git a/snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc b/snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc new file mode 100644 index 000000000000..a93404d2fca3 --- /dev/null +++ b/snippets/pg-ztp-configuring-ptp-fast-events-linuxptp.adoc @@ -0,0 +1,135 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- path: source-crs/PtpConfigSlave.yaml <1> + patches: + - metadata: + name: "du-ptp-slave" + spec: + recommend: + - match: + - nodeLabel: node-role.kubernetes.io/master + priority: 4 + profile: slave + profile: + - name: "slave" + # This interface must match the hardware in this group + interface: "ens5f0" <2> + ptp4lOpts: "-2 -s --summary_interval -4" <3> + phc2sysOpts: "-a -r -n 24" <4> + ptpSchedulingPolicy: SCHED_FIFO + ptpSchedulingPriority: 10 + ptpSettings: + logReduce: "true" + ptp4lConf: | + [global] + # + # Default Data Set + # + twoStepFlag 1 + slaveOnly 1 + priority1 128 + priority2 128 + domainNumber 24 + #utc_offset 37 + clockClass 255 + clockAccuracy 0xFE + offsetScaledLogVariance 0xFFFF + free_running 0 + freq_est_interval 1 + dscp_event 0 + dscp_general 0 + dataset_comparison G.8275.x + G.8275.defaultDS.localPriority 128 + # + # Port Data Set + # + logAnnounceInterval -3 + logSyncInterval -4 + logMinDelayReqInterval -4 + logMinPdelayReqInterval -4 + announceReceiptTimeout 3 + syncReceiptTimeout 0 + delayAsymmetry 0 + fault_reset_interval -4 + neighborPropDelayThresh 20000000 + masterOnly 0 + G.8275.portDS.localPriority 128 + # + # Run time options + # + assume_two_step 0 + logging_level 6 + path_trace_enabled 0 + follow_up_info 0 + hybrid_e2e 0 + inhibit_multicast_service 0 + net_sync_monitor 0 + tc_spanning_tree 0 + tx_timestamp_timeout 50 + unicast_listen 0 + unicast_master_table 0 + unicast_req_duration 3600 + use_syslog 1 + verbose 0 + summary_interval 0 + kernel_leap 1 + check_fup_sync 0 + clock_class_threshold 7 + # + # Servo Options + # + pi_proportional_const 0.0 + pi_integral_const 0.0 + pi_proportional_scale 0.0 + pi_proportional_exponent -0.3 + pi_proportional_norm_max 0.7 + pi_integral_scale 0.0 + pi_integral_exponent 0.4 + pi_integral_norm_max 0.3 + step_threshold 2.0 + first_step_threshold 0.00002 + max_frequency 900000000 + clock_servo pi + sanity_freq_limit 200000000 + ntpshm_segment 0 + # + # Transport options + # + transportSpecific 0x0 + ptp_dst_mac 01:1B:19:00:00:00 + p2p_dst_mac 01:80:C2:00:00:0E + udp_ttl 1 + udp6_scope 0x0E + uds_address /var/run/ptp4l + # + # Default interface options + # + clock_type OC + network_transport L2 + delay_mechanism E2E + time_stamping hardware + tsproc_mode filter + delay_filter moving_median + delay_filter_length 10 + egressLatency 0 + ingressLatency 0 + boundary_clock_jbod 0 + # + # Clock description + # + productDescription ;; + revisionData ;; + manufacturerIdentity 00:00:00 + userDescription ; + timeSource 0xA0 + ptpClockThreshold: <5> + holdOverTimeout: 30 # seconds + maxOffsetThreshold: 100 # nano seconds + minOffsetThreshold: -100 +---- +<1> Can be one of `PtpConfigMaster.yaml`, `PtpConfigSlave.yaml`, or `PtpConfigSlaveCvl.yaml` depending on your requirements. `PtpConfigSlaveCvl.yaml` configures `linuxptp` services for an Intel E810 Columbiaville NIC. For configurations based on `{policy-prefix}group-du-sno-ranGen.yaml` or `{policy-prefix}group-du-3node-ranGen.yaml`, use `PtpConfigSlave.yaml`. +<2> Device specific interface name. +<3> You must append the `--summary_interval -4` value to `ptp4lOpts` in `.spec.sourceFiles.spec.profile` to enable PTP fast events. +<4> Required `phc2sysOpts` values. `-m` prints messages to `stdout`. The `linuxptp-daemon` `DaemonSet` parses the logs and generates Prometheus metrics. +<5> Optional. If the `ptpClockThreshold` stanza is not present, default values are used for the `ptpClockThreshold` fields. The stanza shows default `ptpClockThreshold` values. The `ptpClockThreshold` values configure how long after the PTP master clock is disconnected before PTP events are triggered. `holdOverTimeout` is the time value in seconds before the PTP clock event state changes to `FREERUN` when the PTP master clock is disconnected. The `maxOffsetThreshold` and `minOffsetThreshold` settings configure offset values in nanoseconds that compare against the values for `CLOCK_REALTIME` (`phc2sys`) or master offset (`ptp4l`). When the `ptp4l` or `phc2sys` offset value is outside this range, the PTP clock state is set to `FREERUN`. When the offset value is within this range, the PTP clock state is set to `LOCKED`. diff --git a/snippets/pg-ztp-configuring-ptp-fast-events.yaml b/snippets/pg-ztp-configuring-ptp-fast-events.yaml new file mode 100644 index 000000000000..6bfe38d92e6d --- /dev/null +++ b/snippets/pg-ztp-configuring-ptp-fast-events.yaml @@ -0,0 +1,13 @@ +- path: source-crs/PtpOperatorConfigForEvent.yaml + patches: + - metadata: + name: default + namespace: openshift-ptp + annotations: + ran.openshift.io/ztp-deploy-wave: "10" + spec: + daemonNodeSelector: + node-role.kubernetes.io/$mcp: "" + ptpEventConfig: + enableEventPublisher: true + transportHost: "http://ptp-event-publisher-service-NODE_NAME.openshift-ptp.svc.cluster.local:9043" diff --git a/snippets/pg-ztp-creating-hwevents-amqp.yaml b/snippets/pg-ztp-creating-hwevents-amqp.yaml new file mode 100644 index 000000000000..91fad4336b8b --- /dev/null +++ b/snippets/pg-ztp-creating-hwevents-amqp.yaml @@ -0,0 +1,8 @@ +# AMQ Interconnect Operator for fast events +- path: source-crs/AmqSubscriptionNS.yaml +- path: source-crs/AmqSubscriptionOperGroup.yaml +- path: source-crs/AmqSubscription.yaml +# Bare Metal Event Relay Operator +- path: source-crs/BareMetalEventRelaySubscriptionNS.yaml +- path: source-crs/BareMetalEventRelaySubscriptionOperGroup.yaml +- path: source-crs/BareMetalEventRelaySubscription.yaml \ No newline at end of file diff --git a/snippets/pg-ztp-example-single-node-cluster-validator.adoc b/snippets/pg-ztp-example-single-node-cluster-validator.adoc new file mode 100644 index 000000000000..efd43e7f010f --- /dev/null +++ b/snippets/pg-ztp-example-single-node-cluster-validator.adoc @@ -0,0 +1,41 @@ +.Example single-node cluster validator inform policy CR (acm-group-du-sno-validator-ranGen.yaml) +[source,yaml] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: group-du-sno-validator-latest +placementBindingDefaults: + name: group-du-sno-validator-latest-placement-binding +policyDefaults: + namespace: ztp-group + placement: + labelSelector: + matchExpressions: + - key: du-profile + operator: In + values: + - latest + - key: group-du-sno + operator: Exists + - key: ztp-done + operator: DoesNotExist + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: group-du-sno-validator-latest-du-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "10000" + evaluationInterval: + compliant: 5s + manifests: + - path: source-crs/validatorCRs/informDuValidator-MCP-master.yaml +---- diff --git a/snippets/pg-ztp-provisioning-lvm-storage-cluster.adoc b/snippets/pg-ztp-provisioning-lvm-storage-cluster.adoc new file mode 100644 index 000000000000..47c4bb1ea633 --- /dev/null +++ b/snippets/pg-ztp-provisioning-lvm-storage-cluster.adoc @@ -0,0 +1,16 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: StorageLVMCluster.yaml + policyName: "lvms-config" + metadata: + name: "lvms-storage-cluster-config" + spec: + storage: + deviceClasses: + - name: vg1 + thinPoolConfig: + name: thin-pool-1 + sizePercent: 90 + overprovisionRatio: 10 +---- diff --git a/snippets/pg-ztp-provisioning-lvm-storage-sub.yaml b/snippets/pg-ztp-provisioning-lvm-storage-sub.yaml new file mode 100644 index 000000000000..359d1d2497c6 --- /dev/null +++ b/snippets/pg-ztp-provisioning-lvm-storage-sub.yaml @@ -0,0 +1,3 @@ +- path: source-crs/StorageLVMSubscriptionNS.yaml +- path: source-crs/StorageLVMSubscriptionOperGroup.yaml +- path: source-crs/StorageLVMSubscription.yaml diff --git a/snippets/pg-ztp-provisioning-lvm-storage.adoc b/snippets/pg-ztp-provisioning-lvm-storage.adoc new file mode 100644 index 000000000000..62c3d6f59057 --- /dev/null +++ b/snippets/pg-ztp-provisioning-lvm-storage.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +- name: subscription-policies + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: + - path: source-crs/StorageLVMOSubscriptionNS.yaml + - path: source-crs/StorageLVMOSubscriptionOperGroup.yaml + - path: source-crs/StorageLVMOSubscription.yaml + spec: + name: lvms-operator + channel: stable-{product-version} +---- diff --git a/snippets/pg-ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml b/snippets/pg-ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml new file mode 100644 index 000000000000..78055287b9e6 --- /dev/null +++ b/snippets/pg-ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml @@ -0,0 +1,101 @@ +--- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: group-du-sno-pgt +placementBindingDefaults: + name: group-du-sno-pgt-placement-binding +policyDefaults: + placement: + labelSelector: + matchExpressions: + - key: group-du-sno-zone + operator: In + values: + - zone-1 + - key: hardware-type + operator: In + values: + - hardware-type-1 + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: group-du-sno-pgt-group-du-sno-cfg-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "10" + manifests: + - path: source-crs/ClusterLogForwarder.yaml + patches: + - spec: + outputs: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-outputs" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' + pipelines: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-pipelines" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' + - path: source-crs/PerformanceProfile-MCP-master.yaml + patches: + - metadata: + name: openshift-node-performance-profile + spec: + additionalKernelArgs: + - rcupdate.rcu_normal_after_boot=0 + - vfio_pci.enable_sriov=1 + - vfio_pci.disable_idle_d3=1 + - efi=runtime + cpu: + isolated: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-isolated" (index .ManagedClusterLabels "hardware-type")) hub}}' + reserved: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-reserved" (index .ManagedClusterLabels "hardware-type")) hub}}' + hugepages: + defaultHugepagesSize: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-default" (index .ManagedClusterLabels "hardware-type")) hub}}' + pages: + - count: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-count" (index .ManagedClusterLabels "hardware-type")) | toInt hub}}' + size: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-size" (index .ManagedClusterLabels "hardware-type")) hub}}' + realTimeKernel: + enabled: true + - name: group-du-sno-pgt-group-du-sno-sriov-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "100" + manifests: + - path: source-crs/SriovNetwork.yaml + patches: + - metadata: + name: sriov-nw-du-fh + spec: + resourceName: du_fh + vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-1" .ManagedClusterName) | toInt hub}}' + - path: source-crs/SriovNetworkNodePolicy-MCP-master.yaml + patches: + - metadata: + name: sriov-nnp-du-fh + spec: + deviceType: netdevice + isRdma: false + nicSelector: + pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-1" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' + numVfs: 8 + priority: 10 + resourceName: du_fh + - path: source-crs/SriovNetwork.yaml + patches: + - metadata: + name: sriov-nw-du-mh + spec: + resourceName: du_mh + vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-2" .ManagedClusterName) | toInt hub}}' + - path: source-crs/SriovNetworkNodePolicy-MCP-master.yaml + patches: + - metadata: + name: sriov-nw-du-fh + spec: + deviceType: netdevice + isRdma: false + nicSelector: + pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-2" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' + numVfs: 8 + priority: 10 + resourceName: du_fh diff --git a/snippets/pg-ztp-the-policygenerator.adoc b/snippets/pg-ztp-the-policygenerator.adoc new file mode 100644 index 000000000000..120bcf3e0789 --- /dev/null +++ b/snippets/pg-ztp-the-policygenerator.adoc @@ -0,0 +1,76 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: common-latest +placementBindingDefaults: + name: common-latest-placement-binding <1> +policyDefaults: + namespace: ztp-common + placement: + labelSelector: + matchExpressions: + - key: common + operator: In + values: + - "true" + - key: du-profile + operator: In + values: + - latest + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: common-latest-config-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "1" + manifests: + - path: source-crs/ReduceMonitoringFootprint.yaml + - path: source-crs/DefaultCatsrc.yaml <2> + patches: + - metadata: + name: redhat-operators-disconnected + spec: + displayName: disconnected-redhat-operators + image: registry.example.com:5000/disconnected-redhat-operators/disconnected-redhat-operator-index:v4.9 + - path: source-crs/DisconnectedICSP.yaml + patches: + - spec: + repositoryDigestMirrors: + - mirrors: + - registry.example.com:5000 + source: registry.redhat.io + - name: common-latest-subscriptions-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "2" + manifests: <3> + - path: source-crs/SriovSubscriptionNS.yaml + - path: source-crs/SriovSubscriptionOperGroup.yaml + - path: source-crs/SriovSubscription.yaml + - path: source-crs/SriovOperatorStatus.yaml + - path: source-crs/PtpSubscriptionNS.yaml + - path: source-crs/PtpSubscriptionOperGroup.yaml + - path: source-crs/PtpSubscription.yaml + - path: source-crs/PtpOperatorStatus.yaml + - path: source-crs/ClusterLogNS.yaml + - path: source-crs/ClusterLogOperGroup.yaml + - path: source-crs/ClusterLogSubscription.yaml + - path: source-crs/ClusterLogOperatorStatus.yaml + - path: source-crs/StorageNS.yaml + - path: source-crs/StorageOperGroup.yaml + - path: source-crs/StorageSubscription.yaml + - path: source-crs/StorageOperatorStatus.yaml +---- +<1> Applies the policies to all clusters with this label. +<2> The `DefaultCatsrc.yaml` file contains the catalog source for the disconnected registry and related registry configuration details. +<3> Files listed under `policies.manifests` create the Operator policies for installed clusters. diff --git a/snippets/pg-ztp-using-pg-to-configure-high-performance-mode.yaml b/snippets/pg-ztp-using-pg-to-configure-high-performance-mode.yaml new file mode 100644 index 000000000000..25c48381f62a --- /dev/null +++ b/snippets/pg-ztp-using-pg-to-configure-high-performance-mode.yaml @@ -0,0 +1,7 @@ +- path: source-crs/PerformanceProfile.yaml + patches: + - spec: + workloadHints: + realTime: true + highPowerConsumption: true + perPodPowerManagement: false \ No newline at end of file diff --git a/snippets/pg-ztp-using-pg-to-configure-performance-mode.yaml b/snippets/pg-ztp-using-pg-to-configure-performance-mode.yaml new file mode 100644 index 000000000000..e50ebfac520a --- /dev/null +++ b/snippets/pg-ztp-using-pg-to-configure-performance-mode.yaml @@ -0,0 +1,7 @@ +- path: source-crs/PerformanceProfile.yaml + patches: + - spec: + workloadHints: + realTime: true + highPowerConsumption: false + perPodPowerManagement: false \ No newline at end of file diff --git a/snippets/pg-ztp-using-pg-to-configure-power-saving-mode.adoc b/snippets/pg-ztp-using-pg-to-configure-power-saving-mode.adoc new file mode 100644 index 000000000000..73f527fec1ce --- /dev/null +++ b/snippets/pg-ztp-using-pg-to-configure-power-saving-mode.adoc @@ -0,0 +1,17 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- path: source-crs/PerformanceProfile.yaml + patches: + - spec: + # ... + workloadHints: + realTime: true + highPowerConsumption: false + perPodPowerManagement: true + # ... + additionalKernelArgs: + - # ... + - "cpufreq.default_governor=schedutil" <1> +---- +<1> The `schedutil` governor is recommended, however, you can also use other governors, including `ondemand` and `powersave`. diff --git a/snippets/pg-ztp-using-pg-to-maximize-power-saving-mode.adoc b/snippets/pg-ztp-using-pg-to-maximize-power-saving-mode.adoc new file mode 100644 index 000000000000..c65ef14c9205 --- /dev/null +++ b/snippets/pg-ztp-using-pg-to-maximize-power-saving-mode.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- path: source-crs/TunedPerformancePatch.yaml + patches: + - spec: + profile: + - name: performance-patch + data: | + # ... + [sysfs] + /sys/devices/system/cpu/intel_pstate/max_perf_pct= <1> +---- +<1> The `max_perf_pct` controls the maximum frequency the `cpufreq` driver is allowed to set as a percentage of the maximum supported CPU frequency. This value applies to all CPUs. You can check the maximum supported frequency in `/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq`. As a starting point, you can use a percentage that caps all CPUs at the `All Cores Turbo` frequency. The `All Cores Turbo` frequency is the frequency that all cores run at when the cores are all fully occupied. diff --git a/snippets/pg-ztp-worker-node-preparing-policies.adoc b/snippets/pg-ztp-worker-node-preparing-policies.adoc new file mode 100644 index 000000000000..299da20a7c19 --- /dev/null +++ b/snippets/pg-ztp-worker-node-preparing-policies.adoc @@ -0,0 +1,100 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: example-sno-workers +placementBindingDefaults: + name: example-sno-workers-placement-binding +policyDefaults: + namespace: example-sno + placement: + labelSelector: + matchExpressions: + - key: sites + operator: In + values: + - example-sno <1> + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: example-sno-workers-config-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: "10" + manifests: + - path: source-crs/MachineConfigGeneric.yaml <2> + patches: + - metadata: + labels: + machineconfiguration.openshift.io/role: worker <3> + name: enable-workload-partitioning + spec: + config: + storage: + files: + - contents: + source: data:text/plain;charset=utf-8;base64,W2NyaW8ucnVudGltZS53b3JrbG9hZHMubWFuYWdlbWVudF0KYWN0aXZhdGlvbl9hbm5vdGF0aW9uID0gInRhcmdldC53b3JrbG9hZC5vcGVuc2hpZnQuaW8vbWFuYWdlbWVudCIKYW5ub3RhdGlvbl9wcmVmaXggPSAicmVzb3VyY2VzLndvcmtsb2FkLm9wZW5zaGlmdC5pbyIKcmVzb3VyY2VzID0geyAiY3B1c2hhcmVzIiA9IDAsICJjcHVzZXQiID0gIjAtMyIgfQo= + mode: 420 + overwrite: true + path: /etc/crio/crio.conf.d/01-workload-partitioning + user: + name: root + - contents: + source: data:text/plain;charset=utf-8;base64,ewogICJtYW5hZ2VtZW50IjogewogICAgImNwdXNldCI6ICIwLTMiCiAgfQp9Cg== + mode: 420 + overwrite: true + path: /etc/kubernetes/openshift-workload-pinning + user: + name: root + - path: source-crs/PerformanceProfile-MCP-worker.yaml + patches: + - metadata: + name: openshift-worker-node-performance-profile + spec: + cpu: <4> + isolated: 4-47 + reserved: 0-3 + hugepages: + defaultHugepagesSize: 1G + pages: + - count: 32 + size: 1G + realTimeKernel: + enabled: true + - path: source-crs/TunedPerformancePatch-MCP-worker.yaml + patches: + - metadata: + name: performance-patch-worker + spec: + profile: + - data: | + [main] + summary=Configuration changes profile inherited from performance created tuned + include=openshift-node-performance-openshift-worker-node-performance-profile + [bootloader] + cmdline_crash=nohz_full=4-47 <5> + [sysctl] + kernel.timer_migration=1 + [scheduler] + group.ice-ptp=0:f:10:*:ice-ptp.* + [service] + service.stalld=start,enable + service.chronyd=stop,disable + name: performance-patch-worker + recommend: + - profile: performance-patch-worker +---- +<1> The policies are applied to all clusters with this label. +<2> This generic `MachineConfig` CR is used to configure workload partitioning on the worker node. +<3> The `MCP` field must be set to `worker`. +<4> The `cpu.isolated` and `cpu.reserved` fields must be configured for each particular hardware platform. +<5> The `cmdline_crash` CPU set must match the `cpu.isolated` set in the `PerformanceProfile` section. diff --git a/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc b/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc new file mode 100644 index 000000000000..242f4a78f682 --- /dev/null +++ b/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-troubleshooting.adoc @@ -0,0 +1,35 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: DefaultCatsrc.yaml + remediationAction: inform + policyName: "operator-catsrc-policy" + metadata: + name: redhat-operators + spec: + displayName: Red Hat Operators Catalog + image: registry.example.com:5000/olm/redhat-operators:v{product-version} + updateStrategy: + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY +- fileName: DefaultCatsrc.yaml + remediationAction: inform + policyName: "operator-catsrc-policy" + metadata: + name: redhat-operators-v2 <1> + spec: + displayName: Red Hat Operators Catalog v2 <2> + image: registry.example.com:5000/olredhat-operators: <3> + updateStrategy: + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY +---- +<1> Update the name for the new configuration. +<2> Update the display name for the new configuration. +<3> Update the index image URL. This `fileName.spec.image` field overrides any configuration in the `DefaultCatsrc.yaml` file. diff --git a/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-update.adoc b/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-update.adoc new file mode 100644 index 000000000000..0ed0e2784190 --- /dev/null +++ b/snippets/pgt-cnf-topology-aware-lifecycle-manager-operator-update.adoc @@ -0,0 +1,32 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "du-upgrade" + namespace: "ztp-group-du-sno" +spec: + bindingRules: + group-du-sno: "" + mcp: "master" + remediationAction: inform + sourceFiles: + - fileName: DefaultCatsrc.yaml + remediationAction: inform + policyName: "operator-catsrc-policy" + metadata: + name: redhat-operators + spec: + displayName: Red Hat Operators Catalog + image: registry.example.com:5000/olm/redhat-operators:v{product-version} <1> + updateStrategy: <2> + registryPoll: + interval: 1h + status: + connectionState: + lastObservedState: READY <3> +---- +<1> The index image URL contains the desired Operator images. If the index images are always pushed to the same image name and tag, this change is not needed. +<2> Set how frequently the Operator Lifecycle Manager (OLM) polls the index image for new Operator versions with the `registryPoll.interval` field. This change is not needed if a new index image tag is always pushed for y-stream and z-stream Operator updates. The `registryPoll.interval` field can be set to a shorter interval to expedite the update, however shorter intervals increase computational load. To counteract this behavior, you can restore `registryPoll.interval` to the default value once the update is complete. +<3> Last observed state of the catalog connection. The `READY` value ensures that the `CatalogSource` policy is ready, indicating that the index pod is pulled and is running. This way, {cgu-operator} upgrades the Operators based on up-to-date policy compliance states. diff --git a/snippets/pgt-cnf-topology-aware-lifecycle-manager-pao-update.yaml b/snippets/pgt-cnf-topology-aware-lifecycle-manager-pao-update.yaml new file mode 100644 index 000000000000..37a4bf4fbdc3 --- /dev/null +++ b/snippets/pgt-cnf-topology-aware-lifecycle-manager-pao-update.yaml @@ -0,0 +1,9 @@ +- fileName: PaoSubscriptionNS.yaml + policyName: "subscriptions-policy" + complianceType: mustnothave +- fileName: PaoSubscriptionOperGroup.yaml + policyName: "subscriptions-policy" + complianceType: mustnothave +- fileName: PaoSubscription.yaml + policyName: "subscriptions-policy" + complianceType: mustnothave \ No newline at end of file diff --git a/snippets/pgt-cnf-topology-aware-lifecycle-manager-platform-update.adoc b/snippets/pgt-cnf-topology-aware-lifecycle-manager-platform-update.adoc new file mode 100644 index 000000000000..d4e6efcb36a6 --- /dev/null +++ b/snippets/pgt-cnf-topology-aware-lifecycle-manager-platform-update.adoc @@ -0,0 +1,48 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "du-upgrade" + namespace: "ztp-group-du-sno" +spec: + bindingRules: + group-du-sno: "" + mcp: "master" + remediationAction: inform + sourceFiles: + - fileName: ImageSignature.yaml <1> + policyName: "platform-upgrade-prep" + binaryData: + ${DIGEST_ALGO}-${DIGEST_ENCODED}: ${SIGNATURE_BASE64} <2> + - fileName: DisconnectedICSP.yaml + policyName: "platform-upgrade-prep" + metadata: + name: disconnected-internal-icsp-for-ocp + spec: + repositoryDigestMirrors: <3> + - mirrors: + - quay-intern.example.com/ocp4/openshift-release-dev + source: quay.io/openshift-release-dev/ocp-release + - mirrors: + - quay-intern.example.com/ocp4/openshift-release-dev + source: quay.io/openshift-release-dev/ocp-v4.0-art-dev + - fileName: ClusterVersion.yaml <4> + policyName: "platform-upgrade" + metadata: + name: version + spec: + channel: "stable-{product-version}" + upstream: http://upgrade.example.com/images/upgrade-graph_stable-{product-version} + desiredUpdate: + version: {product-version}.4 + status: + history: + - version: {product-version}.4 + state: "Completed" +---- +<1> The `ConfigMap` CR contains the signature of the desired release image to update to. +<2> Shows the image signature of the desired {product-title} release. Get the signature from the `checksum-${OCP_RELEASE_NUMBER}.yaml` file you saved when following the procedures in the "Setting up the environment" section. +<3> Shows the mirror repository that contains the desired {product-title} image. Get the mirrors from the `imageContentSources.yaml` file that you saved when following the procedures in the "Setting up the environment" section. +<4> Shows the `ClusterVersion` CR to trigger the update. The `channel`, `upstream`, and `desiredVersion` fields are all required for image pre-caching. diff --git a/snippets/pgt-deprecation-notice.adoc b/snippets/pgt-deprecation-notice.adoc new file mode 100644 index 000000000000..3a77abf30603 --- /dev/null +++ b/snippets/pgt-deprecation-notice.adoc @@ -0,0 +1,8 @@ +:_mod-docs-content-type: SNIPPET +[IMPORTANT] +==== +Using `PolicyGenTemplate` CRs to manage and deploy polices to managed clusters will be deprecated in an upcoming {product-title} release. +Equivalent and improved functionality is available using {rh-rhacm-first} and `PolicyGenerator` CRs. + +For more information about `PolicyGenerator` resources, see the {rh-rhacm} link:https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/{rh-rhacm-version}/html/governance/integrate-third-party-policy-controllers#policy-generator[Policy Generator] documentation. +==== diff --git a/snippets/pgt-group-du-sno-config-policy.yaml b/snippets/pgt-group-du-sno-config-policy.yaml new file mode 100644 index 000000000000..82471c83ec2e --- /dev/null +++ b/snippets/pgt-group-du-sno-config-policy.yaml @@ -0,0 +1,54 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: group-du-ptp-config-policy + namespace: groups-sub + annotations: + policy.open-cluster-management.io/categories: CM Configuration Management + policy.open-cluster-management.io/controls: CM-2 Baseline Configuration + policy.open-cluster-management.io/standards: NIST SP 800-53 +spec: + remediationAction: inform + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: group-du-ptp-config-policy-config + spec: + remediationAction: inform + severity: low + namespaceselector: + exclude: + - kube-* + include: + - '*' + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: ptp.openshift.io/v1 + kind: PtpConfig + metadata: + name: du-ptp-slave + namespace: openshift-ptp + spec: + recommend: + - match: + - nodeLabel: node-role.kubernetes.io/worker-du + priority: 4 + profile: slave + profile: + - interface: ens5f0 + name: slave + phc2sysOpts: -a -r -n 24 + ptp4lConf: | + [global] + # + # Default Data Set + # + twoStepFlag 1 + slaveOnly 0 + priority1 128 + priority2 128 + domainNumber 24 \ No newline at end of file diff --git a/snippets/pgt-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc b/snippets/pgt-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc new file mode 100644 index 000000000000..625521681c10 --- /dev/null +++ b/snippets/pgt-sriov-fec-cnf-topology-aware-lifecycle-manager-operator-update.adoc @@ -0,0 +1,32 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "du-upgrade" + namespace: "ztp-group-du-sno" +spec: + bindingRules: + group-du-sno: "" + mcp: "master" + remediationAction: inform + sourceFiles: + # ... + - fileName: DefaultCatsrc.yaml + remediationAction: inform + policyName: "fec-catsrc-policy" + metadata: + name: certified-operators + spec: + displayName: Intel SRIOV-FEC Operator + image: registry.example.com:5000/olm/far-edge-sriov-fec:v4.10 + updateStrategy: + registryPoll: + interval: 10m + - fileName: AcceleratorsSubscription.yaml + policyName: "subscriptions-fec-policy" + spec: + channel: "stable" + source: certified-operators +---- diff --git a/snippets/pgt-using-ztp-to-update-source-crs.yaml b/snippets/pgt-using-ztp-to-update-source-crs.yaml new file mode 100644 index 000000000000..089d0a4bbd9a --- /dev/null +++ b/snippets/pgt-using-ztp-to-update-source-crs.yaml @@ -0,0 +1,15 @@ +- fileName: PerformanceProfile.yaml + policyName: "config-policy" + metadata: + name: openshift-node-performance-profile + spec: + cpu: + # These must be tailored for the specific hardware platform + isolated: "2-19,22-39" + reserved: "0-1,20-21" + hugepages: + defaultHugepagesSize: 1G + pages: + - size: 1G + count: 10 + globallyDisableIrqLoadBalancing: false diff --git a/snippets/pgt-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc b/snippets/pgt-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc new file mode 100644 index 000000000000..755defb2ceb4 --- /dev/null +++ b/snippets/pgt-ztp-adding-new-content-to-gitops-ztp-folder-structure.adoc @@ -0,0 +1,20 @@ +:_mod-docs-content-type: SNIPPET +[source,terminal] +---- +example +└── policygentemplates + ├── dev.yaml + ├── kustomization.yaml + ├── mec-edge-sno1.yaml + ├── sno.yaml + └── source-crs <1> + ├── PaoCatalogSource.yaml + ├── PaoSubscription.yaml + ├── custom-crs + | ├── apiserver-config.yaml + | └── disable-nic-lldp.yaml + └── elasticsearch + ├── ElasticsearchNS.yaml + └── ElasticsearchOperatorGroup.yaml +---- +<1> The `source-crs` subdirectory must be in the same directory as the `kustomization.yaml` file. diff --git a/snippets/pgt-ztp-adding-new-content-to-gitops-ztp.adoc b/snippets/pgt-ztp-adding-new-content-to-gitops-ztp.adoc new file mode 100644 index 000000000000..1e00cfe1f846 --- /dev/null +++ b/snippets/pgt-ztp-adding-new-content-to-gitops-ztp.adoc @@ -0,0 +1,63 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "group-dev" + namespace: "ztp-clusters" +spec: + bindingRules: + dev: "true" + mcp: "master" + sourceFiles: + # These policies/CRs come from the internal container Image + #Cluster Logging + - fileName: ClusterLogNS.yaml + remediationAction: inform + policyName: "group-dev-cluster-log-ns" + - fileName: ClusterLogOperGroup.yaml + remediationAction: inform + policyName: "group-dev-cluster-log-operator-group" + - fileName: ClusterLogSubscription.yaml + remediationAction: inform + policyName: "group-dev-cluster-log-sub" + #Local Storage Operator + - fileName: StorageNS.yaml + remediationAction: inform + policyName: "group-dev-lso-ns" + - fileName: StorageOperGroup.yaml + remediationAction: inform + policyName: "group-dev-lso-operator-group" + - fileName: StorageSubscription.yaml + remediationAction: inform + policyName: "group-dev-lso-sub" + #These are custom local polices that come from the source-crs directory in the git repo + # Performance Addon Operator + - fileName: PaoSubscriptionNS.yaml + remediationAction: inform + policyName: "group-dev-pao-ns" + - fileName: PaoSubscriptionCatalogSource.yaml + remediationAction: inform + policyName: "group-dev-pao-cat-source" + spec: + image: + - fileName: PaoSubscription.yaml + remediationAction: inform + policyName: "group-dev-pao-sub" + #Elasticsearch Operator + - fileName: elasticsearch/ElasticsearchNS.yaml <1> + remediationAction: inform + policyName: "group-dev-elasticsearch-ns" + - fileName: elasticsearch/ElasticsearchOperatorGroup.yaml + remediationAction: inform + policyName: "group-dev-elasticsearch-operator-group" + #Custom Resources + - fileName: custom-crs/apiserver-config.yaml <1> + remediationAction: inform + policyName: "group-dev-apiserver-config" + - fileName: custom-crs/disable-nic-lldp.yaml + remediationAction: inform + policyName: "group-dev-disable-nic-lldp" +---- +<1> Set `fileName` to include the relative path to the file from the `/source-crs` parent directory. diff --git a/snippets/pgt-ztp-configuring-hwevents-using-pgt-hardware-event.adoc b/snippets/pgt-ztp-configuring-hwevents-using-pgt-hardware-event.adoc new file mode 100644 index 000000000000..2a6905f418a9 --- /dev/null +++ b/snippets/pgt-ztp-configuring-hwevents-using-pgt-hardware-event.adoc @@ -0,0 +1,11 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: HardwareEvent.yaml <1> + policyName: "config-policy" + spec: + nodeSelector: {} + transportHost: "http://hw-event-publisher-service.openshift-bare-metal-events.svc.cluster.local:9043" + logLevel: "info" +---- +<1> Each baseboard management controller (BMC) requires a single `HardwareEvent` CR only. diff --git a/snippets/pgt-ztp-configuring-hwevents-using-pgt.yaml b/snippets/pgt-ztp-configuring-hwevents-using-pgt.yaml new file mode 100644 index 000000000000..dc3f558cdfc7 --- /dev/null +++ b/snippets/pgt-ztp-configuring-hwevents-using-pgt.yaml @@ -0,0 +1,7 @@ +# Bare Metal Event Relay Operator +- fileName: BareMetalEventRelaySubscriptionNS.yaml + policyName: "subscriptions-policy" +- fileName: BareMetalEventRelaySubscriptionOperGroup.yaml + policyName: "subscriptions-policy" +- fileName: BareMetalEventRelaySubscription.yaml + policyName: "subscriptions-policy" \ No newline at end of file diff --git a/snippets/pgt-ztp-configuring-ptp-fast-events-amqp-transport.yaml b/snippets/pgt-ztp-configuring-ptp-fast-events-amqp-transport.yaml new file mode 100644 index 000000000000..c7d52280e160 --- /dev/null +++ b/snippets/pgt-ztp-configuring-ptp-fast-events-amqp-transport.yaml @@ -0,0 +1,7 @@ +- fileName: PtpOperatorConfigForEvent.yaml + policyName: "config-policy" + spec: + daemonNodeSelector: {} + ptpEventConfig: + enableEventPublisher: true + transportHost: "amqp://amq-router.amq-router.svc.cluster.local" \ No newline at end of file diff --git a/snippets/pgt-ztp-configuring-ptp-fast-events-amqp.yaml b/snippets/pgt-ztp-configuring-ptp-fast-events-amqp.yaml new file mode 100644 index 000000000000..35751e41386e --- /dev/null +++ b/snippets/pgt-ztp-configuring-ptp-fast-events-amqp.yaml @@ -0,0 +1,7 @@ +#AMQ interconnect operator for fast events +- fileName: AmqSubscriptionNS.yaml + policyName: "subscriptions-policy" +- fileName: AmqSubscriptionOperGroup.yaml + policyName: "subscriptions-policy" +- fileName: AmqSubscription.yaml + policyName: "subscriptions-policy" \ No newline at end of file diff --git a/snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc b/snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc new file mode 100644 index 000000000000..a9a8637ca4b8 --- /dev/null +++ b/snippets/pgt-ztp-configuring-ptp-fast-events-linuxptp.adoc @@ -0,0 +1,23 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: PtpConfigSlave.yaml <1> + policyName: "config-policy" + metadata: + name: "du-ptp-slave" + spec: + profile: + - name: "slave" + interface: "ens5f1" <2> + ptp4lOpts: "-2 -s --summary_interval -4" <3> + phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16" <4> + ptpClockThreshold: <5> + holdOverTimeout: 30 # seconds + maxOffsetThreshold: 100 # nano seconds + minOffsetThreshold: -100 +---- +<1> Can be one of `PtpConfigMaster.yaml`, `PtpConfigSlave.yaml`, or `PtpConfigSlaveCvl.yaml` depending on your requirements. `PtpConfigSlaveCvl.yaml` configures `linuxptp` services for an Intel E810 Columbiaville NIC. For configurations based on `{policy-prefix}group-du-sno-ranGen.yaml` or `{policy-prefix}group-du-3node-ranGen.yaml`, use `PtpConfigSlave.yaml`. +<2> Device specific interface name. +<3> You must append the `--summary_interval -4` value to `ptp4lOpts` in `.spec.sourceFiles.spec.profile` to enable PTP fast events. +<4> Required `phc2sysOpts` values. `-m` prints messages to `stdout`. The `linuxptp-daemon` `DaemonSet` parses the logs and generates Prometheus metrics. +<5> Optional. If the `ptpClockThreshold` stanza is not present, default values are used for the `ptpClockThreshold` fields. The stanza shows default `ptpClockThreshold` values. The `ptpClockThreshold` values configure how long after the PTP master clock is disconnected before PTP events are triggered. `holdOverTimeout` is the time value in seconds before the PTP clock event state changes to `FREERUN` when the PTP master clock is disconnected. The `maxOffsetThreshold` and `minOffsetThreshold` settings configure offset values in nanoseconds that compare against the values for `CLOCK_REALTIME` (`phc2sys`) or master offset (`ptp4l`). When the `ptp4l` or `phc2sys` offset value is outside this range, the PTP clock state is set to `FREERUN`. When the offset value is within this range, the PTP clock state is set to `LOCKED`. diff --git a/snippets/pgt-ztp-configuring-ptp-fast-events.yaml b/snippets/pgt-ztp-configuring-ptp-fast-events.yaml new file mode 100644 index 000000000000..4c928dd50c07 --- /dev/null +++ b/snippets/pgt-ztp-configuring-ptp-fast-events.yaml @@ -0,0 +1,7 @@ +- fileName: PtpOperatorConfigForEvent.yaml + policyName: "config-policy" + spec: + daemonNodeSelector: {} + ptpEventConfig: + enableEventPublisher: true + transportHost: http://ptp-event-publisher-service-NODE_NAME.openshift-ptp.svc.cluster.local:9043 diff --git a/snippets/pgt-ztp-creating-hwevents-amqp.yaml b/snippets/pgt-ztp-creating-hwevents-amqp.yaml new file mode 100644 index 000000000000..697ba36225c7 --- /dev/null +++ b/snippets/pgt-ztp-creating-hwevents-amqp.yaml @@ -0,0 +1,14 @@ +# AMQ Interconnect Operator for fast events +- fileName: AmqSubscriptionNS.yaml + policyName: "subscriptions-policy" +- fileName: AmqSubscriptionOperGroup.yaml + policyName: "subscriptions-policy" +- fileName: AmqSubscription.yaml + policyName: "subscriptions-policy" +# Bare Metal Event Relay Operator +- fileName: BareMetalEventRelaySubscriptionNS.yaml + policyName: "subscriptions-policy" +- fileName: BareMetalEventRelaySubscriptionOperGroup.yaml + policyName: "subscriptions-policy" +- fileName: BareMetalEventRelaySubscription.yaml + policyName: "subscriptions-policy" \ No newline at end of file diff --git a/snippets/pgt-ztp-example-single-node-cluster-validator.adoc b/snippets/pgt-ztp-example-single-node-cluster-validator.adoc new file mode 100644 index 000000000000..9d62ef4a9bb8 --- /dev/null +++ b/snippets/pgt-ztp-example-single-node-cluster-validator.adoc @@ -0,0 +1,27 @@ +.Example single-node cluster validator inform policy CR (group-du-sno-validator-ranGen.yaml) +[source,yaml] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "group-du-sno-validator" <1> + namespace: "ztp-group" <2> +spec: + bindingRules: + group-du-sno: "" <3> + bindingExcludedRules: + ztp-done: "" <4> + mcp: "master" <5> + sourceFiles: + - fileName: validatorCRs/informDuValidator.yaml + remediationAction: inform <6> + policyName: "du-policy" <7> +---- +<1> The name of the `{policy-gen-crs}` object. This name is also used as part of the names +for the `placementBinding`, `placementRule`, and `policy` that are created in the requested `namespace`. +<2> This value should match the `namespace` used in the group `policy-gen-crs`. +<3> The `group-du-*` label defined in `bindingRules` must exist in the `SiteConfig` files. +<4> The label defined in `bindingExcludedRules` must be`ztp-done:`. The `ztp-done` label is used in coordination with the {cgu-operator-full}. +<5> `mcp` defines the `MachineConfigPool` object that is used in the source file `validatorCRs/informDuValidator.yaml`. It should be `master` for single node and three-node cluster deployments and `worker` for standard cluster deployments. +<6> Optional. The default value is `inform`. +<7> This value is used as part of the name for the generated {rh-rhacm} policy. The generated validator policy for the single node example is `group-du-sno-validator-du-policy`. diff --git a/snippets/pgt-ztp-provisioning-lvm-storage-cluster.adoc b/snippets/pgt-ztp-provisioning-lvm-storage-cluster.adoc new file mode 100644 index 000000000000..bbf4870bd61e --- /dev/null +++ b/snippets/pgt-ztp-provisioning-lvm-storage-cluster.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: StorageLVMCluster.yaml + policyName: "lvms-config" + spec: + storage: + deviceClasses: + - name: vg1 + thinPoolConfig: + name: thin-pool-1 + sizePercent: 90 + overprovisionRatio: 10 +---- diff --git a/snippets/pgt-ztp-provisioning-lvm-storage-sub.yaml b/snippets/pgt-ztp-provisioning-lvm-storage-sub.yaml new file mode 100644 index 000000000000..aca70a7cfeff --- /dev/null +++ b/snippets/pgt-ztp-provisioning-lvm-storage-sub.yaml @@ -0,0 +1,6 @@ +- fileName: StorageLVMSubscriptionNS.yaml + policyName: subscription-policies +- fileName: StorageLVMSubscriptionOperGroup.yaml + policyName: subscription-policies +- fileName: StorageLVMSubscription.yaml + policyName: subscription-policies \ No newline at end of file diff --git a/snippets/pgt-ztp-provisioning-lvm-storage.adoc b/snippets/pgt-ztp-provisioning-lvm-storage.adoc new file mode 100644 index 000000000000..09eb8dd0f924 --- /dev/null +++ b/snippets/pgt-ztp-provisioning-lvm-storage.adoc @@ -0,0 +1,13 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml,subs="attributes+"] +---- +- fileName: StorageLVMOSubscriptionNS.yaml + policyName: subscription-policies +- fileName: StorageLVMOSubscriptionOperGroup.yaml + policyName: subscription-policies +- fileName: StorageLVMOSubscription.yaml + spec: + name: lvms-operator + channel: stable-{product-version} + policyName: subscription-policies +---- diff --git a/snippets/pgt-ztp-the-policygentemplate.adoc b/snippets/pgt-ztp-the-policygentemplate.adoc new file mode 100644 index 000000000000..cd7ed3777688 --- /dev/null +++ b/snippets/pgt-ztp-the-policygentemplate.adoc @@ -0,0 +1,64 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "common-latest" + namespace: "ztp-common" +spec: + bindingRules: + common: "true" <1> + du-profile: "latest" + sourceFiles: <2> + - fileName: SriovSubscriptionNS.yaml + policyName: "subscriptions-policy" + - fileName: SriovSubscriptionOperGroup.yaml + policyName: "subscriptions-policy" + - fileName: SriovSubscription.yaml + policyName: "subscriptions-policy" + - fileName: SriovOperatorStatus.yaml + policyName: "subscriptions-policy" + - fileName: PtpSubscriptionNS.yaml + policyName: "subscriptions-policy" + - fileName: PtpSubscriptionOperGroup.yaml + policyName: "subscriptions-policy" + - fileName: PtpSubscription.yaml + policyName: "subscriptions-policy" + - fileName: PtpOperatorStatus.yaml + policyName: "subscriptions-policy" + - fileName: ClusterLogNS.yaml + policyName: "subscriptions-policy" + - fileName: ClusterLogOperGroup.yaml + policyName: "subscriptions-policy" + - fileName: ClusterLogSubscription.yaml + policyName: "subscriptions-policy" + - fileName: ClusterLogOperatorStatus.yaml + policyName: "subscriptions-policy" + - fileName: StorageNS.yaml + policyName: "subscriptions-policy" + - fileName: StorageOperGroup.yaml + policyName: "subscriptions-policy" + - fileName: StorageSubscription.yaml + policyName: "subscriptions-policy" + - fileName: StorageOperatorStatus.yaml + policyName: "subscriptions-policy" + - fileName: DefaultCatsrc.yaml <3> + policyName: "config-policy" <4> + metadata: + name: redhat-operators-disconnected + spec: + displayName: disconnected-redhat-operators + image: registry.example.com:5000/disconnected-redhat-operators/disconnected-redhat-operator-index:v4.9 + - fileName: DisconnectedICSP.yaml + policyName: "config-policy" + spec: + repositoryDigestMirrors: + - mirrors: + - registry.example.com:5000 + source: registry.redhat.io +---- +<1> `common: "true"` applies the policies to all clusters with this label. +<2> Files listed under `sourceFiles` create the Operator policies for installed clusters. +<3> `DefaultCatsrc.yaml` configures the catalog source for the disconnected registry. +<4> `policyName: "config-policy"` configures Operator subscriptions. The `OperatorHub` CR disables the default and this CR replaces `redhat-operators` with a `CatalogSource` CR that points to the disconnected registry. diff --git a/snippets/pgt-ztp-using-pgt-to-configure-high-performance-mode.yaml b/snippets/pgt-ztp-using-pgt-to-configure-high-performance-mode.yaml new file mode 100644 index 000000000000..345edf98f134 --- /dev/null +++ b/snippets/pgt-ztp-using-pgt-to-configure-high-performance-mode.yaml @@ -0,0 +1,10 @@ +- fileName: PerformanceProfile.yaml + policyName: "config-policy" + metadata: + # ... + spec: + # ... + workloadHints: + realTime: true + highPowerConsumption: true + perPodPowerManagement: false diff --git a/snippets/pgt-ztp-using-pgt-to-configure-performance-mode.yaml b/snippets/pgt-ztp-using-pgt-to-configure-performance-mode.yaml new file mode 100644 index 000000000000..61d4b37ae810 --- /dev/null +++ b/snippets/pgt-ztp-using-pgt-to-configure-performance-mode.yaml @@ -0,0 +1,10 @@ +- fileName: PerformanceProfile.yaml + policyName: "config-policy" + metadata: + # ... + spec: + # ... + workloadHints: + realTime: true + highPowerConsumption: false + perPodPowerManagement: false diff --git a/snippets/pgt-ztp-using-pgt-to-configure-power-saving-mode.adoc b/snippets/pgt-ztp-using-pgt-to-configure-power-saving-mode.adoc new file mode 100644 index 000000000000..0e33606979a2 --- /dev/null +++ b/snippets/pgt-ztp-using-pgt-to-configure-power-saving-mode.adoc @@ -0,0 +1,19 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: PerformanceProfile.yaml + policyName: "config-policy" + metadata: + # ... + spec: + # ... + workloadHints: + realTime: true + highPowerConsumption: false + perPodPowerManagement: true + # ... + additionalKernelArgs: + - # ... + - "cpufreq.default_governor=schedutil" <1> +---- +<1> The `schedutil` governor is recommended, however, other governors that can be used include `ondemand` and `powersave`. diff --git a/snippets/pgt-ztp-using-pgt-to-maximize-power-saving-mode.adoc b/snippets/pgt-ztp-using-pgt-to-maximize-power-saving-mode.adoc new file mode 100644 index 000000000000..34bedf22905e --- /dev/null +++ b/snippets/pgt-ztp-using-pgt-to-maximize-power-saving-mode.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- fileName: TunedPerformancePatch.yaml + policyName: "config-policy" + spec: + profile: + - name: performance-patch + data: | + # ... + [sysfs] + /sys/devices/system/cpu/intel_pstate/max_perf_pct= <1> +---- +<1> The `max_perf_pct` controls the maximum frequency the `cpufreq` driver is allowed to set as a percentage of the maximum supported CPU frequency. This value applies to all CPUs. You can check the maximum supported frequency in `/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq`. As a starting point, you can use a percentage that caps all CPUs at the `All Cores Turbo` frequency. The `All Cores Turbo` frequency is the frequency that all cores will run at when the cores are all fully occupied. diff --git a/snippets/pgt-ztp-worker-node-preparing-policies.adoc b/snippets/pgt-ztp-worker-node-preparing-policies.adoc new file mode 100644 index 000000000000..3abad4dbc6e1 --- /dev/null +++ b/snippets/pgt-ztp-worker-node-preparing-policies.adoc @@ -0,0 +1,80 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "example-sno-workers" + namespace: "example-sno" +spec: + bindingRules: + sites: "example-sno" <1> + mcp: "worker" <2> + sourceFiles: + - fileName: MachineConfigGeneric.yaml <3> + policyName: "config-policy" + metadata: + labels: + machineconfiguration.openshift.io/role: worker + name: enable-workload-partitioning + spec: + config: + storage: + files: + - contents: + source: data:text/plain;charset=utf-8;base64,W2NyaW8ucnVudGltZS53b3JrbG9hZHMubWFuYWdlbWVudF0KYWN0aXZhdGlvbl9hbm5vdGF0aW9uID0gInRhcmdldC53b3JrbG9hZC5vcGVuc2hpZnQuaW8vbWFuYWdlbWVudCIKYW5ub3RhdGlvbl9wcmVmaXggPSAicmVzb3VyY2VzLndvcmtsb2FkLm9wZW5zaGlmdC5pbyIKcmVzb3VyY2VzID0geyAiY3B1c2hhcmVzIiA9IDAsICJjcHVzZXQiID0gIjAtMyIgfQo= + mode: 420 + overwrite: true + path: /etc/crio/crio.conf.d/01-workload-partitioning + user: + name: root + - contents: + source: data:text/plain;charset=utf-8;base64,ewogICJtYW5hZ2VtZW50IjogewogICAgImNwdXNldCI6ICIwLTMiCiAgfQp9Cg== + mode: 420 + overwrite: true + path: /etc/kubernetes/openshift-workload-pinning + user: + name: root + - fileName: PerformanceProfile.yaml + policyName: "config-policy" + metadata: + name: openshift-worker-node-performance-profile + spec: + cpu: <4> + isolated: "4-47" + reserved: "0-3" + hugepages: + defaultHugepagesSize: 1G + pages: + - size: 1G + count: 32 + realTimeKernel: + enabled: true + - fileName: TunedPerformancePatch.yaml + policyName: "config-policy" + metadata: + name: performance-patch-worker + spec: + profile: + - name: performance-patch-worker + data: | + [main] + summary=Configuration changes profile inherited from performance created tuned + include=openshift-node-performance-openshift-worker-node-performance-profile + [bootloader] + cmdline_crash=nohz_full=4-47 <5> + [sysctl] + kernel.timer_migration=1 + [scheduler] + group.ice-ptp=0:f:10:*:ice-ptp.* + [service] + service.stalld=start,enable + service.chronyd=stop,disable + recommend: + - profile: performance-patch-worker +---- +<1> The policies are applied to all clusters with this label. +<2> The `MCP` field must be set to `worker`. +<3> This generic `MachineConfig` CR is used to configure workload partitioning on the worker node. +<4> The `cpu.isolated` and `cpu.reserved` fields must be configured for each particular hardware platform. +<5> The `cmdline_crash` CPU set must match the `cpu.isolated` set in the `PerformanceProfile` section. diff --git a/snippets/ptp-amq-interconnect-eol.adoc b/snippets/ptp-amq-interconnect-eol.adoc index d2810115bf88..4875975de04b 100644 --- a/snippets/ptp-amq-interconnect-eol.adoc +++ b/snippets/ptp-amq-interconnect-eol.adoc @@ -1,3 +1,4 @@ +:_mod-docs-content-type: SNIPPET [NOTE] ==== HTTP transport is the default transport for PTP and bare-metal events. diff --git a/snippets/ztp-creating-hwevents-amqp-hardware-event.adoc b/snippets/ztp-creating-hwevents-amqp-hardware-event.adoc new file mode 100644 index 000000000000..bd91a8084378 --- /dev/null +++ b/snippets/ztp-creating-hwevents-amqp-hardware-event.adoc @@ -0,0 +1,10 @@ +:_mod-docs-content-type: SNIPPET +[source,yaml] +---- +- path: HardwareEvent.yaml + patches: + nodeSelector: {} + transportHost: "amqp://..svc.cluster.local" <1> + logLevel: "info" +---- +<1> The `transportHost` URL is composed of the existing AMQ Interconnect CR `name` and `namespace`. For example, in `transportHost: "amqp://amq-router.amq-router.svc.cluster.local"`, the AMQ Interconnect `name` and `namespace` are both set to `amq-router`. diff --git a/snippets/ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml b/snippets/ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml new file mode 100644 index 000000000000..4f6e605f6f82 --- /dev/null +++ b/snippets/ztp-specifying-nics-in-pgt-hub-cluster-templates.yaml @@ -0,0 +1,80 @@ +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: group-du-sno-pgt + namespace: ztp-group +spec: + bindingRules: + # These policies will correspond to all clusters with these labels + group-du-sno-zone: "zone-1" + hardware-type: "hardware-type-1" + mcp: "master" + sourceFiles: + - fileName: ClusterLogForwarder.yaml # wave 10 + policyName: "group-du-sno-cfg-policy" + spec: + outputs: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-outputs" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' + pipelines: '{{hub fromConfigMap "" "group-zones-configmap" (printf "%s-cluster-log-fwd-pipelines" (index .ManagedClusterLabels "group-du-sno-zone")) | toLiteral hub}}' + + - fileName: PerformanceProfile.yaml # wave 10 + policyName: "group-du-sno-cfg-policy" + metadata: + name: openshift-node-performance-profile + spec: + additionalKernelArgs: + - rcupdate.rcu_normal_after_boot=0 + - vfio_pci.enable_sriov=1 + - vfio_pci.disable_idle_d3=1 + - efi=runtime + cpu: + isolated: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-isolated" (index .ManagedClusterLabels "hardware-type")) hub}}' + reserved: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-cpu-reserved" (index .ManagedClusterLabels "hardware-type")) hub}}' + hugepages: + defaultHugepagesSize: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-default" (index .ManagedClusterLabels "hardware-type")) hub}}' + pages: + - size: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-size" (index .ManagedClusterLabels "hardware-type")) hub}}' + count: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-hugepages-count" (index .ManagedClusterLabels "hardware-type")) | toInt hub}}' + realTimeKernel: + enabled: true + + - fileName: SriovNetwork.yaml # wave 100 + policyName: "group-du-sno-sriov-policy" + metadata: + name: sriov-nw-du-fh + spec: + resourceName: du_fh + vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-1" .ManagedClusterName) | toInt hub}}' + + - fileName: SriovNetworkNodePolicy.yaml # wave 100 + policyName: "group-du-sno-sriov-policy" + metadata: + name: sriov-nnp-du-fh + spec: + deviceType: netdevice + isRdma: false + nicSelector: + pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-1" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' + numVfs: 8 + priority: 10 + resourceName: du_fh + + - fileName: SriovNetwork.yaml # wave 100 + policyName: "group-du-sno-sriov-policy" + metadata: + name: sriov-nw-du-mh + spec: + resourceName: du_mh + vlan: '{{hub fromConfigMap "" "site-data-configmap" (printf "%s-sriov-network-vlan-2" .ManagedClusterName) | toInt hub}}' + + - fileName: SriovNetworkNodePolicy.yaml # wave 100 + policyName: "group-du-sno-sriov-policy" + metadata: + name: sriov-nw-du-fh + spec: + deviceType: netdevice + isRdma: false + nicSelector: + pfNames: '{{hub fromConfigMap "" "group-hardware-types-configmap" (printf "%s-sriov-node-policy-pfNames-2" (index .ManagedClusterLabels "hardware-type")) | toLiteral hub}}' + numVfs: 8 + priority: 10 + resourceName: du_fh \ No newline at end of file diff --git a/snippets/ztp-the-policygenerator-single.yaml b/snippets/ztp-the-policygenerator-single.yaml new file mode 100644 index 000000000000..375cf3d09751 --- /dev/null +++ b/snippets/ztp-the-policygenerator-single.yaml @@ -0,0 +1,152 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: PolicyGenerator +metadata: + name: group-du-sno +placementBindingDefaults: + name: group-du-sno-placement-binding +policyDefaults: + namespace: ztp-group + placement: + labelSelector: + matchExpressions: + - key: group-du-sno + operator: Exists + remediationAction: inform + severity: low + namespaceSelector: + exclude: + - kube-* + include: + - '*' + evaluationInterval: + compliant: 10m + noncompliant: 10s +policies: + - name: group-du-sno-config-policy + policyAnnotations: + ran.openshift.io/ztp-deploy-wave: '10' + manifests: + - path: source-crs/PtpConfigSlave-MCP-master.yaml + patches: + - metadata: null + name: du-ptp-slave + namespace: openshift-ptp + annotations: + ran.openshift.io/ztp-deploy-wave: '10' + spec: + profile: + - name: slave + interface: $interface + ptp4lOpts: '-2 -s' + phc2sysOpts: '-a -r -n 24' + ptpSchedulingPolicy: SCHED_FIFO + ptpSchedulingPriority: 10 + ptpSettings: + logReduce: 'true' + ptp4lConf: | + [global] + # + # Default Data Set + # + twoStepFlag 1 + slaveOnly 1 + priority1 128 + priority2 128 + domainNumber 24 + #utc_offset 37 + clockClass 255 + clockAccuracy 0xFE + offsetScaledLogVariance 0xFFFF + free_running 0 + freq_est_interval 1 + dscp_event 0 + dscp_general 0 + dataset_comparison G.8275.x + G.8275.defaultDS.localPriority 128 + # + # Port Data Set + # + logAnnounceInterval -3 + logSyncInterval -4 + logMinDelayReqInterval -4 + logMinPdelayReqInterval -4 + announceReceiptTimeout 3 + syncReceiptTimeout 0 + delayAsymmetry 0 + fault_reset_interval -4 + neighborPropDelayThresh 20000000 + masterOnly 0 + G.8275.portDS.localPriority 128 + # + # Run time options + # + assume_two_step 0 + logging_level 6 + path_trace_enabled 0 + follow_up_info 0 + hybrid_e2e 0 + inhibit_multicast_service 0 + net_sync_monitor 0 + tc_spanning_tree 0 + tx_timestamp_timeout 50 + unicast_listen 0 + unicast_master_table 0 + unicast_req_duration 3600 + use_syslog 1 + verbose 0 + summary_interval 0 + kernel_leap 1 + check_fup_sync 0 + clock_class_threshold 7 + # + # Servo Options + # + pi_proportional_const 0.0 + pi_integral_const 0.0 + pi_proportional_scale 0.0 + pi_proportional_exponent -0.3 + pi_proportional_norm_max 0.7 + pi_integral_scale 0.0 + pi_integral_exponent 0.4 + pi_integral_norm_max 0.3 + step_threshold 2.0 + first_step_threshold 0.00002 + max_frequency 900000000 + clock_servo pi + sanity_freq_limit 200000000 + ntpshm_segment 0 + # + # Transport options + # + transportSpecific 0x0 + ptp_dst_mac 01:1B:19:00:00:00 + p2p_dst_mac 01:80:C2:00:00:0E + udp_ttl 1 + udp6_scope 0x0E + uds_address /var/run/ptp4l + # + # Default interface options + # + clock_type OC + network_transport L2 + delay_mechanism E2E + time_stamping hardware + tsproc_mode filter + delay_filter moving_median + delay_filter_length 10 + egressLatency 0 + ingressLatency 0 + boundary_clock_jbod 0 + # + # Clock description + # + productDescription ;; + revisionData ;; + manufacturerIdentity 00:00:00 + userDescription ; + timeSource 0xA0 + recommend: + - profile: slave + priority: 4 + match: + - nodeLabel: node-role.kubernetes.io/master diff --git a/snippets/ztp-the-policygentemplate-single.yaml b/snippets/ztp-the-policygentemplate-single.yaml new file mode 100644 index 000000000000..728f2e78d62c --- /dev/null +++ b/snippets/ztp-the-policygentemplate-single.yaml @@ -0,0 +1,20 @@ +apiVersion: ran.openshift.io/v1 +kind: PolicyGenTemplate +metadata: + name: "group-du-sno" + namespace: "ztp-group" +spec: + bindingRules: + group-du-sno: "" + mcp: "master" + sourceFiles: + - fileName: PtpConfigSlave.yaml + policyName: "config-policy" + metadata: + name: "du-ptp-slave" + spec: + profile: + - name: "slave" + interface: "ens5f0" + ptp4lOpts: "-2 -s --summary_interval -4" + phc2sysOpts: "-a -r -n 24" \ No newline at end of file From 08d1cc5891b9b41740bfc1aa19926ca08069662e Mon Sep 17 00:00:00 2001 From: JoeAldinger Date: Wed, 29 May 2024 13:36:33 -0400 Subject: [PATCH 207/339] metrics --- modules/nw-anp-banp-metrics.adoc | 0 networking/nw-anp-banp-metrics.adoc | 50 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 modules/nw-anp-banp-metrics.adoc create mode 100644 networking/nw-anp-banp-metrics.adoc diff --git a/modules/nw-anp-banp-metrics.adoc b/modules/nw-anp-banp-metrics.adoc new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/networking/nw-anp-banp-metrics.adoc b/networking/nw-anp-banp-metrics.adoc new file mode 100644 index 000000000000..614e26107d59 --- /dev/null +++ b/networking/nw-anp-banp-metrics.adoc @@ -0,0 +1,50 @@ +// Module included in the following assemblies: +// +// * list of assemblies where this module is included: +// networking/openshift_network_security/adminnetworkpolicy + +:_mod-docs-content-type: CONCEPT +[id="anp-banp-metrics_{context}"] += AdminNetworkPolicy and BaselineAdminNetworkPolicy metrics + +[cols="1,1,1"] +|=== +| Name |labels/action |Explanation + +|`admin_network_policy_custom_resource_total` +|Not applicable +|The total number of `AdminNetworkPolicy` in the cluster. + +|`baseline_admin_network_policy_custom_resource_total` +|Not applicable +|The total number of `BaselineAdminNetworkPolicy` in the cluster. Values should be 0 or 1. + +|`admin_network_policies_rules` +|*`direction`: specifies either ingress or egress. +* `action`: specifies either `pass`, `allow`, or `deny`. +|The total number of rules across all `AdminNetworkPolicy` in the cluster + +|`baseline_admin_network_policies_rules` +|*`direction`: specifies either ingress or egress. +* `action`: specifies either `pass or `deny`. +|The total number of rules across all `BaselineAdminNetworkPolicy` in the cluster + +| +| +| + +|=== + +[cols="1,1,1"] +|=== +|Cell in column 1, header row |Cell in column 2, header row | cell in column 3 + +|Cell in column 1, row 2 +|Cell in column 2, row 2 + +|Cell in column 1, row 3 +|Cell in column 2, row 3 + +|Cell in column 1, row 4 +|Cell in column 2, row 4 +|=== From 14499650c58478180d413cfc1a55cf0ab29c7ff1 Mon Sep 17 00:00:00 2001 From: JoeAldinger Date: Wed, 29 May 2024 15:13:35 -0400 Subject: [PATCH 208/339] added to assembly for preview --- _topic_maps/_topic_map.yml | 2 + modules/nw-anp-banp-metrics.adoc | 39 +++++++++++++++ .../ovn-k-anp-banp-metrics.adoc | 11 ++++ networking/nw-anp-banp-metrics.adoc | 50 ------------------- 4 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 networking/network_security/AdminNetworkPolicy/ovn-k-anp-banp-metrics.adoc delete mode 100644 networking/nw-anp-banp-metrics.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 742c5821a414..e1726f95a213 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1286,6 +1286,8 @@ Topics: File: ovn-k-anp - Name: About BaselineAdminNetworkPolicy File: ovn-k-banp + - Name: Metrics for AdminNetworkPolicy + File: ovn-k-anp-banp-metrics - Name: Network policy Dir: network_policy Distros: openshift-enterprise, openshift-origin diff --git a/modules/nw-anp-banp-metrics.adoc b/modules/nw-anp-banp-metrics.adoc index e69de29bb2d1..e1e05da42628 100644 --- a/modules/nw-anp-banp-metrics.adoc +++ b/modules/nw-anp-banp-metrics.adoc @@ -0,0 +1,39 @@ +// Module included in the following assemblies: +// +// * list of assemblies where this module is included: +// networking/network_security/AdminNetworkPolicy/nw-ovn-k-anp-banp-metric.adoc + +:_mod-docs-content-type: CONCEPT +[id="anp-banp-metrics_{context}"] += Metrics for AdminNetworkPolicy + +[cols="1,1a,1"] +|=== +| Name | Description |Explanation + +|`ovnkube_controller_admin_network_policies` +|Not applicable +|The total number of `AdminNetworkPolicy` resources in the cluster. + +|`ovnkube_controller_baseline_admin_network_policies` +|Not applicable +|The total number of `BaselineAdminNetworkPolicy` resources in the cluster. The value should be 0 or 1. + +|`ovnkube_controller_admin_network_policies_rules` +|* `direction`: specifies either `Ingress` or `Egress`. +* `action`: specifies either `Pass`, `Allow`, or `Deny`. +|The total number of rules across all ANP policies in the cluster grouped by `direction` and `action`. + +|`ovnkube_controller_baseline_admin_network_policies_rules` +|* `direction`: specifies either `Ingress` or `Egress`. +* `action`: specifies either `Allow` or `Deny`. +|The total number of rules across all BANP policies in the cluster grouped by `direction` and `action`. + +|`ovnkube_controller_admin_network_policies_db_objects` +|`table_name`: specifies either `ACL` or `Address_Set` +|The total number of OVN Northbound database (nbdb) objects that are created by all the ANP in the cluster grouped by the `table_name`. + +|`ovnkube_controller_baseline_admin_network_policies_db_objects` +|`table_name`: specifies either `ACL` or `Address_Set` +|The total number of OVN Northbound database (nbdb) objects that are created by all the BANP in the cluster grouped by the `table_name`. +|=== \ No newline at end of file diff --git a/networking/network_security/AdminNetworkPolicy/ovn-k-anp-banp-metrics.adoc b/networking/network_security/AdminNetworkPolicy/ovn-k-anp-banp-metrics.adoc new file mode 100644 index 000000000000..aad252ae5716 --- /dev/null +++ b/networking/network_security/AdminNetworkPolicy/ovn-k-anp-banp-metrics.adoc @@ -0,0 +1,11 @@ +:_mod-docs-content-type: ASSEMBLY +[id="ovn-k-anp-banp-metrics"] += Monitoring ANP and BANP +include::_attributes/common-attributes.adoc[] +:context: ovn-k-anp-banp-metrics + +toc::[] + +`AdminNetworkPolicy` and `BaselineAdminNetworkPolicy` resources have metrics that can be used for monitoring and managing your policies. See the following table for more details on the metrics. + +include::modules/nw-anp-banp-metrics.adoc[leveloffset=+1] \ No newline at end of file diff --git a/networking/nw-anp-banp-metrics.adoc b/networking/nw-anp-banp-metrics.adoc deleted file mode 100644 index 614e26107d59..000000000000 --- a/networking/nw-anp-banp-metrics.adoc +++ /dev/null @@ -1,50 +0,0 @@ -// Module included in the following assemblies: -// -// * list of assemblies where this module is included: -// networking/openshift_network_security/adminnetworkpolicy - -:_mod-docs-content-type: CONCEPT -[id="anp-banp-metrics_{context}"] -= AdminNetworkPolicy and BaselineAdminNetworkPolicy metrics - -[cols="1,1,1"] -|=== -| Name |labels/action |Explanation - -|`admin_network_policy_custom_resource_total` -|Not applicable -|The total number of `AdminNetworkPolicy` in the cluster. - -|`baseline_admin_network_policy_custom_resource_total` -|Not applicable -|The total number of `BaselineAdminNetworkPolicy` in the cluster. Values should be 0 or 1. - -|`admin_network_policies_rules` -|*`direction`: specifies either ingress or egress. -* `action`: specifies either `pass`, `allow`, or `deny`. -|The total number of rules across all `AdminNetworkPolicy` in the cluster - -|`baseline_admin_network_policies_rules` -|*`direction`: specifies either ingress or egress. -* `action`: specifies either `pass or `deny`. -|The total number of rules across all `BaselineAdminNetworkPolicy` in the cluster - -| -| -| - -|=== - -[cols="1,1,1"] -|=== -|Cell in column 1, header row |Cell in column 2, header row | cell in column 3 - -|Cell in column 1, row 2 -|Cell in column 2, row 2 - -|Cell in column 1, row 3 -|Cell in column 2, row 3 - -|Cell in column 1, row 4 -|Cell in column 2, row 4 -|=== From 746fcb50d55969121560be7e91647d2d6e2683f2 Mon Sep 17 00:00:00 2001 From: bmcelvee Date: Fri, 14 Jun 2024 16:48:44 -0400 Subject: [PATCH 209/339] OSDOCS-10865: Update command to create VPC in Hosted Control Planes guide tutorial --- .../cloud-experts-getting-started-hcp.adoc | 110 +++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/cloud_experts_tutorials/cloud-experts-getting-started/cloud-experts-getting-started-deploying/cloud-experts-getting-started-hcp.adoc b/cloud_experts_tutorials/cloud-experts-getting-started/cloud-experts-getting-started-deploying/cloud-experts-getting-started-hcp.adoc index fe6bff5dd1bf..19c72b095f92 100644 --- a/cloud_experts_tutorials/cloud-experts-getting-started/cloud-experts-getting-started-deploying/cloud-experts-getting-started-hcp.adoc +++ b/cloud_experts_tutorials/cloud-experts-getting-started/cloud-experts-getting-started-deploying/cloud-experts-getting-started-hcp.adoc @@ -31,11 +31,115 @@ In this tutorial, we will create these resources first. We will also set up some rosa list regions --hosted-cp ---- -. Create the VPC. For this tutorial, the following script will create the VPC and its required components for you. It will use the region configured for the `aws` CLI. +. Create the VPC. For this tutorial, the following link:https://github.com/openshift-cs/rosaworkshop/blob/master/rosa-workshop/rosa/resources/setup-vpc.sh[script] creates the VPC and its required components for you. It uses the region configured for the `aws` CLI. + -[source,terminal] +[source,bash] ---- -curl https://raw.githubusercontent.com/openshift-cs/rosaworkshop/master/rosa-workshop/rosa/resources/setup-vpc.sh | bash +#!/bin/bash + +set -e +########## +# This script will create the network requirements for a ROSA cluster. This will be +# a public cluster. This creates: +# - VPC +# - Public and private subnets +# - Internet Gateway +# - Relevant route tables +# - NAT Gateway +# +# This will automatically use the region configured for the aws cli +# +########## + +VPC_CIDR=10.0.0.0/16 +PUBLIC_CIDR_SUBNET=10.0.1.0/24 +PRIVATE_CIDR_SUBNET=10.0.0.0/24 + +# Create VPC +echo -n "Creating VPC..." +VPC_ID=$(aws ec2 create-vpc --cidr-block $VPC_CIDR --query Vpc.VpcId --output text) + +# Create tag name +aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=$CLUSTER_NAME + +# Enable dns hostname +aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames +echo "done." + +# Create Public Subnet +echo -n "Creating public subnet..." +PUBLIC_SUBNET_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_CIDR_SUBNET --query Subnet.SubnetId --output text) + +aws ec2 create-tags --resources $PUBLIC_SUBNET_ID --tags Key=Name,Value=$CLUSTER_NAME-public +echo "done." + +# Create private subnet +echo -n "Creating private subnet..." +PRIVATE_SUBNET_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_CIDR_SUBNET --query Subnet.SubnetId --output text) + +aws ec2 create-tags --resources $PRIVATE_SUBNET_ID --tags Key=Name,Value=$CLUSTER_NAME-private +echo "done." + +# Create an internet gateway for outbound traffic and attach it to the VPC. +echo -n "Creating internet gateway..." +IGW_ID=$(aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text) +echo "done." + +aws ec2 create-tags --resources $IGW_ID --tags Key=Name,Value=$CLUSTER_NAME + +aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID > /dev/null 2>&1 +echo "Attached IGW to VPC." + +# Create a route table for outbound traffic and associate it to the public subnet. +echo -n "Creating route table for public subnet..." +PUBLIC_ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --query RouteTable.RouteTableId --output text) + +aws ec2 create-tags --resources $PUBLIC_ROUTE_TABLE_ID --tags Key=Name,Value=$CLUSTER_NAME +echo "done." + +aws ec2 create-route --route-table-id $PUBLIC_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID > /dev/null 2>&1 +echo "Created default public route." + +aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_ID --route-table-id $PUBLIC_ROUTE_TABLE_ID > /dev/null 2>&1 +echo "Public route table associated" + +# Create a NAT gateway in the public subnet for outgoing traffic from the private network. +echo -n "Creating NAT Gateway..." +NAT_IP_ADDRESS=$(aws ec2 allocate-address --domain vpc --query AllocationId --output text) + +NAT_GATEWAY_ID=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_ID --allocation-id $NAT_IP_ADDRESS --query NatGateway.NatGatewayId --output text) + +aws ec2 create-tags --resources $NAT_IP_ADDRESS --resources $NAT_GATEWAY_ID --tags Key=Name,Value=$CLUSTER_NAME +sleep 10 +echo "done." + +# Create a route table for the private subnet to the NAT gateway. +echo -n "Creating a route table for the private subnet to the NAT gateway..." +PRIVATE_ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --query RouteTable.RouteTableId --output text) + +aws ec2 create-tags --resources $PRIVATE_ROUTE_TABLE_ID $NAT_IP_ADDRESS --tags Key=Name,Value=$CLUSTER_NAME-private + +aws ec2 create-route --route-table-id $PRIVATE_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $NAT_GATEWAY_ID > /dev/null 2>&1 + +aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_ID --route-table-id $PRIVATE_ROUTE_TABLE_ID > /dev/null 2>&1 + +echo "done." + +# echo "***********VARIABLE VALUES*********" +# echo "VPC_ID="$VPC_ID +# echo "PUBLIC_SUBNET_ID="$PUBLIC_SUBNET_ID +# echo "PRIVATE_SUBNET_ID="$PRIVATE_SUBNET_ID +# echo "PUBLIC_ROUTE_TABLE_ID="$PUBLIC_ROUTE_TABLE_ID +# echo "PRIVATE_ROUTE_TABLE_ID="$PRIVATE_ROUTE_TABLE_ID +# echo "NAT_GATEWAY_ID="$NAT_GATEWAY_ID +# echo "IGW_ID="$IGW_ID +# echo "NAT_IP_ADDRESS="$NAT_IP_ADDRESS + +echo "Setup complete." +echo "" +echo "To make the cluster create commands easier, please run the following commands to set the environment variables:" +echo "export PUBLIC_SUBNET_ID=$PUBLIC_SUBNET_ID" +echo "export PRIVATE_SUBNET_ID=$PRIVATE_SUBNET_ID" ---- + For more about VPC requirements, see the xref:../../../rosa_planning/rosa-sts-aws-prereqs.adoc#rosa-vpc_rosa-sts-aws-prereqs[VPC documentation]. From b6238f58fab29b7781de881f349877418f02256e Mon Sep 17 00:00:00 2001 From: RichardHoch Date: Sun, 2 Jun 2024 11:25:47 +0300 Subject: [PATCH 210/339] Add scanning for deprecated images to the 'Updating deprecated internal images' troubleshooting procedure --- ...n-updating-deprecated-internal-images.adoc | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/modules/migration-updating-deprecated-internal-images.adoc b/modules/migration-updating-deprecated-internal-images.adoc index 05db06943c56..6b1cbb6134aa 100644 --- a/modules/migration-updating-deprecated-internal-images.adoc +++ b/modules/migration-updating-deprecated-internal-images.adoc @@ -25,28 +25,39 @@ If an {product-title} 3 image is deprecated in {product-title} {product-version} The {product-registry} is exposed by default on {product-title} 4. . If you are using insecure registries, add your registry host values to the `[registries.insecure]` section of `/etc/container/registries.conf` to ensure that `podman` does not encounter a TLS verification error. -. Log in to the {product-title} 3 registry: +. Log in to the {product-title} 3 registry by running the following command: + [source,terminal] ---- $ podman login -u $(oc whoami) -p $(oc whoami -t) --tls-verify=false : ---- -. Log in to the {product-title} 4 registry: +. Log in to the {product-title} 4 registry by running the following command: + [source,terminal] ---- $ podman login -u $(oc whoami) -p $(oc whoami -t) --tls-verify=false : ---- -. Pull the {product-title} 3 image: +. Pull the {product-title} 3 image by running the following command: + [source,terminal] ---- $ podman pull :/openshift/ ---- -. Tag the {product-title} 3 image for the {product-title} 4 registry: +. Scan the {product-title} 3 image for deprecated namespaces by running the following command: ++ +[source,terminal] +---- +$ oc get bc --all-namespaces --template='range .items +"BuildConfig:" .metadata.namespace/.metadata.name => +"\t""ImageStream(FROM):" .spec.strategy.sourceStrategy.from.namespace/.spec.strategy.sourceStrategy.from.name +"\t""ImageStream(TO):" .spec.output.to.namespace/.spec.output.to.name +end' +---- + +. Tag the {product-title} 3 image for the {product-title} 4 registry by running the following command: + [source,terminal] ---- @@ -56,7 +67,7 @@ $ podman tag :/openshift/ \ <1> <1> Specify the registry URL and port for the {product-title} 3 cluster. <2> Specify the registry URL and port for the {product-title} 4 cluster. -. Push the image to the {product-title} 4 registry: +. Push the image to the {product-title} 4 registry by running the following command: + [source,terminal] ---- @@ -64,7 +75,7 @@ $ podman push :/openshift/ <1> ---- <1> Specify the {product-title} 4 cluster. -. Verify that the image has a valid image stream: +. Verify that the image has a valid image stream by running the following command: + [source,terminal] ---- From ad729b7c7c96b3f9e6fd795831433dc1564651dd Mon Sep 17 00:00:00 2001 From: Andrew Taylor Date: Tue, 18 Jun 2024 07:28:06 -0400 Subject: [PATCH 211/339] OSDOCS-9885: updated the TechPreviewNoUpgrade list --- ...nodes-cluster-enabling-features-about.adoc | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/modules/nodes-cluster-enabling-features-about.adoc b/modules/nodes-cluster-enabling-features-about.adoc index 57f6ffa03121..5605ffb18d4b 100644 --- a/modules/nodes-cluster-enabling-features-about.adoc +++ b/modules/nodes-cluster-enabling-features-about.adoc @@ -31,7 +31,6 @@ The following Technology Preview features are enabled by this feature set: ** StatefulSet pod availability upgrading limits. Enables users to define the maximum number of statefulset pods unavailable during updates which reduces application downtime. (`MaxUnavailableStatefulSet`) ** Admin Network Policy and Baseline Admin Network Policy. Enables `AdminNetworkPolicy` and `BaselineAdminNetworkPolicy` resources, which are part of the Network Policy V2 API, in clusters running the OVN-Kubernetes CNI plugin. Cluster administrators can apply cluster-scoped policies and safeguards for an entire cluster before namespaces are created. Network administrators can secure clusters by enforcing network traffic controls that cannot be overridden by users. Network administrators can enforce optional baseline network traffic controls that can be overridden by users in the cluster, if necessary. Currently, these APIs support only expressing policies for intra-cluster traffic. (`AdminNetworkPolicy`) ** `MatchConditions` is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of `matchConditions` matches all requests. (`admissionWebhookMatchConditions`) -** Gateway API. To enable the {product-title} Gateway API, set the value of the `enabled` field to `true` in the `techPreview.gatewayAPI` specification of the `ServiceMeshControlPlane` resource.(`gateGatewayAPI`) ** `gcpLabelsTags` ** `vSphereStaticIPs` ** `routeExternalCertificate` @@ -47,6 +46,38 @@ The following Technology Preview features are enabled by this feature set: ** `managedBootImages` ** `onClusterBuild` ** `signatureStores` +** `DisableKubeletCloudCredentialProviders` +** `BareMetalLoadBalancer` +** `ClusterAPIInstallAWS` +** `ClusterAPIInstallNutanix` +** `ClusterAPIInstallOpenStack` +** `ClusterAPIInstallVSphere` +** `HardwareSpeed` +** `KMSv1` +** `NetworkDiagnosticsConfig` +** `VSphereDriverConfiguration` +** `ExternalOIDC` +** `ChunkSizeMiB` +** `ClusterAPIInstallGCP` +** `ClusterAPIInstallPowerVS` +** `EtcdBackendQuota` +** `Example` +** `ExternalRouteCertificate` +** `ImagePolicy` +** `InsightsConfig` +** `InsightsOnDemandDataGather` +** `MetricsCollectionProfiles` +** `NewOLM` +** `NodeDisruptionPolicy` +** `PinnedImages` +** `PlatformOperators` +** `ServiceAccountTokenNodeBinding` +** `ServiceAccountTokenNodeBindingValidation` +** `ServiceAccountTokenPodNodeInfo` +** `TranslateStreamCloseWebsocketRequests` +** `UpgradeStatus` +** `VSphereMultiVCenters` +** `VolumeGroupSnapshot` -- //// From 2f7cff94ece6f2f44fd58145d4d0f9e750a30132 Mon Sep 17 00:00:00 2001 From: shreyasiddhartha Date: Mon, 10 Jun 2024 12:21:31 +0530 Subject: [PATCH 212/339] Logging 5.9.3 Release Notes --- modules/logging-release-notes-5-9-2.adoc | 2 +- modules/logging-release-notes-5-9-3.adoc | 21 +++++++++++++++++++ .../logging-5-9-release-notes.adoc | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 modules/logging-release-notes-5-9-3.adoc diff --git a/modules/logging-release-notes-5-9-2.adoc b/modules/logging-release-notes-5-9-2.adoc index 6b314e4ae57b..928aa474a73b 100644 --- a/modules/logging-release-notes-5-9-2.adoc +++ b/modules/logging-release-notes-5-9-2.adoc @@ -1,4 +1,4 @@ -/module included in logging-5-9-release-notes.adoc +// module included in logging-5-9-release-notes.adoc :_mod-docs-content-type: REFERENCE [id="logging-release-notes-5-9-2_{context}"] = Logging 5.9.2 diff --git a/modules/logging-release-notes-5-9-3.adoc b/modules/logging-release-notes-5-9-3.adoc new file mode 100644 index 000000000000..e13553abca85 --- /dev/null +++ b/modules/logging-release-notes-5-9-3.adoc @@ -0,0 +1,21 @@ +// module included in logging-5-9-release-notes.adoc +:_mod-docs-content-type: REFERENCE +[id="logging-release-notes-5-9-3_{context}"] += Logging 5.9.3 +This release includes link:https://access.redhat.com/errata/RHBA-2024:3736[OpenShift Logging Bug Fix Release 5.9.3] + +[id="logging-release-notes-5-9-3-bug-fixes"] +== Bug Fixes + +* Before this update, there was a delay in restarting Ingesters when configuring `LokiStack`, because the {loki-op} sets the write-ahead log `replay_memory_ceiling` to zero bytes for the `1x.demo` size. With this update, the minimum value used for the `replay_memory_ceiling` has been increased to avoid delays. (link:https://issues.redhat.com/browse/LOG-5614[LOG-5614]) + +* Before this update, monitoring the Vector collector output buffer state was not possible. With this update, monitoring and alerting the Vector collector output buffer size is possible that improves observability capabilities and helps keep the system running optimally. (link:https://issues.redhat.com/browse/LOG-5586[LOG-5586]) + +[id="logging-release-notes-5-9-3-CVEs"] +== CVEs +* link:https://access.redhat.com/security/cve/CVE-2024-2961[CVE-2024-2961] +* link:https://access.redhat.com/security/cve/CVE-2024-28182[CVE-2024-28182] +* link:https://access.redhat.com/security/cve/CVE-2024-33599[CVE-2024-33599] +* link:https://access.redhat.com/security/cve/CVE-2024-33600[CVE-2024-33600] +* link:https://access.redhat.com/security/cve/CVE-2024-33601[CVE-2024-33601] +* link:https://access.redhat.com/security/cve/CVE-2024-33602[CVE-2024-33602] \ No newline at end of file diff --git a/observability/logging/logging_release_notes/logging-5-9-release-notes.adoc b/observability/logging/logging_release_notes/logging-5-9-release-notes.adoc index 071aafadda66..268de051fb3b 100644 --- a/observability/logging/logging_release_notes/logging-5-9-release-notes.adoc +++ b/observability/logging/logging_release_notes/logging-5-9-release-notes.adoc @@ -10,6 +10,8 @@ include::snippets/logging-compatibility-snip.adoc[] include::snippets/logging-stable-updates-snip.adoc[] +include::modules/logging-release-notes-5-9-3.adoc[leveloffset=+1] + include::modules/logging-release-notes-5-9-2.adoc[leveloffset=+1] include::modules/logging-release-notes-5-9-1.adoc[leveloffset=+1] From 9382d3e7f797330cac61cecfe895f9e7e532e8ab Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Wed, 29 May 2024 14:39:25 -0400 Subject: [PATCH 213/339] Adds live migration procedures for sdn to ovnk --- .../how-the-live-migration-process-works.adoc | 102 ++++++++++++++++ .../live-migration-metrics-information.adoc | 54 +++++++++ .../nw-network-plugin-migration-process.adoc | 8 +- ...netes-checking-live-migration-metrics.adoc | 75 ++++++++++++ ...w-ovn-kubernetes-live-migration-about.adoc | 88 ++++++++++++++ modules/nw-ovn-kubernetes-live-migration.adoc | 113 ++++++++++++++++++ .../nw-ovn-kubernetes-migration-about.adoc | 45 ++++--- modules/nw-ovn-kubernetes-migration.adoc | 4 +- .../migrate-from-openshift-sdn.adoc | 10 +- .../network-operator-openshift-io-v1.adoc | 2 +- 10 files changed, 478 insertions(+), 23 deletions(-) create mode 100644 modules/how-the-live-migration-process-works.adoc create mode 100644 modules/live-migration-metrics-information.adoc create mode 100644 modules/nw-ovn-kubernetes-checking-live-migration-metrics.adoc create mode 100644 modules/nw-ovn-kubernetes-live-migration-about.adoc create mode 100644 modules/nw-ovn-kubernetes-live-migration.adoc diff --git a/modules/how-the-live-migration-process-works.adoc b/modules/how-the-live-migration-process-works.adoc new file mode 100644 index 000000000000..baba295405fe --- /dev/null +++ b/modules/how-the-live-migration-process-works.adoc @@ -0,0 +1,102 @@ +// Module included in the following assemblies: +// +// * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc + +ifeval::["{context}" == "migrate-to-openshift-sdn"] +:sdn: OpenShift SDN +:previous-sdn: OVN-Kubernetes +:type: OpenShiftSDN +endif::[] +ifeval::["{context}" == "migrate-from-openshift-sdn"] +:sdn: OVN-Kubernetes +:previous-sdn: OpenShift SDN +:type: OVNKubernetes +endif::[] + +[id="how-the-live-migration-process-works_{context}"] += How the live migration process works + +The following table summarizes the live migration process by segmenting between the user-initiated steps in the process and the actions that the migration script performs in response. + +.Live migration to OVNKubernetes from OpenShiftSDN +[cols="1,1a",options="header"] +|=== +|User-initiated steps|Migration activity +ifdef::openshift-rosa,openshift-dedicated[] +| Add the `unsupported-red-hat-internal-testing` annotation to the cluster-level network configuration. +| The Cluster Network Operator (CNO) acknowledges the unsupported testing environment. +endif::[] + +| Patch the cluster-level networking configuration by changing the `networkType` from `OpenShiftSDN` to `OVNKubernetes`. +| +Cluster Network Operator (CNO):: ++ +-- +* Sets migration-related fields in the `network.operator` custom resource (CR) and waits for routable MTUs to be applied to all nodes. +* Patches the `network.operator` CR to set the migration mode to `Live` for OVN-Kubernetes and deploys the OpenShift SDN network plugin in migration mode. +* Deploys OVN-Kubernetes with hybrid overlay enabled, ensuring that no racing conditions occur. +* Waits for the OVN-Kubernetes deployment and updates the conditions in the status of the `network.config` CR. +* Triggers the Machine Config Operator (MCO) to apply the new machine config to each machine config pool, which includes node cordoning, draining, and rebooting. +* OVN-Kubernetes adds nodes to the appropriate zones and recreates pods using OVN-Kubernetes as the default CNI plugin. +* Removes migration-related fields from the network.operator CR and performs cleanup actions, such as deleting OpenShift SDN resources and redeploying OVN-Kubernetes in normal mode with the necessary configurations. +* Waits for the OVN-Kubernetes redeployment and updates the status conditions in the `network.config` CR to indicate migration completion. If your migration is blocked, see "Checking live migration metrics" for information on troubleshooting the issue. +-- +|=== + +//// +ifeval::["{context}" == "migrate-from-openshift-sdn"] +If a rollback to OpenShift SDN is required, the following table describes the process. + +[IMPORTANT] +==== +You must wait until the migration process from OpenShift SDN to OVN-Kubernetes network plugin is successful before initiating a rollback. +==== + +.Performing a rollback to OpenShift SDN +[cols="1,1a",options="header"] +|=== + +|User-initiated steps|Migration activity + +|Suspend the MCO to ensure that it does not interrupt the migration. +|The MCO stops. + +| +Set the `migration` field of the `Network.operator.openshift.io` custom resource (CR) named `cluster` to `OpenShiftSDN`. Make sure the `migration` field is `null` before setting it to a value. +| +CNO:: Updates the status of the `Network.config.openshift.io` CR named `cluster` accordingly. + +|Update the `networkType` field. +| +CNO:: Performs the following actions: ++ +-- +* Destroys the OVN-Kubernetes control plane pods. +* Deploys the OpenShift SDN control plane pods. +* Updates the Multus objects to reflect the new network plugin. +-- + +| +Reboot each node in the cluster. +| +Cluster:: As nodes reboot, the cluster assigns IP addresses to pods on the OpenShift-SDN network. + +| +Enable the MCO after all nodes in the cluster reboot. +| +MCO:: Rolls out an update to the systemd configuration necessary for OpenShift SDN; the MCO updates a single machine per pool at a time by default, so the total time the migration takes increases with the size of the cluster. + +|=== +endif::[] + +//// + +ifdef::sdn[] +:!sdn: +endif::[] +ifdef::previous-sdn[] +:!previous-sdn: +endif::[] +ifdef::type[] +:!type: +endif::[] diff --git a/modules/live-migration-metrics-information.adoc b/modules/live-migration-metrics-information.adoc new file mode 100644 index 000000000000..dfc51e5d1858 --- /dev/null +++ b/modules/live-migration-metrics-information.adoc @@ -0,0 +1,54 @@ +// Module included in the following assemblies: +// +// * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc + +:_mod-docs-content-type: PROCEDURE +[id="live-migration-metrics-information"] += Information about live migration metrics + +The following table shows you the available metrics and the label values populated from the `openshift_network_operator_live_migration_procedure` expression. Use this information to monitor progress or to troubleshoot the migration. + + +.Live migration metrics +[cols="1a,1a",options="header"] +|=== +| Metric | Label values +| +*`openshift_network_operator_live_migration_blocked:`*:: ++ +-- +A Prometheus gauge vector metric. A metric that contains a constant `1` value labeled with the reason that the CNI live migration might not have started. This metric is available when the CNI live migration has started by annotating the `Network` custom resource. + +This metric is not published unless the live migration is blocked. +-- +| +The list of label values includes the following:: ++ +-- +* `UnsupportedCNI`: Unable to migrate to the unsupported target CNI. Valid CNI is `OVNKubernetes` when migrating from OpenShift SDN. +* `UnsupportedHyperShiftCluster`: Live migration is unsupported within an HCP cluster. +* `UnsupportedSDNNetworkIsolationMode`: OpenShift SDN is configured with an unsupported network isolation mode `Multitenant`. Migrate to a supported network isolation mode before performing live migration. +* `UnsupportedMACVLANInterface`: Remove the egress router or any pods which contain the pod annotation `pod.network.openshift.io/assign-macvlan`. +Find the offending pod's namespace or pod name with the following command: + + + +`oc get pods -Ao=jsonpath='{range .items[?(@.metadata.annotations.pod\.network\.openshift\.io/assign-macvlan=="")]}{@.metadata.namespace}{"\t"}{@.metadata.name}{"\n"}'`. +-- + +| +*`openshift_network_operator_live_migration_condition:`*:: ++ +-- +A metric which represents the status of each condition type for the CNI live migration. The set of status condition types is defined for `network.config` to support observability of the CNI live migration. + +A `1` value represents condition status `true`. A `0` value represents `false`. `-1` represents unknown. This metric is available when the CNI live migration has started by annotating the `Network` custom resource (CR). + +This metric is only available when the live migration has been triggered by adding the relevant annotation to the `Network` CR cluster, otherwise, it is not published. If the following condition types are not present within the Network CR cluster, the metric and their labels are cleared. +-- +| +The list of label values includes the following:: ++ +-- +* `NetworkTypeMigrationInProgress` +* `NetworkTypeMigrationTargetCNIAvailable` +* `NetworkTypeMigrationTargetCNIInUse` +* `NetworkTypeMigrationOriginalCNIPurged` +* `NetworkTypeMigrationMTUReady` +-- +|=== diff --git a/modules/nw-network-plugin-migration-process.adoc b/modules/nw-network-plugin-migration-process.adoc index c69d1123a464..3a8c860f2b4a 100644 --- a/modules/nw-network-plugin-migration-process.adoc +++ b/modules/nw-network-plugin-migration-process.adoc @@ -15,11 +15,11 @@ ifeval::["{context}" == "migrate-from-openshift-sdn"] endif::[] [id="how-the-migration-process-works_{context}"] -= How the migration process works += How the offline migration process works The following table summarizes the migration process by segmenting between the user-initiated steps in the process and the actions that the migration performs in response. -.Migrating to {sdn} from {previous-sdn} +.Offline migration to {sdn} from {previous-sdn} [cols="1,1a",options="header"] |=== @@ -38,7 +38,7 @@ CNO:: Performs the following actions: -- * Destroys the {previous-sdn} control plane pods. * Deploys the {sdn} control plane pods. -* Updates the Multus objects to reflect the new network plugin. +* Updates the Multus daemon sets and config map objects to reflect the new network plugin. -- | @@ -48,6 +48,7 @@ Cluster:: As nodes reboot, the cluster assigns IP addresses to pods on the {sdn} |=== +//// ifeval::["{context}" == "migrate-from-openshift-sdn"] If a rollback to OpenShift SDN is required, the following table describes the process. @@ -92,6 +93,7 @@ MCO:: Rolls out an update to the systemd configuration necessary for OpenShift S |=== endif::[] +//// ifdef::sdn[] :!sdn: diff --git a/modules/nw-ovn-kubernetes-checking-live-migration-metrics.adoc b/modules/nw-ovn-kubernetes-checking-live-migration-metrics.adoc new file mode 100644 index 000000000000..23ee0628b401 --- /dev/null +++ b/modules/nw-ovn-kubernetes-checking-live-migration-metrics.adoc @@ -0,0 +1,75 @@ +// Module included in the following assemblies: +// +// * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc + +:_mod-docs-content-type: PROCEDURE +[id="checking-live-migration-metrics"] += Checking live migration metrics + +Metrics are available to monitor the progress of the live migration. Metrics can be viewed on the {product-title} web console, or by using the `oc` CLI. + +.Prerequisites + +* You have initiated a live migration to OVN-Kubernetes. + +.Procedure + +. To view live migration metrics on the {product-title} web console: + +.. Click *Observe* -> *Metrics*. + +.. In the *Expression* box, type *openshift_network* and click the *openshift_network_operator_live_migration_procedure* option. + +. To view metrics by using the `oc` CLI: + +.. Enter the following command to generate a token for the `prometheus-k8s` service account in the `openshift-monitoring` namespace: ++ +[source,terminal] +---- +$ oc create token prometheus-k8s -n openshift-monitoring +---- ++ +.Example output ++ +[source,terminal] +---- +eyJhbGciOiJSUzI1NiIsImtpZCI6IlZiSUtwclcwbEJ2VW9We... +---- + +.. Enter the following command to request information about the `openshift_network_operator_live_migration_condition` metric: ++ +[source,terminal] +---- +$ oc -n openshift-monitoring exec -c prometheus prometheus-k8s-0 -- curl -k -H "Authorization: " "https://" --data-urlencode "query=openshift_network_operator_live_migration_condition" | jq` +---- ++ +.Example output ++ +[source,terminal] +---- + "status": "success", + "data": { + "resultType": "vector", + "result": [ + { + "metric": { + "__name__": "openshift_network_operator_live_migration_condition", + "container": "network-operator", + "endpoint": "metrics", + "instance": "10.0.83.62:9104", + "job": "metrics", + "namespace": "openshift-network-operator", + "pod": "network-operator-6c87754bc6-c8qld", + "prometheus": "openshift-monitoring/k8s", + "service": "metrics", + "type": "NetworkTypeMigrationInProgress" + }, + "value": [ + 1717653579.587, + "1" + ] + }, +... +---- + +The table in "Information about live migration metrics" shows you the available metrics and the label values populated from the `openshift_network_operator_live_migration_procedure` expression. Use this information to monitor progress or to troubleshoot the migration. \ No newline at end of file diff --git a/modules/nw-ovn-kubernetes-live-migration-about.adoc b/modules/nw-ovn-kubernetes-live-migration-about.adoc new file mode 100644 index 000000000000..37fe568c0556 --- /dev/null +++ b/modules/nw-ovn-kubernetes-live-migration-about.adoc @@ -0,0 +1,88 @@ +// Module included in the following assemblies: +// +// * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc + +[id="nw-ovn-kubernetes-live-migration-about_{context}"] += Live migration to the OVN-Kubernetes network plugin overview + +The live migration method is the process in which the OpenShift SDN network plugin and its network configurations, connections, and associated resources, are migrated to the OVN-Kubernetes network plugin without service interruption. It is available for {product-title}, {product-dedicated}, {product-rosa}, and Azure Red Hat OpenShift deployment types. It is not available for HyperShift deployment types. This migration method is valuable for deployment types that require constant service availability and offers the following benefits: + +* Continuous service availability +* Minimized downtime +* Automatic node rebooting +* Seamless transition from the OpenShift SDN network plugin to the OVN-Kubernetes network plugin + +Although a rollback procedure is provided, the live migration is intended to be a one-way process. + +include::snippets/sdn-deprecation-statement.adoc[] + +The following sections provide more information about the live migration method. + +[id="supported-platforms-live-migrating-ovn-kubernetes"] +== Supported platforms when using the live migration method + +The following table provides information about the supported platforms for the live migration type. + +.Supported platforms for the live migration method +[cols="1,1", options="header"] +|=== +| Platform | Live Migration + +| Bare metal hardware (IPI and UPI) |✓ +| Amazon Web Services (AWS) (IPI and UPI) |✓ +| Google Cloud Platform (GCP) (IPI and UPI) |✓ +| {ibm-cloud-name} (IPI and UPI) |✓ +| Microsoft Azure (IPI and UPI) |✓ +| {rh-openstack-first} (IPI and UPI) |✓ +| VMware vSphere (IPI and UPI) |✓ +| AliCloud (IPI and UPI) |✓ +| Nutanix (IPI and UPI) |✓ +|=== + +[id="considerations-live-migrating-ovn-kubernetes-network-provider_{context}"] +== Considerations for live migration to the OVN-Kubernetes network plugin + +Before using the live migration method to the OVN-Kubernetes network plugin, cluster administrators should consider the following information: + +* The live migration procedure is unsupported for clusters with OpenShift SDN multitenant mode enabled. + +* Egress router pods block the live migration process. They must be removed before beginning the live migration process. + +* During the live migration, multicast, egress IP addresses, and egress firewalls are temporarily disabled. They can be migrated from OpenShift SDN to OVN-Kubernetes after the live migration process has finished. + +* The migration is intended to be a one-way process. However, for users that want to rollback to OpenShift-SDN, migration from OpenShift-SDN to OVN-Kubernetes must have succeeded. Users can follow the same procedure below to migrate to the OpenShift SDN network plugin from the OVN-Kubernetes network plugin. + +* The live migration is not supported on HyperShift clusters. + +* OpenShift SDN does not support IPsec. After the migration, cluster administrators can enable IPsec. + +* OpenShift SDN does not support IPv6. After the migration, cluster administrators can enable dual-stack. + +* The cluster MTU is the MTU value for pod interfaces. It is always less than your hardware MTU to account for the cluster network overlay overhead. The overhead is 100 bytes for OVN-Kubernetes and 50 bytes for OpenShift SDN. ++ +During the live migration, both OVN-Kubernetes and OpenShift SDN run in parallel. OVN-Kubernetes manages the cluster network of some nodes, while OpenShift SDN manages the cluster network of others. To ensure that cross-CNI traffic remains functional, the Cluster Network Operator updates the routable MTU to ensure that both CNIs share the same overlay MTU. As a result, after the migration has completed, the cluster MTU is 50 bytes less. + +* Some parameters of OVN-Kubernetes cannot be changed after installation. The following parameters can be set only before starting the live migration: + +** `InternalTransitSwitchSubnet` +** `internalJoinSubnet` + +* Unless otherwise configured, OVN-Kubernetes uses the following IP address ranges: +** `100.64.0.0/1`. This IP address range is used for the `internalJoinSubnet` parameter of OVN-Kubernetes by default. If this IP address range is already in use, enter the following command to update it to `100.63.0.0/16`: ++ +[source,terminal] +---- +$ oc patch network.operator.openshift.io cluster --type='merge' -p='{"spec":{"defaultNetwork":{"ovnKubernetesConfig":{"ipv4":{"internalJoinSubnet": "100.63.0.0/16"}}}}}' +---- +** `100.88.0.0/16`. This IP address range is used for the `internalTransSwitchSubnet` parameter of OVN-Kubernetes by default. If this IP address range is already in use by another network, enter the following command to update it to `100.99.0.0/16`: ++ +[source,terminal] +---- +$ oc patch network.operator.openshift.io cluster --type='merge' -p='{"spec":{"defaultNetwork":{"ovnKubernetesConfig":{"ipv4":{"internalTransitSwitchSubnet": "100.99.0.0/16"}}}}}' +---- + +* In most cases, the live migration is independent of the secondary interfaces of pods created by the Multus CNI plugin. However, if these secondary interfaces were set up on the default network interface controller (NIC) of the host, for example, using MACVLAN, IPVLAN, SR-IOV, or bridge interfaces with the default NIC as the control node, OVN-Kubernetes might encounter malfunctions. Users should remove such configurations before proceeding with the live migration. + +* When there are multiple NICs inside of the host, and the default route is not on the interface that has the Kubernetes NodeIP, you must use the offline migration instead. + +* All `DaemonSet` objects in the `openshift-sdn` namespace, which are not managed by the Cluster Network Operator (CNO), must be removed before initiating the live migration. These unmanaged daemon sets can cause the migration status to remain incomplete if not properly handled. \ No newline at end of file diff --git a/modules/nw-ovn-kubernetes-live-migration.adoc b/modules/nw-ovn-kubernetes-live-migration.adoc new file mode 100644 index 000000000000..3af7f382e8a5 --- /dev/null +++ b/modules/nw-ovn-kubernetes-live-migration.adoc @@ -0,0 +1,113 @@ +// Module included in the following assemblies: +// +// * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc +// * networking/openshift_sdn/rollback-to-ovn-kubernetes.adoc + +:_mod-docs-content-type: PROCEDURE +[id="nw-ovn-kubernetes-live-migration_{context}"] += Migrating to the OVN-Kubernetes network plugin by using the live migration method + +The following procedure checks for egress router resources and uses the live migration method to migrate from the OpenShift SDN network plugin to the OVN-Kubernetes network plugin. + +.Prerequisites + +* A cluster has been configured with the OpenShift SDN CNI network plugin in the network policy isolation mode. +* You have installed the OpenShift CLI (`oc`). +* You have access to the cluster as a user with the `cluster-admin` role. +* You have created a recent backup of the etcd database. +* The cluster is in a known good state without any errors. +* Before migration to OVN-Kubernetes, a security group rule must be in place to allow UDP packets on port `6081` for all nodes on all cloud platforms. +* Cluster administrators must remove any egress router pods before beginning the live migration. For more information about egress router pods, see "Deploying an egress router pod in redirect mode". +* You have reviewed the "Considerations for live migration to the OVN-Kubernetes network plugin" section of this document. + +.Procedure + +. Before initiating the live migration, you must check for any egress router pods. If there is an egress router pod on the cluster when performing a live migration, the Network Operator blocks the migration and returns the following error: ++ +[source,text] +---- +The cluster configuration is invalid (network type live migration is not supported for pods with `pod.network.openshift.io/assign-macvlan` annotation. Please remove all egress router pods). Use `oc edit network.config.openshift.io cluster` to fix. +---- ++ +** Enter the following command to locate egress router pods on your cluster: ++ +[source,terminal] +---- +$ oc get pods --all-namespaces -o json | jq '.items[] | select(.metadata.annotations."pod.network.openshift.io/assign-macvlan" == "true") | {name: .metadata.name, namespace: .metadata.namespace}' +---- ++ +.Example output ++ +[source,terminal] +---- +{ + "name": "egress-multi", + "namespace": "egress-router-project" +} +---- ++ +** Alternatively, you can query metrics on the {product-title} web console or by using the `oc` CLI to check for egress router pods. For more information, see "Checking live migration metrics". + +. Enter the following command to remove an egress router pod: ++ +[source,terminal] +---- +$ oc delete pod -n +---- + +ifdef::openshift-rosa,openshift-dedicated[] +. Enter the following command to add the `unsupported-red-hat-internal-testing` annotation to the cluster-level network configuration: ++ +[source,terminal] +---- +$ oc patch Network.config.openshift.io cluster --type='merge' --patch '{"metadata":{"annotations":{"unsupported-red-hat-internal-testing": "true"}}}' +---- +endif::[] + +. Enter the following command to patch the cluster-level networking configuration and initiate the migration from OpenShift SDN to OVN-Kubernetes: ++ +[source,terminal] +---- +$ oc patch Network.config.openshift.io cluster --type='merge' --patch '{"metadata":{"annotations":{"network.openshift.io/network-type-migration":""}},"spec":{"networkType":"OVNKubernetes"}}' +---- ++ +After running these commands, the migration process begins. During this process, the Machine Config Operator reboots the nodes in your cluster twice. It is expected that the migration takes approximately twice as long as a cluster upgrade. + +. Optional: You can enter the following commands to ensure that the migration process has completed, and to check the status of the `network.config`: ++ +[source,terminal] +---- +$ oc get network.config.openshift.io cluster -o jsonpath='{.status.networkType}' +---- ++ +[source,terminal] +---- +$ oc get network.config cluster -o=jsonpath='{.status.conditions}' | jq . +---- ++ +You can check live migration metrics for troubleshooting issues. For more information, see "Checking live migration metrics". + +. Complete the following steps only if the migration succeeds and your cluster is in a good state: + +.. To remove the migration configuration from the `network.config` custom resource, enter the following command: ++ +[source,terminal] +---- +$ oc patch Network.operator.openshift.io cluster --type='merge' \ + --patch '{ "spec": { "migration": null } }' +---- + +.. To remove custom configuration for the OpenShift SDN network provider, enter the following command: ++ +[source,terminal] +---- +$ oc patch Network.operator.openshift.io cluster --type='merge' \ + --patch '{ "spec": { "defaultNetwork": { "openshiftSDNConfig": null } } }' +---- + +.. To remove the OpenShift SDN network provider namespace, enter the following command: ++ +[source,terminal] +---- +$ oc delete namespace openshift-sdn +---- \ No newline at end of file diff --git a/modules/nw-ovn-kubernetes-migration-about.adoc b/modules/nw-ovn-kubernetes-migration-about.adoc index 34b4aad1babf..2dc4773966d8 100644 --- a/modules/nw-ovn-kubernetes-migration-about.adoc +++ b/modules/nw-ovn-kubernetes-migration-about.adoc @@ -3,30 +3,45 @@ // * networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc [id="nw-ovn-kubernetes-migration-about_{context}"] -= Migration to the OVN-Kubernetes network plugin += Offline migration to the OVN-Kubernetes network plugin overview -Migrating to the OVN-Kubernetes network plugin is a manual process that includes some downtime during which your cluster is unreachable. Although a rollback procedure is provided, the migration is intended to be a one-way process. +The offline migration method is a manual process that includes some downtime, during which your cluster is unreachable. This method is primarily used for self-managed {product-title} deployments. -A migration to the OVN-Kubernetes network plugin is supported on the following platforms: - -* Bare metal hardware -* Amazon Web Services (AWS) -* Google Cloud Platform (GCP) -* {ibm-cloud-name} -* Microsoft Azure -* {rh-openstack-first} -* VMware vSphere -* Nutanix +Although a rollback procedure is provided, the offline migration is intended to be a one-way process. +//// [IMPORTANT] ==== Migrating to or from the OVN-Kubernetes network plugin is not supported for managed OpenShift cloud services such as {product-dedicated}, Azure Red Hat OpenShift(ARO), and Red Hat OpenShift Service on AWS (ROSA). ==== - +//// include::snippets/sdn-deprecation-statement.adoc[] +The following sections provide more information about the offline migration method. + +[id="supported-platforms-offline-migrating-ovn-kubernetes"] +== Supported platforms when using the offline migration method + +The following table provides information about the supported platforms for the offline migration type. + +.Supported platforms for the offline migration method +[cols="1,1", options="header"] +|=== +| Platform | Offline Migration + +| Bare metal hardware (IPI and UPI) |✓ +| Amazon Web Services (AWS) (IPI and UPI) |✓ +| Google Cloud Platform (GCP) (IPI and UPI) |✓ +| {ibm-cloud-name} (IPI and UPI) |✓ +| Microsoft Azure (IPI and UPI) |✓ +| {rh-openstack-first} (IPI and UPI) |✓ +| VMware vSphere (IPI and UPI) |✓ +| AliCloud (IPI and UPI) |✓ +| Nutanix (IPI and UPI) |✓ +|=== + [id="considerations-migrating-ovn-kubernetes-network-provider_{context}"] -== Considerations for migrating to the OVN-Kubernetes network plugin +== Considerations for offline migration to the OVN-Kubernetes network plugin If you have more than 150 nodes in your {product-title} cluster, then open a support case for consultation on your migration to the OVN-Kubernetes network plugin. @@ -144,4 +159,4 @@ For more information on using multicast in OVN-Kubernetes, see "Enabling multica [id="network-policies_{context}"] === Network policies -OVN-Kubernetes fully supports the Kubernetes `NetworkPolicy` API in the `networking.k8s.io/v1` API group. No changes are necessary in your network policies when migrating from OpenShift SDN. +OVN-Kubernetes fully supports the Kubernetes `NetworkPolicy` API in the `networking.k8s.io/v1` API group. No changes are necessary in your network policies when migrating from OpenShift SDN. \ No newline at end of file diff --git a/modules/nw-ovn-kubernetes-migration.adoc b/modules/nw-ovn-kubernetes-migration.adoc index 7bac28001d1a..027275902f15 100644 --- a/modules/nw-ovn-kubernetes-migration.adoc +++ b/modules/nw-ovn-kubernetes-migration.adoc @@ -5,7 +5,7 @@ :_mod-docs-content-type: PROCEDURE [id="nw-ovn-kubernetes-migration_{context}"] -= Migrating to the OVN-Kubernetes network plugin += Migrating to the OVN-Kubernetes network plugin by using the offline migration method As a cluster administrator, you can change the network plugin for your cluster to OVN-Kubernetes. During the migration, you must reboot every node in your cluster. @@ -24,7 +24,7 @@ Perform the migration only when an interruption in service is acceptable. * A recent backup of the etcd database is available. * A reboot can be triggered manually for each node. * The cluster is in a known good state, without any errors. -* On all cloud platforms after updating software, a security group rule must be in place to allow UDP packets on port `6081` for all nodes. +* Before migration to OVN-Kubernetes, a security group rule must be in place to allow UDP packets on port `6081` for all nodes on all cloud platforms. .Procedure diff --git a/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc b/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc index a8cdb9a4cdf9..47006d1caee0 100644 --- a/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc +++ b/networking/ovn_kubernetes_network_provider/migrate-from-openshift-sdn.adoc @@ -6,14 +6,19 @@ include::_attributes/common-attributes.adoc[] toc::[] -As a cluster administrator, you can migrate to the OVN-Kubernetes network plugin from the OpenShift SDN network plugin. +As a cluster administrator, you can migrate to the OVN-Kubernetes network plugin from the OpenShift SDN network plugin using the _offline_ migration method or the _live_ migration method. To learn more about OVN-Kubernetes, read xref:../../networking/ovn_kubernetes_network_provider/about-ovn-kubernetes#about-ovn-kubernetes[About the OVN-Kubernetes network plugin]. include::modules/nw-ovn-kubernetes-migration-about.adoc[leveloffset=+1] include::modules/nw-network-plugin-migration-process.adoc[leveloffset=+2] +include::modules/nw-ovn-kubernetes-migration.adoc[leveloffset=+2] -include::modules/nw-ovn-kubernetes-migration.adoc[leveloffset=+1] +include::modules/nw-ovn-kubernetes-live-migration-about.adoc[leveloffset=+1] +include::modules/how-the-live-migration-process-works.adoc[leveloffset=+2] +include::modules/nw-ovn-kubernetes-live-migration.adoc[leveloffset=+2] +include::modules/nw-ovn-kubernetes-checking-live-migration-metrics.adoc[leveloffset=+2] +include::modules/live-migration-metrics-information.adoc[leveloffset=+3] [role="_additional-resources"] [id="migrate-from-openshift-sdn-additional-resources"] @@ -33,4 +38,5 @@ include::modules/nw-ovn-kubernetes-migration.adoc[leveloffset=+1] - xref:../../networking/openshift_sdn/assigning-egress-ips.adoc#assigning-egress-ips[Configuring egress IPs for a project] - xref:../../networking/openshift_sdn/configuring-egress-firewall.adoc#configuring-egress-firewall[Configuring an egress firewall for a project] - xref:../../networking/openshift_sdn/enabling-multicast.adoc#enabling-multicast[Enabling multicast for a project] +- xref:../../networking/openshift_sdn/deploying-egress-router-layer3-redirection.adoc#deploying-egress-router-layer3-redirection[Deploying an egress router pod in redirect mode] * xref:../../rest_api/operator_apis/network-operator-openshift-io-v1.adoc#network-operator-openshift-io-v1[Network [operator.openshift.io/v1]] diff --git a/rest_api/operator_apis/network-operator-openshift-io-v1.adoc b/rest_api/operator_apis/network-operator-openshift-io-v1.adoc index f39ac3b3db63..14f019248479 100644 --- a/rest_api/operator_apis/network-operator-openshift-io-v1.adoc +++ b/rest_api/operator_apis/network-operator-openshift-io-v1.adoc @@ -760,7 +760,7 @@ Type:: Description:: + -- -ipv4 allows users to configure IP settings for IPv4 connections. When ommitted, this means no opinions and the default configuration is used. Check individual fields within ipv4 for details of default values. +ipv4 allows users to configure IP settings for IPv4 connections. When omitted, this means no opinions and the default configuration is used. Check individual fields within ipv4 for details of default values. -- Type:: From ae3a67fbbfba90085ad4432522429debbc42a2f8 Mon Sep 17 00:00:00 2001 From: Ben Scott Date: Fri, 14 Jun 2024 12:09:56 -0400 Subject: [PATCH 214/339] OSDOCS-10900 adding new required permissions for AWS install --- modules/installation-aws-permissions.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/installation-aws-permissions.adoc b/modules/installation-aws-permissions.adoc index 4b1184ab53b5..cdea1069907e 100644 --- a/modules/installation-aws-permissions.adoc +++ b/modules/installation-aws-permissions.adoc @@ -46,6 +46,7 @@ cluster, the IAM user requires the following permissions: * `ec2:DescribeNetworkAcls` * `ec2:DescribeNetworkInterfaces` * `ec2:DescribePrefixLists` +* `ec2:DescribePublicIpv4Pools` (only required if `publicIpv4Pool` is specified in `install-config.yaml`) * `ec2:DescribeRegions` * `ec2:DescribeRouteTables` * `ec2:DescribeSecurityGroupRules` @@ -58,6 +59,7 @@ cluster, the IAM user requires the following permissions: * `ec2:DescribeVpcClassicLinkDnsSupport` * `ec2:DescribeVpcEndpoints` * `ec2:DescribeVpcs` +* `ec2:DisassociateAddress` (only required if `publicIpv4Pool` is specified in `install-config.yaml`) * `ec2:GetEbsDefaultKmsKeyId` * `ec2:ModifyInstanceAttribute` * `ec2:ModifyNetworkInterfaceAttribute` @@ -119,6 +121,7 @@ If you use an existing Virtual Private Cloud (VPC), your account does not requir * `elasticloadbalancing:RegisterInstancesWithLoadBalancer` * `elasticloadbalancing:RegisterTargets` * `elasticloadbalancing:SetLoadBalancerPoliciesOfListener` +* `elasticloadbalancing:SetSecurityGroups` [IMPORTANT] ===== @@ -192,6 +195,7 @@ If you have not created a load balancer in your AWS account, the IAM user also r * `s3:GetReplicationConfiguration` * `s3:ListBucket` * `s3:PutBucketAcl` +* `s3:PutBucketPolicy` * `s3:PutBucketTagging` * `s3:PutEncryptionConfiguration` ==== From 74b94348d33f376ba9dfd78dd6b1a26162042dff Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Tue, 18 Jun 2024 14:02:15 +0100 Subject: [PATCH 215/339] OCPBUGS-35498 remove Multi-network policy support stated as Tech Preview --- .../configuring-multi-network-policy.adoc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/networking/multiple_networks/configuring-multi-network-policy.adoc b/networking/multiple_networks/configuring-multi-network-policy.adoc index 3dd3bbc50d94..b41fcfb8166c 100644 --- a/networking/multiple_networks/configuring-multi-network-policy.adoc +++ b/networking/multiple_networks/configuring-multi-network-policy.adoc @@ -8,13 +8,6 @@ toc::[] As a cluster administrator, you can configure multi-network for additional networks. You can specify multi-network policy for SR-IOV, macvlan, and OVN-Kubernetes additional networks. Macvlan additional networks are fully supported. Other types of additional networks, such as ipvlan, are not supported. -[IMPORTANT] -==== -Support for configuring multi-network policies for SR-IOV additional networks is a Technology Preview feature and is only supported with kernel network interface cards (NICs). SR-IOV is not supported for Data Plane Development Kit (DPDK) applications. - -For more information about the support scope of Red Hat Technology Preview features, see link:https://access.redhat.com/support/offerings/techpreview/[Technology Preview Features Support Scope]. -==== - include::modules/nw-multi-network-policy-differences.adoc[leveloffset=+1] include::modules/nw-multi-network-policy-enable.adoc[leveloffset=+1] include::modules/nw-multi-network-policy-ipv6-suppport.adoc[leveloffset=+1] From b5c7fefaf466577f566ab86268a8dd195db0b659 Mon Sep 17 00:00:00 2001 From: Alexandra Molnar Date: Wed, 5 Jun 2024 09:53:31 +0100 Subject: [PATCH 216/339] TELCODOCS-1707: Add Preparing/Configuring shared container dir --- _topic_maps/_topic_map.yml | 12 +-- ...cnf-understanding-image-based-upgrade.adoc | 2 +- .../_attributes | 1 + ...-based-upgrade-shared-container-image.adoc | 16 ++++ .../preparing_for_image_based_upgrade/images | 1 + .../preparing_for_image_based_upgrade/modules | 1 + .../snippets | 1 + ...sed-upgrade-share-container-directory.adoc | 68 +++++++++++++ ...sed-upgrade-share-container-directory.adoc | 95 ++----------------- 9 files changed, 105 insertions(+), 92 deletions(-) create mode 120000 edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/_attributes create mode 100644 edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/cnf-image-based-upgrade-shared-container-image.adoc create mode 120000 edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/images create mode 120000 edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/modules create mode 120000 edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/snippets create mode 100644 modules/cnf-image-based-upgrade-share-container-directory.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index e1726f95a213..39a3a51ed9be 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -3078,12 +3078,12 @@ Topics: Topics: - Name: Understanding the image-based upgrade for single-node OpenShift clusters File: cnf-understanding-image-based-upgrade -# - Name: Preparing for an image-based upgrade for single-node OpenShift clusters -# Dir: preparing_for_image_based_upgrade -# Distros: openshift-origin,openshift-enterprise -# Topics: -# - Name: Configuring a shared container directory for the image-based upgrade -# File: cnf-image-based-upgrade-shared-container-image + - Name: Preparing for an image-based upgrade for single-node OpenShift clusters + Dir: preparing_for_image_based_upgrade + Distros: openshift-origin,openshift-enterprise + Topics: + - Name: Configuring a shared container directory for the image-based upgrade + File: cnf-image-based-upgrade-shared-container-image # - Name: Installing Operators for the image-based upgrade # File: cnf-image-based-upgrade-install-operators # - Name: Generating a seed image for the image-based upgrade with Lifecycle Agent diff --git a/edge_computing/image_based_upgrade/cnf-understanding-image-based-upgrade.adoc b/edge_computing/image_based_upgrade/cnf-understanding-image-based-upgrade.adoc index 0a0babba56c9..f186713d6c9b 100644 --- a/edge_computing/image_based_upgrade/cnf-understanding-image-based-upgrade.adoc +++ b/edge_computing/image_based_upgrade/cnf-understanding-image-based-upgrade.adoc @@ -127,4 +127,4 @@ include::modules/ztp-image-based-upgrade-extra-manifests-guide.adoc[leveloffset= * xref:../../edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/ztp-image-based-upgrade-prep-resources.adoc#ztp-image-based-upgrade-creating-backup-resources-with-ztp_ztp-gitops[Creating ConfigMap objects for the image-based upgrade with GitOps ZTP] * xref:../../backup_and_restore/application_backup_and_restore/installing/about-installing-oadp.adoc#about-installing-oadp[About installing OADP] -//// \ No newline at end of file +//// diff --git a/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/_attributes b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/_attributes new file mode 120000 index 000000000000..bf7c2529fdb4 --- /dev/null +++ b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/_attributes @@ -0,0 +1 @@ +../../../_attributes/ \ No newline at end of file diff --git a/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/cnf-image-based-upgrade-shared-container-image.adoc b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/cnf-image-based-upgrade-shared-container-image.adoc new file mode 100644 index 000000000000..33247cf38a6a --- /dev/null +++ b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/cnf-image-based-upgrade-shared-container-image.adoc @@ -0,0 +1,16 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cnf-image-based-upgrade-shared-varlibcontainers"] += Configuring a shared container directory for the image-based upgrade +include::_attributes/common-attributes.adoc[] +:context: shared-container-directory + +toc::[] + +Your {sno} clusters need to have a shared `var/lib/containers` partition for the image-based upgrade. +You can do this at install time. + +:FeatureName: The Lifecycle Agent + +include::modules/cnf-image-based-upgrade-share-container-directory.adoc[leveloffset=+1] + +include::modules/ztp-image-based-upgrade-share-container-directory.adoc[leveloffset=+1] \ No newline at end of file diff --git a/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/images b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/images new file mode 120000 index 000000000000..4399cbb3c0f3 --- /dev/null +++ b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/images @@ -0,0 +1 @@ +../../../images/ \ No newline at end of file diff --git a/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/modules b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/modules new file mode 120000 index 000000000000..7e8b50bee77a --- /dev/null +++ b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/modules @@ -0,0 +1 @@ +../../../modules/ \ No newline at end of file diff --git a/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/snippets b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/snippets new file mode 120000 index 000000000000..ce62fd7c41e2 --- /dev/null +++ b/edge_computing/image_based_upgrade/preparing_for_image_based_upgrade/snippets @@ -0,0 +1 @@ +../../../snippets/ \ No newline at end of file diff --git a/modules/cnf-image-based-upgrade-share-container-directory.adoc b/modules/cnf-image-based-upgrade-share-container-directory.adoc new file mode 100644 index 000000000000..62733cca6e58 --- /dev/null +++ b/modules/cnf-image-based-upgrade-share-container-directory.adoc @@ -0,0 +1,68 @@ +// Module included in the following assemblies: +// * edge_computing/image-based-upgrade/cnf-preparing-for-image-based-upgrade.adoc + +:_mod-docs-content-type: PROCEDURE +[id="cnf-image-based-upgrade-shared-container-directory_{context}"] += Configuring a shared container directory between ostree stateroots + +Apply a `MachineConfig` to both the seed and the target clusters during installation time to create a separate partition and share the `/var/lib/containers` directory between the two `ostree` stateroots that will be used during the upgrade process. + +[IMPORTANT] +==== +You must complete this procedure at installation time. +==== + +.Procedure + +* Apply a `MachineConfig` to create a separate partition: ++ +[source,yaml] +---- +apiVersion: machineconfiguration.openshift.io/v1 +kind: MachineConfig +metadata: + labels: + machineconfiguration.openshift.io/role: master + name: 98-var-lib-containers-partitioned +spec: + config: + ignition: + version: 3.2.0 + storage: + disks: + - device: /dev/disk/by-id/wwn- <1> + partitions: + - label: varlibcontainers + startMiB: <2> + sizeMiB: <3> + filesystems: + - device: /dev/disk/by-partlabel/varlibcontainers + format: xfs + mountOptions: + - defaults + - prjquota + path: /var/lib/containers + wipeFilesystem: true + systemd: + units: + - contents: |- + # Generated by Butane + [Unit] + Before=local-fs.target + Requires=systemd-fsck@dev-disk-by\x2dpartlabel-varlibcontainers.service + After=systemd-fsck@dev-disk-by\x2dpartlabel-varlibcontainers.service + + [Mount] + Where=/var/lib/containers + What=/dev/disk/by-partlabel/varlibcontainers + Type=xfs + Options=defaults,prjquota + + [Install] + RequiredBy=local-fs.target + enabled: true + name: var-lib-containers.mount +---- +<1> Specify the root disk. +<2> Specify the start of the partition in MiB. If the value is too small, the installation will fail. +<3> Specify a minimum size for the partition of 500 GB to ensure adequate disk space for precached images. If the value is too small, the deployments after installation will fail. \ No newline at end of file diff --git a/modules/ztp-image-based-upgrade-share-container-directory.adoc b/modules/ztp-image-based-upgrade-share-container-directory.adoc index 4c11c2b9b4cd..759fabf8bef1 100644 --- a/modules/ztp-image-based-upgrade-share-container-directory.adoc +++ b/modules/ztp-image-based-upgrade-share-container-directory.adoc @@ -1,85 +1,11 @@ // Module included in the following assemblies: -// * scalability_and_performance/ztp-image-based-upgrade.adoc +// * edge_computing/image-based-upgrade/cnf-preparing-for-image-based-upgrade.adoc :_mod-docs-content-type: PROCEDURE [id="ztp-image-based-upgrade-shared-container-directory_{context}"] -= Sharing the container directory between `ostree` stateroots += Configuring a shared container directory between ostree stateroots when using {ztp} -You must apply a `MachineConfig` to both the seed and the target clusters during installation time to create a separate partition and share the `/var/lib/containers` directory between the two `ostree` stateroots that will be used during the upgrade process. - -[id="ztp-image-based-upgrade-shared-container-directory-acm_{context}"] -== Sharing the container directory between `ostree` stateroots when using {rh-rhacm} - -When you are using {rh-rhacm}, you must apply a `MachineConfig` to both the seed and target clusters. - -[IMPORTANT] -==== -You must complete this procedure at installation time. -==== - -.Prerequisites - -* Log in as a user with `cluster-admin` privileges. - -.Procedure - -. Apply a `MachineConfig` to create a separate partition. -+ -[source,yaml] ----- -apiVersion: machineconfiguration.openshift.io/v1 -kind: MachineConfig -metadata: - labels: - machineconfiguration.openshift.io/role: master - name: 98-var-lib-containers-partitioned -spec: - config: - ignition: - version: 3.2.0 - storage: - disks: - - device: /dev/disk/by-id/wwn- <1> - partitions: - - label: varlibcontainers - startMiB: <2> - sizeMiB: <3> - filesystems: - - device: /dev/disk/by-partlabel/varlibcontainers - format: xfs - mountOptions: - - defaults - - prjquota - path: /var/lib/containers - wipeFilesystem: true - systemd: - units: - - contents: |- - # Generated by Butane - [Unit] - Before=local-fs.target - Requires=systemd-fsck@dev-disk-by\x2dpartlabel-varlibcontainers.service - After=systemd-fsck@dev-disk-by\x2dpartlabel-varlibcontainers.service - - [Mount] - Where=/var/lib/containers - What=/dev/disk/by-partlabel/varlibcontainers - Type=xfs - Options=defaults,prjquota - - [Install] - RequiredBy=local-fs.target - enabled: true - name: var-lib-containers.mount ----- -<1> Specify the root disk. -<2> Specify the start of the partition in MiB. If the value is too small, the installation will fail. -<3> Specify the size of the partition. If the value is too small, the deployments after installation will fail. - -[id="ztp-image-based-upgrade-shared-container-directory-ztp_{context}"] -== Sharing the container directory between `ostree` stateroots when using GitOps ZTP - -When you are using the GitOps ZTP workflow, you can do the following procedure to create a separate disk partition on both the seed and target cluster and to share the `/var/lib/containers` directory. +When you are using the {ztp-first} workflow, you do the following procedure to create a separate disk partition on both the seed and target cluster and to share the `/var/lib/containers` directory. [IMPORTANT] ==== @@ -88,12 +14,11 @@ You must complete this procedure at installation time. .Prerequisites -* Log in as a user with `cluster-admin` privileges. * Install Butane. .Procedure -. Create the `storage.bu` file. +. Create the `storage.bu` file: + [source,yaml] ---- @@ -105,8 +30,8 @@ storage: wipe_table: false partitions: - label: var-lib-containers - start_mib: <2> - size_mib: <3> + start_mib: <2> + size_mib: <3> filesystems: - path: /var/lib/containers device: /dev/disk/by-partlabel/var-lib-containers @@ -119,9 +44,9 @@ storage: ---- <1> Specify the root disk. <2> Specify the start of the partition in MiB. If the value is too small, the installation will fail. -<3> Specify the size of the partition. If the value is too small, the deployments after installation will fail. +<3> Specify a minimum size for the partition of 500 GB to ensure adequate disk space for precached images. If the value is too small, the deployments after installation will fail. -. Convert the `storage.bu` to an Ignition file. +. Convert the `storage.bu` to an Ignition file: + -- [source,terminal] @@ -136,7 +61,7 @@ $ butane storage.bu ---- -- -. Copy the output into the `.spec.clusters.nodes.ignitionConfigOverride` field in the `SiteConfig` CR. +. Copy the output into the `.spec.clusters.nodes.ignitionConfigOverride` field in the `SiteConfig` CR: + [source,yaml] ---- @@ -150,7 +75,7 @@ spec: .Verification -. During or after installation, verify on the hub cluster that the `BareMetalHost` object shows the annotation. +. During or after installation, verify on the hub cluster that the `BareMetalHost` object shows the annotation: + -- [source,terminal] From 28761514ef181ca3f201dcf31e21610b7ff4237a Mon Sep 17 00:00:00 2001 From: xJustin Date: Tue, 23 Jan 2024 07:51:18 -0500 Subject: [PATCH 217/339] OSDOCS-8390 deployment --- _topic_maps/_topic_map_rosa.yml | 2 + ...erts-deploying-application-deployment.adoc | 153 ++++++++++++++++++ images/4-cli-login.png | Bin 0 -> 11896 bytes images/4-createnewproj.png | Bin 0 -> 52728 bytes images/4-ostoy-homepage.png | Bin 0 -> 138012 bytes 5 files changed, 155 insertions(+) create mode 100644 cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-deployment.adoc create mode 100644 images/4-cli-login.png create mode 100644 images/4-createnewproj.png create mode 100644 images/4-ostoy-homepage.png diff --git a/_topic_maps/_topic_map_rosa.yml b/_topic_maps/_topic_map_rosa.yml index 1ab9d376d46a..e3e8fe133195 100644 --- a/_topic_maps/_topic_map_rosa.yml +++ b/_topic_maps/_topic_map_rosa.yml @@ -186,6 +186,8 @@ Topics: File: cloud-experts-deploying-application-prerequisites - Name: Lab Overview File: cloud-experts-deploying-application-lab-overview + - Name: Deployment + File: cloud-experts-deploying-application-deployment - Name: Networking File: cloud-experts-deploying-application-networking --- diff --git a/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-deployment.adoc b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-deployment.adoc new file mode 100644 index 000000000000..918666bbc52e --- /dev/null +++ b/cloud_experts_tutorials/cloud-experts-deploying-application/cloud-experts-deploying-application-deployment.adoc @@ -0,0 +1,153 @@ +:_mod-docs-content-type: ASSEMBLY +[id="cloud-experts-deploying-application-deployment"] += Tutorial: Deploying an application +include::_attributes/attributes-openshift-dedicated.adoc[] +:context: cloud-experts-deploying-application-deployment + +toc::[] + +//rosaworkshop.io content metadata +//Brought into ROSA product docs 23-JAN-2024 + +== Deploying the OSToy application with Kubernetes + +You can deploy the OSToy application by creating and storing the images for the front-end and back-end microservice containers in an image repository. You can then create Kubernetes deployments to deploy the application. + +=== Retrieving the login command + +. If you are not logged in to the CLI, access your cluster with the web console. + +. Click the dropdown arrow next to your login name in the upper right, and select *Copy Login Command*. ++ +image::4-cli-login.png[CLI login screen] ++ +A new tab opens. + +. Select your authentication method. + +. Click *Display Token*. + +. Copy the command under *Log in with this token*. + +. From your terminal, paste and run the copied command. If the login is successful, you will see the following confirmation message: ++ +[source,terminal] +---- +$ oc login --token= --server=https://api.osd4-demo.abc1.p1.openshiftapps.com:6443 +Logged into "https://api.myrosacluster.abcd.p1.openshiftapps.com:6443" as "rosa-user" using the token provided. + +You don't have any projects. You can try to create a new project, by running + +oc new-project +---- + +=== Creating a new project + +==== Using the CLI + +. Create a new project named `ostoy` in your cluster by running following command: ++ +[source,terminal] +---- +$ oc new-project ostoy +---- ++ +.Example output +[source,terminal] +---- +Now using project "ostoy" on server "https://api.myrosacluster.abcd.p1.openshiftapps.com:6443". +---- + +. *Optional*: Alternatively, create a unique project name by running the following command: ++ +[source,terminal] +---- +$ oc new-project ostoy-$(uuidgen | cut -d - -f 2 | tr '[:upper:]' '[:lower:]') +---- + +==== Using the web console + +. From the web console, click *Home -> Projects*. + +. On the *Projects* page, click create *Create Project*. ++ +image::4-createnewproj.png[The project creation screen] + +=== Deploying the back-end microservice + +The microservice serves internal web requests and returns a JSON object containing the current hostname and a randomly generated color string. + +* Deploy the microservice by running the following command from your terminal: ++ +[source,terminal] +---- +$ oc apply -f https://raw.githubusercontent.com/openshift-cs/rosaworkshop/master/rosa-workshop/ostoy/yaml/ostoy-microservice-deployment.yaml +---- ++ +.Example output +[source,terminal] +---- +$ oc apply -f https://raw.githubusercontent.com/openshift-cs/rosaworkshop/master/rosa-workshop/ostoy/yaml/ostoy-microservice-deployment.yaml +deployment.apps/ostoy-microservice created +service/ostoy-microservice-svc created +---- + +=== Deploying the front-end service + +The front-end deployment uses the Node.js front-end for the application and additional Kubernetes objects. + +The `ostoy-frontend-deployment.yaml` file shows that front-end deployment defines the following features: + +- Persistent volume claim +- Deployment object +- Service +- Route +- Configmaps +- Secrets + +* Deploy the application front-end and create all of the objects by entering the following command: ++ +[source,terminal] +---- +$ oc apply -f https://raw.githubusercontent.com/openshift-cs/rosaworkshop/master/rosa-workshop/ostoy/yaml/ostoy-frontend-deployment.yaml +---- ++ +.Example output +[source,terminal] +---- +persistentvolumeclaim/ostoy-pvc created +deployment.apps/ostoy-frontend created +service/ostoy-frontend-svc created +route.route.openshift.io/ostoy-route created +configmap/ostoy-configmap-env created +secret/ostoy-secret-env created +configmap/ostoy-configmap-files created +secret/ostoy-secret created +---- ++ +You should see all objects created successfully. + +=== Getting the route + +You must get the route to access the application. + +* Get the route to your application by running the following command: ++ +[source,terminal] +---- +$ oc get route +---- ++ +.Example output +[source,terminal] +---- +NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD +ostoy-route ostoy-route-ostoy.apps..abcd.p1.openshiftapps.com ostoy-frontend-svc None +---- + +=== Viewing the application + +. Copy the `ostoy-route-ostoy.apps..abcd.p1.openshiftapps.com` URL output from the previous step. +. Paste the copied URL into your web browser and press enter. You should see the homepage of your application. If the page does not load, make sure you use `http` and not `https`. ++ +image::4-ostoy-homepage.png[OStoy application homepage] diff --git a/images/4-cli-login.png b/images/4-cli-login.png new file mode 100644 index 0000000000000000000000000000000000000000..425d9327b34abeea8d53a84f9cd5c90d80b6096d GIT binary patch literal 11896 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