Skip to content

Commit

Permalink
Allow customize route via spec.Override.Route
Browse files Browse the repository at this point in the history
Allows to customize the service route vie the `spec.Override.Route`.
This allows e.g. to add custom labels, configure the route via
annotations as in [1], or set TLS parameters.

~~~
apiVersion: keystone.openstack.org/v1beta1
kind: KeystoneAPI
metadata:
  name: keystone
  namespace: openstack
spec:
  ...
  override:
    routeOverride:
      metadata:
        annotations:
          haproxy.router.openshift.io/timeout: "60"
        labels:
          mylabel: boo
~~~

[1] https://docs.openshift.com/container-platform/4.13/networking/routes/route-configuration.html#nw-route-specific-annotations_route-configuration

Depends-On: openstack-k8s-operators/lib-common#293

Jira: OSP-21715
Jira: OSP-26299
  • Loading branch information
stuggi committed Jul 14, 2023
1 parent 1c2b04a commit e2b8581
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 12 deletions.
226 changes: 226 additions & 0 deletions api/bases/keystone.openstack.org_keystoneapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,232 @@ 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:
route:
description: OverrideSpec configuration for the Route created
to serve traffic to the cluster.
properties:
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. New labels/annotations
get merged with the ones created by the operator. If a privided
annotation/label is the same as one created by the service
operator, the ones provided via this override will replace
the one from the operator.
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 Route. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
\n The spec will be merged using StrategicMergePatch - Provided
parameters will override the ones from the original spec.
- Required parameters of sub structs have to be named. -
For parameters which are list of struct it depends on the
patchStrategy defined on the list https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#notes-on-the-strategic-merge-patch
If `patchStrategy:\"merge\"` is set, src and dst list gets
merged, otherwise they get replaced."
properties:
alternateBackends:
description: alternateBackends allows up to 3 additional
backends to be assigned to the route. Only the Service
kind is allowed, and it will be defaulted to Service.
Use the weight field in RouteTargetReference object
to specify relative preference.
items:
description: TargetReference specifies the target that
resolve into endpoints. Only the 'Service' kind is
allowed. Use 'weight' field to emphasize one over
others. Copy of RouteTargetReference in https://github.com/openshift/api/blob/master/route/v1/types.go,
parameters set to be optional, have omitempty, and
no default.
properties:
kind:
description: The kind of target that the route is
referring to. Currently, only 'Service' is allowed
enum:
- Service
- ""
type: string
name:
description: name of the service/target that is
being referred to. e.g. name of the service
type: string
weight:
description: weight as an integer between 0 and
256, default 100, that specifies the target's
relative weight against other target reference
objects. 0 suppresses requests to this backend.
format: int32
maximum: 256
minimum: 0
type: integer
type: object
maxItems: 3
type: array
host:
description: host is an alias/DNS that points to the service.
Optional. If not specified a route name will typically
be automatically chosen. Must follow DNS952 subdomain
conventions.
maxLength: 253
pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
type: string
path:
description: path that the router watches for, to route
traffic for to the service. Optional
pattern: ^/
type: string
port:
description: If specified, the port to be used by the
router. Most routers will use all endpoints exposed
by the service by default - set this value to instruct
routers which port to use.
properties:
targetPort:
anyOf:
- type: integer
- type: string
description: The target port on pods selected by the
service this route points to. If this is a string,
it will be looked up as a named port in the target
endpoints port list. Required
x-kubernetes-int-or-string: true
required:
- targetPort
type: object
subdomain:
description: "subdomain is a DNS subdomain that is requested
within the ingress controller's domain (as a subdomain).
If host is set this field is ignored. An ingress controller
may choose to ignore this suggested name, in which case
the controller will report the assigned name in the
status.ingress array or refuse to admit the route. If
this value is set and the server does not support this
field host will be populated automatically. Otherwise
host is left empty. The field may have multiple parts
separated by a dot, but not all ingress controllers
may honor the request. This field may not be changed
after creation except by a user with the update routes/custom-host
permission. \n Example: subdomain `frontend` automatically
receives the router subdomain `apps.mycluster.com` to
have a full hostname `frontend.apps.mycluster.com`."
maxLength: 253
pattern: ^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
type: string
tls:
description: The tls field provides the ability to configure
certificates and termination for the route.
properties:
caCertificate:
description: caCertificate provides the cert authority
certificate contents
type: string
certificate:
description: certificate provides certificate contents.
This should be a single serving certificate, not
a certificate chain. Do not include a CA certificate.
type: string
destinationCACertificate:
description: destinationCACertificate provides the
contents of the ca certificate of the final destination. When
using reencrypt termination this file should be
provided in order to have routers use it for health
checks on the secure connection. If this field is
not specified, the router may provide its own destination
CA and perform hostname validation using the short
service name (service.namespace.svc), which allows
infrastructure generated certificates to automatically
verify.
type: string
insecureEdgeTerminationPolicy:
description: "insecureEdgeTerminationPolicy indicates
the desired behavior for insecure connections to
a route. While each router may make its own decisions
on which ports to expose, this is normally port
80. \n * Allow - traffic is sent to the server on
the insecure port (default) * Disable - no traffic
is allowed on the insecure port. * Redirect - clients
are redirected to the secure port."
type: string
key:
description: key provides key file contents
type: string
termination:
description: "termination indicates termination type.
\n * edge - TLS termination is done by the router
and http is used to communicate with the backend
(default) * passthrough - Traffic is sent straight
to the destination without the router providing
TLS termination * reencrypt - TLS termination is
done by the router and https is used to communicate
with the backend"
enum:
- edge
- reencrypt
- passthrough
type: string
required:
- termination
type: object
to:
description: to is an object the route should use as the
primary backend. Only the Service kind is allowed, and
it will be defaulted to Service. If the weight field
(0-256 default 100) is set to zero, no traffic will
be sent to this backend.
properties:
kind:
description: The kind of target that the route is
referring to. Currently, only 'Service' is allowed
enum:
- Service
- ""
type: string
name:
description: name of the service/target that is being
referred to. e.g. name of the service
type: string
weight:
description: weight as an integer between 0 and 256,
default 100, that specifies the target's relative
weight against other target reference objects. 0
suppresses requests to this backend.
format: int32
maximum: 256
minimum: 0
type: integer
type: object
wildcardPolicy:
description: Wildcard policy if any for the route. Currently
only 'Subdomain' or 'None' is allowed.
enum:
- None
- Subdomain
- ""
type: string
type: object
type: object
type: object
passwordSelectors:
default:
admin: AdminPassword
Expand Down
7 changes: 6 additions & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ require (
github.com/go-logr/zapr v1.2.3 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/tools v0.9.3 // indirect
)
Expand Down Expand Up @@ -79,3 +78,9 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

// map to latest commit from release-4.13 tag
// must consistent with lib-common
replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7

replace github.com/openstack-k8s-operators/lib-common/modules/common => github.com/stuggi/lib-common/modules/common v0.0.0-20230713142642-ad7565492dfa
9 changes: 4 additions & 5 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,8 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=
github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openstack-k8s-operators/lib-common/modules/common v0.0.0-20230619102827-49e72f626a11 h1:Cst9DN3Xb6UzuamSueknPqRQlWLtgip8wMBFMUUcdLQ=
github.com/openstack-k8s-operators/lib-common/modules/common v0.0.0-20230619102827-49e72f626a11/go.mod h1:cAXLyeKp6TiLW8qongnw6WR63Jnsm8CeRC5y07z3TAY=
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/openstack v0.0.0-20230522113906-6f4206cbf317 h1:1gQSTk3ereXLrhb9BhqbYn5kKIemplc8tyzvonXyKGk=
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.0.0-20230522113906-6f4206cbf317/go.mod h1:doFbVg0WhS++gy17cbP9/BrCySjCpuqKx7TbvmKPChY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -271,7 +269,6 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
Expand All @@ -293,6 +290,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-20230713142642-ad7565492dfa h1:w01lCKtNHOKNuTgQJ1D7zDPeaXcQbux6EQEBgYrmbY0=
github.com/stuggi/lib-common/modules/common v0.0.0-20230713142642-ad7565492dfa/go.mod h1:UTwtKN9s/re95Fh4bLcTWOSj8UK7Hhnmv4o0EzTvDqM=
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=
Expand Down
11 changes: 11 additions & 0 deletions api/v1beta1/keystoneapi_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
"github.com/openstack-k8s-operators/lib-common/modules/common/route"
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -152,6 +153,16 @@ type KeystoneAPISpec struct {
// +kubebuilder:validation:Optional
// ExternalEndpoints, expose a VIP using a pre-created IPAddressPool
ExternalEndpoints []MetalLBConfig `json:"externalEndpoints,omitempty"`

// +kubebuilder:validation:Optional
// Override, provides the ability to override the generated manifest of several child resources.
Override KeystoneAPIOverrideSpec `json:"override,omitempty"`
}

// KeystoneAPIOverrideSpec to override the generated manifest of several child resources.
type KeystoneAPIOverrideSpec struct {
// +kubebuilder:validation:Optional
Route *route.OverrideSpec `json:"route,omitempty"`
}

// MetalLBConfig to configure the MetalLB loadbalancer service
Expand Down
Loading

0 comments on commit e2b8581

Please sign in to comment.