diff --git a/enhancements/cert-manager/istio-csr-controller.md b/enhancements/cert-manager/istio-csr-controller.md index e0e2222411..703bf16c86 100644 --- a/enhancements/cert-manager/istio-csr-controller.md +++ b/enhancements/cert-manager/istio-csr-controller.md @@ -9,7 +9,7 @@ approvers: api-approvers: - "@tgeer" ## approver for cert-manager component creation-date: 2024-01-22 -last-updated: 2024-11-21 +last-updated: 2025-09-24 tracking-link: - https://issues.redhat.com/browse/CM-234 see-also: @@ -51,16 +51,23 @@ manager, requiring integration with OSSM so that certificate requests are signed ### User Stories -- As an OpenShift user, I want to have an option to dynamically deploy `istio-csr` agent, so that it can be used only - when required by creating the custom resource. -- As an OpenShift user, I want to have an option to dynamically configure `istio-csr` agent, so that only the required - features can be enabled by updating the custom resource. -- As an OpenShift user, I should be able to remove `istio-csr` agent when not required by removing the custom resource, - and controller should cleanup all resources created for the `istio-csr` agent deployment. -- As an OpenShift user, I should be able to install `istio-csr` agent in the upgrade cluster where istiod control plane - is active and should be able to update the certificate endpoint to `istio-csr` agent endpoint. -- As an OpenShift user, I want to have an option to dynamically enable monitoring for the `istio-csr` project and - to use the OpenShift monitoring solution when required. +- As an OpenShift administrator, I want to have an option to deploy istio-csr agent, so that it can be enabled as a day2 operation. +- As an OpenShift administrator, I want to be able to configure istio-csr agent, so that only required +features can be enabled. +- As an OpenShift administrator, I should be able to uninstall istio-csr agent when not required as a day2 operation without disrupting + the cert-manager installation. +- As an OpenShift administrator, I should be able to choose to keep secrets and related controller should clean up all resources created + for the istio-csr agent deployment. +- As an OpenShift security engineer, I want to be able to identify all artefacts created by istio-csr agent, for better auditability. +- As an OpenShift SRE, I should be able to get details information as part of different status conditions and messages to identify the + reasons of failures and carry out corrective actions successfully. +- As an OpenShift service mesh administrator, I should be able to use istio-csr endpoint to automate certificate requests via istiod on + the pre-installed service mesh clusters. +- As an OpenShift SRE, I should be able to collect metrics for istio-csr for monitoring. +- As an OpenShift security engineer, I want to restrict istio-csr operation to only member namespaces of the Service Mesh, to prevent the + ConfigMap with the `istiod` CA certificates from being unnecessarily provisioned in namespaces outside the mesh. +- As an OpenShift administrator, I want to configure istio cluster id that can be verified against the csr to avoid misconfiguration or + infer any default value ### Goals @@ -71,9 +78,15 @@ manager, requiring integration with OSSM so that certificate requests are signed - `istio-csr` agent can be used only with supported version of `OpenShift Service Mesh`. Please refer `Version Skew Strategy` section for more details. -- Removing `istiocsr.operator.openshift.io` CR object will not remove `istio-csr` agent deployment. But will only stop - the reconciliation of kubernetes resources created for agent deployment. (Note: This will be a limitation for TechPreview - and will be re-evaluated for GA) +- Removing `istiocsr.operator.openshift.io` CR object will not remove `istio-csr` agent deployment. But will only stop the reconciliation + of the Kubernetes resources created for the operand installation. (Note: This is a limitation for GA release and will be + re-evaluated in future releases). +- As an OpenShift security engineer, I want an automatic cleanup of `istio-ca-root-cert` configmap from the selected namespaces which + were previously part of the mesh. +- As an OpenShift administrator, I want the namespaces chosen for istio-ca-root-cert configmap injection to be validated against + service mesh configuration to avoid drift in the namespace selection. +- As an OpenShift security engineer, I want to harden RBAC permissions of `istio-csr` agent to restrict ConfigMap creation permission + to only selected namespaces. ## Proposal @@ -103,10 +116,13 @@ Each of the resource created for `istio-csr` agent deployment will have below se * `app: cert-manager-istio-csr` * `app.kubernetes.io/name: cert-manager-istio-csr` * `app.kubernetes.io/instance: cert-manager-istio-csr` -* `app.kubernetes.io/version: "v0.12.0"` +* `app.kubernetes.io/version: "v0.14.2"` * `app.kubernetes.io/managed-by: cert-manager-operator` * `app.kubernetes.io/part-of: cert-manager-operator` +These labels adhere to Kubernetes and OpenShift conventions, aiding in identifying, categorizing, and managing the +`istio-csr` components within the cluster environment, thereby facilitating operations like monitoring and resource discovery. + Refer below links for more information on the labels used - [Guidelines for Labels and Annotations for OpenShift applications](https://github.com/redhat-developer/app-labels/blob/master/labels-annotation-for-openshift.adoc) - [Well-Known Labels, Annotations and Taints](https://kubernetes.io/docs/reference/labels-annotations-taints/) @@ -117,7 +133,7 @@ Refer below links for more information on the labels used Configurations made available in the spec of `istiocsr.operator.openshift.io` CR are passed as command line arguments to `istio-csr` agent and updating these configurations would cause new rollout of the `istio-csr` agent deployment, which means a new pod will be created and old pod will terminate resulting in `istio-csr` agent restart. -All configurations can be updated on-demand, except for below which can be configured only while creating the `istiocsr.operator.openshift.io` +All configurations can be updated on-demand, except for below which can be configured only once during or after creating `istiocsr.operator.openshift.io` CR, which is enforced in the CRD using CEL validations. - `.spec.istioCSRConfig.certmanager.issuerRef` - `.spec.istioCSRConfig.istiodTLSConfig.privateKeySize` @@ -127,7 +143,7 @@ CR, which is enforced in the CRD using CEL validations. - `.spec.istioCSRConfig.istio.namespace` When an OpenShift user deletes `istiocsr.operator.openshift.io` CR object, `istio-csr-controller` will stop managing all -the resources created for installing `istio-csr` agent and user will manually clean up the resources. Please refer +the resources created for installing `istio-csr` agent and user will have to manually clean up the resources. Please refer `Operational Aspects of API Extensions` section for command to list all the resources. `istiocsr.operator.openshift.io` CR status sub-resource will be used for updating the status of the `istio-csr` agent @@ -158,18 +174,37 @@ Below new API `istiocsrs.operator.openshift.io` is introduced for managing istio ```golang package v1alpha1 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true + +// IstioCSRList is a list of IstioCSR objects. +type IstioCSRList struct { + metav1.TypeMeta `json:",inline"` + + // metadata is the standard list's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + Items []IstioCSR `json:"items"` +} + // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true // +kubebuilder:subresource:status - -// IstioCSR describes configuration and information about the managed istio-csr -// agent. The name must be `default`. +// +kubebuilder:resource:path=istiocsrs,scope=Namespaced,categories={cert-manager-operator, istio-csr, istiocsr},shortName=istiocsr;icsr +// +kubebuilder:printcolumn:name="GRPC Endpoint",type="string",JSONPath=".status.istioCSRGRPCEndpoint" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status" +// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:metadata:labels={"app.kubernetes.io/name=istiocsr", "app.kubernetes.io/part-of=cert-manager-operator"} + +// IstioCSR describes the configuration and information about the managed istio-csr agent. +// The name must be `default` to make IstioCSR a singleton that is, to allow only one instance of IstioCSR per namespace. +// +// When an IstioCSR is created, istio-csr agent is deployed in the IstioCSR-created namespace. // -// When an IstioCSR is created, a new deployment is created which manages the -// istio-csr agent and keeps it in the desired state. -// +kubebuilder:object:root=true -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" // +kubebuilder:validation:XValidation:rule="self.metadata.name == 'default'",message="istiocsr is a singleton, .metadata.name must be 'default'" +// +operator-sdk:csv:customresourcedefinitions:displayName="IstioCSR" type IstioCSR struct { metav1.TypeMeta `json:",inline"` @@ -178,197 +213,320 @@ type IstioCSR struct { metav1.ObjectMeta `json:"metadata,omitempty"` // spec is the specification of the desired behavior of the IstioCSR. - Spec IstioCSRSpec `json:"spec,omitempty"` + // +kubebuilder:validation:Required + // +required + Spec IstioCSRSpec `json:"spec"` // status is the most recently observed status of the IstioCSR. + // +kubebuilder:validation:Optional + // +optional Status IstioCSRStatus `json:"status,omitempty"` } // IstioCSRSpec is the specification of the desired behavior of the IstioCSR. type IstioCSRSpec struct { - // istioCSRConfig is for configuring the istio-csr agent behavior. - IstioCSRConfig *IstioCSRConfig `json:"istioCSRConfig,omitempty"` + // istioCSRConfig configures the istio-csr agent's behavior. + // +kubebuilder:validation:Required + // +required + IstioCSRConfig IstioCSRConfig `json:"istioCSRConfig"` - // controllerConfig is for configuring the controller for setting up - // defaults to enable istio-csr agent. + // controllerConfig configures the controller for setting up defaults to enable the istio-csr agent. + // +kubebuilder:validation:Optional + // +optional ControllerConfig *ControllerConfig `json:"controllerConfig,omitempty"` } -// IstioCSRConfig is for configuring the istio-csr agent behavior. +// IstioCSRConfig configures the istio-csr agent's behavior. type IstioCSRConfig struct { - // logLevel is for setting verbosity of istio-csr agent logging. - // Supported log levels: 1-5. + // logLevel supports a value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). // +kubebuilder:default:=1 // +kubebuilder:validation:Minimum:=1 // +kubebuilder:validation:Maximum:=5 + // +kubebuilder:validation:Optional // +optional LogLevel int32 `json:"logLevel,omitempty"` - // logFormat is for specifying the output format of istio-csr agent logging. - // Support log formats are text and json. - // +kubebuilder:default:=text + // logFormat specifies the output format for istio-csr agent logging. + // Supported log formats are text and json. + // +kubebuilder:validation:Enum:="text";"json" + // +kubebuilder:default:="text" + // +kubebuilder:validation:Optional // +optional LogFormat string `json:"logFormat,omitempty"` - // certmanager is for configuring cert-manager specifics. + // Istio-csr creates a ConfigMap named `istio-ca-root-cert` containing the root CA certificate, which the Istio data plane uses to verify server certificates. Its default behavior is to create and monitor ConfigMaps in all namespaces. + // The istioDataPlaneNamespaceSelector restricts the namespaces where the ConfigMap is created by using label selectors, such as maistra.io/member-of=istio-system. This selector is also attached to all desired namespaces that are part of the data plane. + // This field can have a maximum of 4096 characters. + // +kubebuilder:example:="maistra.io/member-of=istio-system" + // +kubebuilder:validation:MinLength:=0 + // +kubebuilder:validation:MaxLength:=4096 + // +kubebuilder:validation:Optional + // +optional + IstioDataPlaneNamespaceSelector string `json:"istioDataPlaneNamespaceSelector,omitempty"` + + // certManager is for configuring cert-manager specifics. + // +kubebuilder:validation:Required // +required - CertManager *CertManagerConfig `json:"certmanager,omitempty"` + CertManager CertManagerConfig `json:"certManager"` // istiodTLSConfig is for configuring istiod certificate specifics. + // +kubebuilder:validation:Required // +required - IstiodTLSConfig *IstiodTLSConfig `json:"istiodTLSConfig,omitempty"` + IstiodTLSConfig IstiodTLSConfig `json:"istiodTLSConfig"` - // server is for configuring the server endpoint used by istio - // for obtaining the certificates. + // server is for configuring the server endpoint used by istio for obtaining the certificates. + // +kubebuilder:validation:Optional // +optional Server *ServerConfig `json:"server,omitempty"` // istio is for configuring the istio specifics. - Istio *IstioConfig `json:"istio,omitempty"` + // +kubebuilder:validation:Required + // +required + Istio IstioConfig `json:"istio"` - // Resources is for defining the resource requirements. + // resources is for defining the resource requirements. + // Cannot be updated. // ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + // +kubebuilder:validation:Optional // +optional Resources corev1.ResourceRequirements `json:"resources,omitempty"` - // Affinity is for setting scheduling affinity rules. + // affinity is for setting scheduling affinity rules. // ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + // +kubebuilder:validation:Optional // +optional Affinity *corev1.Affinity `json:"affinity,omitempty"` - // Tolerations is for setting the pod tolerations. + // tolerations is for setting the pod tolerations. + // This field can have a maximum of 50 entries. // ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + // +listType=atomic + // +kubebuilder:validation:MinItems:=0 + // +kubebuilder:validation:MaxItems:=50 + // +kubebuilder:validation:Optional // +optional Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - // NodeSelector is for defining the scheduling criteria using node labels. + // nodeSelector is for defining the scheduling criteria using node labels. + // This field can have a maximum of 50 entries. // ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // +mapType=atomic + // +kubebuilder:validation:MinProperties:=0 + // +kubebuilder:validation:MaxProperties:=50 + // +kubebuilder:validation:Optional // +optional NodeSelector map[string]string `json:"nodeSelector,omitempty"` } // CertManagerConfig is for configuring cert-manager specifics. +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.issuerRef) && !has(self.issuerRef) || has(oldSelf.issuerRef) && has(self.issuerRef)",message="issuerRef may only be configured during creation" type CertManagerConfig struct { - // issuerRef contains details to the referenced object used for - // obtaining the certificates. - // When unset operator will create Issuer in the configured istio's - // namespace. - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="issuerRef is immutable once set" + // issuerRef contains details of the referenced object used for obtaining certificates. + // When `issuerRef.Kind` is `Issuer`, it must exist in the `.spec.istioCSRConfig.istio.namespace`. + // This field is immutable once set. + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="issuerRef is immutable once set" + // +kubebuilder:validation:XValidation:rule="self.kind.lowerAscii() == 'issuer' || self.kind.lowerAscii() == 'clusterissuer'",message="kind must be either 'Issuer' or 'ClusterIssuer'" + // +kubebuilder:validation:XValidation:rule="self.group.lowerAscii() == 'cert-manager.io'",message="group must be 'cert-manager.io'" + // +kubebuilder:validation:Required // +required - IssuerRef certmanagerv1.ObjectReference `json:"issuerRef,omitempty"` + IssuerRef certmanagerv1.ObjectReference `json:"issuerRef"` + + // istioCACertificate when provided, the operator will use the CA certificate from the specified ConfigMap. + // If empty, the operator will automatically extract the CA certificate from the Secret containing the istiod certificate obtained from cert-manager. + // +kubebuilder:validation:Optional + // +optional + IstioCACertificate *ConfigMapReference `json:"istioCACertificate,omitempty"` } -// IstiodTLSConfig is for configuring certificate specifics. +// IstiodTLSConfig is for configuring istiod certificate specifics. +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.privateKeyAlgorithm) && !has(self.privateKeyAlgorithm) || has(oldSelf.privateKeyAlgorithm) && has(self.privateKeyAlgorithm)",message="privateKeyAlgorithm may only be configured during creation" +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.privateKeySize) && !has(self.privateKeySize) || has(oldSelf.privateKeySize) && has(self.privateKeySize)",message="privateKeySize may only be configured during creation" +// +kubebuilder:validation:XValidation:rule="(!has(self.privateKeyAlgorithm) || self.privateKeyAlgorithm == 'RSA') ? (self.privateKeySize in [2048,4096,8192]) : (self.privateKeySize in [256,384])",message="privateKeySize must match with configured privateKeyAlgorithm" type IstiodTLSConfig struct { - // TrustDomain is the cluster's trust domain. - // +required - TrustDomain string `json:"trustDomain,omitempty"` - - // RootCAFile is for setting the file location containing the root CA which is - // present in the configured IssuerRef. File should be made available using the - // Volume and VolumeMount options. + // commonName is the common name to be set in the cert-manager.io Certificate created for istiod. + // The commonName will be of the form istiod..svc when not set. + // This field can have a maximum of 64 characters. + // +kubebuilder:validation:MinLength:=0 + // +kubebuilder:validation:MaxLength:=64 + // +kubebuilder:example:="istiod.istio-system.svc" + // +kubebuilder:validation:Optional // +optional - RootCAFile string `json:"rootCAFile,omitempty"` - - // CertificateDNSNames contains DNS names to be added to the certificate SAN. + CommonName string `json:"commonName,omitempty"` + + // trustDomain is the Istio cluster's trust domain, which will also be used for deriving the SPIFFE URI. + // This field can have a maximum of 63 characters. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=63 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="trustDomain must consist of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). Each block, separated by periods, must start and end with an alphanumeric character. Hyphens are not allowed at the start or end of a block, and consecutive periods are not permitted." + // +kubebuilder:validation:Required // +required + TrustDomain string `json:"trustDomain"` + + // certificateDNSNames contains the additional DNS names to be added to the istiod certificate SAN. + // This field can have a maximum of 25 entries. + // +kubebuilder:validation:MinItems:=0 + // +kubebuilder:validation:MaxItems:=25 + // +kubebuilder:validation:items:MinLength:=1 + // +kubebuilder:validation:items:MaxLength:=253 + // +listType=set + // +kubebuilder:validation:Optional + // +optional CertificateDNSNames []string `json:"certificateDNSNames,omitempty"` - // certificateDuration is the istio's certificate validity period. + // certificateDuration is the validity period for the istio-csr and istiod certificates. // +kubebuilder:default:="1h" + // +kubebuilder:validation:Optional // +optional - CertificateDuration time.Duration `json:"certificateDuration,omitempty"` + CertificateDuration *metav1.Duration `json:"certificateDuration,omitempty"` - // certificateRenewBefore is the ahead time to renew the istio's certificate before - // expiry. + // certificateRenewBefore is the time before expiry to renew the istio-csr and istiod certificates. // +kubebuilder:default:="30m" + // +kubebuilder:validation:Optional // +optional - CertificateRenewBefore time.Duration `json:"certificateRenewBefore,omitempty"` + CertificateRenewBefore *metav1.Duration `json:"certificateRenewBefore,omitempty"` - // privateKeySize is the key size to be for RSAKey. - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="privateKeySize is immutable once set" + // privateKeySize is the key size for the istio-csr and istiod certificates. Allowed values when privateKeyAlgorithm is RSA are 2048, 4096, 8192; and for ECDSA, they are 256, 384. + // This field is immutable once set. + // +kubebuilder:validation:Enum:=256;384;2048;4096;8192 // +kubebuilder:default:=2048 + // +kubebuilder:validation:XValidation:rule="oldSelf == 0 || self == oldSelf",message="privateKeySize is immutable once set" + // +kubebuilder:validation:Optional // +optional PrivateKeySize int32 `json:"privateKeySize,omitempty"` -} - -// ServerConfig is for configuring the server endpoint used by istio -// for obtaining the certificates. -type ServerConfig struct { - // Address to serve istio-csr gRPC service. - // +kubebuilder:default:="0.0.0.0" - // +optional - Address string `json:"address,omitempty"` - // Port to serve istio-csr gRPC service. - // +kubebuilder:default:="6443" + // privateKeyAlgorithm is the algorithm to use when generating private keys. Allowed values are RSA, and ECDSA. + // This field is immutable once set. + // +kubebuilder:default:="RSA" + // +kubebuilder:validation:Enum:="RSA";"ECDSA" + // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="privateKeyAlgorithm is immutable once set" + // +kubebuilder:validation:Optional // +optional - Port string `json:"port,omitempty"` + PrivateKeyAlgorithm string `json:"privateKeyAlgorithm,omitempty"` - // CertificateKeySize is the server's serving certificate's key size. - // +kubebuilder:default:=2048 - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="certificateKeySize is immutable once set" + // MaxCertificateDuration is the maximum validity duration that can be requested for a certificate. + // +kubebuilder:default:="1h" + // +kubebuilder:validation:Optional // +optional - CertificateKeySize int32 `json:"certificateKeySize,omitempty"` + MaxCertificateDuration *metav1.Duration `json:"maxCertificateDuration,omitempty"` +} - // SignatureAlgorithm is the signature algorithm to use when generating - // private keys. At present only RSA and ECDSA are supported. - // +kubebuilder:default:="RSA" - // +kubebuilder:validation:Enum:="RSA";"ECDSA" - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="signatureAlgorithm is immutable once set" +// ServerConfig is for configuring the server endpoint used by istio +// for obtaining the certificates. +type ServerConfig struct { + // clusterID is the Istio cluster ID used to verify incoming CSRs. + // This field can have a maximum of 253 characters. + // +kubebuilder:default:="Kubernetes" + // +kubebuilder:validation:MinLength:=0 + // +kubebuilder:validation:MaxLength:=253 + // +kubebuilder:validation:Optional // +optional - SignatureAlgorithm string `json:"signatureAlgorithm,omitempty"` + ClusterID string `json:"clusterID,omitempty"` - // MaxCertificateDuration is the maximum validity duration that can be - // requested for a certificate. - // +kubebuilder:default:="1h" + // port to serve the istio-csr gRPC service. + // +kubebuilder:default:=443 + // +kubebuilder:validation:Minimum:=1 + // +kubebuilder:validation:Maximum:=65535 + // +kubebuilder:validation:XValidation:rule="oldSelf == 0 || self == oldSelf",message="port is immutable once set" + // +kubebuilder:validation:Optional // +optional - MaxCertificateDuration time.Duration `json:"certificateDuration,omitempty"` + Port int32 `json:"port,omitempty"` } // IstioConfig is for configuring the istio specifics. type IstioConfig struct { - // Revisions are the istio revisions that are currently installed in the cluster. - // Changing this field will modify the DNS names that will be requested for - // the istiod certificate. - // +kubebuilder:default:=["default"] - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="revisions is immutable once set" + // revisions are the Istio revisions that are currently installed in the cluster. + // Changing this field will modify the DNS names that will be requested for the istiod certificate. + // This field can have a maximum of 25 entries. + // +listType=set + // +kubebuilder:default:={"default"} + // +kubebuilder:validation:MinItems=0 + // +kubebuilder:validation:MaxItems=25 + // +kubebuilder:validation:items:MinLength:=1 + // +kubebuilder:validation:items:MaxLength:=63 + // +kubebuilder:validation:Optional // +optional Revisions []string `json:"revisions,omitempty"` - // namespace of the istio control-plane. In the same namespace issuer will be created - // used for obtaining the serving certificates. - // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="namespace is immutable once set" + // namespace of the Istio control plane. + // This field can have a maximum of 63 characters. + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="namespace is immutable once set" + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=63 + // +kubebuilder:validation:XValidation:rule=`!format.dns1123Label().validate(self).hasValue()`,message="namespace must consist of only lowercase alphanumeric characters and hyphens, and must start with an alphabetic character and end with an alphanumeric character." + // +kubebuilder:validation:Required // +required - Namespace string `json:"namespace,omitempty"` + Namespace string `json:"namespace"` } -// ControllerConfig is for configuring the controller for setting up -// defaults to enable istio-csr agent. +// ControllerConfig configures the controller for setting up defaults to +// enable the istio-csr agent. type ControllerConfig struct { - // labels to apply to all resources created for istio-csr agent deployment. + // labels to apply to all resources created for the istio-csr agent deployment. + // This field can have a maximum of 20 entries. + // +mapType=granular + // +kubebuilder:validation:MinProperties:=0 + // +kubebuilder:validation:MaxProperties:=20 + // +kubebuilder:validation:Optional + // +optional Labels map[string]string `json:"labels,omitempty"` } // IstioCSRStatus is the most recently observed status of the IstioCSR. type IstioCSRStatus struct { - // conditions holds information of the current state of the istio-csr agent deployment. - Conditions *metav1.Condition `json:"conditions,omitempty"` + // conditions holds information about the current state of the istio-csr agent deployment. + ConditionalStatus `json:",inline,omitempty"` // istioCSRImage is the name of the image and the tag used for deploying istio-csr. IstioCSRImage string `json:"istioCSRImage,omitempty"` - // istioCSRGRPCEndpoint is the service endpoint of istio-csr made available for user - // to configure the same in istiod config to enable istio to use istio-csr for - // certificate requests. + // istioCSRGRPCEndpoint is the service endpoint of istio-csr, made available for users to configure in the istiod config to enable Istio to use istio-csr for certificate requests. IstioCSRGRPCEndpoint string `json:"istioCSRGRPCEndpoint,omitempty"` // serviceAccount created by the controller for the istio-csr agent. ServiceAccount string `json:"serviceAccount,omitempty"` + // clusterRole created by the controller for the istio-csr agent. + ClusterRole string `json:"clusterRole,omitempty"` + // clusterRoleBinding created by the controller for the istio-csr agent. ClusterRoleBinding string `json:"clusterRoleBinding,omitempty"` } + +type ConditionalStatus struct { + // conditions holds information about the current state of the istio-csr agent deployment. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// ConfigMapReference holds the details of a configmap. +type ConfigMapReference struct { + // name of the ConfigMap. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must consist of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). Each block, separated by periods, must start and end with an alphanumeric character. Hyphens are not allowed at the start or end of a block, and consecutive periods are not permitted." + // +kubebuilder:validation:Required + // +required + Name string `json:"name"` + + // namespace in which the ConfigMap exists. If empty, ConfigMap will be looked up in IstioCSR created namespace. + // +kubebuilder:validation:MinLength:=0 + // +kubebuilder:validation:MaxLength:=63 + // +kubebuilder:validation:XValidation:rule=`size(self) == 0 || !format.dns1123Label().validate(self).hasValue()`,message="namespace must consist of only lowercase alphanumeric characters and hyphens, and must start with an alphabetic character and end with an alphanumeric character." + // +kubebuilder:validation:Optional + // +optional + Namespace string `json:"namespace,omitempty"` + + // key name holding the required data. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=253 + // +kubebuilder:validation:Pattern:=^[-._a-zA-Z0-9]+$ + // +kubebuilder:validation:Required + // +required + Key string `json:"key"` +} ``` ### Topology Considerations @@ -387,6 +545,51 @@ None ### Implementation Details/Notes/Constraints +#### New API changes for GA release + +Below new fields are added in `istiocsrs.operator.openshift.io` to support functionality not included in TP and also +based on user feedback. +- `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` - `istio-csr` agent by default creates a configmap with the + CA certificate used for signing the istio server certificate and is required by the proxies in the data plane to verify + the server certificate to enable mTLS. `istio-csr` agent just creates and updates the configmap `istio-ca-root-cert` + and does not delete/removes it. Creating the configmap in all namespaces would not be required for and namespaces created + for OpenShift control plane like `kube-system`, and those starting `openshift` can be excluded. `istioDataPlaneNamespaceSelector` + helps in filtering the namespaces. Please refer `Risks and Mitigations` section for other details. +- `spec.istioCSRConfig.certManager.istioCACertificate` - In the TP release, operator was extracting the CA certificate + from the configured self-signed issuer and was making it available in the container using volumes. But for issuer types + like vault, venafi, the CA certificate used is not available in the issuer. `istioCACertificate` allows configuring the configmap + which contains the CA certificate used for signing the istiod server certificates, and it will be made available to `istio-csr` + using volumes, after basic validations like certificate is indeed CA and the CA attribute in certificates `Basic Constraints` + section it set to true and was used for signing the istiod server certificate. When `istioCACertificate` is not provided + operator instead of looking in the configured `Issuer/ClusterIssuer` will instead look in the secret containing the + certificates obtained from cert-manager for istiod server. The `Certificate` object having the specifics of the istiod + server certificate is managed by operator. The operator will not directly mount the configured ConfigMap, but instead + will create a copy of its own and manage it by watching the both the ConfigMaps. This is required because, whenever the + ConfigMaps are updated, the changes get automatically propagated to the pod. And by operator having a copy of its own, can + validate any changes on the ConfigMap before making it available to the `istio-csr` agent. Please refer `Risks and Mitigations` + section for other details. Use case reference: https://issues.redhat.com/browse/CM-564 +- `spec.istioCSRConfig.server.clusterID` - The `clusterID` field is used to configure the Istiod cluster ID. This ensures + that only certificate signing requests (CSRs) from the matching Istio control plane are allowed. + +Validations for fields in the `istiocsrs.operator.openshift.io` API are updated with minimum and maximum limits to +restrict the values that can be configured, preventing users from setting arbitrarily large data that could cause +system instability. +For below fields, the lower and upper bounds have been set based on what could be considered as reasonable, as there is +no defined standard. And can be updated in future based on user feedback. +- `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` is for setting a label selector to filter the namespaces + where `isito-csr` should create the config containing the istiod CA certificate. An upper limit of `4096` is fixed allowing + to configure up to 10 namespaces considering the limitations on the label selectors and when equality operators are used. +- `spec.istioCSRConfig.tolerations` and `spec.istioCSRConfig.nodeSelector` fields are allowed to max of `50` entries. +- `spec.istioCSRConfig.istio.revisions` field has upper bound limit of `25` and each revision name can be of maximum `63` characters. +- `spec.controllerConfig.labels` field allows to configure a maximum of `20` labels to be attached to all the resources created + by the operator to deploy `istio-csr` agent. +- `spec.istioCSRConfig.istiodTLSConfig.certificateDNSNames` field allows to configure a maximum of `25` DNS names in the SAN section + of the Certificate, and each DNS Name can have a maximum of `253` characters. +- `spec.istioCSRConfig.certManager.istioCACertificate.key` is for setting the key name to be looked up in the referenced ConfigMap + containing the CA certificates. An upper limit of `253` characters is fixed. + +#### Manifests for installing `istio-csr` agent. + Below are the example static manifests used for creating required resources for installing `istio-csr` agent. 1. Service for creating istio-csr grpc server, for serving CertificateRequests endpoint. ```yaml @@ -394,16 +597,20 @@ Below are the example static manifests used for creating required resources for kind: Service metadata: name: cert-manager-istio-csr - namespace: istio-system + namespace: cert-manager labels: app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator spec: type: ClusterIP ports: - - port: 443 - targetPort: 6443 - protocol: TCP - name: grpc + - port: 443 + targetPort: 6443 + protocol: TCP + name: web selector: app: cert-manager-istio-csr ``` @@ -415,9 +622,12 @@ Below are the example static manifests used for creating required resources for kind: ServiceAccount metadata: labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator name: cert-manager-istio-csr - namespace: istio-system + namespace: cert-manager ``` 3. ClusterRoles and Roles required by istio-csr. @@ -427,26 +637,37 @@ Below are the example static manifests used for creating required resources for kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: cert-manager-istio-csr labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator + name: cert-manager-istio-csr rules: - - apiGroups: - - "" - resources: - - "configmaps" - verbs: ["get", "list", "create", "update", "watch"] - - apiGroups: - - "" - resources: - - "namespaces" - verbs: ["get", "list", "watch"] - - apiGroups: - - "authentication.k8s.io" - resources: - - "tokenreviews" - verbs: - - "create" + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - create + - update + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create ``` ```yaml @@ -454,16 +675,19 @@ Below are the example static manifests used for creating required resources for apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: cert-manager-istio-csr - generateName: cert-manager-istio-csr- + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator + name: cert-manager-istio-csr roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cert-manager-istio-csr subjects: - - kind: ServiceAccount - name: cert-manager-istio-csr - namespace: istio-system + - kind: ServiceAccount + name: cert-manager-istio-csr + namespace: cert-manager ``` ```yaml @@ -471,25 +695,31 @@ Below are the example static manifests used for creating required resources for kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: + labels: + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator name: cert-manager-istio-csr namespace: istio-system - labels: - app: cert-manager-istio-csr rules: - - apiGroups: - - "cert-manager.io" - resources: - - "certificaterequests" - verbs: - - "get" - - "list" - - "create" - - "update" - - "delete" - - "watch" - - apiGroups: [""] - resources: ["events"] - verbs: ["create"] + - apiGroups: + - cert-manager.io + resources: + - certificaterequests + verbs: + - get + - list + - create + - update + - delete + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create ``` ```yaml @@ -499,15 +729,18 @@ Below are the example static manifests used for creating required resources for name: cert-manager-istio-csr namespace: istio-system labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: cert-manager-istio-csr subjects: - - kind: ServiceAccount - name: cert-manager-istio-csr - namespace: istio-system + - kind: ServiceAccount + name: cert-manager-istio-csr + namespace: cert-manager ``` ```yaml @@ -515,20 +748,29 @@ Below are the example static manifests used for creating required resources for apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator name: cert-manager-istio-csr-leases namespace: istio-system rules: - - apiGroups: - - "coordination.k8s.io" - resources: - - "leases" - verbs: - - "get" - - "create" - - "update" - - "watch" - - "list" + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - create + - update + - watch + - list + - apiGroups: + - "" + resources: + - events + verbs: + - create ``` ```yaml @@ -538,15 +780,18 @@ Below are the example static manifests used for creating required resources for name: cert-manager-istio-csr-leases namespace: istio-system labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: cert-manager-istio-csr-leases subjects: - - kind: ServiceAccount - name: cert-manager-istio-csr - namespace: istio-system + - kind: ServiceAccount + name: cert-manager-istio-csr + namespace: cert-manager ``` 4. Certificate required by the istiod. @@ -558,13 +803,16 @@ Below are the example static manifests used for creating required resources for name: istiod namespace: istio-system labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator spec: commonName: istiod.istio-system.svc dnsNames: - - istiod-basic.istio-system.svc + - istiod.istio-system.svc uris: - - spiffe://cluster.local/ns/istio-system/sa/istiod-service-account + - spiffe://cluster.local/ns/istio-system/sa/istiod-service-account secretName: istiod-tls duration: 1h renewBefore: 30m @@ -574,7 +822,7 @@ Below are the example static manifests used for creating required resources for size: 2048 revisionHistoryLimit: 1 issuerRef: - name: istio-csr-issuer + name: istio-ca kind: Issuer group: cert-manager.io ``` @@ -585,9 +833,12 @@ Below are the example static manifests used for creating required resources for kind: Deployment metadata: name: cert-manager-istio-csr - namespace: istio-system + namespace: cert-manager labels: - app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 + app.kubernetes.io/managed-by: cert-manager-operator spec: replicas: 1 selector: @@ -597,66 +848,110 @@ Below are the example static manifests used for creating required resources for metadata: labels: app: cert-manager-istio-csr + app.kubernetes.io/name: cert-manager-istio-csr + app.kubernetes.io/instance: cert-manager-istio-csr + app.kubernetes.io/version: v0.14.2 spec: serviceAccountName: cert-manager-istio-csr + nodeSelector: + kubernetes.io/os: linux containers: - - name: cert-manager-istio-csr - image: "quay.io/jetstack/cert-manager-istio-csr:v0.7.1" - imagePullPolicy: IfNotPresent - ports: - - containerPort: 6443 - - containerPort: 9402 - readinessProbe: - httpGet: - port: 6060 - path: /readyz - initialDelaySeconds: 3 - periodSeconds: 7 - command: ["cert-manager-istio-csr"] - args: - - "--log-level=1" - - "--metrics-port=9402" - - "--readiness-probe-path=/readyz" - - "--readiness-probe-port=6060" - - # cert-manager - - "--certificate-namespace=istio-system" - - "--issuer-group=cert-manager.io" - - "--issuer-kind=Issuer" - - "--issuer-name=istio-csr-issuer" - - "--preserve-certificate-requests=false" - - # AdditionalAnnotations - - # tls - - "--root-ca-file=/var/run/secrets/istio-csr/ca.crt" - - "--serving-certificate-dns-names=cert-manager-istio-csr.istio-system.svc" - - "--serving-certificate-duration=1h" - - "--serving-certificate-key-size=2048" - - "--serving-signature-algorithm=RSA" - - "--trust-domain=cluster.local" - - # server - - "--max-client-certificate-duration=1h" - - "--serving-address=0.0.0.0:6443" - - # controller - - "--configmap-namespace-selector=maistra.io/member-of=istio-system" - - "--leader-election-namespace=istio-system" - volumeMounts: - - mountPath: /var/run/secrets/istio-csr - name: root-ca - volumes: - - name: root-ca - secret: - secretName: istio-csr-ca + - name: cert-manager-istio-csr + image: quay.io/jetstack/cert-manager-istio-csr:v0.14.2 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 6443 + - containerPort: 9402 + readinessProbe: + httpGet: + port: 6060 + path: /readyz + initialDelaySeconds: 3 + periodSeconds: 7 + args: + - --log-level=1 + - --log-format=text + - --metrics-port=9402 + - --readiness-probe-port=6060 + - --readiness-probe-path=/readyz + - --certificate-namespace=istio-system + - --issuer-enabled=true + - --issuer-name=istio-ca + - --issuer-kind=Issuer + - --issuer-group=cert-manager.io + - --preserve-certificate-requests=false + - --root-ca-file= + - --serving-certificate-dns-names=cert-manager-istio-csr.cert-manager.svc + - --serving-certificate-duration=1h + - --trust-domain=cluster.local + - --cluster-id=Kubernetes + - --max-client-certificate-duration=1h + - --serving-address=0.0.0.0:6443 + - --serving-certificate-key-size=2048 + - --serving-signature-algorithm=RSA + - --enable-client-cert-authenticator=false + - --leader-election-namespace=istio-system + - --disable-kubernetes-client-rate-limiter=false + - --runtime-issuance-config-map-name= + - --runtime-issuance-config-map-namespace=cert-manager + - --istiod-cert-enabled=false + - --istiod-cert-name=istiod-dynamic + - --istiod-cert-namespace=istio-system + - --istiod-cert-duration=1h + - --istiod-cert-renew-before=30m + - --istiod-cert-key-algorithm=RSA + - --istiod-cert-key-size=2048 + - --istiod-cert-additional-dns-names= + - --istiod-cert-istio-revisions=default + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault ``` ### Risks and Mitigations -An OpenShift administrator configuring `istiocsr.operator.openshift.io` CR object could configure insecure certificate +- An OpenShift administrator configuring `istiocsr.operator.openshift.io` CR object could configure insecure certificate signature algorithm, certificate key size or certificate validity to be too long which could cause vulnerability. - These configurations could be validated and can be overridden with default values. +- `istio-csr` agents creates the configmap `istio-ca-root-cert` with the CA certificate used for signing the istio server + certificates. And istio also creates the same configmap when it's configured to obtain certificates from `istio-csr`. Due + to both `istio` and `istio-csr` creating the configmap with same name for same purpose below issues can occur + - When multiple istio instance are installed, and not all configured to use `istio-csr` for certificate needs, conflict + will happen with both trying to update the CA certificate configmaps. + - Mitigation is to make use the namespace filtering `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` in `istiocsrs.operator.openshift.io` + and the equivalent in `istio` to avoid the conflict. When using `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` + one should be mindful to label the namespaces to not overlap with multiple instances of istio. +- When the `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` is updated or added later after `istiocsr.operator.openshift.io` creation, + and in this scenario where namespaces matched by the earlier selector are excluded, the `istio-ca-root-cert` ConfigMaps in these + excluded requires manual cleanup. + Below command can be made use of to list all the ConfigMaps not part of `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` matching + namespaces. In the example, `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` is having `maistra.io/member-of=istio-system` value. + ```shell + printf "%-25s %10s\n" "ConfigMap" "Namespace"; for ns in $(oc get namespaces -l "maistra.io/member-of!=istio-system" \ + -o=jsonpath='{.items[*].metadata.name}'); do oc get configmaps -l "istio.io/config=true" \ + -n $ns --no-headers -o jsonpath='{.items[*].metadata.name}{"\t"}{.items[*].metadata.namespace}{"\n"}'; done + ``` +- If the `spec.istioCSRConfig.istioDataPlaneNamespaceSelector` is updated or added after `istiocsr.operator.openshift.io` creation, and + the revised selector no longer includes namespaces that were previously targeted, then the `istio-ca-root-cert` ConfigMaps within + those excluded namespaces will require manual cleanup. +- When user wants to delete `istio-csr` agent deployment, must make sure the `istio-csr`service is not configured in any istio instances + for certificate needs. If deleted without proper checks + - Fetching certificates for new members of mesh would fail, as the endpoint would not be available. + - The configmap `istio-ca-root-cert` would not be updated whenever the CA has been updated and would degrade + functionalities of multiple services part of the mesh. +- Operator creates a copy of ConfigMap assigned to `spec.istioCSRConfig.certManager.istioCACertificate` to validate the content before + making it available to the `istio-csr` agent, since ConfigMap changes gets automatically propagated to the pods. But if the user + modifies both the created and operator copy, this goes unnoticed and could cause istiod to be in degraded state. +- The secret zero problem is inherent, i.e. the certificate key pairs issued by cert-manager is stored in Kubernetes + native `Secret` object which would need to be secured with additional encryption and fine-grained permissions. The `Secret` + object containing the `istiod` certificate key pair can be misused to request certificates from the `istio-csr` agent. ### Drawbacks @@ -690,7 +985,10 @@ None ### Tech Preview -> GA -N/A. This feature is for Tech Preview, until decided for GA. +- Feature is enabled by default, with option to disable. +- Feature available for end-to-end usage. +- Complete end user documentation. +- UTs and e2e tests are present. ### Removing a deprecated feature @@ -704,7 +1002,7 @@ On upgrade: with Service Mesh. - Enabling istio-csr when Service Mesh was already deployed before upgrade is not [supported](https://cert-manager.io/docs/usage/istio-csr/#installing-istio-csr-after-istio) but can be made possible by following certain steps. Please refer - `Operational Aspects of API Extensions` section for more details.. + `Operational Aspects of API Extensions` section for more details. ## Version Skew Strategy @@ -752,19 +1050,33 @@ Istio-csr will be supported for OpenShift Service Mesh Operator 2.4+, Istio v1.1 - Listing all the resources created for installing the `istio-csr` agent ```bash - oc get all -l "app=cert-manager-istio-csr,app.kubernetes.io/name=cert-manager-istio-csr" -A + oc get Certificates,ClusterRoles,ClusterRoleBindings,Deployments,Roles,RoleBindings,Services,ServiceAccounts -l "app=cert-manager-istio-csr" -n ``` +- Listing all the `OpenShift Service Mesh` instances configured to use `istio-csr` for certificate needs + - `OpenShift Service Mesh v2` + ```bash + oc get servicemeshcontrolplanes.maistra.io -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name --no-headers | while read namespace name; do value=$(oc get servicemeshcontrolplanes.maistra.io $name -n $namespace -o jsonpath='{.spec.security.certificateAuthority.cert-manager.address}'); echo "servicemeshcontrolplanes.maistra.io $namespace/$name - $value"; done + ``` + - `OpenShift Service Mesh v3` + ```bash + for resource in $(oc get istios.sailoperator.io -o name -A); do value=$(oc get $resource -o jsonpath='{.spec.values.global.caAddress}'); if [[ -n "$value" ]]; then echo "$resource - $value"; fi; done; + ``` + ## Support Procedures None ## Alternatives (Not Implemented) -Instead of having `cert-manager-operator` manage `istio-csr`, having `istio-csr` itself as a product was +- Instead of having `cert-manager-operator` manage `istio-csr`, having `istio-csr` itself as a product was considered. But since `istio-csr` is an agent dependent on `cert-manager` for obtaining the certificates and the configurations supported are specific to service mesh, approach described in this proposal was considered to be logical. +- When `istiocsr.operator.openshift.io` is deleted instead of asking user to manually check if any istiod +is configured to use `istio-csr` agent for certificate needs, option to use validatingwebhook was +considered. But since this would add dependency on the operator managing istiod, instead the OpenShift docs +will have the steps to check the configuration and decision to proceed is left to user. ## Infrastructure Needed [optional] diff --git a/enhancements/cert-manager/istio-csr-delete.png b/enhancements/cert-manager/istio-csr-delete.png index d5ea211bd7..960dd10a2d 100644 Binary files a/enhancements/cert-manager/istio-csr-delete.png and b/enhancements/cert-manager/istio-csr-delete.png differ diff --git a/enhancements/cert-manager/istio-csr-delete.puml b/enhancements/cert-manager/istio-csr-delete.puml index 0f720ffa7a..f42fbd259c 100644 --- a/enhancements/cert-manager/istio-csr-delete.puml +++ b/enhancements/cert-manager/istio-csr-delete.puml @@ -12,8 +12,8 @@ participant "cert-manager-operator" as Operator User -> API : Delete istiocsr CR API -> Operator : Reconcile istiocsr delete event note over Operator -stop managing resources created +stop managing the resources created for istio-csr agent installation. endnote -@enduml \ No newline at end of file +@enduml