--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{"controller-gen.kubebuilder.io/version":"v0.16.4"},"labels":{"app.kubernetes.io/component":"models-as-a-service","app.kubernetes.io/name":"maas-controller","app.kubernetes.io/part-of":"models-as-a-service"},"name":"configs.maas.opendatahub.io"},"spec":{"group":"maas.opendatahub.io","names":{"kind":"Config","listKind":"ConfigList","plural":"configs","shortNames":["maasconfig"],"singular":"config"},"scope":"Cluster","versions":[{"additionalPrinterColumns":[{"description":"Ready","jsonPath":".status.conditions[?(@.type==\"Ready\")].status","name":"Ready","type":"string"},{"jsonPath":".metadata.creationTimestamp","name":"Age","type":"date"}],"name":"v1alpha1","schema":{"openAPIV3Schema":{"description":"Config is a cluster-scoped anchor for MaaS platform resources. Namespaced and\ncluster-scoped operands created by maas-controller reference this object as their controller\nowner so Kubernetes garbage collection can tear down the full graph when the Config\nis deleted (subject to finalizers on dependents).","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore 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.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds","type":"string"},"metadata":{"type":"object"},"spec":{"description":"ConfigSpec defines the desired state of Config.\nAdmission CEL keeps a low-cost shape check; strict restricted-egress validation\n(both to and ports, except the Kubernetes API port-only rule) runs at reconcile\ntime in tenantreconcile.validateRestrictedEgressRules.","properties":{"limitadorScrapeInterval":{"default":"30s","description":"LimitadorScrapeInterval defines the scrape interval for Limitador metrics in the ServiceMonitor.\nDefaults to \"30s\" if not specified.","maxLength":16,"pattern":"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$","type":"string"},"maasApiEgressNetworkPolicy":{"allOf":[{"enum":["Managed","Disabled"]},{"enum":["Managed","Disabled"]}],"default":"Managed","description":"MaasAPIEgressNetworkPolicy controls whether maas-controller reconciles\nmaas-api-egress-restrict. Managed (default) applies the operand egress policy;\nDisabled deletes it so customers can manage egress NetworkPolicies themselves.","type":"string"},"networkPolicyAdditionalEgressRules":{"description":"NetworkPolicyAdditionalEgressRules specifies egress rules appended after the\nbase egress block (either defaults or NetworkPolicyEgressRules). Use for\nnon-standard ports or extra database peers when retaining default allow-all.","items":{"description":"NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods\nmatched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.\nThis type is beta-level in 1.8","properties":{"ports":{"description":"ports is a list of destination ports for outgoing traffic.\nEach item in this list is combined using a logical OR. If this field is\nempty or missing, this rule matches all ports (traffic not restricted by port).\nIf this field is present and contains at least one item, then this rule allows\ntraffic only if the traffic matches at least one port in the list.","items":{"description":"NetworkPolicyPort describes a port to allow traffic on","properties":{"endPort":{"description":"endPort indicates that the range of ports from port to endPort if set, inclusive,\nshould be allowed by the policy. This field cannot be defined if the port field\nis not defined or if the port field is defined as a named (string) port.\nThe endPort must be equal or greater than port.","format":"int32","type":"integer"},"port":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"port represents the port on the given protocol. This can either be a numerical or named\nport on a pod. If this field is not provided, this matches all port names and\nnumbers.\nIf present, only traffic on the specified protocol AND port will be matched.","x-kubernetes-int-or-string":true},"protocol":{"description":"protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match.\nIf not specified, this field defaults to TCP.","type":"string"}},"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"to":{"description":"to is a list of destinations for outgoing traffic of pods selected for this rule.\nItems in this list are combined using a logical OR operation. If this field is\nempty or missing, this rule matches all destinations (traffic not restricted by\ndestination). If this field is present and contains at least one item, this rule\nallows traffic only if the traffic matches at least one item in the to list.","items":{"description":"NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of\nfields are allowed","properties":{"ipBlock":{"description":"ipBlock defines policy on a particular IPBlock. If this field is set then\nneither of the other fields can be.","properties":{"cidr":{"description":"cidr is a string representing the IPBlock\nValid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"","type":"string"},"except":{"description":"except is a slice of CIDRs that should not be included within an IPBlock\nValid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"\nExcept values will be rejected if they are outside the cidr range","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["cidr"],"type":"object"},"namespaceSelector":{"description":"namespaceSelector selects namespaces using cluster-scoped labels. This field follows\nstandard label selector semantics; if present but empty, it selects all namespaces.\n\nIf podSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe pods matching podSelector in the namespaces selected by namespaceSelector.\nOtherwise it selects all pods in the namespaces selected by namespaceSelector.","properties":{"matchExpressions":{"description":"matchExpressions is a list of label selector requirements. The requirements are ANDed.","items":{"description":"A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.","properties":{"key":{"description":"key is the label key that the selector applies to.","type":"string"},"operator":{"description":"operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.","type":"string"},"values":{"description":"values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["key","operator"],"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"matchLabels":{"additionalProperties":{"type":"string"},"description":"matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.","type":"object"}},"type":"object","x-kubernetes-map-type":"atomic"},"podSelector":{"description":"podSelector is a label selector which selects pods. This field follows standard label\nselector semantics; if present but empty, it selects all pods.\n\nIf namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe pods matching podSelector in the Namespaces selected by NamespaceSelector.\nOtherwise it selects the pods matching podSelector in the policy's own namespace.","properties":{"matchExpressions":{"description":"matchExpressions is a list of label selector requirements. The requirements are ANDed.","items":{"description":"A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.","properties":{"key":{"description":"key is the label key that the selector applies to.","type":"string"},"operator":{"description":"operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.","type":"string"},"values":{"description":"values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["key","operator"],"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"matchLabels":{"additionalProperties":{"type":"string"},"description":"matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.","type":"object"}},"type":"object","x-kubernetes-map-type":"atomic"}},"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"}},"type":"object"},"maxItems":32,"type":"array"},"networkPolicyEgressRules":{"description":"NetworkPolicyEgressRules, when non-empty, replaces the default egress block of\nmaas-api-egress-restrict. The caller must include DNS, Kubernetes API, database,\nand any other required destinations. When empty, the operator applies DNS, API\nports, and allow-all egress for customer-provided dependencies.\nRules from NetworkPolicyAdditionalEgressRules are appended after this list.","items":{"description":"NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods\nmatched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.\nThis type is beta-level in 1.8","properties":{"ports":{"description":"ports is a list of destination ports for outgoing traffic.\nEach item in this list is combined using a logical OR. If this field is\nempty or missing, this rule matches all ports (traffic not restricted by port).\nIf this field is present and contains at least one item, then this rule allows\ntraffic only if the traffic matches at least one port in the list.","items":{"description":"NetworkPolicyPort describes a port to allow traffic on","properties":{"endPort":{"description":"endPort indicates that the range of ports from port to endPort if set, inclusive,\nshould be allowed by the policy. This field cannot be defined if the port field\nis not defined or if the port field is defined as a named (string) port.\nThe endPort must be equal or greater than port.","format":"int32","type":"integer"},"port":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"port represents the port on the given protocol. This can either be a numerical or named\nport on a pod. If this field is not provided, this matches all port names and\nnumbers.\nIf present, only traffic on the specified protocol AND port will be matched.","x-kubernetes-int-or-string":true},"protocol":{"description":"protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match.\nIf not specified, this field defaults to TCP.","type":"string"}},"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"to":{"description":"to is a list of destinations for outgoing traffic of pods selected for this rule.\nItems in this list are combined using a logical OR operation. If this field is\nempty or missing, this rule matches all destinations (traffic not restricted by\ndestination). If this field is present and contains at least one item, this rule\nallows traffic only if the traffic matches at least one item in the to list.","items":{"description":"NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of\nfields are allowed","properties":{"ipBlock":{"description":"ipBlock defines policy on a particular IPBlock. If this field is set then\nneither of the other fields can be.","properties":{"cidr":{"description":"cidr is a string representing the IPBlock\nValid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"","type":"string"},"except":{"description":"except is a slice of CIDRs that should not be included within an IPBlock\nValid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"\nExcept values will be rejected if they are outside the cidr range","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["cidr"],"type":"object"},"namespaceSelector":{"description":"namespaceSelector selects namespaces using cluster-scoped labels. This field follows\nstandard label selector semantics; if present but empty, it selects all namespaces.\n\nIf podSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe pods matching podSelector in the namespaces selected by namespaceSelector.\nOtherwise it selects all pods in the namespaces selected by namespaceSelector.","properties":{"matchExpressions":{"description":"matchExpressions is a list of label selector requirements. The requirements are ANDed.","items":{"description":"A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.","properties":{"key":{"description":"key is the label key that the selector applies to.","type":"string"},"operator":{"description":"operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.","type":"string"},"values":{"description":"values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["key","operator"],"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"matchLabels":{"additionalProperties":{"type":"string"},"description":"matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.","type":"object"}},"type":"object","x-kubernetes-map-type":"atomic"},"podSelector":{"description":"podSelector is a label selector which selects pods. This field follows standard label\nselector semantics; if present but empty, it selects all pods.\n\nIf namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe pods matching podSelector in the Namespaces selected by NamespaceSelector.\nOtherwise it selects the pods matching podSelector in the policy's own namespace.","properties":{"matchExpressions":{"description":"matchExpressions is a list of label selector requirements. The requirements are ANDed.","items":{"description":"A label selector requirement is a selector that contains values, a key, and an operator that\nrelates the key and values.","properties":{"key":{"description":"key is the label key that the selector applies to.","type":"string"},"operator":{"description":"operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.","type":"string"},"values":{"description":"values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.","items":{"type":"string"},"type":"array","x-kubernetes-list-type":"atomic"}},"required":["key","operator"],"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"},"matchLabels":{"additionalProperties":{"type":"string"},"description":"matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.","type":"object"}},"type":"object","x-kubernetes-map-type":"atomic"}},"type":"object"},"type":"array","x-kubernetes-list-type":"atomic"}},"type":"object"},"maxItems":32,"type":"array"},"usageLogging":{"default":false,"description":"UsageLogging is retained for compatibility and does not gate deployment.\nWhen true, the gateway EnvoyFilter exports usage logs to usage-logs-collector.\nWhen false or unset, it exports to data-science-usage-logs-collector.\nWhen MaasTenantConfig telemetry is enabled and usageLogging is false or unset,\nMaasTenantConfig is Degraded unless DSCInitialization reports LokiStackAvailable,\nUsageLogsCollectorAvailable, and PersesAvailable as True.\nWhen usageLogging is true and telemetry is enabled, MaasTenantConfig is Degraded\nunless PersesAvailable is True.\nUser identity (user_id) is included in those logs only when\nMaasTenantConfig.spec.telemetry.logs.captureUser is true.","type":"boolean"},"usageMetricsDashboard":{"default":false,"description":"UsageMetricsDashboard deploys the legacy Prometheus-based Perses usage dashboard\n(dashboard-3-maas-usage-admin). When disabled (the default), the controller\nremoves any controller-owned copy of that dashboard and does not mark\nMaasTenantConfig Degraded when the ODH monitoring stack is unavailable.\nWhen enabled and MaasTenantConfig telemetry is enabled, an unavailable monitoring\nstack sets MaasTenantConfig phase to Degraded.\nPrefer the logs-based usage dashboards, which are deployed with the usage-log resources.","type":"boolean"}},"type":"object","x-kubernetes-validations":[{"message":"each networkPolicyEgressRules entry must specify at least one port or one destination","rule":"!has(self.networkPolicyEgressRules) || self.networkPolicyEgressRules.all(r, (has(r.ports) \u0026\u0026 size(r.ports) \u003e 0) || (has(r.to) \u0026\u0026 size(r.to) \u003e 0))"},{"message":"each networkPolicyAdditionalEgressRules entry must specify at least one port or one destination","rule":"!has(self.networkPolicyAdditionalEgressRules) || self.networkPolicyAdditionalEgressRules.all(r, (has(r.ports) \u0026\u0026 size(r.ports) \u003e 0) || (has(r.to) \u0026\u0026 size(r.to) \u003e 0))"},{"message":"networkPolicyEgressRules and networkPolicyAdditionalEgressRules must be unset when maasApiEgressNetworkPolicy is Disabled","rule":"!has(self.maasApiEgressNetworkPolicy) || self.maasApiEgressNetworkPolicy != 'Disabled' || ((!has(self.networkPolicyEgressRules) || size(self.networkPolicyEgressRules) == 0) \u0026\u0026 (!has(self.networkPolicyAdditionalEgressRules) || size(self.networkPolicyAdditionalEgressRules) == 0))"}]},"status":{"description":"ConfigStatus defines the observed state of Config.","properties":{"conditions":{"description":"Conditions represent the latest available observations of the MaaS platform state.\nThe Ready condition aggregates status from the default AITenant and MaasTenantConfig\nso that the platform operator (DSC) can report configuration issues without watching\nMaaS operands directly.\nThe TenantsHealthy condition aggregates the Ready state of all AITenant CRs into a\nthree-state model (Healthy/Degraded/Blocked) per ADR ODH-ADR-MS-0003.","items":{"description":"Condition contains details for one aspect of the current state of this API Resource.","properties":{"lastTransitionTime":{"description":"lastTransitionTime is the last time the condition transitioned from one status to another.\nThis 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.\nThis may be an empty string.","maxLength":32768,"type":"string"},"observedGeneration":{"description":"observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith 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.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.","maxLength":1024,"minLength":1,"pattern":"^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$","type":"string"},"status":{"description":"status of the condition, one of True, False, Unknown.","enum":["True","False","Unknown"],"type":"string"},"type":{"description":"type of condition in CamelCase or in foo.example.com/CamelCase.","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"}},"required":["lastTransitionTime","message","reason","status","type"],"type":"object"},"type":"array"}},"type":"object"}},"type":"object","x-kubernetes-validations":[{"message":"Config name must be default","rule":"self.metadata.name == 'default'"}]}},"served":true,"storage":true,"subresources":{"status":{}}}]}} creationTimestamp: "2026-10-31T16:07:15Z" generation: 1 labels: app.kubernetes.io/component: models-as-a-service app.kubernetes.io/name: maas-controller app.kubernetes.io/part-of: models-as-a-service managedFields: - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:status: f:acceptedNames: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:conditions: k:{"type":"Established"}: .: {} f:lastTransitionTime: {} f:message: {} f:reason: {} f:status: {} f:type: {} k:{"type":"NamesAccepted"}: .: {} f:lastTransitionTime: {} f:message: {} f:reason: {} f:status: {} f:type: {} manager: kube-apiserver operation: Update subresource: status time: "2026-10-31T16:07:15Z" - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:annotations: .: {} f:controller-gen.kubebuilder.io/version: {} f:kubectl.kubernetes.io/last-applied-configuration: {} f:labels: .: {} f:app.kubernetes.io/component: {} f:app.kubernetes.io/name: {} f:app.kubernetes.io/part-of: {} f:spec: f:conversion: .: {} f:strategy: {} f:group: {} f:names: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:scope: {} f:versions: {} manager: kubectl-client-side-apply operation: Update time: "2026-10-31T16:08:16Z" name: configs.maas.opendatahub.io resourceVersion: "16752" uid: a58f42df-8f1d-4bd8-acd3-1f4039097c20 spec: conversion: strategy: None group: maas.opendatahub.io names: kind: Config listKind: ConfigList plural: configs shortNames: - maasconfig singular: config scope: Cluster versions: - additionalPrinterColumns: - description: Ready jsonPath: .status.conditions[?(@.type=="Ready")].status name: Ready type: string - jsonPath: .metadata.creationTimestamp name: Age type: date name: v1alpha1 schema: openAPIV3Schema: description: |- Config is a cluster-scoped anchor for MaaS platform resources. Namespaced and cluster-scoped operands created by maas-controller reference this object as their controller owner so Kubernetes garbage collection can tear down the full graph when the Config is deleted (subject to finalizers on dependents). 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 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 type: string metadata: type: object spec: description: |- ConfigSpec defines the desired state of Config. Admission CEL keeps a low-cost shape check; strict restricted-egress validation (both to and ports, except the Kubernetes API port-only rule) runs at reconcile time in tenantreconcile.validateRestrictedEgressRules. properties: limitadorScrapeInterval: default: 30s description: |- LimitadorScrapeInterval defines the scrape interval for Limitador metrics in the ServiceMonitor. Defaults to "30s" if not specified. maxLength: 16 pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ type: string maasApiEgressNetworkPolicy: allOf: - enum: - Managed - Disabled - enum: - Managed - Disabled default: Managed description: |- MaasAPIEgressNetworkPolicy controls whether maas-controller reconciles maas-api-egress-restrict. Managed (default) applies the operand egress policy; Disabled deletes it so customers can manage egress NetworkPolicies themselves. type: string networkPolicyAdditionalEgressRules: description: |- NetworkPolicyAdditionalEgressRules specifies egress rules appended after the base egress block (either defaults or NetworkPolicyEgressRules). Use for non-standard ports or extra database peers when retaining default allow-all. items: description: |- NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8 properties: ports: description: |- ports is a list of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list. items: description: NetworkPolicyPort describes a port to allow traffic on properties: endPort: description: |- endPort indicates that the range of ports from port to endPort if set, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. format: int32 type: integer port: anyOf: - type: integer - type: string description: |- port represents the port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched. x-kubernetes-int-or-string: true protocol: description: |- protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. type: string type: object type: array x-kubernetes-list-type: atomic to: description: |- to is a list of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list. items: description: |- NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of fields are allowed properties: ipBlock: description: |- ipBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be. properties: cidr: description: |- cidr is a string representing the IPBlock Valid examples are "192.168.1.0/24" or "2001:db8::/64" type: string except: description: |- except is a slice of CIDRs that should not be included within an IPBlock Valid examples are "192.168.1.0/24" or "2001:db8::/64" Except values will be rejected if they are outside the cidr range items: type: string type: array x-kubernetes-list-type: atomic required: - cidr type: object namespaceSelector: description: |- namespaceSelector selects namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces. If podSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the namespaces selected by namespaceSelector. Otherwise it selects all pods in the namespaces selected by namespaceSelector. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic podSelector: description: |- podSelector is a label selector which selects pods. This field follows standard label selector semantics; if present but empty, it selects all pods. If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the pods matching podSelector in the policy's own namespace. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: array x-kubernetes-list-type: atomic type: object maxItems: 32 type: array networkPolicyEgressRules: description: |- NetworkPolicyEgressRules, when non-empty, replaces the default egress block of maas-api-egress-restrict. The caller must include DNS, Kubernetes API, database, and any other required destinations. When empty, the operator applies DNS, API ports, and allow-all egress for customer-provided dependencies. Rules from NetworkPolicyAdditionalEgressRules are appended after this list. items: description: |- NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8 properties: ports: description: |- ports is a list of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list. items: description: NetworkPolicyPort describes a port to allow traffic on properties: endPort: description: |- endPort indicates that the range of ports from port to endPort if set, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. format: int32 type: integer port: anyOf: - type: integer - type: string description: |- port represents the port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched. x-kubernetes-int-or-string: true protocol: description: |- protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP. type: string type: object type: array x-kubernetes-list-type: atomic to: description: |- to is a list of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list. items: description: |- NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of fields are allowed properties: ipBlock: description: |- ipBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be. properties: cidr: description: |- cidr is a string representing the IPBlock Valid examples are "192.168.1.0/24" or "2001:db8::/64" type: string except: description: |- except is a slice of CIDRs that should not be included within an IPBlock Valid examples are "192.168.1.0/24" or "2001:db8::/64" Except values will be rejected if they are outside the cidr range items: type: string type: array x-kubernetes-list-type: atomic required: - cidr type: object namespaceSelector: description: |- namespaceSelector selects namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces. If podSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the namespaces selected by namespaceSelector. Otherwise it selects all pods in the namespaces selected by namespaceSelector. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic podSelector: description: |- podSelector is a label selector which selects pods. This field follows standard label selector semantics; if present but empty, it selects all pods. If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the pods matching podSelector in the policy's own namespace. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: description: |- operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: description: |- values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. items: type: string type: array x-kubernetes-list-type: atomic required: - key - operator type: object type: array x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: array x-kubernetes-list-type: atomic type: object maxItems: 32 type: array usageLogging: default: false description: |- UsageLogging is retained for compatibility and does not gate deployment. When true, the gateway EnvoyFilter exports usage logs to usage-logs-collector. When false or unset, it exports to data-science-usage-logs-collector. When MaasTenantConfig telemetry is enabled and usageLogging is false or unset, MaasTenantConfig is Degraded unless DSCInitialization reports LokiStackAvailable, UsageLogsCollectorAvailable, and PersesAvailable as True. When usageLogging is true and telemetry is enabled, MaasTenantConfig is Degraded unless PersesAvailable is True. User identity (user_id) is included in those logs only when MaasTenantConfig.spec.telemetry.logs.captureUser is true. type: boolean usageMetricsDashboard: default: false description: |- UsageMetricsDashboard deploys the legacy Prometheus-based Perses usage dashboard (dashboard-3-maas-usage-admin). When disabled (the default), the controller removes any controller-owned copy of that dashboard and does not mark MaasTenantConfig Degraded when the ODH monitoring stack is unavailable. When enabled and MaasTenantConfig telemetry is enabled, an unavailable monitoring stack sets MaasTenantConfig phase to Degraded. Prefer the logs-based usage dashboards, which are deployed with the usage-log resources. type: boolean type: object x-kubernetes-validations: - message: each networkPolicyEgressRules entry must specify at least one port or one destination rule: '!has(self.networkPolicyEgressRules) || self.networkPolicyEgressRules.all(r, (has(r.ports) && size(r.ports) > 0) || (has(r.to) && size(r.to) > 0))' - message: each networkPolicyAdditionalEgressRules entry must specify at least one port or one destination rule: '!has(self.networkPolicyAdditionalEgressRules) || self.networkPolicyAdditionalEgressRules.all(r, (has(r.ports) && size(r.ports) > 0) || (has(r.to) && size(r.to) > 0))' - message: networkPolicyEgressRules and networkPolicyAdditionalEgressRules must be unset when maasApiEgressNetworkPolicy is Disabled rule: '!has(self.maasApiEgressNetworkPolicy) || self.maasApiEgressNetworkPolicy != ''Disabled'' || ((!has(self.networkPolicyEgressRules) || size(self.networkPolicyEgressRules) == 0) && (!has(self.networkPolicyAdditionalEgressRules) || size(self.networkPolicyAdditionalEgressRules) == 0))' status: description: ConfigStatus defines the observed state of Config. properties: conditions: description: |- Conditions represent the latest available observations of the MaaS platform state. The Ready condition aggregates status from the default AITenant and MaasTenantConfig so that the platform operator (DSC) can report configuration issues without watching MaaS operands directly. The TenantsHealthy condition aggregates the Ready state of all AITenant CRs into a three-state model (Healthy/Degraded/Blocked) per ADR ODH-ADR-MS-0003. items: description: Condition contains details for one aspect of the current state of this API Resource. 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. format: date-time type: string message: 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. 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. This field may not be empty. maxLength: 1024 minLength: 1 pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ type: string status: description: status of the condition, one of True, False, Unknown. enum: - "True" - "False" - Unknown type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. 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 required: - lastTransitionTime - message - reason - status - type type: object type: array type: object type: object x-kubernetes-validations: - message: Config name must be default rule: self.metadata.name == 'default' served: true storage: true subresources: status: {} status: acceptedNames: kind: Config listKind: ConfigList plural: configs shortNames: - maasconfig singular: config conditions: - lastTransitionTime: "2026-10-31T16:07:15Z" message: no conflicts found reason: NoConflicts status: "True" type: NamesAccepted - lastTransitionTime: "2026-10-31T16:07:15Z" message: the initial names have been accepted reason: InitialNamesAccepted status: "True" type: Established storedVersions: - v1alpha1