From 1582d1363d8f8946d9e1031aa1080732a5eabfa1 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 22 Nov 2024 10:53:45 -0800 Subject: [PATCH] feat: update operator to use Authorino api v1beta3, switch to using unstructured type for AuthConfig to avoid authorino golang dependecy issues Signed-off-by: Dhiraj Bokde --- Makefile | 2 +- cmd/main.go | 3 - ...gistry.opendatahub.io_modelregistries.yaml | 489 +++++++++--------- go.mod | 6 +- go.sum | 15 +- .../templates/istio/authconfig.yaml.tmpl | 2 +- .../controller/modelregistry_controller.go | 27 +- .../modelregistry_controller_status.go | 33 +- 8 files changed, 298 insertions(+), 279 deletions(-) diff --git a/Makefile b/Makefile index 4f78b0e..a6b257c 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ GOVULNCHECK_VERSION ?= v1.1.3 ## Tool Versions KUSTOMIZE_VERSION ?= v5.1.1 -CONTROLLER_TOOLS_VERSION ?= v0.13.0 +CONTROLLER_TOOLS_VERSION ?= v0.14.0 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. diff --git a/cmd/main.go b/cmd/main.go index f900b2a..edae653 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -19,7 +19,6 @@ package main import ( "context" "flag" - authorino "github.com/kuadrant/authorino/api/v1beta2" "github.com/opendatahub-io/model-registry-operator/internal/controller/config" networking "istio.io/client-go/pkg/apis/networking/v1beta1" security "istio.io/client-go/pkg/apis/security/v1beta1" @@ -58,8 +57,6 @@ func init() { // openshift scheme utilruntime.Must(oapi.Install(scheme)) utilruntime.Must(oapiconfig.Install(scheme)) - // authorino scheme - utilruntime.Must(authorino.AddToScheme(scheme)) // istio security scheme utilruntime.Must(security.AddToScheme(scheme)) // istio networking scheme diff --git a/config/crd/bases/modelregistry.opendatahub.io_modelregistries.yaml b/config/crd/bases/modelregistry.opendatahub.io_modelregistries.yaml index be6d9a6..dfac84e 100644 --- a/config/crd/bases/modelregistry.opendatahub.io_modelregistries.yaml +++ b/config/crd/bases/modelregistry.opendatahub.io_modelregistries.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: modelregistries.modelregistry.opendatahub.io spec: group: modelregistry.opendatahub.io @@ -45,30 +45,38 @@ spec: description: ModelRegistry is the Schema for the modelregistries API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may 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' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may 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 type: string metadata: type: object spec: - description: ModelRegistrySpec defines the desired state of ModelRegistry. + description: |- + ModelRegistrySpec defines the desired state of ModelRegistry. One of `postgres` or `mysql` database configurations MUST be provided! properties: downgrade_db_schema_version: - description: Database downgrade schema version value. If set the database - schema version is downgraded to the set value during initialization - (Optional Parameter) + description: |- + Database downgrade schema version value. If set the database + schema version is downgraded to the set value during + initialization (Optional Parameter) format: int64 type: integer enable_database_upgrade: - description: Flag specifying database upgrade option. If set to true, - it enables database migration during initialization (Optional parameter) + description: |- + Flag specifying database upgrade option. If set to true, it enables + database migration during initialization (Optional parameter) type: boolean grpc: description: Configuration for gRPC endpoint @@ -88,19 +96,24 @@ spec: description: Resource requirements properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry in - pod.spec.resourceClaims of the Pod where this field - is used. It makes that resource available inside a - container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -116,8 +129,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -126,11 +140,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: '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/' + description: |- + 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/ type: object type: object type: object @@ -138,38 +152,42 @@ spec: description: Istio servicemesh configuration options properties: audiences: - description: Optional Authorino AuthConfig credential audiences. - This depends on the cluster identity provider. If not specified, - operator will determine the cluster's audience using its own - service account. + description: |- + Optional Authorino AuthConfig credential audiences. This depends on the cluster identity provider. + If not specified, operator will determine the cluster's audience using its own service account. items: type: string type: array authConfigLabels: additionalProperties: type: string - description: "Authorino AuthConfig selector labels. \n If missing, - it is set using the operator environment property DEFAULT_AUTH_CONFIG_LABELS" + description: |- + Authorino AuthConfig selector labels. + + + If missing, it is set using the operator environment property DEFAULT_AUTH_CONFIG_LABELS type: object authProvider: - description: "Authorino authentication provider name \n If missing, - it is set using the operator environment property DEFAULT_AUTH_PROVIDER - Model registry will have an error status if the operator property - is also missing" + description: |- + Authorino authentication provider name + + + If missing, it is set using the operator environment property DEFAULT_AUTH_PROVIDER + Model registry will have an error status if the operator property is also missing type: string gateway: - description: Optional Istio Gateway for registry services. Gateway - is not created if set to null (default). + description: |- + Optional Istio Gateway for registry services. + Gateway is not created if set to null (default). properties: controlPlane: description: Maistra/OpenShift Servicemesh control plane name type: string domain: - description: Domain name for Gateway configuration. If not - provided, it is set automatically using model registry operator - env variable DEFAULT_DOMAIN. If the env variable is not - set, it is set to the OpenShift `cluster` ingress domain - in an OpenShift cluster. + description: |- + Domain name for Gateway configuration. + If not provided, it is set automatically using model registry operator env variable DEFAULT_DOMAIN. + If the env variable is not set, it is set to the OpenShift `cluster` ingress domain in an OpenShift cluster. type: string grpc: description: gRPC gateway server config @@ -189,54 +207,40 @@ spec: minimum: 0 type: integer tls: - description: Set of TLS related options that govern the - server's behavior. Use these options to control if all - http requests should be redirected to https, and the - TLS modes to use. + description: |- + Set of TLS related options that govern the server's behavior. Use + these options to control if all http requests should be redirected to + https, and the TLS modes to use. properties: credentialName: - description: 'The name of the secret that holds the - TLS certs including the CA certificates. If not - provided, it is set automatically using model registry - operator env variable DEFAULT_CERT. An Opaque secret - should contain the following keys and values: `tls.key: - ` and `tls.crt: ` or `key: - ` and `cert: `. For mutual - TLS, `cacert: ` and `crl: ` - can be provided in the same secret or a separate - secret named `-cacert`. A TLS secret for - server certificates with an additional `tls.ocsp-staple` - key for specifying OCSP staple information, `ca.crt` - key for CA certificates and `ca.crl` for certificate - revocation list is also supported. Only one of server - certificates and CA certificate or credentialName - can be specified.' + description: |- + The name of the secret that holds the TLS certs including the CA certificates. + If not provided, it is set automatically using model registry operator env variable DEFAULT_CERT. + An Opaque secret should contain the following + keys and values: `tls.key: ` and `tls.crt: ` or + `key: ` and `cert: `. + For mutual TLS, `cacert: ` and `crl: ` + can be provided in the same secret or a separate secret named `-cacert`. + A TLS secret for server certificates with an additional `tls.ocsp-staple` key + for specifying OCSP staple information, `ca.crt` key for CA certificates + and `ca.crl` for certificate revocation list is also supported. + Only one of server certificates and CA certificate + or credentialName can be specified. type: string mode: default: SIMPLE - description: "The value of this field determines how - TLS is enforced. SIMPLE: Secure connections with - standard TLS semantics. In this mode client certificate - is not requested during handshake. \n MUTUAL: Secure - connections to the downstream using mutual TLS by - presenting server certificates for authentication. - A client certificate will also be requested during - the handshake and at least one valid certificate - is required to be sent by the client. \n ISTIO_MUTUAL: - Secure connections from the downstream using mutual - TLS by presenting server certificates for authentication. - Compared to Mutual mode, this mode uses certificates, - representing gateway workload identity, generated - automatically by Istio for mTLS authentication. - When this mode is used, all other TLS fields should - be empty. \n OPTIONAL_MUTUAL: Similar to MUTUAL - mode, except that the client certificate is optional. - Unlike SIMPLE mode, A client certificate will still - be explicitly requested during handshake, but the - client is not required to send a certificate. If - a client certificate is presented, it will be validated. - ca_certificates should be specified for validating - client certificates." + description: |- + The value of this field determines how TLS is enforced. + SIMPLE: Secure connections with standard TLS semantics. In this mode client certificate is not requested during handshake. + + + MUTUAL: Secure connections to the downstream using mutual TLS by presenting server certificates for authentication. A client certificate will also be requested during the handshake and at least one valid certificate is required to be sent by the client. + + + ISTIO_MUTUAL: Secure connections from the downstream using mutual TLS by presenting server certificates for authentication. Compared to Mutual mode, this mode uses certificates, representing gateway workload identity, generated automatically by Istio for mTLS authentication. When this mode is used, all other TLS fields should be empty. + + + OPTIONAL_MUTUAL: Similar to MUTUAL mode, except that the client certificate is optional. Unlike SIMPLE mode, A client certificate will still be explicitly requested during handshake, but the client is not required to send a certificate. If a client certificate is presented, it will be validated. ca_certificates should be specified for validating client certificates. enum: - SIMPLE - MUTUAL @@ -268,54 +272,40 @@ spec: minimum: 0 type: integer tls: - description: Set of TLS related options that govern the - server's behavior. Use these options to control if all - http requests should be redirected to https, and the - TLS modes to use. + description: |- + Set of TLS related options that govern the server's behavior. Use + these options to control if all http requests should be redirected to + https, and the TLS modes to use. properties: credentialName: - description: 'The name of the secret that holds the - TLS certs including the CA certificates. If not - provided, it is set automatically using model registry - operator env variable DEFAULT_CERT. An Opaque secret - should contain the following keys and values: `tls.key: - ` and `tls.crt: ` or `key: - ` and `cert: `. For mutual - TLS, `cacert: ` and `crl: ` - can be provided in the same secret or a separate - secret named `-cacert`. A TLS secret for - server certificates with an additional `tls.ocsp-staple` - key for specifying OCSP staple information, `ca.crt` - key for CA certificates and `ca.crl` for certificate - revocation list is also supported. Only one of server - certificates and CA certificate or credentialName - can be specified.' + description: |- + The name of the secret that holds the TLS certs including the CA certificates. + If not provided, it is set automatically using model registry operator env variable DEFAULT_CERT. + An Opaque secret should contain the following + keys and values: `tls.key: ` and `tls.crt: ` or + `key: ` and `cert: `. + For mutual TLS, `cacert: ` and `crl: ` + can be provided in the same secret or a separate secret named `-cacert`. + A TLS secret for server certificates with an additional `tls.ocsp-staple` key + for specifying OCSP staple information, `ca.crt` key for CA certificates + and `ca.crl` for certificate revocation list is also supported. + Only one of server certificates and CA certificate + or credentialName can be specified. type: string mode: default: SIMPLE - description: "The value of this field determines how - TLS is enforced. SIMPLE: Secure connections with - standard TLS semantics. In this mode client certificate - is not requested during handshake. \n MUTUAL: Secure - connections to the downstream using mutual TLS by - presenting server certificates for authentication. - A client certificate will also be requested during - the handshake and at least one valid certificate - is required to be sent by the client. \n ISTIO_MUTUAL: - Secure connections from the downstream using mutual - TLS by presenting server certificates for authentication. - Compared to Mutual mode, this mode uses certificates, - representing gateway workload identity, generated - automatically by Istio for mTLS authentication. - When this mode is used, all other TLS fields should - be empty. \n OPTIONAL_MUTUAL: Similar to MUTUAL - mode, except that the client certificate is optional. - Unlike SIMPLE mode, A client certificate will still - be explicitly requested during handshake, but the - client is not required to send a certificate. If - a client certificate is presented, it will be validated. - ca_certificates should be specified for validating - client certificates." + description: |- + The value of this field determines how TLS is enforced. + SIMPLE: Secure connections with standard TLS semantics. In this mode client certificate is not requested during handshake. + + + MUTUAL: Secure connections to the downstream using mutual TLS by presenting server certificates for authentication. A client certificate will also be requested during the handshake and at least one valid certificate is required to be sent by the client. + + + ISTIO_MUTUAL: Secure connections from the downstream using mutual TLS by presenting server certificates for authentication. Compared to Mutual mode, this mode uses certificates, representing gateway workload identity, generated automatically by Istio for mTLS authentication. When this mode is used, all other TLS fields should be empty. + + + OPTIONAL_MUTUAL: Similar to MUTUAL mode, except that the client certificate is optional. Unlike SIMPLE mode, A client certificate will still be explicitly requested during handshake, but the client is not required to send a certificate. If a client certificate is presented, it will be validated. ca_certificates should be specified for validating client certificates. enum: - SIMPLE - MUTUAL @@ -330,36 +320,47 @@ spec: type: object tlsMode: default: ISTIO_MUTUAL - description: "DestinationRule TLS mode. Defaults to ISTIO_MUTUAL. - \n DISABLE: Do not setup a TLS connection to the upstream endpoint. - \n SIMPLE: Originate a TLS connection to the upstream endpoint. - \n MUTUAL: Secure connections to the upstream using mutual TLS - by presenting client certificates for authentication. \n ISTIO_MUTUAL: - Secure connections to the upstream using mutual TLS by presenting - client certificates for authentication. Compared to Mutual mode, - this mode uses certificates generated automatically by Istio - for mTLS authentication. When this mode is used, all other fields - in `ClientTLSSettings` should be empty." + description: |- + DestinationRule TLS mode. Defaults to ISTIO_MUTUAL. + + + DISABLE: Do not setup a TLS connection to the upstream endpoint. + + + SIMPLE: Originate a TLS connection to the upstream endpoint. + + + MUTUAL: Secure connections to the upstream using mutual TLS by presenting + client certificates for authentication. + + + ISTIO_MUTUAL: Secure connections to the upstream using mutual TLS by presenting + client certificates for authentication. + Compared to Mutual mode, this mode uses certificates generated + automatically by Istio for mTLS authentication. When this mode is + used, all other fields in `ClientTLSSettings` should be empty. type: string type: object mysql: description: MySQL configuration options properties: database: - description: The database to connect to. Must be specified. After - connecting to the MYSQL server, this database is created if - not already present unless SkipDBCreation is set. All queries - after Connect() are assumed to be for this database. + description: |- + The database to connect to. Must be specified. + After connecting to the MYSQL server, this database is created if not + already present unless SkipDBCreation is set. + All queries after Connect() are assumed to be for this database. type: string host: - description: 'The hostname or IP address of the MYSQL server: - If unspecified, a connection to the local host is assumed. Currently, - a replicated MYSQL backend is not supported.' + description: |- + The hostname or IP address of the MYSQL server: + If unspecified, a connection to the local host is assumed. + Currently, a replicated MYSQL backend is not supported. type: string passwordSecret: - description: The password to use for `Username`. If empty, only - MYSQL user ids that don't have a password set are allowed to - connect. + description: |- + The password to use for `Username`. If empty, only MYSQL user ids that don't + have a password set are allowed to connect. properties: key: description: Key name in secret @@ -373,8 +374,9 @@ spec: type: object port: default: 3306 - description: Port number to connect to at the server host. The - TCP Port number that the MYSQL server accepts connections on. + description: |- + Port number to connect to at the server host. + The TCP Port number that the MYSQL server accepts connections on. If unspecified, the default MYSQL port (3306) is used. format: int32 maximum: 65535 @@ -382,8 +384,9 @@ spec: type: integer skipDBCreation: default: false - description: True if skipping database instance creation during - ML Metadata service initialization. By default, it is false. + description: |- + True if skipping database instance creation during ML Metadata + service initialization. By default, it is false. type: boolean sslCertificateSecret: description: This parameter specifies the Kubernetes Secret name @@ -404,8 +407,9 @@ spec: ciphers for SSL encryption. type: string sslKeySecret: - description: This parameter specifies the Kubernetes Secret name - and key used for the client private key. + description: |- + This parameter specifies the Kubernetes Secret name and key used for the + client private key. properties: key: description: Key name in secret @@ -418,8 +422,9 @@ spec: - name type: object sslRootCertificateConfigMap: - description: This parameter specifies the Kubernetes ConfigMap - name and key containing certificate authority (CA) certificate. + description: |- + This parameter specifies the Kubernetes ConfigMap name and key containing + certificate authority (CA) certificate. properties: key: description: Key name in configmap @@ -432,8 +437,9 @@ spec: - name type: object sslRootCertificateSecret: - description: This parameter specifies the Kubernetes Secret name - and key containing certificate authority (CA) certificate. + description: |- + This parameter specifies the Kubernetes Secret name and key containing + certificate authority (CA) certificate. properties: key: description: Key name in secret @@ -446,21 +452,22 @@ spec: - name type: object sslRootCertificatesConfigMapName: - description: This parameter specifies the Kubernetes ConfigMap - name containing multiple certificate authority (CA) certificate(s) - as keys. + description: |- + This parameter specifies the Kubernetes ConfigMap name containing + multiple certificate authority (CA) certificate(s) as keys. type: string sslRootCertificatesSecretName: - description: This parameter specifies the Kubernetes Secret name - containing multiple certificate authority (CA) certificate(s) - as keys. + description: |- + This parameter specifies the Kubernetes Secret name containing + multiple certificate authority (CA) certificate(s) as keys. type: string username: description: The MYSQL login id. type: string verifyServerCert: - description: If set, enable verification of the server certificate - against the host name used when connecting to the server. + description: |- + If set, enable verification of the server certificate against the host + name used when connecting to the server. type: boolean required: - database @@ -477,8 +484,9 @@ spec: description: Name of host to connect to. type: string hostAddress: - description: Numeric IP address of host to connect to. If this - field is provided, "host" field is ignored. + description: |- + Numeric IP address of host to connect to. If this field is + provided, "host" field is ignored. type: string passwordSecret: description: Password to be used if required by the PostgreSQL @@ -503,8 +511,9 @@ spec: type: integer skipDBCreation: default: false - description: True if skipping database instance creation during - ML Metadata service initialization. By default, it is false. + description: |- + True if skipping database instance creation during ML Metadata + service initialization. By default, it is false. type: boolean sslCertificateSecret: description: This parameter specifies the Kubernetes Secret name @@ -521,8 +530,9 @@ spec: - name type: object sslKeySecret: - description: This parameter specifies the Kubernetes Secret name - and key used for the client certificate SSL secret key. + description: |- + This parameter specifies the Kubernetes Secret name and key used for the + client certificate SSL secret key. properties: key: description: Key name in secret @@ -536,8 +546,9 @@ spec: type: object sslMode: default: disable - description: PostgreSQL sslmode setup. Values can be disable, - allow, prefer, require, verify-ca, verify-full. + description: |- + PostgreSQL sslmode setup. Values can be disable, allow, prefer, + require, verify-ca, verify-full. enum: - disable - allow @@ -547,11 +558,11 @@ spec: - verify-full type: string sslPasswordSecret: - description: This parameter specifies the Kubernetes Secret name - and key of the password for the SSL secret key specified in - sslKeySecret, allowing client certificate private keys to be - stored in encrypted form on disk even when interactive passphrase - input is not practical. + description: |- + This parameter specifies the Kubernetes Secret name and key of the password for the SSL secret key + specified in sslKeySecret, allowing client certificate private keys + to be stored in encrypted form on disk even when interactive + passphrase input is not practical. properties: key: description: Key name in secret @@ -564,8 +575,9 @@ spec: - name type: object sslRootCertificateConfigMap: - description: This parameter specifies the Kubernetes ConfigMap - name and key containing SSL certificate authority (CA) certificate(s). + description: |- + This parameter specifies the Kubernetes ConfigMap name and key containing SSL + certificate authority (CA) certificate(s). properties: key: description: Key name in configmap @@ -578,8 +590,9 @@ spec: - name type: object sslRootCertificateSecret: - description: This parameter specifies the Kubernetes Secret name - and key containing SSL certificate authority (CA) certificate(s). + description: |- + This parameter specifies the Kubernetes Secret name and key containing SSL + certificate authority (CA) certificate(s). properties: key: description: Key name in secret @@ -615,19 +628,24 @@ spec: description: Resource requirements properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry in - pod.spec.resourceClaims of the Pod where this field - is used. It makes that resource available inside a - container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -643,8 +661,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -653,11 +672,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: '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/' + description: |- + 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/ type: object type: object serviceRoute: @@ -678,42 +697,42 @@ spec: conditions: items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -727,11 +746,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -744,8 +764,9 @@ spec: type: object type: array hosts: - description: 'Hosts where model registry services are available NOTE: - Gateway service names are different for gRPC and REST service routes' + description: |- + Hosts where model registry services are available + NOTE: Gateway service names are different for gRPC and REST service routes items: type: string type: array diff --git a/go.mod b/go.mod index 6637a19..5fb4d02 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.21 require ( github.com/banzaicloud/k8s-objectmatcher v1.8.0 + github.com/evanphx/json-patch/v5 v5.6.0 github.com/go-logr/logr v1.4.1 - github.com/kuadrant/authorino v0.17.1 github.com/onsi/ginkgo/v2 v2.16.0 github.com/onsi/gomega v1.31.1 github.com/openshift/api v0.0.0-20231116201359-a5824a0c15b6 @@ -31,7 +31,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -78,9 +77,6 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/tidwall/gjson v1.14.0 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect go.etcd.io/etcd/api/v3 v3.5.10 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect go.etcd.io/etcd/client/v3 v3.5.10 // indirect diff --git a/go.sum b/go.sum index 965a607..e8d4833 100644 --- a/go.sum +++ b/go.sum @@ -99,7 +99,6 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -149,8 +148,8 @@ github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -187,8 +186,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kuadrant/authorino v0.17.1 h1:NXcYLDGSpokDE5VwzqWuRI07ChUsRNVKJB85uzOf35k= -github.com/kuadrant/authorino v0.17.1/go.mod h1:al71fN0FX6c9Orrhk9GR4CtjtC+CD/lUHJCs7drlRNM= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -278,12 +275,6 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -473,8 +464,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= istio.io/api v1.20.3-0.20240116015448-5563f7225778 h1:F+6gDkT2g1uPIVhu8HIykfKJrdQxJdCRNIvlsHRHXD4= diff --git a/internal/controller/config/templates/istio/authconfig.yaml.tmpl b/internal/controller/config/templates/istio/authconfig.yaml.tmpl index 03afdf8..d52e4c1 100644 --- a/internal/controller/config/templates/istio/authconfig.yaml.tmpl +++ b/internal/controller/config/templates/istio/authconfig.yaml.tmpl @@ -1,4 +1,4 @@ -apiVersion: authorino.kuadrant.io/v1beta2 +apiVersion: authorino.kuadrant.io/v1beta3 kind: AuthConfig metadata: name: {{.Name}} diff --git a/internal/controller/modelregistry_controller.go b/internal/controller/modelregistry_controller.go index d87bd7b..0718ae9 100644 --- a/internal/controller/modelregistry_controller.go +++ b/internal/controller/modelregistry_controller.go @@ -21,13 +21,13 @@ import ( errors2 "errors" "fmt" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes" "strings" "text/template" "github.com/banzaicloud/k8s-objectmatcher/patch" "github.com/go-logr/logr" - authorino "github.com/kuadrant/authorino/api/v1beta2" modelregistryv1alpha1 "github.com/opendatahub-io/model-registry-operator/api/v1alpha1" "github.com/opendatahub-io/model-registry-operator/internal/controller/config" routev1 "github.com/openshift/api/route/v1" @@ -259,7 +259,7 @@ func (r *ModelRegistryReconciler) SetupWithManager(mgr ctrl.Manager) error { } if r.HasIstio { if r.CreateAuthResources { - builder = builder.Owns(&authorino.AuthConfig{}). + builder = builder.Owns(CreateAuthConfig()). Owns(&security.AuthorizationPolicy{}) } builder = builder.Owns(&networking.DestinationRule{}). @@ -481,8 +481,10 @@ func (r *ModelRegistryReconciler) deleteIstioConfig(ctx context.Context, params return ResourceUpdated, err } - authConfig := authorino.AuthConfig{ObjectMeta: objectMeta} - if err = r.Client.Delete(ctx, &authConfig); client.IgnoreNotFound(err) != nil { + authConfig := CreateAuthConfig() + authConfig.SetName(params.Name) + authConfig.SetNamespace(params.Namespace) + if err = r.Client.Delete(ctx, authConfig); client.IgnoreNotFound(err) != nil { return ResourceUpdated, err } } @@ -623,25 +625,30 @@ func (r *ModelRegistryReconciler) createOrUpdateAuthConfig(ctx context.Context, } result = ResourceUnchanged - var authConfig authorino.AuthConfig - if err = r.Apply(params, templateName, &authConfig); err != nil { + authConfig := CreateAuthConfig() + if err = r.Apply(params, templateName, authConfig); err != nil { return result, err } - if err = ctrl.SetControllerReference(registry, &authConfig, r.Scheme); err != nil { + if err = ctrl.SetControllerReference(registry, authConfig, r.Scheme); err != nil { return result, err } // NOTE: AuthConfig CRD uses maps, which is not supported in k8s 3-way merge patch // use an Unstructured current object to force it to use a json merge patch instead - current := unstructured.Unstructured{} - current.SetGroupVersionKind(authConfig.GroupVersionKind()) - result, err = r.createOrUpdate(ctx, ¤t, &authConfig) + current := CreateAuthConfig() + result, err = r.createOrUpdate(ctx, current, authConfig) if err != nil { return result, err } return result, nil } +func CreateAuthConfig() *unstructured.Unstructured { + authConfig := unstructured.Unstructured{} + authConfig.SetGroupVersionKind(schema.GroupVersionKind{Group: "authorino.kuadrant.io", Version: "v1beta3", Kind: "AuthConfig"}) + return &authConfig +} + func (r *ModelRegistryReconciler) createOrUpdateAuthorizationPolicy(ctx context.Context, params *ModelRegistryParams, registry *modelregistryv1alpha1.ModelRegistry, templateName string) (result OperationResult, err error) { result = ResourceUnchanged diff --git a/internal/controller/modelregistry_controller_status.go b/internal/controller/modelregistry_controller_status.go index b6f434c..4cfac75 100644 --- a/internal/controller/modelregistry_controller_status.go +++ b/internal/controller/modelregistry_controller_status.go @@ -22,7 +22,6 @@ import ( "fmt" "github.com/evanphx/json-patch/v5" "github.com/go-logr/logr" - authorino "github.com/kuadrant/authorino/api/v1beta2" modelregistryv1alpha1 "github.com/opendatahub-io/model-registry-operator/api/v1alpha1" routev1 "github.com/openshift/api/route/v1" "istio.io/client-go/pkg/apis/networking/v1beta1" @@ -31,6 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/json" "regexp" @@ -417,7 +417,7 @@ func (r *ModelRegistryReconciler) CheckDeploymentPods(ctx context.Context, name } func (r *ModelRegistryReconciler) CheckAuthConfigCondition(ctx context.Context, name types.NamespacedName, log logr.Logger, message string, available bool, reason string) (string, bool, string) { - authConfig := &authorino.AuthConfig{} + authConfig := CreateAuthConfig() if err := r.Get(ctx, name, authConfig); err != nil { log.Error(err, "Failed to get model registry Istio Authorino AuthConfig", "name", name) message = fmt.Sprintf("Failed to find AuthConfig: %s", err.Error()) @@ -426,17 +426,26 @@ func (r *ModelRegistryReconciler) CheckAuthConfigCondition(ctx context.Context, // check authconfig Ready condition if available { - for _, c := range authConfig.Status.Conditions { - if c.Type == authorino.StatusConditionReady { - available = c.Status == corev1.ConditionTrue - if available { - reason = ReasonResourcesAvailable - message = "Istio resources are available" - } else { - reason = ReasonResourcesUnavailable - message = fmt.Sprintf("Istio AuthConfig is not ready: {reason: %s, message: %s}", c.Reason, c.Message) + conditions, _, _ := unstructured.NestedSlice(authConfig.Object, "status", "conditions") + for _, c := range conditions { + switch con := c.(type) { + case map[string]interface{}: + + condType, _, _ := unstructured.NestedString(con, "type") + if condType == "Ready" { + status, _, _ := unstructured.NestedString(con, "status") + available = status == "True" + if available { + reason = ReasonResourcesAvailable + message = "Istio resources are available" + } else { + reason = ReasonResourcesUnavailable + condReason, _, _ := unstructured.NestedString(con, "reason") + condMessage, _, _ := unstructured.NestedString(con, "message") + message = fmt.Sprintf("Istio AuthConfig is not ready: {reason: %s, message: %s}", condReason, condMessage) + } + break } - break } } }