diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 07255aa46..b1af6f31e 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -684,6 +684,24 @@ spec: x-kubernetes-int-or-string: true type: object type: object + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage type: object @@ -4568,6 +4586,24 @@ spec: type: string storageRequest: type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object type: default: split enum: @@ -6432,6 +6468,24 @@ spec: type: object secret: type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object trustFlushArgs: default: "" type: string @@ -6445,6 +6499,7 @@ spec: - containerImage - databaseInstance - memcachedInstance + - rabbitMqClusterName - secret type: object type: object @@ -8663,6 +8718,24 @@ spec: serviceUser: default: neutron type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage - databaseInstance @@ -15953,6 +16026,23 @@ spec: - type type: object type: array + tls: + properties: + caBundleSecretName: + type: string + endpoint: + additionalProperties: + properties: + expires: + type: string + name: + type: string + required: + - expires + - name + type: object + type: object + type: object type: object type: object served: true diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 5fb99367c..0c41b595d 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -652,6 +652,22 @@ type OpenStackControlPlaneStatus struct { //+operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"} // Conditions Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` + + //+operator-sdk:csv:customresourcedefinitions:type=spec + // TLS + TLS TLSStatus `json:"tls,omitempty" optional:"true"` +} + +// TLSStatus defines the observed state of TLS +type TLSStatus struct { + Endpoint map[service.Endpoint]TLSCAStatus `json:"endpoint,omitempty"` + tls.Ca `json:",inline"` +} + +// TLSCAStatus defines the observed state of TLS +type TLSCAStatus struct { + Name string `json:"name"` + Expires string `json:"expires"` } //+kubebuilder:object:root=true @@ -748,3 +764,13 @@ func SetupDefaults() { SetupOpenStackControlPlaneDefaults(openstackControlPlaneDefaults) } + +// Enabled - returns status of tls configuration for the passed in endpoint type +func (t *TLSSection) Enabled(endpt service.Endpoint) bool { + if t != nil { + if cfg, ok := t.Endpoint[service.EndpointInternal]; ok && cfg.Enabled { + return true + } + } + return false +} diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index d2f048834..275ac84fe 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -480,6 +480,7 @@ func (in *OpenStackControlPlaneStatus) DeepCopyInto(out *OpenStackControlPlaneSt (*in)[i].DeepCopyInto(&(*out)[i]) } } + in.TLS.DeepCopyInto(&out.TLS) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackControlPlaneStatus. @@ -673,6 +674,21 @@ func (in *SwiftSection) DeepCopy() *SwiftSection { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSCAStatus) DeepCopyInto(out *TLSCAStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSCAStatus. +func (in *TLSCAStatus) DeepCopy() *TLSCAStatus { + if in == nil { + return nil + } + out := new(TLSCAStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSEndpointConfig) DeepCopyInto(out *TLSEndpointConfig) { *out = *in @@ -726,6 +742,29 @@ func (in *TLSServiceOverride) DeepCopy() *TLSServiceOverride { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSStatus) DeepCopyInto(out *TLSStatus) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = make(map[service.Endpoint]TLSCAStatus, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + out.Ca = in.Ca +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSStatus. +func (in *TLSStatus) DeepCopy() *TLSStatus { + if in == nil { + return nil + } + out := new(TLSStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TelemetrySection) DeepCopyInto(out *TelemetrySection) { *out = *in diff --git a/apis/go.mod b/apis/go.mod index d608d2816..654bb3e13 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -25,13 +25,14 @@ require ( github.com/openstack-k8s-operators/swift-operator/api v0.3.1-0.20240104130506-42419651f900 github.com/openstack-k8s-operators/telemetry-operator/api v0.3.1-0.20240103003254-97178240dd81 github.com/rabbitmq/cluster-operator/v2 v2.5.0 - k8s.io/apimachinery v0.27.7 + k8s.io/apimachinery v0.28.1 sigs.k8s.io/controller-runtime v0.15.1 ) require ( github.com/go-logr/zapr v1.2.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect github.com/rhobs/obo-prometheus-operator/pkg/apis/monitoring v0.64.1-rhobs3 // indirect github.com/rhobs/observability-operator v0.0.20 // indirect @@ -78,7 +79,7 @@ require ( github.com/prometheus/procfs v0.11.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -89,12 +90,12 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.27.7 - k8s.io/apiextensions-apiserver v0.27.7 //indirect - k8s.io/client-go v0.27.7 - k8s.io/component-base v0.27.7 //indirect + k8s.io/api v0.28.1 + k8s.io/apiextensions-apiserver v0.28.1 //indirect + k8s.io/client-go v0.28.1 + k8s.io/component-base v0.28.1 //indirect k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 //indirect + k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f //indirect k8s.io/utils v0.0.0-20240102154912-e7106e64919e //indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect @@ -102,13 +103,22 @@ require ( ) replace ( //allow-merging + github.com/google/gnostic => github.com/google/gnostic v0.6.9 // pin to k8s 0.26.x for now - k8s.io/api => k8s.io/api v0.26.9 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.9 - k8s.io/client-go => k8s.io/client-go v0.26.9 - sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.14.6 + k8s.io/api => k8s.io/api v0.26.11 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.11 + k8s.io/client-go => k8s.io/client-go v0.26.11 + sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.14.7 ) // 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/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6 + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1 diff --git a/apis/go.sum b/apis/go.sum index acfffc5e9..1c96055d5 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -76,6 +76,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -132,12 +134,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/barbican-operator/api v0.0.0-20240104150405-d50607d50e9a h1:fmfQTsJtpDja6jueqDxLEQv3AvrWqdybTr9cgeVrF6I= github.com/openstack-k8s-operators/barbican-operator/api v0.0.0-20240104150405-d50607d50e9a/go.mod h1:6NxyDHpJgkcxmmxRzsQMMrkBqdLWuaBY/bVsg2DzD/0= -github.com/openstack-k8s-operators/cinder-operator/api v0.3.1-0.20240104132718-a962cceb867d h1:xRKsN1KzdHFwIRAEBMAC+3/pg6ST1NmQcN1oPLiRGWM= -github.com/openstack-k8s-operators/cinder-operator/api v0.3.1-0.20240104132718-a962cceb867d/go.mod h1:GH+wo5YUPX95Mqst0yKXZGobehtlIqxDPjjE9GCl8IY= github.com/openstack-k8s-operators/designate-operator/api v0.0.0-20240104144436-858a0383741c h1:XSRqnJnHCUjn3PRQX16J7gasxnl5DIlyfE3p0F72gL8= github.com/openstack-k8s-operators/designate-operator/api v0.0.0-20240104144436-858a0383741c/go.mod h1:Wn+GO3Kddf7C5wM2vLNo2Ub1KRmy6qCuTwdyJlxXUuc= -github.com/openstack-k8s-operators/glance-operator/api v0.3.1-0.20240109080016-338d4287e4ec h1:rLcBTCgJphWY83hTJrFmYdnzUWXvorh0LiNRycrAxYs= -github.com/openstack-k8s-operators/glance-operator/api v0.3.1-0.20240109080016-338d4287e4ec/go.mod h1:4eraW+FyYsboi+a75FvKokgv0oeITVQMUAKYYqhViiQ= github.com/openstack-k8s-operators/heat-operator/api v0.3.1-0.20240104130506-4f3841d6042d h1:d6b8XI8UZF0q84DoznhWWydu0fAk2txGZAXjLiUu/FY= github.com/openstack-k8s-operators/heat-operator/api v0.3.1-0.20240104130506-4f3841d6042d/go.mod h1:R5j2Efz687VHonvB3cxWRhOjWS3OFSKu9U5mjOOcyeQ= github.com/openstack-k8s-operators/horizon-operator/api v0.3.1-0.20240104144435-fdfef4b8a33f h1:92xuDVbOiDEtJ8igh1wkoNj+UlzZWmYKH+rOb9OmLJ8= @@ -146,8 +144,6 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240104150635-c github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240104150635-c4ffc51e0752/go.mod h1:y4qeIT1ubUm9SKrvhVTuEYWSm0so38P5Hu3ZpdMJMek= github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240104144719-8030e9e8c962 h1:X7+Z4UVuYDCe4lD/y66H/Yf3TF/YckTTVDyAGfHJ4Tw= github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240104144719-8030e9e8c962/go.mod h1:H6BuZ52u+Dq/vWJgpGIJLttRTnPPH3xdVeqhI99QE/k= -github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240104144437-5355d932c316 h1:IwTuIoC78bbp3awd8P0tWeknCe2jNLB1FCJDIwI/2Pg= -github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240104144437-5355d932c316/go.mod h1:qx+z+k0RMK8Vcl5Nug6bOScEg7ROSxEV4FFy0gjcQDQ= github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240110131857-e70e1dec4d14 h1:8batipIElAHscbsVUJz8w/2NOvu+pRi8ixF1XUP6WiQ= github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240110131857-e70e1dec4d14/go.mod h1:ov4lAbniNUsLqZCBp1RTixpqXc8JlzA5B+yTcCkJXQg= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240104154954-dc504be0d9be h1:DuW+qO6nZFeJMDvLvhoP1a0+ynHTzNvUDwngizejgDo= @@ -158,8 +154,6 @@ github.com/openstack-k8s-operators/manila-operator/api v0.3.1-0.20240104144719-7 github.com/openstack-k8s-operators/manila-operator/api v0.3.1-0.20240104144719-72b9a4ab968c/go.mod h1:AIdqCEAycRS/78wgnLhAjRkgkt7gygVmakvOp//vlz0= github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240104162634-fe72003c6343 h1:KrzABqo34PVd4kGxVwTZj/j4ZbTmH/vE/TL13t/ojGA= github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240104162634-fe72003c6343/go.mod h1:Ehw3pMZJrmmIscJ4npkAux7BuZ+2XSXnCuSeF1tzeL0= -github.com/openstack-k8s-operators/neutron-operator/api v0.3.1-0.20240104150349-c082ca19cafe h1:NdGc285xWKj21A8+DNSmamBI/CzO5njfQ4Fb0ACgh60= -github.com/openstack-k8s-operators/neutron-operator/api v0.3.1-0.20240104150349-c082ca19cafe/go.mod h1:oZ3qXiAcjEa0Zyy6WyjW35uvtI1FLzMRWInK/nlSi9w= github.com/openstack-k8s-operators/nova-operator/api v0.3.1-0.20240104123738-13980c2f529d h1:bQWbPEd9iBcFoil+id1kYUcxjxI83DLscgLZlyz0Hz0= github.com/openstack-k8s-operators/nova-operator/api v0.3.1-0.20240104123738-13980c2f529d/go.mod h1:NuZtXGv0KqWpN9A6HeclDgIQZn9SD3ompfiiyI2fV4c= github.com/openstack-k8s-operators/octavia-operator/api v0.3.1-0.20240104150350-1cb9656d2d92 h1:mJyxKHC80qo1F9FtYrg7ZUgb8QQ80zdc1VRHlaHfZT8= @@ -209,6 +203,14 @@ 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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1 h1:L/lO4dxSFJjFy7h00o7QTD/0I7VX1O0d0XCLgMpmmfU= +github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1/go.mod h1:Ozgk9komox+YQxkS43VncPzHjvef2Hga/nu6fX/G0ek= +github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7 h1:zMjEVG3OAizMDsPy6eE3PdPEXPOgM1AMw5m/c17nb+g= +github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7/go.mod h1:xBiocMjWKyYmFQ+sx4G5Es1kaCCleILvq3/cZ30OmtA= +github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6 h1:NPd4H7TpNCDO8VT/8H3O4kot8+AZYUraO0Sx6OP5V1Q= +github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6/go.mod h1:5quo1o1B7wLTXAD6j8sPXDxB5ASYaL9ImyiouAPrXtg= +github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a h1:r19DMgleke1s0KfyMFawd6Zs3WmOL3bOE0JZwrMYVnY= +github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a/go.mod h1:yPMojR9cveY8v9D33Xg7TKgMLv1/eC5iUx38I+oW+os= 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= @@ -258,8 +260,8 @@ golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= 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= @@ -357,24 +359,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.26.9 h1:s8Y+G1u2JM55b90+Yo2RVb3PGT/hkWNVPN4idPERxJg= -k8s.io/api v0.26.9/go.mod h1:W/W4fEWRVzPD36820LlVUQfNBiSbiq0VPWRFJKwzmUg= -k8s.io/apiextensions-apiserver v0.27.7 h1:YqIOwZAUokzxJIjunmUd4zS1v3JhK34EPXn+pP0/bsU= -k8s.io/apiextensions-apiserver v0.27.7/go.mod h1:x0p+b5a955lfPz9gaDeBy43obM12s+N9dNHK6+dUL+g= -k8s.io/apimachinery v0.26.9 h1:5yAV9cFR7Z4gIorKcAjWnx4uxtxiFsERwq4Pvmx0CCg= -k8s.io/apimachinery v0.26.9/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0= -k8s.io/client-go v0.26.9 h1:TGWi/6guEjIgT0Hg871Gsmx0qFuoGyGFjlFedrk7It0= -k8s.io/client-go v0.26.9/go.mod h1:tU1FZS0bwAmAFyPYpZycUQrQnUMzQ5MHloop7EbX6ow= -k8s.io/component-base v0.27.7 h1:kngM58HR9W9Nqpv7e4rpdRyWnKl/ABpUhLAZ+HoliMs= -k8s.io/component-base v0.27.7/go.mod h1:YGjlCVL1oeKvG3HSciyPHFh+LCjIEqsxz4BDR3cfHRs= +k8s.io/api v0.26.11 h1:hLhTZRdYc3vBBOY4wbEyTLWgMyieOAk2Ws9NG57QqO4= +k8s.io/api v0.26.11/go.mod h1:bSr/A0TKRt5W2OMDdexkM/ER1NxOxiQqNNFXW2nMZrM= +k8s.io/apiextensions-apiserver v0.28.1 h1:l2ThkBRjrWpw4f24uq0Da2HaEgqJZ7pcgiEUTKSmQZw= +k8s.io/apiextensions-apiserver v0.28.1/go.mod h1:sVvrI+P4vxh2YBBcm8n2ThjNyzU4BQGilCQ/JAY5kGs= +k8s.io/apimachinery v0.26.11 h1:w//840HHdwSRKqD15j9YX9HLlU6RPlfrvW0xEhLk2+0= +k8s.io/apimachinery v0.26.11/go.mod h1:2/HZp0l6coXtS26du1Bk36fCuAEr/lVs9Q9NbpBtd1Y= +k8s.io/client-go v0.26.11 h1:RjfZr5+vQjjTRmk4oCqHyC0cgrZXPjw+X+ge35sk4GI= +k8s.io/client-go v0.26.11/go.mod h1:+emNszw9va/uRJIM5ALTBtFnlZMTjwBrNjRfEh0iuw8= +k8s.io/component-base v0.28.1 h1:LA4AujMlK2mr0tZbQDZkjWbdhTV5bRyEyAFe0TJxlWg= +k8s.io/component-base v0.28.1/go.mod h1:jI11OyhbX21Qtbav7JkhehyBsIRfnO8oEgoAR12ArIU= 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-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI= -k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515/go.mod h1:kzo02I3kQ4BTtEfVLaPbjvCkX97YqGve33wzlb3fofQ= +k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f h1:eeEUOoGYWhOz7EyXqhlR2zHKNw2mNJ9vzJmub6YN6kk= +k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= -sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/controller-runtime v0.14.7 h1:Vrnm2vk9ZFlRkXATHz0W0wXcqNl7kPat8q2JyxVy0Q8= +sigs.k8s.io/controller-runtime v0.14.7/go.mod h1:ErTs3SJCOujNUnTz4AS+uh8hp6DHMo1gj6fFndJT1X8= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 07255aa46..b1af6f31e 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -684,6 +684,24 @@ spec: x-kubernetes-int-or-string: true type: object type: object + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage type: object @@ -4568,6 +4586,24 @@ spec: type: string storageRequest: type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object type: default: split enum: @@ -6432,6 +6468,24 @@ spec: type: object secret: type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object trustFlushArgs: default: "" type: string @@ -6445,6 +6499,7 @@ spec: - containerImage - databaseInstance - memcachedInstance + - rabbitMqClusterName - secret type: object type: object @@ -8663,6 +8718,24 @@ spec: serviceUser: default: neutron type: string + tls: + properties: + api: + properties: + internal: + properties: + secretName: + type: string + type: object + public: + properties: + secretName: + type: string + type: object + type: object + caBundleSecretName: + type: string + type: object required: - containerImage - databaseInstance @@ -15953,6 +16026,23 @@ spec: - type type: object type: array + tls: + properties: + caBundleSecretName: + type: string + endpoint: + additionalProperties: + properties: + expires: + type: string + name: + type: string + required: + - expires + - name + type: object + type: object + type: object type: object type: object served: true diff --git a/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tlse.yaml b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tlse.yaml new file mode 100644 index 000000000..61e175cd2 --- /dev/null +++ b/config/samples/core_v1beta1_openstackcontrolplane_network_isolation_tlse.yaml @@ -0,0 +1,387 @@ +apiVersion: core.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: openstack-network-isolation +spec: + secret: osp-secret + storageClass: local-storage + tls: + endpoint: + internal: + enabled: true + public: + enabled: true + dns: + template: + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: ctlplane + metallb.universe.tf/allow-shared-ip: ctlplane + metallb.universe.tf/loadBalancerIPs: 192.168.122.80 + spec: + type: LoadBalancer + options: + - key: server + values: + - 192.168.122.1 + replicas: 1 + cinder: + apiOverride: + route: {} + template: + databaseInstance: openstack + secret: osp-secret + cinderAPI: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + cinderScheduler: + replicas: 1 + cinderBackup: + networkAttachments: + - storage + replicas: 0 # backend needs to be configured + cinderVolumes: + volume1: + networkAttachments: + - storage + replicas: 0 # backend needs to be configured + barbican: + apiOverride: + route: {} + template: + databaseInstance: openstack + secret: osp-secret + barbicanAPI: + replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + barbicanWorker: + replicas: 1 + barbicanKeystoneListener: + replicas: 1 + glance: + apiOverrides: + default: + route: {} + template: + databaseInstance: openstack + storageClass: "" + storageRequest: 10G + secret: osp-secret + keystoneEndpoint: default + glanceAPIs: + default: + type: single + replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + networkAttachments: + - storage + keystone: + apiOverride: + route: {} + template: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + databaseInstance: openstack + secret: osp-secret + galera: + templates: + openstack: + storageRequest: 500M + openstack-cell1: + storageRequest: 500M + memcached: + templates: + memcached: + replicas: 1 + neutron: + apiOverride: + route: {} + template: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + databaseInstance: openstack + secret: osp-secret + networkAttachments: + - internalapi + horizon: + apiOverride: + route: {} + template: + replicas: 1 + secret: osp-secret + nova: + apiOverride: + route: {} + template: + apiServiceTemplate: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + metadataServiceTemplate: + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + secret: osp-secret + manila: + apiOverride: + route: {} + template: + manilaAPI: + replicas: 1 + networkAttachments: + - internalapi + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + manilaScheduler: + replicas: 1 + manilaShares: + share1: + replicas: 1 + networkAttachments: + - storage + ovn: + template: + ovnDBCluster: + ovndbcluster-nb: + dbType: NB + storageRequest: 10G + networkAttachment: internalapi + ovndbcluster-sb: + dbType: SB + storageRequest: 10G + networkAttachment: internalapi + ovnNorthd: + networkAttachment: internalapi + ovnController: + external-ids: + system-id: "random" + ovn-bridge: "br-int" + ovn-encap-type: "geneve" + networkAttachment: tenant + placement: + apiOverride: + route: {} + template: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + databaseInstance: openstack + secret: osp-secret + rabbitmq: + templates: + rabbitmq: + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + spec: + type: LoadBalancer + rabbitmq-cell1: + override: + service: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + spec: + type: LoadBalancer + heat: + apiOverride: + route: {} + cnfAPIOverride: + route: {} + enabled: false + template: + databaseInstance: openstack + heatAPI: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + replicas: 1 + heatEngine: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + replicas: 1 + secret: osp-secret + ironic: + enabled: false + template: + databaseInstance: openstack + ironicAPI: + replicas: 1 + ironicConductors: + - replicas: 1 + storageRequest: 10G + ironicInspector: + replicas: 1 + ironicNeutronAgent: + replicas: 1 + secret: osp-secret + telemetry: + enabled: true + template: + autoscaling: + enabled: false + prometheus: + deployPrometheus: false + aodh: + databaseInstance: openstack + memcachedInstance: memcached + secret: osp-secret + heatInstance: heat + ceilometer: + enabled: true + secret: osp-secret + swift: + enabled: true + proxyOverride: + route: {} + template: + swiftRing: + ringReplicas: 1 + swiftStorage: + replicas: 1 + swiftProxy: + replicas: 1 + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + octavia: + enabled: false + template: + databaseInstance: openstack + octaviaAPI: + replicas: 1 + secret: osp-secret + redis: + enabled: false + designate: + enabled: false + apiOverride: + route: {} + template: + databaseInstance: openstack + secret: osp-secret + designateAPI: + override: + service: + internal: + metadata: + annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + spec: + type: LoadBalancer + designateCentral: + replicas: 1 + designateWorker: + replicas: 0 + networkAttachements: + - designate + designateProducer: + replicas: 0 + designateMdns: + replicas: 0 + networkAttachements: + - designate + designateBackendbind9: + replicas: 0 + networkAttachements: + - designate diff --git a/go.mod b/go.mod index baf249fbc..897e06afe 100644 --- a/go.mod +++ b/go.mod @@ -38,9 +38,9 @@ require ( github.com/rabbitmq/cluster-operator/v2 v2.5.0 go.uber.org/zap v1.26.0 golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc - k8s.io/api v0.27.7 - k8s.io/apimachinery v0.27.7 - k8s.io/client-go v0.27.7 + k8s.io/api v0.28.1 + k8s.io/apimachinery v0.28.1 + k8s.io/client-go v0.28.1 sigs.k8s.io/controller-runtime v0.15.1 ) @@ -96,7 +96,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -107,10 +107,10 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.27.7 //indirect - k8s.io/component-base v0.27.7 //indirect + k8s.io/apiextensions-apiserver v0.28.1 //indirect + k8s.io/component-base v0.28.1 //indirect k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 //indirect + k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f //indirect k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd //indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect @@ -118,11 +118,15 @@ require ( ) replace ( //allow-merging + github.com/cert-manager/cert-manager => github.com/cert-manager/cert-manager v1.11.5 + github.com/google/gnostic => github.com/google/gnostic v0.6.9 // pin to k8s 0.26.x for now - k8s.io/api => k8s.io/api v0.26.9 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.9 - k8s.io/client-go => k8s.io/client-go v0.26.9 - sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.14.6 + k8s.io/api => k8s.io/api v0.26.11 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.11 + k8s.io/client-go => k8s.io/client-go v0.26.11 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c + sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.14.7 + sigs.k8s.io/gateway-api => sigs.k8s.io/gateway-api v0.6.0 ) replace github.com/openstack-k8s-operators/openstack-operator/apis => ./apis @@ -130,3 +134,11 @@ replace github.com/openstack-k8s-operators/openstack-operator/apis => ./apis // 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/keystone-operator/api => github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6 + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1 diff --git a/go.sum b/go.sum index e97013358..f2f3130bf 100644 --- a/go.sum +++ b/go.sum @@ -143,14 +143,10 @@ 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/barbican-operator/api v0.0.0-20240104150405-d50607d50e9a h1:fmfQTsJtpDja6jueqDxLEQv3AvrWqdybTr9cgeVrF6I= github.com/openstack-k8s-operators/barbican-operator/api v0.0.0-20240104150405-d50607d50e9a/go.mod h1:6NxyDHpJgkcxmmxRzsQMMrkBqdLWuaBY/bVsg2DzD/0= -github.com/openstack-k8s-operators/cinder-operator/api v0.3.1-0.20240104132718-a962cceb867d h1:xRKsN1KzdHFwIRAEBMAC+3/pg6ST1NmQcN1oPLiRGWM= -github.com/openstack-k8s-operators/cinder-operator/api v0.3.1-0.20240104132718-a962cceb867d/go.mod h1:GH+wo5YUPX95Mqst0yKXZGobehtlIqxDPjjE9GCl8IY= github.com/openstack-k8s-operators/dataplane-operator/api v0.3.1-0.20240104172704-238ed4f5b9f5 h1:WwzhU7ckL3FLMRYJV/siSsoYbKubvpLX9Fm4XKjIMjI= github.com/openstack-k8s-operators/dataplane-operator/api v0.3.1-0.20240104172704-238ed4f5b9f5/go.mod h1:sKylgv/UxHSpnbTK6lUtnWxNf+fM2ELqngxtM8XD/Sw= github.com/openstack-k8s-operators/designate-operator/api v0.0.0-20240104144436-858a0383741c h1:XSRqnJnHCUjn3PRQX16J7gasxnl5DIlyfE3p0F72gL8= github.com/openstack-k8s-operators/designate-operator/api v0.0.0-20240104144436-858a0383741c/go.mod h1:Wn+GO3Kddf7C5wM2vLNo2Ub1KRmy6qCuTwdyJlxXUuc= -github.com/openstack-k8s-operators/glance-operator/api v0.3.1-0.20240109080016-338d4287e4ec h1:rLcBTCgJphWY83hTJrFmYdnzUWXvorh0LiNRycrAxYs= -github.com/openstack-k8s-operators/glance-operator/api v0.3.1-0.20240109080016-338d4287e4ec/go.mod h1:4eraW+FyYsboi+a75FvKokgv0oeITVQMUAKYYqhViiQ= github.com/openstack-k8s-operators/heat-operator/api v0.3.1-0.20240104130506-4f3841d6042d h1:d6b8XI8UZF0q84DoznhWWydu0fAk2txGZAXjLiUu/FY= github.com/openstack-k8s-operators/heat-operator/api v0.3.1-0.20240104130506-4f3841d6042d/go.mod h1:R5j2Efz687VHonvB3cxWRhOjWS3OFSKu9U5mjOOcyeQ= github.com/openstack-k8s-operators/horizon-operator/api v0.3.1-0.20240104144435-fdfef4b8a33f h1:92xuDVbOiDEtJ8igh1wkoNj+UlzZWmYKH+rOb9OmLJ8= @@ -159,8 +155,6 @@ github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240104150635-c github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240104150635-c4ffc51e0752/go.mod h1:y4qeIT1ubUm9SKrvhVTuEYWSm0so38P5Hu3ZpdMJMek= github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240104144719-8030e9e8c962 h1:X7+Z4UVuYDCe4lD/y66H/Yf3TF/YckTTVDyAGfHJ4Tw= github.com/openstack-k8s-operators/ironic-operator/api v0.3.1-0.20240104144719-8030e9e8c962/go.mod h1:H6BuZ52u+Dq/vWJgpGIJLttRTnPPH3xdVeqhI99QE/k= -github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240104144437-5355d932c316 h1:IwTuIoC78bbp3awd8P0tWeknCe2jNLB1FCJDIwI/2Pg= -github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240104144437-5355d932c316/go.mod h1:qx+z+k0RMK8Vcl5Nug6bOScEg7ROSxEV4FFy0gjcQDQ= github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.0.0-20240110131857-e70e1dec4d14 h1:ufG9wUWSMiOMkJuzOGAoShuULamanaM5gfaAaUPXx2g= github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.0.0-20240110131857-e70e1dec4d14/go.mod h1:XGpipHyxzc+oqOX0aJFYtdGms9SiJwkAooyYc6MW4Ys= github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240110131857-e70e1dec4d14 h1:8batipIElAHscbsVUJz8w/2NOvu+pRi8ixF1XUP6WiQ= @@ -175,8 +169,6 @@ github.com/openstack-k8s-operators/manila-operator/api v0.3.1-0.20240104144719-7 github.com/openstack-k8s-operators/manila-operator/api v0.3.1-0.20240104144719-72b9a4ab968c/go.mod h1:AIdqCEAycRS/78wgnLhAjRkgkt7gygVmakvOp//vlz0= github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240104162634-fe72003c6343 h1:KrzABqo34PVd4kGxVwTZj/j4ZbTmH/vE/TL13t/ojGA= github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240104162634-fe72003c6343/go.mod h1:Ehw3pMZJrmmIscJ4npkAux7BuZ+2XSXnCuSeF1tzeL0= -github.com/openstack-k8s-operators/neutron-operator/api v0.3.1-0.20240104150349-c082ca19cafe h1:NdGc285xWKj21A8+DNSmamBI/CzO5njfQ4Fb0ACgh60= -github.com/openstack-k8s-operators/neutron-operator/api v0.3.1-0.20240104150349-c082ca19cafe/go.mod h1:oZ3qXiAcjEa0Zyy6WyjW35uvtI1FLzMRWInK/nlSi9w= github.com/openstack-k8s-operators/nova-operator/api v0.3.1-0.20240104123738-13980c2f529d h1:bQWbPEd9iBcFoil+id1kYUcxjxI83DLscgLZlyz0Hz0= github.com/openstack-k8s-operators/nova-operator/api v0.3.1-0.20240104123738-13980c2f529d/go.mod h1:NuZtXGv0KqWpN9A6HeclDgIQZn9SD3ompfiiyI2fV4c= github.com/openstack-k8s-operators/octavia-operator/api v0.3.1-0.20240104150350-1cb9656d2d92 h1:mJyxKHC80qo1F9FtYrg7ZUgb8QQ80zdc1VRHlaHfZT8= @@ -234,6 +226,14 @@ 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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1 h1:L/lO4dxSFJjFy7h00o7QTD/0I7VX1O0d0XCLgMpmmfU= +github.com/stuggi/cinder-operator/api v0.0.0-20240110132541-fed2378a8cb1/go.mod h1:Ozgk9komox+YQxkS43VncPzHjvef2Hga/nu6fX/G0ek= +github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7 h1:zMjEVG3OAizMDsPy6eE3PdPEXPOgM1AMw5m/c17nb+g= +github.com/stuggi/glance-operator/api v0.0.0-20240110140133-e82ebb00ccb7/go.mod h1:xBiocMjWKyYmFQ+sx4G5Es1kaCCleILvq3/cZ30OmtA= +github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6 h1:NPd4H7TpNCDO8VT/8H3O4kot8+AZYUraO0Sx6OP5V1Q= +github.com/stuggi/keystone-operator/api v0.0.0-20240110132207-643df3216ef6/go.mod h1:5quo1o1B7wLTXAD6j8sPXDxB5ASYaL9ImyiouAPrXtg= +github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a h1:r19DMgleke1s0KfyMFawd6Zs3WmOL3bOE0JZwrMYVnY= +github.com/stuggi/neutron-operator/api v0.0.0-20240110132446-b7dd116f719a/go.mod h1:yPMojR9cveY8v9D33Xg7TKgMLv1/eC5iUx38I+oW+os= 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= @@ -284,8 +284,8 @@ golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= 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= @@ -384,24 +384,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.26.9 h1:s8Y+G1u2JM55b90+Yo2RVb3PGT/hkWNVPN4idPERxJg= -k8s.io/api v0.26.9/go.mod h1:W/W4fEWRVzPD36820LlVUQfNBiSbiq0VPWRFJKwzmUg= -k8s.io/apiextensions-apiserver v0.27.7 h1:YqIOwZAUokzxJIjunmUd4zS1v3JhK34EPXn+pP0/bsU= -k8s.io/apiextensions-apiserver v0.27.7/go.mod h1:x0p+b5a955lfPz9gaDeBy43obM12s+N9dNHK6+dUL+g= -k8s.io/apimachinery v0.26.9 h1:5yAV9cFR7Z4gIorKcAjWnx4uxtxiFsERwq4Pvmx0CCg= -k8s.io/apimachinery v0.26.9/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0= -k8s.io/client-go v0.26.9 h1:TGWi/6guEjIgT0Hg871Gsmx0qFuoGyGFjlFedrk7It0= -k8s.io/client-go v0.26.9/go.mod h1:tU1FZS0bwAmAFyPYpZycUQrQnUMzQ5MHloop7EbX6ow= -k8s.io/component-base v0.27.7 h1:kngM58HR9W9Nqpv7e4rpdRyWnKl/ABpUhLAZ+HoliMs= -k8s.io/component-base v0.27.7/go.mod h1:YGjlCVL1oeKvG3HSciyPHFh+LCjIEqsxz4BDR3cfHRs= +k8s.io/api v0.26.11 h1:hLhTZRdYc3vBBOY4wbEyTLWgMyieOAk2Ws9NG57QqO4= +k8s.io/api v0.26.11/go.mod h1:bSr/A0TKRt5W2OMDdexkM/ER1NxOxiQqNNFXW2nMZrM= +k8s.io/apiextensions-apiserver v0.28.1 h1:l2ThkBRjrWpw4f24uq0Da2HaEgqJZ7pcgiEUTKSmQZw= +k8s.io/apiextensions-apiserver v0.28.1/go.mod h1:sVvrI+P4vxh2YBBcm8n2ThjNyzU4BQGilCQ/JAY5kGs= +k8s.io/apimachinery v0.26.11 h1:w//840HHdwSRKqD15j9YX9HLlU6RPlfrvW0xEhLk2+0= +k8s.io/apimachinery v0.26.11/go.mod h1:2/HZp0l6coXtS26du1Bk36fCuAEr/lVs9Q9NbpBtd1Y= +k8s.io/client-go v0.26.11 h1:RjfZr5+vQjjTRmk4oCqHyC0cgrZXPjw+X+ge35sk4GI= +k8s.io/client-go v0.26.11/go.mod h1:+emNszw9va/uRJIM5ALTBtFnlZMTjwBrNjRfEh0iuw8= +k8s.io/component-base v0.28.1 h1:LA4AujMlK2mr0tZbQDZkjWbdhTV5bRyEyAFe0TJxlWg= +k8s.io/component-base v0.28.1/go.mod h1:jI11OyhbX21Qtbav7JkhehyBsIRfnO8oEgoAR12ArIU= 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-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI= -k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515/go.mod h1:kzo02I3kQ4BTtEfVLaPbjvCkX97YqGve33wzlb3fofQ= +k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c h1:EFfsozyzZ/pggw5qNx7ftTVZdp7WZl+3ih89GEjYEK8= +k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= -sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/controller-runtime v0.14.7 h1:Vrnm2vk9ZFlRkXATHz0W0wXcqNl7kPat8q2JyxVy0Q8= +sigs.k8s.io/controller-runtime v0.14.7/go.mod h1:ErTs3SJCOujNUnTz4AS+uh8hp6DHMo1gj6fFndJT1X8= sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/openstack/barbican.go b/pkg/openstack/barbican.go index dd648299e..69d635ffe 100644 --- a/pkg/openstack/barbican.go +++ b/pkg/openstack/barbican.go @@ -56,6 +56,7 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr } } + var endpointDetails = Endpoints{} if barbican.Status.Conditions.IsTrue(barbicanv1.BarbicanAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -68,7 +69,7 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr } var ctrlResult reconcile.Result - instance.Spec.Barbican.Template.BarbicanAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -77,12 +78,15 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr instance.Spec.Barbican.Template.BarbicanAPI.Override.Service, instance.Spec.Barbican.APIOverride, corev1beta1.OpenStackControlPlaneExposeBarbicanReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Barbican.Template.BarbicanAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() } helper.GetLogger().Info("Reconciling Barbican", "Barbican.Namespace", instance.Namespace, "Barbican.Name", "barbican") diff --git a/pkg/openstack/ca.go b/pkg/openstack/ca.go index 4f2cf6021..c20ad0016 100644 --- a/pkg/openstack/ca.go +++ b/pkg/openstack/ca.go @@ -27,19 +27,6 @@ import ( ctrl "sigs.k8s.io/controller-runtime" ) -const ( - // CombinedCASecret - - CombinedCASecret = "combined-ca-bundle" - // TLSCABundleFile - - TLSCABundleFile = "tls-ca-bundle.pem" - // DefaultCAPrefix - - DefaultCAPrefix = "rootca-" - // DownstreamTLSCABundlePath - - DownstreamTLSCABundlePath = "/etc/pki/ca-trust/extracted/pem/" + TLSCABundleFile - // UpstreamTLSCABundlePath - - UpstreamTLSCABundlePath = "/etc/ssl/certs/ca-certificates.crt" -) - // ReconcileCAs - func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, helper *helper.Helper) (ctrl.Result, error) { // create selfsigned-issuer @@ -86,21 +73,34 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h } bundle := newBundle() + caOnlyBundle := newBundle() // load current CA bundle from secret if exist - currentCASecret, _, err := secret.GetSecret(ctx, helper, CombinedCASecret, instance.Namespace) + currentCASecret, _, err := secret.GetSecret(ctx, helper, tls.CABundleSecret, instance.Namespace) if err != nil && !k8s_errors.IsNotFound(err) { return ctrl.Result{}, err } if currentCASecret != nil { - if _, ok := currentCASecret.Data[TLSCABundleFile]; ok { - err = bundle.getCertsFromPEM(currentCASecret.Data[TLSCABundleFile]) + // full CA Bundle file + if _, ok := currentCASecret.Data[tls.CABundleKey]; ok { + err = bundle.getCertsFromPEM(currentCASecret.Data[tls.CABundleKey]) + if err != nil { + return ctrl.Result{}, err + } + } + + // only issuer CA bundle + if _, ok := currentCASecret.Data[tls.InternalCABundleKey]; ok { + err = caOnlyBundle.getCertsFromPEM(currentCASecret.Data[tls.InternalCABundleKey]) if err != nil { return ctrl.Result{}, err } } } + if instance.Status.TLS.Endpoint == nil { + instance.Status.TLS.Endpoint = map[service.Endpoint]corev1.TLSCAStatus{} + } // create RootCA cert and Issuer that uses the generated CA certificate to issue certs for endpoint, config := range instance.Spec.TLS.Endpoint { if config.Enabled { @@ -109,6 +109,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h if endpoint == service.EndpointInternal { labels[certmanager.RootCAIssuerInternalLabel] = "" } + caName := tls.DefaultCAPrefix + string(endpoint) // always create a root CA and issuer for the endpoint as we can // not expect that all services are yet configured to be provided with // a custom secret holding the cert/private key @@ -117,7 +118,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h instance, helper, issuerReq, - DefaultCAPrefix+string(endpoint), + caName, labels, ) if err != nil { @@ -130,6 +131,19 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h if err != nil { return ctrl.Result{}, err } + err = caOnlyBundle.getCertsFromPEM(caCert) + if err != nil { + return ctrl.Result{}, err + } + + status := corev1.TLSCAStatus{ + Name: caName, + } + if len(caOnlyBundle.certs) > 0 { + status.Expires = caOnlyBundle.certs[0].expire.String() + } + + instance.Status.TLS.Endpoint[endpoint] = status } } instance.Status.Conditions.MarkTrue(corev1.OpenStackControlPlaneCAReadyCondition, corev1.OpenStackControlPlaneCAReadyMessage) @@ -146,8 +160,14 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h "secret", instance.Spec.TLS.CaBundleSecretName, err.Error())) + if k8s_errors.IsNotFound(err) { + timeout := time.Second * 10 + helper.GetLogger().Info(fmt.Sprintf("Certificate %s not found, reconcile in %s", instance.Spec.TLS.CaBundleSecretName, timeout.String())) - return ctrlResult, err + return ctrl.Result{RequeueAfter: timeout}, nil + } + + return ctrl.Result{}, err } for _, caCert := range caSecret.Data { @@ -160,13 +180,13 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h // get CA bundle from operator image. Downstream and upstream build use a different // base image, so the ca bundle cert file can be in different locations - caBundle, err := getOperatorCABundle(DownstreamTLSCABundlePath) + caBundle, err := getOperatorCABundle(tls.DownstreamTLSCABundlePath) if err != nil { // if the DownstreamTLSCABundlePath does not exist in the operator image, // check for UpstreamTLSCABundlePath if errors.Is(err, os.ErrNotExist) { - helper.GetLogger().Info(fmt.Sprintf("Downstream CA bundle not found using: %s", UpstreamTLSCABundlePath)) - caBundle, err = getOperatorCABundle(UpstreamTLSCABundlePath) + helper.GetLogger().Info(fmt.Sprintf("Downstream CA bundle not found using: %s", tls.UpstreamTLSCABundlePath)) + caBundle, err = getOperatorCABundle(tls.UpstreamTLSCABundlePath) if err != nil { return ctrl.Result{}, err } @@ -181,7 +201,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h saSecretTemplate := []util.Template{ { - Name: CombinedCASecret, + Name: tls.CABundleSecret, Namespace: instance.Namespace, Type: util.TemplateTypeNone, InstanceType: instance.Kind, @@ -191,7 +211,11 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h tls.CABundleLabel: "", }, ConfigOptions: nil, - CustomData: map[string]string{TLSCABundleFile: bundle.getBundlePEM()}, + CustomData: map[string]string{ + tls.CABundleKey: bundle.getBundlePEM(), + tls.InternalCABundleKey: caOnlyBundle.getBundlePEM(), + }, + SkipSetOwner: true, // TODO: (mschuppert) instead add e.g. keystoneapi to secret to prevent keystoneapi on cleanup to switch to not ready }, } @@ -202,12 +226,14 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h condition.SeverityWarning, corev1.OpenStackControlPlaneCAReadyErrorMessage, "secret", - CombinedCASecret, + tls.CABundleSecret, err.Error())) return ctrlResult, err } + instance.Status.TLS.CaBundleSecretName = tls.CABundleSecret + return ctrl.Result{}, nil } @@ -352,8 +378,9 @@ type caBundle struct { } type caCert struct { - hash string - cert *x509.Certificate + hash string + cert *x509.Certificate + expire time.Time } // newBundle returns a new, empty Bundle @@ -415,8 +442,9 @@ func (cab *caBundle) getCertsFromPEM(PEMdata []byte) error { if idx == -1 { cab.certs = append(cab.certs, caCert{ - hash: blockHash, - cert: certificate, + hash: blockHash, + cert: certificate, + expire: certificate.NotAfter, }) } } diff --git a/pkg/openstack/cinder.go b/pkg/openstack/cinder.go index aa7d348b7..3e8ed076d 100644 --- a/pkg/openstack/cinder.go +++ b/pkg/openstack/cinder.go @@ -57,6 +57,13 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl } } + // preserve any previously set TLS certs,set CA cert + if instance.Spec.TLS.Enabled(service.EndpointInternal) { + instance.Spec.Cinder.Template.CinderAPI.TLS = cinder.Spec.CinderAPI.TLS + } + instance.Spec.Cinder.Template.CinderAPI.TLS.CaBundleSecretName = instance.Status.TLS.CaBundleSecretName + + var endpointDetails = Endpoints{} if cinder.Status.Conditions.IsTrue(cinderv1.CinderAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -69,7 +76,7 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl } var ctrlResult reconcile.Result - instance.Spec.Cinder.Template.CinderAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -78,12 +85,19 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Cinder.Template.CinderAPI.Override.Service, instance.Spec.Cinder.APIOverride, corev1beta1.OpenStackControlPlaneExposeCinderReadyCondition, + false, // TODO (mschuppert) could be removed when all integrated service support TLS ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Cinder.Template.CinderAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() + + // update TLS settings with cert secret + instance.Spec.Cinder.Template.CinderAPI.TLS.API.Public.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointPublic) + instance.Spec.Cinder.Template.CinderAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal) } Log.Info("Reconciling Cinder", "Cinder.Namespace", instance.Namespace, "Cinder.Name", "cinder") diff --git a/pkg/openstack/common.go b/pkg/openstack/common.go index bf78bec23..ff91a5141 100644 --- a/pkg/openstack/common.go +++ b/pkg/openstack/common.go @@ -24,7 +24,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/route" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" "github.com/openstack-k8s-operators/lib-common/modules/common/service" - "github.com/openstack-k8s-operators/lib-common/modules/common/util" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" @@ -74,17 +74,19 @@ func EnsureDeleted(ctx context.Context, helper *helper.Helper, obj client.Object // AddServiceComponentLabel - adds component label to the service override to be able to query // the service labels to check for any route creation func AddServiceComponentLabel(svcOverride service.RoutedOverrideSpec, value string) service.RoutedOverrideSpec { - if svcOverride.EmbeddedLabelsAnnotations == nil { - svcOverride.EmbeddedLabelsAnnotations = &service.EmbeddedLabelsAnnotations{} - } - svcOverride.EmbeddedLabelsAnnotations.Labels = util.MergeStringMaps( - svcOverride.EmbeddedLabelsAnnotations.Labels, map[string]string{common.AppSelector: value}) + svcOverride.AddLabel(map[string]string{common.AppSelector: value}) return svcOverride } -// EndpointDetails - endpoint details -type EndpointDetails struct { +// Endpoints +type Endpoints struct { + EndpointDetails map[service.Endpoint]EndpointDetail + tls.Ca +} + +// EndpointDetail - endpoint details +type EndpointDetail struct { Name string Namespace string Type service.Endpoint @@ -93,31 +95,38 @@ type EndpointDetails struct { Service ServiceDetails Route RouteDetails Hostname *string + Proto service.Protocol EndpointURL string - TLS TLSDetails } -// TLSDetails - tls settings for the endpoint -type TLSDetails struct { - Enabled bool - Issuer string - CertSecret *string - InternalCA string - - //PublicEndpoint bool - //InternalEndpoint bool +// ServiceTLSDetails - tls settings for the endpoint +type ServiceTLSDetails struct { + Enabled bool + tls.GenericService + tls.Ca } // ServiceDetails - service details type ServiceDetails struct { Spec *k8s_corev1.Service OverrideSpec service.RoutedOverrideSpec + TLS ServiceTLSDetails } // RouteDetails - route details type RouteDetails struct { + Create bool Route *routev1.Route OverrideSpec route.OverrideSpec + TLS RouteTLSDetails +} + +// RouteTLSDetails - tls settings for the endpoint +type RouteTLSDetails struct { + Enabled bool + SecretName *string + IssuerName *string + tls.Ca } // GetRoutesListWithLabel - Get all routes in namespace of the obj matching label selector @@ -141,6 +150,16 @@ func GetRoutesListWithLabel( return routeList, nil } +// GetEndpointServiceOverrides - +func (e *Endpoints) GetEndpointServiceOverrides() map[service.Endpoint]service.RoutedOverrideSpec { + overrides := map[service.Endpoint]service.RoutedOverrideSpec{} + for endpt, endptCfg := range e.EndpointDetails { + overrides[endpt] = *endptCfg.Service.OverrideSpec.DeepCopy() + } + + return overrides +} + // EnsureEndpointConfig - func EnsureEndpointConfig( ctx context.Context, @@ -151,9 +170,14 @@ func EnsureEndpointConfig( svcOverrides map[service.Endpoint]service.RoutedOverrideSpec, publicOverride corev1.Override, condType condition.Type, -) (map[service.Endpoint]service.RoutedOverrideSpec, ctrl.Result, error) { + serviceTLSDisabled bool, +) (Endpoints, ctrl.Result, error) { + endpoints := Endpoints{ + EndpointDetails: map[service.Endpoint]EndpointDetail{}, + } + for _, svc := range svcs.Items { - ed := EndpointDetails{ + ed := EndpointDetail{ Name: svc.Name, Namespace: svc.Namespace, Type: service.Endpoint(svc.Annotations[service.AnnotationEndpointKey]), @@ -161,43 +185,112 @@ func EnsureEndpointConfig( Spec: &svc, }, } - if publicOverride.Route != nil { - ed.Route.OverrideSpec = *publicOverride.Route - } - if tlsEndpointConfig := instance.Spec.TLS.Endpoint[ed.Type]; tlsEndpointConfig.Enabled { - ed.TLS.Enabled = true - ed.TLS.Issuer = DefaultCAPrefix + string(ed.Type) + ed.Service.OverrideSpec = svcOverrides[ed.Type] - // TODO: (mschuppert) for TLSE create TLS cert for service - //if ed.Type == service.EndpointInternal { - // TODO: for TLSE create TLS cert for service - //} + // TLS on the pod level is enabled if + // * TLS is enabled for internal endpoint + // * the particular service has not TLS.Disabled set to true + if tlsEndpointConfig := instance.Spec.TLS.Endpoint[service.EndpointInternal]; tlsEndpointConfig.Enabled && !serviceTLSDisabled { + ed.Service.TLS.Enabled = true + } else { + ed.Service.TLS.Enabled = false } - if instance.Spec.TLS.Endpoint[service.EndpointInternal].Enabled { - // TODO: (mschuppert) get the CA cert for internal CA to add it to the route - // to be able to connect to the TLS internal endpoint - ed.TLS.InternalCA = "" - } + switch ed.Type { + case service.EndpointPublic: + // If the service has the create ingress annotation and its a default ClusterIP service -> create route + ed.Route.Create = svc.ObjectMeta.Annotations[service.AnnotationIngressCreateKey] == "true" && + svc.Spec.Type == k8s_corev1.ServiceTypeClusterIP - ed.Service.OverrideSpec = svcOverrides[ed.Type] + if publicOverride.Route != nil { + ed.Route.OverrideSpec = *publicOverride.Route + } + + // if public endpoint TLS is enabled + if tlsEndpointConfig := instance.Spec.TLS.Endpoint[ed.Type]; tlsEndpointConfig.Enabled { + // TLS for route enabled if public endpoint TLS is true + ed.Route.TLS.Enabled = true - if ed.Type == service.EndpointPublic { - if ed.TLS.Enabled { // if a custom cert secret was provided we'll use this for // the route, otherwise the issuer is used to request one // for the endpoint. if publicOverride.TLS != nil && publicOverride.TLS.SecretName != "" { - ed.TLS.CertSecret = ptr.To(publicOverride.TLS.SecretName) + ed.Route.TLS.SecretName = ptr.To(publicOverride.TLS.SecretName) + } else { + // use public issuer to create cert for the route + ed.Route.TLS.IssuerName = ptr.To(tls.DefaultCAPrefix + ed.Type.String()) + } + + // For re-encryption the route required the internal CA bundle to validate + // internal certificate from route -> service -> pod. Add the internal CA bundle when + // * TLS is enabled for internal endpoint + // * the particular service has not TLS.Disabled set to true + if ed.Service.TLS.Enabled { + ed.Service.TLS.CaBundleSecretName = tls.CABundleSecret + // create certificate for public pod virthost + // TODO: (mschuppert) - if ed.Route.Create == false and custom cert secret provided + // for the public endpoint, use this and not the issuer. This is the case when + // env got deployed with LoadBalancer service instead of a route for the public + // endpoint. + // request certificate + certRequest := certmanager.CertificateRequest{ + IssuerName: tls.DefaultCAPrefix + ed.Type.String(), + CertName: fmt.Sprintf("%s-svc", ed.Name), + Duration: nil, + Hostnames: []string{fmt.Sprintf("%s.%s.svc", ed.Name, instance.Namespace)}, + Ips: nil, + Annotations: ed.Annotations, + Labels: ed.Labels, + Usages: nil, + } + certSecret, ctrlResult, err := certmanager.EnsureCert( + ctx, + helper, + certRequest) + if err != nil { + return endpoints, ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return endpoints, ctrlResult, nil + } + + ed.Service.TLS.SecretName = &certSecret.Name } } ctrlResult, err := ed.ensureRoute(ctx, instance, helper, &svc, owner, condType) if err != nil { - return svcOverrides, ctrlResult, err + return endpoints, ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { - return svcOverrides, ctrlResult, nil + return endpoints, ctrlResult, nil + } + + case service.EndpointInternal: + if ed.Service.TLS.Enabled { + ed.Service.TLS.CaBundleSecretName = tls.CABundleSecret + // create certificate for internal pod virthost + // request certificate + certRequest := certmanager.CertificateRequest{ + IssuerName: tls.DefaultCAPrefix + ed.Type.String(), + CertName: fmt.Sprintf("%s-svc", ed.Name), + Duration: nil, + Hostnames: []string{fmt.Sprintf("%s.%s.svc", ed.Name, instance.Namespace)}, + Ips: nil, + Annotations: ed.Annotations, + Labels: ed.Labels, + Usages: nil, + } + certSecret, ctrlResult, err := certmanager.EnsureCert( + ctx, + helper, + certRequest) + if err != nil { + return endpoints, ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return endpoints, ctrlResult, nil + } + + ed.Service.TLS.SecretName = &certSecret.Name } } @@ -208,13 +301,13 @@ func EnsureEndpointConfig( instance.Status.Conditions.MarkTrue(condType, corev1.OpenStackControlPlaneExposeServiceReadyMessage, owner.GetName()) } - svcOverrides[ed.Type] = ed.Service.OverrideSpec + endpoints.EndpointDetails[ed.Type] = ed } - return svcOverrides, ctrl.Result{}, nil + return endpoints, ctrl.Result{}, nil } -func (ed *EndpointDetails) ensureRoute( +func (ed *EndpointDetail) ensureRoute( ctx context.Context, instance *corev1.OpenStackControlPlane, helper *helper.Helper, @@ -269,8 +362,7 @@ func (ed *EndpointDetails) ensureRoute( } } - // If the service has the create ingress annotation and its a default ClusterIP service -> create route - if svc.ObjectMeta.Annotations[service.AnnotationIngressCreateKey] == "true" && svc.Spec.Type == k8s_corev1.ServiceTypeClusterIP { + if ed.Route.Create { if instance.Status.Conditions.Get(condType) == nil { instance.Status.Conditions.Set(condition.UnknownCondition( condType, @@ -312,7 +404,7 @@ func (ed *EndpointDetails) ensureRoute( } // CreateRoute - -func (ed *EndpointDetails) CreateRoute( +func (ed *EndpointDetail) CreateRoute( ctx context.Context, helper *helper.Helper, owner metav1.Object, @@ -339,7 +431,7 @@ func (ed *EndpointDetails) CreateRoute( // to get the hostname for creating the cert serviceRoute := &routev1.Route{} err = helper.GetClient().Get(ctx, types.NamespacedName{Name: ed.Name, Namespace: ed.Namespace}, serviceRoute) - if !ed.TLS.Enabled || (ed.TLS.Enabled && err != nil && k8s_errors.IsNotFound(err)) { + if !ed.Route.TLS.Enabled || (ed.Route.TLS.Enabled && err != nil && k8s_errors.IsNotFound(err)) { ctrlResult, err := enptRoute.CreateOrPatch(ctx, helper) if err != nil { return ctrlResult, err @@ -354,8 +446,8 @@ func (ed *EndpointDetails) CreateRoute( ed.Hostname = &serviceRoute.Spec.Host } - // if the issuer is provided TLS is enabled - if ed.TLS.Enabled { + // if TLS is enabled for the route + if ed.Route.TLS.Enabled { var ctrlResult reconcile.Result certSecret := &k8s_corev1.Secret{} @@ -365,11 +457,11 @@ func (ed *EndpointDetails) CreateRoute( // Right now there is no check if certificate is valid for // the hostname of the route. If the referenced secret is // there and has the required files it is just being used. - if ed.TLS.CertSecret != nil { - certSecret, _, err = secret.GetSecret(ctx, helper, *ed.TLS.CertSecret, ed.Namespace) + if ed.Route.TLS.SecretName != nil { + certSecret, _, err = secret.GetSecret(ctx, helper, *ed.Route.TLS.SecretName, ed.Namespace) if err != nil { if k8s_errors.IsNotFound(err) { - return ctrl.Result{}, fmt.Errorf("certificate secret %s not found: %w", *ed.TLS.CertSecret, err) + return ctrl.Result{}, fmt.Errorf("certificate secret %s not found: %w", *ed.Route.TLS.SecretName, err) } return ctrl.Result{}, err @@ -379,14 +471,14 @@ func (ed *EndpointDetails) CreateRoute( if certSecret != nil { for _, key := range []string{"tls.crt", "tls.key", "ca.crt"} { if _, exist := certSecret.Data[key]; !exist { - return ctrl.Result{}, fmt.Errorf("certificate secret %s does not provide %s", *ed.TLS.CertSecret, key) + return ctrl.Result{}, fmt.Errorf("certificate secret %s does not provide %s", *ed.Route.TLS.SecretName, key) } } } } else { certRequest := certmanager.CertificateRequest{ - IssuerName: ed.TLS.Issuer, - CertName: ed.Name, + IssuerName: *ed.Route.TLS.IssuerName, + CertName: fmt.Sprintf("%s-route", ed.Name), Duration: nil, Hostnames: []string{*ed.Hostname}, Ips: nil, @@ -409,16 +501,25 @@ func (ed *EndpointDetails) CreateRoute( // create default TLS route override tlsConfig := &routev1.TLSConfig{ Termination: routev1.TLSTerminationEdge, - Certificate: string(certSecret.Data["tls.crt"]), - Key: string(certSecret.Data["tls.key"]), - CACertificate: string(certSecret.Data["ca.crt"]), + Certificate: string(certSecret.Data[tls.CertKey]), + Key: string(certSecret.Data[tls.PrivateKey]), + CACertificate: string(certSecret.Data[tls.CAKey]), InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect, } // for internal TLS (TLSE) use routev1.TLSTerminationReencrypt - if ed.TLS.InternalCA != "" { + if ed.Service.TLS.Enabled { + // get the TLSInternalCABundleFile to add it to the route + // to be able to validate public/internal service endpoints + tlsConfig.DestinationCACertificate, ctrlResult, err = secret.GetDataFromSecret( + ctx, helper, ed.Service.TLS.CaBundleSecretName, 5, tls.InternalCABundleKey) + if err != nil { + return ctrlResult, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + tlsConfig.Termination = routev1.TLSTerminationReencrypt - tlsConfig.DestinationCACertificate = ed.TLS.InternalCA } enptRoute, err = route.NewRoute( @@ -444,14 +545,27 @@ func (ed *EndpointDetails) CreateRoute( return ctrlResult, nil } - ed.EndpointURL = "https://" + *ed.Hostname + ed.Proto = service.ProtocolHTTPS } else { - ed.EndpointURL = "http://" + *ed.Hostname + ed.Proto = service.ProtocolHTTP } + ed.EndpointURL = ed.Proto.String() + "://" + *ed.Hostname + return ctrl.Result{}, nil } +// GetEndptCertSecret - +func (e *Endpoints) GetEndptCertSecret(endpt service.Endpoint) *string { + var endptTLSSecret *string + + if endptCfg, ok := e.EndpointDetails[endpt]; ok && endptCfg.Service.TLS.Enabled { + endptTLSSecret = endptCfg.Service.TLS.SecretName + } + + return endptTLSSecret +} + // Set up any defaults used by service operator defaulting logic func SetupServiceOperatorDefaults() { // Acquire environmental defaults and initialize service operators that diff --git a/pkg/openstack/designate.go b/pkg/openstack/designate.go index 811066254..c4e7eba95 100644 --- a/pkg/openstack/designate.go +++ b/pkg/openstack/designate.go @@ -56,6 +56,7 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont } } + var endpointDetails = Endpoints{} if designate.Status.Conditions.IsTrue(designatev1.DesignateAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -68,7 +69,7 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont } var ctrlResult reconcile.Result - instance.Spec.Designate.Template.DesignateAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -77,12 +78,15 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont instance.Spec.Designate.Template.DesignateAPI.Override.Service, instance.Spec.Designate.APIOverride, corev1beta1.OpenStackControlPlaneExposeDesignateReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Designate.Template.DesignateAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() } helper.GetLogger().Info("Reconciling Designate", "Designate.Namespace", instance.Namespace, "Designate.Name", "designate") diff --git a/pkg/openstack/glance.go b/pkg/openstack/glance.go index 90f794619..d4fd6b034 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.go @@ -43,6 +43,13 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl return ctrl.Result{}, nil } + // When component services got created check if there is the need to create a route + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "glance", Namespace: instance.Namespace}, glance); err != nil { + if !k8s_errors.IsNotFound(err) { + return ctrl.Result{}, err + } + } + // add selector to service overrides for name, glanceAPI := range instance.Spec.Glance.Template.GlanceAPIs { for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { @@ -55,16 +62,17 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl svcOverride := glanceAPI.Override.Service[endpointType] svcOverride.AddLabel(getGlanceAPILabelMap(glance.Name, name)) glanceAPI.Override.Service[endpointType] = svcOverride - instance.Spec.Glance.Template.GlanceAPIs[name] = glanceAPI } - } - // When component services got created check if there is the need to create a route - if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "glance", Namespace: instance.Namespace}, glance); err != nil { - if !k8s_errors.IsNotFound(err) { - return ctrl.Result{}, err + + // preserve any previously set TLS certs,set CA cert + if instance.Spec.TLS.Enabled(service.EndpointInternal) { + glanceAPI.TLS.API = glance.Spec.GlanceAPIs[name].TLS.API } + glanceAPI.TLS.CaBundleSecretName = instance.Status.TLS.CaBundleSecretName + instance.Spec.Glance.Template.GlanceAPIs[name] = glanceAPI } + var endpointDetails = Endpoints{} if glance.Status.Conditions.IsTrue(glancev1.GlanceAPIReadyCondition) { // initialize the main APIOverride struct if instance.Spec.Glance.APIOverride == nil { @@ -74,7 +82,7 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl var ctrlResult reconcile.Result var changed bool = false for name, glanceAPI := range instance.Spec.Glance.Template.GlanceAPIs { - if _, ok := instance.Spec.Glance.APIOverride[name]; ok { + if _, ok := instance.Spec.Glance.APIOverride[name]; !ok { instance.Spec.Glance.APIOverride[name] = corev1beta1.Override{} } // Retrieve the services by Label and filter on glanceAPI: for @@ -92,7 +100,7 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl if err != nil { return ctrl.Result{}, err } - _, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -101,10 +109,18 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl glanceAPI.Override.Service, instance.Spec.Glance.APIOverride[name], corev1beta1.OpenStackControlPlaneExposeGlanceReadyCondition, + false, // TODO (mschuppert) could be removed when all integrated service support TLS ) if err != nil { return ctrlResult, err } + glanceAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() + + // update TLS cert secret + glanceAPI.TLS.API.Public.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointPublic) + glanceAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal) + instance.Spec.Glance.Template.GlanceAPIs[name] = glanceAPI + // let's keep track of changes for any instance, but return // only when the iteration on the whole APIList is over if (ctrlResult != ctrl.Result{}) { @@ -144,6 +160,7 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl } glance.Spec.ExtraMounts = glanceVolumes } + err := controllerutil.SetControllerReference(helper.GetBeforeObject(), glance, helper.GetScheme()) if err != nil { return err diff --git a/pkg/openstack/heat.go b/pkg/openstack/heat.go index 7df0f4208..14cbbbf51 100644 --- a/pkg/openstack/heat.go +++ b/pkg/openstack/heat.go @@ -69,6 +69,7 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl } // Heat API + var apiServiceEndpointDetails = Endpoints{} if heat.Status.Conditions.IsTrue(heatv1.HeatAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -81,7 +82,7 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl } var ctrlResult reconcile.Result - instance.Spec.Heat.Template.HeatAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + apiServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -90,15 +91,19 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Heat.Template.HeatAPI.Override.Service, instance.Spec.Heat.APIOverride, corev1beta1.OpenStackControlPlaneExposeHeatReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Heat.Template.HeatAPI.Override.Service = apiServiceEndpointDetails.GetEndpointServiceOverrides() } // Heat CFNAPI + var cfnAPIServiceEndpointDetails = Endpoints{} if heat.Status.Conditions.IsTrue(heatv1.HeatCfnAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -111,7 +116,7 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl } var ctrlResult reconcile.Result - instance.Spec.Heat.Template.HeatCfnAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + cfnAPIServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -120,12 +125,15 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Heat.Template.HeatCfnAPI.Override.Service, instance.Spec.Heat.CnfAPIOverride, corev1beta1.OpenStackControlPlaneExposeHeatReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Heat.Template.HeatCfnAPI.Override.Service = cfnAPIServiceEndpointDetails.GetEndpointServiceOverrides() } Log := GetLogger(ctx) diff --git a/pkg/openstack/horizon.go b/pkg/openstack/horizon.go index 853344920..2cd5e7359 100644 --- a/pkg/openstack/horizon.go +++ b/pkg/openstack/horizon.go @@ -68,6 +68,7 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro } } + var endpointDetails = Endpoints{} if horizon.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -80,7 +81,7 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro } var ctrlResult reconcile.Result - serviceOverrides, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -89,12 +90,14 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro serviceOverrides, instance.Spec.Horizon.APIOverride, corev1beta1.OpenStackControlPlaneExposeHorizonReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + serviceOverrides = endpointDetails.GetEndpointServiceOverrides() } Log.Info("Reconcile Horizon", "horizon.Namespace", instance.Namespace, "horizon.Name", "horizon") diff --git a/pkg/openstack/ironic.go b/pkg/openstack/ironic.go index dee21538f..354cd6e44 100644 --- a/pkg/openstack/ironic.go +++ b/pkg/openstack/ironic.go @@ -66,6 +66,7 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl } // Ironic API + var apiServiceEndpointDetails = Endpoints{} if ironic.Status.Conditions.IsTrue(ironicv1.IronicAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -78,7 +79,7 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl } var ctrlResult reconcile.Result - instance.Spec.Ironic.Template.IronicAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + apiServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -87,15 +88,19 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Ironic.Template.IronicAPI.Override.Service, instance.Spec.Ironic.APIOverride, corev1beta1.OpenStackControlPlaneExposeIronicReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Ironic.Template.IronicAPI.Override.Service = apiServiceEndpointDetails.GetEndpointServiceOverrides() } // Ironic Inspector + var inspectorServiceEndpointDetails = Endpoints{} if ironic.Status.Conditions.IsTrue(ironicv1.IronicInspectorReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -108,7 +113,7 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl } var ctrlResult reconcile.Result - instance.Spec.Ironic.Template.IronicInspector.Override.Service, ctrlResult, err = EnsureEndpointConfig( + inspectorServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -117,12 +122,15 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Ironic.Template.IronicInspector.Override.Service, instance.Spec.Ironic.InspectorOverride, corev1beta1.OpenStackControlPlaneExposeIronicReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Ironic.Template.IronicInspector.Override.Service = inspectorServiceEndpointDetails.GetEndpointServiceOverrides() } Log.Info("Reconciling Ironic", "Ironic.Namespace", instance.Namespace, "Ironic.Name", "ironic") diff --git a/pkg/openstack/keystone.go b/pkg/openstack/keystone.go index f21c8417b..b7ca75c3e 100644 --- a/pkg/openstack/keystone.go +++ b/pkg/openstack/keystone.go @@ -58,6 +58,13 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo } } + // preserve any previously set TLS certs,set CA cert + if instance.Spec.TLS.Enabled(service.EndpointInternal) { + instance.Spec.Keystone.Template.TLS = keystoneAPI.Spec.TLS + } + instance.Spec.Keystone.Template.TLS.CaBundleSecretName = instance.Status.TLS.CaBundleSecretName + + var endpointDetails = Endpoints{} if keystoneAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -70,7 +77,7 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo } var ctrlResult reconcile.Result - instance.Spec.Keystone.Template.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -79,15 +86,21 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo instance.Spec.Keystone.Template.Override.Service, instance.Spec.Keystone.APIOverride, corev1beta1.OpenStackControlPlaneExposeKeystoneAPIReadyCondition, + false, // TODO (mschuppert) could be removed when all integrated service support TLS ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Keystone.Template.Override.Service = endpointDetails.GetEndpointServiceOverrides() + + // update TLS settings with cert secret + instance.Spec.Keystone.Template.TLS.API.Public.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointPublic) + instance.Spec.Keystone.Template.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal) } - helper.GetLogger().Info("Reconciling KeystoneAPI", "KeystoneAPI.Namespace", instance.Namespace, "KeystoneAPI.Name", "keystone") Log.Info("Reconciling KeystoneAPI", "KeystoneAPI.Namespace", instance.Namespace, "KeystoneAPI.Name", "keystone") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), keystoneAPI, func() error { instance.Spec.Keystone.Template.DeepCopyInto(&keystoneAPI.Spec) @@ -102,6 +115,7 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo //keystoneAPI.Spec.DatabaseInstance = instance.Name // name of MariaDB we create here keystoneAPI.Spec.DatabaseInstance = "openstack" //FIXME: see above } + err := controllerutil.SetControllerReference(helper.GetBeforeObject(), keystoneAPI, helper.GetScheme()) if err != nil { return err diff --git a/pkg/openstack/manila.go b/pkg/openstack/manila.go index d32af249c..810e52b98 100644 --- a/pkg/openstack/manila.go +++ b/pkg/openstack/manila.go @@ -58,6 +58,7 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl } // When component services got created check if there is the need to create a route + var endpointDetails = Endpoints{} if manila.Status.Conditions.IsTrue(manilav1.ManilaAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -70,7 +71,7 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl } var ctrlResult reconcile.Result - instance.Spec.Manila.Template.ManilaAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -79,12 +80,15 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl instance.Spec.Manila.Template.ManilaAPI.Override.Service, instance.Spec.Manila.APIOverride, corev1beta1.OpenStackControlPlaneExposeManilaReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Manila.Template.ManilaAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() } Log.Info("Reconciling Manila", "Manila.Namespace", instance.Namespace, "Manila.Name", "manila") diff --git a/pkg/openstack/neutron.go b/pkg/openstack/neutron.go index 87f3332a9..8605b26b0 100644 --- a/pkg/openstack/neutron.go +++ b/pkg/openstack/neutron.go @@ -57,6 +57,13 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro } } + // preserve any previously set TLS certs,set CA cert + if instance.Spec.TLS.Enabled(service.EndpointInternal) { + instance.Spec.Neutron.Template.TLS = neutronAPI.Spec.TLS + } + instance.Spec.Neutron.Template.TLS.CaBundleSecretName = instance.Status.TLS.CaBundleSecretName + + var endpointDetails = Endpoints{} if neutronAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -69,7 +76,7 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro } var ctrlResult reconcile.Result - instance.Spec.Neutron.Template.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -78,12 +85,19 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Neutron.Template.Override.Service, instance.Spec.Neutron.APIOverride, corev1beta1.OpenStackControlPlaneExposeNeutronReadyCondition, + false, // TODO (mschuppert) could be removed when all integrated service support TLS ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Neutron.Template.Override.Service = endpointDetails.GetEndpointServiceOverrides() + + // update TLS settings with cert secret + instance.Spec.Neutron.Template.TLS.API.Public.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointPublic) + instance.Spec.Neutron.Template.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal) } Log.Info("Reconciling NeutronAPI", "NeutronAPI.Namespace", instance.Namespace, "NeutronAPI.Name", "neutron") diff --git a/pkg/openstack/nova.go b/pkg/openstack/nova.go index f12194118..79704135e 100644 --- a/pkg/openstack/nova.go +++ b/pkg/openstack/nova.go @@ -94,6 +94,7 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl } // Nova API + var apiServiceEndpointDetails = Endpoints{} if nova.Status.Conditions.IsTrue(novav1.NovaAPIReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -106,7 +107,7 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl } var ctrlResult reconcile.Result - instance.Spec.Nova.Template.APIServiceTemplate.Override.Service, ctrlResult, err = EnsureEndpointConfig( + apiServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -115,12 +116,15 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl instance.Spec.Nova.Template.APIServiceTemplate.Override.Service, instance.Spec.Nova.APIOverride, corev1beta1.OpenStackControlPlaneExposeNovaReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Nova.Template.APIServiceTemplate.Override.Service = apiServiceEndpointDetails.GetEndpointServiceOverrides() } if nova.Status.Conditions.IsTrue(novav1.NovaAllCellsReadyCondition) { @@ -148,7 +152,8 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl } var ctrlResult reconcile.Result - routedOverrideSpec, ctrlResult, err := EnsureEndpointConfig( + var cellServiceEndpointDetails = Endpoints{} + cellServiceEndpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -159,6 +164,7 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl }, instance.Spec.Nova.CellOverride[cellName].NoVNCProxy, corev1beta1.OpenStackControlPlaneExposeNovaReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err @@ -166,6 +172,7 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl return ctrlResult, nil } + routedOverrideSpec := cellServiceEndpointDetails.GetEndpointServiceOverrides() cellTemplate.NoVNCProxyServiceTemplate.Override.Service = ptr.To(routedOverrideSpec[service.EndpointPublic]) instance.Spec.Nova.Template.CellTemplates[cellName] = cellTemplate diff --git a/pkg/openstack/octavia.go b/pkg/openstack/octavia.go index cb534fa8c..2843fa5da 100644 --- a/pkg/openstack/octavia.go +++ b/pkg/openstack/octavia.go @@ -72,6 +72,7 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro } } + var endpointDetails = Endpoints{} if octavia.Status.Conditions.IsTrue(condition.ReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -84,7 +85,7 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro } var ctrlResult reconcile.Result - instance.Spec.Octavia.Template.OctaviaAPI.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -93,12 +94,15 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro instance.Spec.Octavia.Template.OctaviaAPI.Override.Service, instance.Spec.Octavia.APIOverride, corev1beta1.OpenStackControlPlaneExposeOctaviaReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Octavia.Template.OctaviaAPI.Override.Service = endpointDetails.GetEndpointServiceOverrides() } helper.GetLogger().Info("Reconciling Octavia", "Octavia.Namespace", instance.Namespace, "Octavia.Name", octavia.Name) diff --git a/pkg/openstack/openstackclient.go b/pkg/openstack/openstackclient.go index c2cfe361a..4d8dcb47e 100644 --- a/pkg/openstack/openstackclient.go +++ b/pkg/openstack/openstackclient.go @@ -18,6 +18,7 @@ import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" clientv1 "github.com/openstack-k8s-operators/openstack-operator/apis/client/v1beta1" corev1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -48,7 +49,7 @@ func ReconcileOpenStackClient(ctx context.Context, instance *corev1.OpenStackCon for _, config := range instance.Spec.TLS.Endpoint { if config.Enabled { - openstackclient.Spec.Ca.CaBundleSecretName = CombinedCASecret + openstackclient.Spec.Ca.CaBundleSecretName = tls.CABundleSecret break } } diff --git a/pkg/openstack/placement.go b/pkg/openstack/placement.go index 3f8590c49..5586b5fc2 100644 --- a/pkg/openstack/placement.go +++ b/pkg/openstack/placement.go @@ -56,6 +56,7 @@ func ReconcilePlacementAPI(ctx context.Context, instance *corev1beta1.OpenStackC } } + var endpointDetails = Endpoints{} if placementAPI.Status.Conditions.IsTrue(condition.ExposeServiceReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -68,7 +69,7 @@ func ReconcilePlacementAPI(ctx context.Context, instance *corev1beta1.OpenStackC } var ctrlResult reconcile.Result - instance.Spec.Placement.Template.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -77,12 +78,15 @@ func ReconcilePlacementAPI(ctx context.Context, instance *corev1beta1.OpenStackC instance.Spec.Placement.Template.Override.Service, instance.Spec.Placement.APIOverride, corev1beta1.OpenStackControlPlaneExposePlacementAPIReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Placement.Template.Override.Service = endpointDetails.GetEndpointServiceOverrides() } Log.Info("Reconciling PlacementAPI", "PlacementAPI.Namespace", instance.Namespace, "PlacementAPI.Name", "placement") diff --git a/pkg/openstack/swift.go b/pkg/openstack/swift.go index a12441262..1bfce7d42 100644 --- a/pkg/openstack/swift.go +++ b/pkg/openstack/swift.go @@ -58,6 +58,7 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP } } + var endpointDetails = Endpoints{} if swift.Status.Conditions.IsTrue(swiftv1.SwiftProxyReadyCondition) { svcs, err := service.GetServicesListWithLabel( ctx, @@ -70,7 +71,7 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP } var ctrlResult reconcile.Result - instance.Spec.Swift.Template.SwiftProxy.Override.Service, ctrlResult, err = EnsureEndpointConfig( + endpointDetails, ctrlResult, err = EnsureEndpointConfig( ctx, instance, helper, @@ -79,12 +80,15 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP instance.Spec.Swift.Template.SwiftProxy.Override.Service, instance.Spec.Swift.ProxyOverride, corev1beta1.OpenStackControlPlaneExposeSwiftReadyCondition, + true, // TODO: (mschuppert) disable TLS for now until implemented ) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + + instance.Spec.Swift.Template.SwiftProxy.Override.Service = endpointDetails.GetEndpointServiceOverrides() } helper.GetLogger().Info("Reconciling Swift", "Swift.Namespace", instance.Namespace, "Swift.Name", "swift") diff --git a/pkg/openstackclient/funcs.go b/pkg/openstackclient/funcs.go index 6d019b87d..1744561f5 100644 --- a/pkg/openstackclient/funcs.go +++ b/pkg/openstackclient/funcs.go @@ -98,7 +98,6 @@ func clientPodVolumes( instance *clientv1.OpenStackClient, ) []corev1.Volume { return []corev1.Volume{ - { Name: "openstack-config", VolumeSource: corev1.VolumeSource{ diff --git a/tests/functional/openstackoperator_controller_test.go b/tests/functional/openstackoperator_controller_test.go index f2ae37c94..90164c4c2 100644 --- a/tests/functional/openstackoperator_controller_test.go +++ b/tests/functional/openstackoperator_controller_test.go @@ -27,6 +27,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/service" . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" clientv1 "github.com/openstack-k8s-operators/openstack-operator/apis/client/v1beta1" ) @@ -122,14 +123,16 @@ var _ = Describe("OpenStackOperator controller", func() { }, timeout, interval).Should(Succeed()) }) - It("should create ca bundle", func() { + It("should create full ca bundle", func() { crtmgr.GetCert(names.RootCAPublicName) crtmgr.GetIssuer(names.RootCAPublicName) Eventually(func(g Gomega) { th.GetSecret(names.RootCAPublicName) caBundle := th.GetSecret(names.CABundleName) - g.Expect(caBundle.Data).Should(HaveLen(int(1))) + g.Expect(caBundle.Data).Should(HaveLen(int(2))) + g.Expect(caBundle.Data).Should(HaveKey(tls.CABundleKey)) + g.Expect(caBundle.Data).Should(HaveKey(tls.InternalCABundleKey)) }, timeout, interval).Should(Succeed()) })