diff --git a/api/bases/placement.openstack.org_placementapis.yaml b/api/bases/placement.openstack.org_placementapis.yaml index 03948b96..49a502e8 100644 --- a/api/bases/placement.openstack.org_placementapis.yaml +++ b/api/bases/placement.openstack.org_placementapis.yaml @@ -92,48 +92,6 @@ spec: to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement' type: object - externalEndpoints: - description: ExternalEndpoints, expose a VIP using a pre-created IPAddressPool - items: - description: MetalLBConfig to configure the MetalLB loadbalancer - service - properties: - endpoint: - description: Endpoint, OpenStack endpoint this service maps - to - enum: - - internal - - public - type: string - ipAddressPool: - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - minLength: 1 - type: string - loadBalancerIPs: - description: LoadBalancerIPs, request given IPs from the pool - if available. Using a list to allow dual stack (IPv4/IPv6) - support - items: - type: string - type: array - sharedIP: - default: true - description: SharedIP if true, VIP/VIPs get shared with multiple - services - type: boolean - sharedIPKey: - default: "" - description: SharedIPKey specifies the sharing key which gets - set as the annotation on the LoadBalancer service. Services - which share the same VIP must have the same SharedIPKey. Defaults - to the IPAddressPool if SharedIP is true, but no SharedIPKey - specified. - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -146,6 +104,418 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + override: + description: Override, provides the ability to override the generated + manifest of several child resources. + properties: + service: + description: Override configuration for the Service created to + serve traffic to the cluster. + items: + description: OverrideSpec - service override configuration for + the Service created to serve traffic to the cluster. Allows + for the manifest of the created Service to be overwritten + with custom configuration. + properties: + endpoint: + description: Endpoint, OpenStack endpoint this service maps + to + enum: + - internal + - public + type: string + endpointURL: + description: EndpointURL to be used to register the service + in keystone. + type: string + metadata: + description: EmbeddedLabelsAnnotations is an embedded subset + of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta. + Only labels and annotations are included. + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value + map stored with a resource that may be set by external + tools to store and retrieve arbitrary metadata. They + are not queryable and should be preserved when modifying + objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can + be used to organize and categorize (scope and select) + objects. May match selectors of replication controllers + and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + type: object + spec: + description: Spec defines the behavior of a Service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: allocateLoadBalancerNodePorts defines if + NodePorts will be automatically allocated for services + with type LoadBalancer. Default is "true". It may + be set to "false" if the cluster load-balancer does + not rely on NodePorts. If the caller requests specific + NodePorts (by specifying a value), those requests + will be respected, regardless of this field. This + field may only be set for services with type LoadBalancer + and will be cleared if the type is changed to any + other type. + type: boolean + clusterIP: + description: 'clusterIP is the IP address of the service + and is usually assigned randomly. If an address is + specified manually, is in-range (as per system configuration), + and is not in use, it will be allocated to the service; + otherwise creation of the service will fail. This + field may not be changed through updates unless the + type field is also being changed to ExternalName (which + requires this field to be blank) or the type field + is being changed from ExternalName (in which case + this field may optionally be specified, as describe + above). Valid values are "None", empty string (""), + or a valid IP address. Setting this to "None" makes + a "headless service" (no virtual IP), which is useful + when direct endpoint connections are preferred and + proxying is not required. Only applies to types ClusterIP, + NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation + will fail. This field will be wiped when updating + a Service to type ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + type: string + clusterIPs: + description: "ClusterIPs is a list of IP addresses assigned + to this service, and are usually assigned randomly. + \ If an address is specified manually, is in-range + (as per system configuration), and is not in use, + it will be allocated to the service; otherwise creation + of the service will fail. This field may not be changed + through updates unless the type field is also being + changed to ExternalName (which requires this field + to be empty) or the type field is being changed from + ExternalName (in which case this field may optionally + be specified, as describe above). Valid values are + \"None\", empty string (\"\"), or a valid IP address. + \ Setting this to \"None\" makes a \"headless service\" + (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. + \ Only applies to types ClusterIP, NodePort, and LoadBalancer. + If this field is specified when creating a Service + of type ExternalName, creation will fail. This field + will be wiped when updating a Service to type ExternalName. + \ If this field is not specified, it will be initialized + from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP + have the same value. \n This field may hold a maximum + of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies + field. Both clusterIPs and ipFamilies are governed + by the ipFamilyPolicy field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: externalIPs is a list of IP addresses for + which nodes in the cluster will also accept traffic + for this service. These IPs are not managed by Kubernetes. The + user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external + load-balancers that are not part of the Kubernetes + system. + items: + type: string + type: array + externalName: + description: externalName is the external reference + that discovery mechanisms will return as an alias + for this service (e.g. a DNS CNAME record). No proxying + will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires + `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: externalTrafficPolicy describes how nodes + distribute service traffic they receive on one of + the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", + the proxy will configure the service in a way that + assumes that external load balancers will take care + of balancing the service traffic between nodes, and + so each node will deliver traffic only to the node-local + endpoints of the service, without masquerading the + client source IP. (Traffic mistakenly sent to a node + with no endpoints will be dropped.) The default value, + "Cluster", uses the standard behavior of routing to + all endpoints evenly (possibly modified by topology + and other features). Note that traffic sent to an + External IP or LoadBalancer IP from within the cluster + will always get "Cluster" semantics, but clients sending + to a NodePort from within the cluster may need to + take traffic policy into account when picking a node. + type: string + healthCheckNodePort: + description: healthCheckNodePort specifies the healthcheck + nodePort for the service. This only applies when type + is set to LoadBalancer and externalTrafficPolicy is + set to Local. If a value is specified, is in-range, + and is not in use, it will be used. If not specified, + a value will be automatically allocated. External + systems (e.g. load-balancers) can use this port to + determine if a given node holds endpoints for this + service or not. If this field is specified when creating + a Service which does not need it, creation will fail. + This field will be wiped when updating a Service to + no longer need it (e.g. changing type). This field + cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: InternalTrafficPolicy describes how nodes + distribute service traffic they receive on the ClusterIP. + If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the + same node as the pod, dropping the traffic if there + are no local endpoints. The default value, "Cluster", + uses the standard behavior of routing to all endpoints + evenly (possibly modified by topology and other features). + type: string + ipFamilies: + description: "IPFamilies is a list of IP families (e.g. + IPv4, IPv6) assigned to this service. This field is + usually assigned automatically based on cluster configuration + and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the + cluster, and ipFamilyPolicy allows it, it will be + used; otherwise creation of the service will fail. + This field is conditionally mutable: it allows for + adding or removing a secondary IP family, but it does + not allow changing the primary IP family of the Service. + Valid values are \"IPv4\" and \"IPv6\". This field + only applies to Services of types ClusterIP, NodePort, + and LoadBalancer, and does apply to \"headless\" services. + This field will be wiped when updating a Service to + type ExternalName. \n This field may hold a maximum + of two entries (dual-stack families, in either order). + \ These families must correspond to the values of + the clusterIPs field, if specified. Both clusterIPs + and ipFamilies are governed by the ipFamilyPolicy + field." + items: + description: IPFamily represents the IP Family (IPv4 + or IPv6). This type is used to express the family + of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: IPFamilyPolicy represents the dual-stack-ness + requested or required by this Service. If there is + no value provided, then this field will be set to + SingleStack. Services can be "SingleStack" (a single + IP family), "PreferDualStack" (two IP families on + dual-stack configured clusters or a single IP family + on single-stack clusters), or "RequireDualStack" (two + IP families on dual-stack configured clusters, otherwise + fail). The ipFamilies and clusterIPs fields depend + on the value of this field. This field will be wiped + when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: loadBalancerClass is the class of the load + balancer implementation this Service belongs to. If + specified, the value of this field must be a label-style + identifier, with an optional prefix, e.g. "internal-vip" + or "example.com/internal-vip". Unprefixed names are + reserved for end-users. This field can only be set + when the Service type is 'LoadBalancer'. If not set, + the default load balancer implementation is used, + today this is typically done through the cloud provider + integration, but should apply for any default implementation. + If set, it is assumed that a load balancer implementation + is watching for Services with a matching class. Any + default load balancer implementation (e.g. cloud providers) + should ignore Services that set this field. This field + can only be set when creating or updating a Service + to type 'LoadBalancer'. Once set, it can not be changed. + This field will be wiped when a service is updated + to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: 'Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider + supports specifying the loadBalancerIP when a load + balancer is created. This field will be ignored if + the cloud-provider does not support the feature. Deprecated: + This field was under-specified and its meaning varies + across implementations, and it cannot support dual-stack. + As of Kubernetes v1.24, users are encouraged to use + implementation-specific annotations when available. + This field may be removed in a future API version.' + type: string + loadBalancerSourceRanges: + description: 'If specified and supported by the platform, + this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified + client IPs. This field will be ignored if the cloud-provider + does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/' + items: + type: string + type: array + ports: + description: 'The list of ports that are exposed by + this service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: The application protocol for this + port. This field follows standard Kubernetes + label syntax. Un-prefixed names are reserved + for IANA standard service names (as per RFC-6335 + and https://www.iana.org/assignments/service-names). + Non-standard protocols should use prefixed names + such as mycompany.com/my-custom-protocol. + type: string + name: + description: The name of this port within the + service. This must be a DNS_LABEL. All ports + within a ServiceSpec must have unique names. + When considering the endpoints for a Service, + this must match the 'name' field in the EndpointPort. + Optional if only one ServicePort is defined + on this service. + type: string + nodePort: + description: 'The port on each node on which this + service is exposed when type is NodePort or + LoadBalancer. Usually assigned by the system. + If a value is specified, in-range, and not in + use it will be used, otherwise the operation + will fail. If not specified, a port will be + allocated if this Service requires one. If + this field is specified when creating a Service + which does not need it, creation will fail. + This field will be wiped when updating a Service + to no longer need it (e.g. changing type from + NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' + format: int32 + type: integer + port: + description: The port that will be exposed by + this service. + format: int32 + type: integer + protocol: + default: TCP + description: The IP protocol for this port. Supports + "TCP", "UDP", and "SCTP". Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: 'Number or name of the port to access + on the pods targeted by the service. Number + must be in the range 1 to 65535. Name must be + an IANA_SVC_NAME. If this is a string, it will + be looked up as a named port in the target Pod''s + container ports. If this is not specified, the + value of the ''port'' field is used (an identity + map). This field is ignored for services with + clusterIP=None, and should be omitted or set + equal to the ''port'' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: publishNotReadyAddresses indicates that + any agent which deals with endpoints for this Service + should disregard any indications of ready/not-ready. + The primary use case for setting this field is for + a StatefulSet's Headless Service to propagate SRV + DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints + and EndpointSlice resources for Services interpret + this to mean that all endpoints are considered "ready" + even if the Pods themselves are not. Agents which + consume only Kubernetes generated endpoints through + the Endpoints or EndpointSlice resources can safely + assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: 'Route service traffic to pods with label + keys and values matching this selector. If empty or + not present, the service is assumed to have an external + process managing its endpoints, which Kubernetes will + not modify. Only applies to types ClusterIP, NodePort, + and LoadBalancer. Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/' + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: 'Supports "ClientIP" and "None". Used to + maintain session affinity. Enable client IP based + session affinity. Must be ClientIP or None. Defaults + to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: timeoutSeconds specifies the seconds + of ClientIP type session sticky time. The + value must be >0 && <=86400(for 1 day) if + ServiceAffinity == "ClientIP". Default value + is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: 'type determines how the Service is exposed. + Defaults to ClusterIP. Valid options are ExternalName, + ClusterIP, NodePort, and LoadBalancer. "ClusterIP" + allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector + or if that is not specified, by manual construction + of an Endpoints object or EndpointSlice objects. If + clusterIP is "None", no virtual IP is allocated and + the endpoints are published as a set of endpoints + rather than a virtual IP. "NodePort" builds on ClusterIP + and allocates a port on every node which routes to + the same endpoints as the clusterIP. "LoadBalancer" + builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to + the same endpoints as the clusterIP. "ExternalName" + aliases this service to the specified externalName. + Several other fields do not apply to ExternalName + services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types' + type: string + type: object + required: + - endpoint + type: object + type: array + type: object passwordSelectors: default: database: PlacementDatabasePassword diff --git a/api/go.mod b/api/go.mod index f519527a..f43a1e78 100644 --- a/api/go.mod +++ b/api/go.mod @@ -11,7 +11,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect @@ -43,7 +43,7 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect + golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect @@ -57,7 +57,7 @@ require ( k8s.io/apiextensions-apiserver v0.26.7 //indirect k8s.io/client-go v0.26.7 //indirect k8s.io/component-base v0.26.7 //indirect - k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a //indirect k8s.io/utils v0.0.0-20230711102312-30195339c3c7 //indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect @@ -68,3 +68,9 @@ require ( // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 + +replace github.com/openstack-k8s-operators/lib-common/modules/openstack => github.com/stuggi/lib-common/modules/openstack v0.0.0-20230808072208-e8d9f1a8a0b8 + +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 diff --git a/api/go.sum b/api/go.sum index e3bea377..c04f5951 100644 --- a/api/go.sum +++ b/api/go.sum @@ -48,8 +48,9 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -221,8 +222,6 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0 h1:F1iYRBwa0cZ2VHw8Zs4frqSWQ1B/tiCuSwH/DuHb8VM= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0/go.mod h1:3hAC5Ce0AOSt85BqD6DgTKNkJHmpXwqbwL8mVWRJQqo= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -277,6 +276,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 h1:E5EGKIZHyAV1oofcXkcUq4NZfTtgFjjKpU6A0Yv2vls= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -373,8 +374,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -621,8 +622,8 @@ k8s.io/client-go v0.26.7 h1:hyU9aKHlwVOykgyxzGYkrDSLCc4+mimZVyUJjPyUn1E= k8s.io/client-go v0.26.7/go.mod h1:okYjy0jtq6sdeztALDvCh24tg4opOQS1XNvsJlERDAo= k8s.io/component-base v0.26.7 h1:uqsOyZh0Zqoaup8tmHa491D/CvgFdGUs+X2H/inNUKM= k8s.io/component-base v0.26.7/go.mod h1:CZe1HTmX/DQdeBrb9XYOXzs96jXth8ZbFvhLMsoJLUg= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg= k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= diff --git a/api/v1beta1/placementapi_types.go b/api/v1beta1/placementapi_types.go index 1e5ba692..6d843f5a 100644 --- a/api/v1beta1/placementapi_types.go +++ b/api/v1beta1/placementapi_types.go @@ -19,6 +19,7 @@ package v1beta1 import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" endpoint "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/util" corev1 "k8s.io/api/core/v1" @@ -113,8 +114,14 @@ type PlacementAPISpec struct { NetworkAttachments []string `json:"networkAttachments,omitempty"` // +kubebuilder:validation:Optional - // ExternalEndpoints, expose a VIP using a pre-created IPAddressPool - ExternalEndpoints []MetalLBConfig `json:"externalEndpoints,omitempty"` + // Override, provides the ability to override the generated manifest of several child resources. + Override APIOverrideSpec `json:"override,omitempty"` +} + +// APIOverrideSpec to override the generated manifest of several child resources. +type APIOverrideSpec struct { + // Override configuration for the Service created to serve traffic to the cluster. + Service []service.OverrideSpec `json:"service,omitempty"` } // MetalLBConfig to configure the MetalLB loadbalancer service diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index b7ffb68d..96910be1 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -23,9 +23,32 @@ package v1beta1 import ( "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIOverrideSpec) DeepCopyInto(out *APIOverrideSpec) { + *out = *in + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = make([]service.OverrideSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIOverrideSpec. +func (in *APIOverrideSpec) DeepCopy() *APIOverrideSpec { + if in == nil { + return nil + } + out := new(APIOverrideSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MetalLBConfig) DeepCopyInto(out *MetalLBConfig) { *out = *in @@ -180,13 +203,7 @@ func (in *PlacementAPISpec) DeepCopyInto(out *PlacementAPISpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.ExternalEndpoints != nil { - in, out := &in.ExternalEndpoints, &out.ExternalEndpoints - *out = make([]MetalLBConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.Override.DeepCopyInto(&out.Override) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementAPISpec. diff --git a/config/crd/bases/placement.openstack.org_placementapis.yaml b/config/crd/bases/placement.openstack.org_placementapis.yaml index 03948b96..49a502e8 100644 --- a/config/crd/bases/placement.openstack.org_placementapis.yaml +++ b/config/crd/bases/placement.openstack.org_placementapis.yaml @@ -92,48 +92,6 @@ spec: to add additional files. Those get added to the service config dir in /etc/ . TODO: -> implement' type: object - externalEndpoints: - description: ExternalEndpoints, expose a VIP using a pre-created IPAddressPool - items: - description: MetalLBConfig to configure the MetalLB loadbalancer - service - properties: - endpoint: - description: Endpoint, OpenStack endpoint this service maps - to - enum: - - internal - - public - type: string - ipAddressPool: - description: IPAddressPool expose VIP via MetalLB on the IPAddressPool - minLength: 1 - type: string - loadBalancerIPs: - description: LoadBalancerIPs, request given IPs from the pool - if available. Using a list to allow dual stack (IPv4/IPv6) - support - items: - type: string - type: array - sharedIP: - default: true - description: SharedIP if true, VIP/VIPs get shared with multiple - services - type: boolean - sharedIPKey: - default: "" - description: SharedIPKey specifies the sharing key which gets - set as the annotation on the LoadBalancer service. Services - which share the same VIP must have the same SharedIPKey. Defaults - to the IPAddressPool if SharedIP is true, but no SharedIPKey - specified. - type: string - required: - - endpoint - - ipAddressPool - type: object - type: array networkAttachments: description: NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network @@ -146,6 +104,418 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + override: + description: Override, provides the ability to override the generated + manifest of several child resources. + properties: + service: + description: Override configuration for the Service created to + serve traffic to the cluster. + items: + description: OverrideSpec - service override configuration for + the Service created to serve traffic to the cluster. Allows + for the manifest of the created Service to be overwritten + with custom configuration. + properties: + endpoint: + description: Endpoint, OpenStack endpoint this service maps + to + enum: + - internal + - public + type: string + endpointURL: + description: EndpointURL to be used to register the service + in keystone. + type: string + metadata: + description: EmbeddedLabelsAnnotations is an embedded subset + of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta. + Only labels and annotations are included. + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value + map stored with a resource that may be set by external + tools to store and retrieve arbitrary metadata. They + are not queryable and should be preserved when modifying + objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can + be used to organize and categorize (scope and select) + objects. May match selectors of replication controllers + and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + type: object + spec: + description: Spec defines the behavior of a Service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: allocateLoadBalancerNodePorts defines if + NodePorts will be automatically allocated for services + with type LoadBalancer. Default is "true". It may + be set to "false" if the cluster load-balancer does + not rely on NodePorts. If the caller requests specific + NodePorts (by specifying a value), those requests + will be respected, regardless of this field. This + field may only be set for services with type LoadBalancer + and will be cleared if the type is changed to any + other type. + type: boolean + clusterIP: + description: 'clusterIP is the IP address of the service + and is usually assigned randomly. If an address is + specified manually, is in-range (as per system configuration), + and is not in use, it will be allocated to the service; + otherwise creation of the service will fail. This + field may not be changed through updates unless the + type field is also being changed to ExternalName (which + requires this field to be blank) or the type field + is being changed from ExternalName (in which case + this field may optionally be specified, as describe + above). Valid values are "None", empty string (""), + or a valid IP address. Setting this to "None" makes + a "headless service" (no virtual IP), which is useful + when direct endpoint connections are preferred and + proxying is not required. Only applies to types ClusterIP, + NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation + will fail. This field will be wiped when updating + a Service to type ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + type: string + clusterIPs: + description: "ClusterIPs is a list of IP addresses assigned + to this service, and are usually assigned randomly. + \ If an address is specified manually, is in-range + (as per system configuration), and is not in use, + it will be allocated to the service; otherwise creation + of the service will fail. This field may not be changed + through updates unless the type field is also being + changed to ExternalName (which requires this field + to be empty) or the type field is being changed from + ExternalName (in which case this field may optionally + be specified, as describe above). Valid values are + \"None\", empty string (\"\"), or a valid IP address. + \ Setting this to \"None\" makes a \"headless service\" + (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. + \ Only applies to types ClusterIP, NodePort, and LoadBalancer. + If this field is specified when creating a Service + of type ExternalName, creation will fail. This field + will be wiped when updating a Service to type ExternalName. + \ If this field is not specified, it will be initialized + from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP + have the same value. \n This field may hold a maximum + of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies + field. Both clusterIPs and ipFamilies are governed + by the ipFamilyPolicy field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: externalIPs is a list of IP addresses for + which nodes in the cluster will also accept traffic + for this service. These IPs are not managed by Kubernetes. The + user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external + load-balancers that are not part of the Kubernetes + system. + items: + type: string + type: array + externalName: + description: externalName is the external reference + that discovery mechanisms will return as an alias + for this service (e.g. a DNS CNAME record). No proxying + will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires + `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: externalTrafficPolicy describes how nodes + distribute service traffic they receive on one of + the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", + the proxy will configure the service in a way that + assumes that external load balancers will take care + of balancing the service traffic between nodes, and + so each node will deliver traffic only to the node-local + endpoints of the service, without masquerading the + client source IP. (Traffic mistakenly sent to a node + with no endpoints will be dropped.) The default value, + "Cluster", uses the standard behavior of routing to + all endpoints evenly (possibly modified by topology + and other features). Note that traffic sent to an + External IP or LoadBalancer IP from within the cluster + will always get "Cluster" semantics, but clients sending + to a NodePort from within the cluster may need to + take traffic policy into account when picking a node. + type: string + healthCheckNodePort: + description: healthCheckNodePort specifies the healthcheck + nodePort for the service. This only applies when type + is set to LoadBalancer and externalTrafficPolicy is + set to Local. If a value is specified, is in-range, + and is not in use, it will be used. If not specified, + a value will be automatically allocated. External + systems (e.g. load-balancers) can use this port to + determine if a given node holds endpoints for this + service or not. If this field is specified when creating + a Service which does not need it, creation will fail. + This field will be wiped when updating a Service to + no longer need it (e.g. changing type). This field + cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: InternalTrafficPolicy describes how nodes + distribute service traffic they receive on the ClusterIP. + If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the + same node as the pod, dropping the traffic if there + are no local endpoints. The default value, "Cluster", + uses the standard behavior of routing to all endpoints + evenly (possibly modified by topology and other features). + type: string + ipFamilies: + description: "IPFamilies is a list of IP families (e.g. + IPv4, IPv6) assigned to this service. This field is + usually assigned automatically based on cluster configuration + and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the + cluster, and ipFamilyPolicy allows it, it will be + used; otherwise creation of the service will fail. + This field is conditionally mutable: it allows for + adding or removing a secondary IP family, but it does + not allow changing the primary IP family of the Service. + Valid values are \"IPv4\" and \"IPv6\". This field + only applies to Services of types ClusterIP, NodePort, + and LoadBalancer, and does apply to \"headless\" services. + This field will be wiped when updating a Service to + type ExternalName. \n This field may hold a maximum + of two entries (dual-stack families, in either order). + \ These families must correspond to the values of + the clusterIPs field, if specified. Both clusterIPs + and ipFamilies are governed by the ipFamilyPolicy + field." + items: + description: IPFamily represents the IP Family (IPv4 + or IPv6). This type is used to express the family + of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: IPFamilyPolicy represents the dual-stack-ness + requested or required by this Service. If there is + no value provided, then this field will be set to + SingleStack. Services can be "SingleStack" (a single + IP family), "PreferDualStack" (two IP families on + dual-stack configured clusters or a single IP family + on single-stack clusters), or "RequireDualStack" (two + IP families on dual-stack configured clusters, otherwise + fail). The ipFamilies and clusterIPs fields depend + on the value of this field. This field will be wiped + when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: loadBalancerClass is the class of the load + balancer implementation this Service belongs to. If + specified, the value of this field must be a label-style + identifier, with an optional prefix, e.g. "internal-vip" + or "example.com/internal-vip". Unprefixed names are + reserved for end-users. This field can only be set + when the Service type is 'LoadBalancer'. If not set, + the default load balancer implementation is used, + today this is typically done through the cloud provider + integration, but should apply for any default implementation. + If set, it is assumed that a load balancer implementation + is watching for Services with a matching class. Any + default load balancer implementation (e.g. cloud providers) + should ignore Services that set this field. This field + can only be set when creating or updating a Service + to type 'LoadBalancer'. Once set, it can not be changed. + This field will be wiped when a service is updated + to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: 'Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider + supports specifying the loadBalancerIP when a load + balancer is created. This field will be ignored if + the cloud-provider does not support the feature. Deprecated: + This field was under-specified and its meaning varies + across implementations, and it cannot support dual-stack. + As of Kubernetes v1.24, users are encouraged to use + implementation-specific annotations when available. + This field may be removed in a future API version.' + type: string + loadBalancerSourceRanges: + description: 'If specified and supported by the platform, + this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified + client IPs. This field will be ignored if the cloud-provider + does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/' + items: + type: string + type: array + ports: + description: 'The list of ports that are exposed by + this service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: The application protocol for this + port. This field follows standard Kubernetes + label syntax. Un-prefixed names are reserved + for IANA standard service names (as per RFC-6335 + and https://www.iana.org/assignments/service-names). + Non-standard protocols should use prefixed names + such as mycompany.com/my-custom-protocol. + type: string + name: + description: The name of this port within the + service. This must be a DNS_LABEL. All ports + within a ServiceSpec must have unique names. + When considering the endpoints for a Service, + this must match the 'name' field in the EndpointPort. + Optional if only one ServicePort is defined + on this service. + type: string + nodePort: + description: 'The port on each node on which this + service is exposed when type is NodePort or + LoadBalancer. Usually assigned by the system. + If a value is specified, in-range, and not in + use it will be used, otherwise the operation + will fail. If not specified, a port will be + allocated if this Service requires one. If + this field is specified when creating a Service + which does not need it, creation will fail. + This field will be wiped when updating a Service + to no longer need it (e.g. changing type from + NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' + format: int32 + type: integer + port: + description: The port that will be exposed by + this service. + format: int32 + type: integer + protocol: + default: TCP + description: The IP protocol for this port. Supports + "TCP", "UDP", and "SCTP". Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: 'Number or name of the port to access + on the pods targeted by the service. Number + must be in the range 1 to 65535. Name must be + an IANA_SVC_NAME. If this is a string, it will + be looked up as a named port in the target Pod''s + container ports. If this is not specified, the + value of the ''port'' field is used (an identity + map). This field is ignored for services with + clusterIP=None, and should be omitted or set + equal to the ''port'' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: publishNotReadyAddresses indicates that + any agent which deals with endpoints for this Service + should disregard any indications of ready/not-ready. + The primary use case for setting this field is for + a StatefulSet's Headless Service to propagate SRV + DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints + and EndpointSlice resources for Services interpret + this to mean that all endpoints are considered "ready" + even if the Pods themselves are not. Agents which + consume only Kubernetes generated endpoints through + the Endpoints or EndpointSlice resources can safely + assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: 'Route service traffic to pods with label + keys and values matching this selector. If empty or + not present, the service is assumed to have an external + process managing its endpoints, which Kubernetes will + not modify. Only applies to types ClusterIP, NodePort, + and LoadBalancer. Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/' + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: 'Supports "ClientIP" and "None". Used to + maintain session affinity. Enable client IP based + session affinity. Must be ClientIP or None. Defaults + to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations + of Client IP based session affinity. + properties: + timeoutSeconds: + description: timeoutSeconds specifies the seconds + of ClientIP type session sticky time. The + value must be >0 && <=86400(for 1 day) if + ServiceAffinity == "ClientIP". Default value + is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: 'type determines how the Service is exposed. + Defaults to ClusterIP. Valid options are ExternalName, + ClusterIP, NodePort, and LoadBalancer. "ClusterIP" + allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector + or if that is not specified, by manual construction + of an Endpoints object or EndpointSlice objects. If + clusterIP is "None", no virtual IP is allocated and + the endpoints are published as a set of endpoints + rather than a virtual IP. "NodePort" builds on ClusterIP + and allocates a port on every node which routes to + the same endpoints as the clusterIP. "LoadBalancer" + builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to + the same endpoints as the clusterIP. "ExternalName" + aliases this service to the specified externalName. + Several other fields do not apply to ExternalName + services. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types' + type: string + type: object + required: + - endpoint + type: object + type: array + type: object passwordSelectors: default: database: PlacementDatabasePassword diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 342c17f3..11a995dc 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -192,18 +192,6 @@ rules: - list - update - watch -- apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - security.openshift.io resourceNames: diff --git a/controllers/placementapi_controller.go b/controllers/placementapi_controller.go index 4d945e62..e9fd3a7c 100644 --- a/controllers/placementapi_controller.go +++ b/controllers/placementapi_controller.go @@ -29,7 +29,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "github.com/go-logr/logr" - routev1 "github.com/openshift/api/route/v1" keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" common "github.com/openstack-k8s-operators/lib-common/modules/common" @@ -44,6 +43,7 @@ import ( nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac" oko_secret "github.com/openstack-k8s-operators/lib-common/modules/common/secret" + "github.com/openstack-k8s-operators/lib-common/modules/common/service" util "github.com/openstack-k8s-operators/lib-common/modules/common/util" database "github.com/openstack-k8s-operators/lib-common/modules/database" @@ -76,7 +76,6 @@ type PlacementAPIReconciler struct { // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list; // +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;patch;delete; // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete; // +kubebuilder:rbac:groups=mariadb.openstack.org,resources=mariadbdatabases,verbs=get;list;watch;create;update;patch;delete; // +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapis,verbs=get;list;watch; // +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneservices,verbs=get;list;watch;create;update;patch;delete; @@ -202,7 +201,6 @@ func (r *PlacementAPIReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&corev1.Secret{}). Owns(&corev1.ConfigMap{}). Owns(&appsv1.Deployment{}). - Owns(&routev1.Route{}). Owns(&corev1.ServiceAccount{}). Owns(&rbacv1.Role{}). Owns(&rbacv1.RoleBinding{}). @@ -354,48 +352,78 @@ func (r *PlacementAPIReconciler) reconcileInit( // // expose the service (create service, route and return the created endpoint URLs) // - var ports = map[endpoint.Endpoint]endpoint.Data{ - endpoint.EndpointPublic: {Port: placement.PlacementPublicPort}, - endpoint.EndpointInternal: {Port: placement.PlacementInternalPort}, + var placementEndpoints = map[service.Endpoint]endpoint.Data{ + service.EndpointPublic: {Port: placement.PlacementPublicPort}, + service.EndpointInternal: {Port: placement.PlacementInternalPort}, } + apiEndpoints := make(map[string]string) - for _, metallbcfg := range instance.Spec.ExternalEndpoints { - portCfg := ports[metallbcfg.Endpoint] + for endpointType, data := range placementEndpoints { + endpointName := placement.ServiceName + "-" + string(endpointType) + svcOverride := service.GetOverrideSpecForEndpoint(instance.Spec.Override.Service, endpointType) - portCfg.MetalLB = &endpoint.MetalLBData{ - IPAddressPool: metallbcfg.IPAddressPool, - SharedIP: metallbcfg.SharedIP, - SharedIPKey: metallbcfg.SharedIPKey, - LoadBalancerIPs: metallbcfg.LoadBalancerIPs, + exportLabels := util.MergeStringMaps( + serviceLabels, + map[string]string{ + string(endpointType): "true", + }, + ) + + // Create the service + svc, err := service.NewService( + service.GenericService(&service.GenericServiceDetails{ + Name: endpointName, + Namespace: instance.Namespace, + Labels: exportLabels, + Selector: serviceLabels, + Port: service.GenericServicePort{ + Name: endpointName, + Port: data.Port, + Protocol: corev1.ProtocolTCP, + }, + }), + 5, + svcOverride, + ) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.ExposeServiceReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.ExposeServiceReadyErrorMessage, + err.Error())) + + return ctrl.Result{}, err } - ports[metallbcfg.Endpoint] = portCfg - } + ctrlResult, err := svc.CreateOrPatch(ctx, helper) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.ExposeServiceReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.ExposeServiceReadyErrorMessage, + err.Error())) - apiEndpoints, ctrlResult, err := endpoint.ExposeEndpoints( - ctx, - helper, - placement.ServiceName, - serviceLabels, - ports, - time.Duration(5)*time.Second, - ) - if err != nil { - instance.Status.Conditions.Set(condition.FalseCondition( - condition.ExposeServiceReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - condition.ExposeServiceReadyErrorMessage, - err.Error())) - return ctrlResult, err - } else if (ctrlResult != ctrl.Result{}) { - instance.Status.Conditions.Set(condition.FalseCondition( - condition.ExposeServiceReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - condition.ExposeServiceReadyRunningMessage)) - return ctrlResult, nil + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.ExposeServiceReadyCondition, + condition.RequestedReason, + condition.SeverityInfo, + condition.ExposeServiceReadyRunningMessage)) + return ctrlResult, nil + } + // create service - end + + // TODO: TLS, pass in https as protocol, create TLS cert + apiEndpoints[string(endpointType)], err = svc.GetAPIEndpoint( + svcOverride, data.Protocol, data.Path) + if err != nil { + return ctrl.Result{}, err + } } + instance.Status.Conditions.MarkTrue(condition.ExposeServiceReadyCondition, condition.ExposeServiceReadyMessage) // expose service - end diff --git a/go.mod b/go.mod index 603c1d10..a0674abe 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.8 - github.com/openshift/api v3.9.0+incompatible github.com/openstack-k8s-operators/keystone-operator/api v0.1.0 github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0 github.com/openstack-k8s-operators/lib-common/modules/database v0.1.0 @@ -32,7 +31,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect @@ -56,6 +55,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openshift/api v3.9.0+incompatible // indirect github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0 //indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.14.0 // indirect @@ -67,7 +67,7 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect + golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect @@ -80,7 +80,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.26.7 //indirect k8s.io/component-base v0.26.7 //indirect - k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a //indirect k8s.io/utils v0.0.0-20230711102312-30195339c3c7 //indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect @@ -93,3 +93,9 @@ replace github.com/openstack-k8s-operators/placement-operator/api => ./api // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 + +replace github.com/openstack-k8s-operators/lib-common/modules/openstack => github.com/stuggi/lib-common/modules/openstack v0.0.0-20230808072208-e8d9f1a8a0b8 + +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 diff --git a/go.sum b/go.sum index f19228af..6e4125b8 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,9 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -236,14 +237,8 @@ github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxC github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= github.com/openstack-k8s-operators/infra-operator/apis v0.0.0-20230720153501-076b82bb4427 h1:GdJNpT/MDfw3gYKdPVpmtgw522UZfeiRDNaXYjJNvZM= github.com/openstack-k8s-operators/infra-operator/apis v0.0.0-20230720153501-076b82bb4427/go.mod h1:uuwrYRvdp5VwsWJpA47MnDT+UQjX1UWixagit7FzwV8= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0 h1:p98vKnS4KzdgU/+vrVKFY3y9n9v1Z6cpo4JvbTNRxlM= -github.com/openstack-k8s-operators/keystone-operator/api v0.1.0/go.mod h1:LNJJdteQG4E2fhWDerE+f8S2/ephEJg8yBkH1eqYYOo= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0 h1:F1iYRBwa0cZ2VHw8Zs4frqSWQ1B/tiCuSwH/DuHb8VM= -github.com/openstack-k8s-operators/lib-common/modules/common v0.1.0/go.mod h1:3hAC5Ce0AOSt85BqD6DgTKNkJHmpXwqbwL8mVWRJQqo= github.com/openstack-k8s-operators/lib-common/modules/database v0.1.0 h1:JWLX0pyQXANEULDbjv4rWcYQ8y4OSqnQl0L6O/gIv7U= github.com/openstack-k8s-operators/lib-common/modules/database v0.1.0/go.mod h1:bbauLidBocb/iigxC0D4fIbqjkvR80o6fsKpOGyVk00= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0 h1:mMeJvCQfZmakssvMyHjzp/ngxKysETDj9GJYhRwydzg= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.1.0/go.mod h1:+paEFOL5IlJzhg9fy7/1+HSErVkWUgUj1ORLFwgvxnI= github.com/openstack-k8s-operators/lib-common/modules/test v0.1.1 h1:upLnnux++Cuzxuta7z4VhD3aVwslXYYuptKk5R1EJPU= github.com/openstack-k8s-operators/lib-common/modules/test v0.1.1/go.mod h1:lIJaEPmGwyY4k9ti39OXzZCtv+SybPHSRMg+PfXvPTQ= github.com/openstack-k8s-operators/mariadb-operator/api v0.1.0 h1:oM0ZzFHHj+ioCc7NXHIO6+sy7I2yiN29DI9/jh4fe54= @@ -304,6 +299,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4 h1:qVwSTi3ZDWl8ITLcVBOwJlEDlMi3UyFykZh5qN76BSI= +github.com/stuggi/keystone-operator/api v0.0.0-20230808074553-872e7cb2e6f4/go.mod h1:XdvO78DPVkkGFf5kPLDDb7a8/DGuv/JwxzhmipalUhw= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8 h1:E5EGKIZHyAV1oofcXkcUq4NZfTtgFjjKpU6A0Yv2vls= +github.com/stuggi/lib-common/modules/common v0.0.0-20230808072208-e8d9f1a8a0b8/go.mod h1:2fZFojsJsTA4MfGy50JEwbXaIP7Hr7h7x8hbhlMBedY= +github.com/stuggi/lib-common/modules/openstack v0.0.0-20230808072208-e8d9f1a8a0b8 h1:ZU38RkdsmtOJhLqhznRc/knWK2IofsYeOitm3739Nxo= +github.com/stuggi/lib-common/modules/openstack v0.0.0-20230808072208-e8d9f1a8a0b8/go.mod h1:xe/pl0p06/pdhDWCplbMaW21Ggz34zWZBLDOTGXJpzI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -413,8 +414,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -664,8 +665,8 @@ k8s.io/client-go v0.26.7 h1:hyU9aKHlwVOykgyxzGYkrDSLCc4+mimZVyUJjPyUn1E= k8s.io/client-go v0.26.7/go.mod h1:okYjy0jtq6sdeztALDvCh24tg4opOQS1XNvsJlERDAo= k8s.io/component-base v0.26.7 h1:uqsOyZh0Zqoaup8tmHa491D/CvgFdGUs+X2H/inNUKM= k8s.io/component-base v0.26.7/go.mod h1:CZe1HTmX/DQdeBrb9XYOXzs96jXth8ZbFvhLMsoJLUg= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg= k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= diff --git a/main.go b/main.go index b19ece02..b483bb92 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,6 @@ import ( "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth" - routev1 "github.com/openshift/api/route/v1" "go.uber.org/zap/zapcore" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -55,7 +54,6 @@ func init() { utilruntime.Must(placementv1.AddToScheme(scheme)) utilruntime.Must(mariadbv1.AddToScheme(scheme)) utilruntime.Must(keystonev1.AddToScheme(scheme)) - utilruntime.Must(routev1.AddToScheme(scheme)) utilruntime.Must(networkv1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/tests/functional/suite_test.go b/tests/functional/suite_test.go index 750b2721..70110858 100644 --- a/tests/functional/suite_test.go +++ b/tests/functional/suite_test.go @@ -38,7 +38,6 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - routev1 "github.com/openshift/api/route/v1" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -135,8 +134,6 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = routev1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme logger = ctrl.Log.WithName("---Test---") diff --git a/tests/kuttl/common/assert_sample_deployment.yaml b/tests/kuttl/common/assert_sample_deployment.yaml index bdee71a5..25c7ae19 100644 --- a/tests/kuttl/common/assert_sample_deployment.yaml +++ b/tests/kuttl/common/assert_sample_deployment.yaml @@ -205,25 +205,6 @@ spec: service: placement type: ClusterIP --- -apiVersion: route.openshift.io/v1 -kind: Route -metadata: - name: placement-public - labels: - public: "true" - service: placement -spec: - port: - targetPort: placement-public - to: - kind: Service - name: placement-public -status: - ingress: - - conditions: - - status: "True" - type: Admitted ---- apiVersion: v1 kind: ConfigMap metadata: diff --git a/tests/kuttl/common/errors_cleanup_placement.yaml b/tests/kuttl/common/errors_cleanup_placement.yaml index caa6da14..667149a8 100644 --- a/tests/kuttl/common/errors_cleanup_placement.yaml +++ b/tests/kuttl/common/errors_cleanup_placement.yaml @@ -5,7 +5,6 @@ # No Deployment for PlacementAPI CR # No Pods in placement Deployment # No Placement Services -# No Placement Routes # apiVersion: placement.openstack.org/v1beta1 kind: PlacementAPI @@ -70,20 +69,6 @@ spec: service: placement type: ClusterIP --- -apiVersion: route.openshift.io/v1 -kind: Route -metadata: - name: placement-public - labels: - public: "true" - service: placement -spec: - port: - targetPort: placement-public - to: - kind: Service - name: placement-public ---- apiVersion: v1 kind: ConfigMap metadata: