From 807cf1bd9343c4770a440dbc44236b1be000c21a Mon Sep 17 00:00:00 2001 From: Axel Christ Date: Tue, 28 Mar 2023 14:48:02 +0200 Subject: [PATCH] Enhance machinepoollet address / service --- .../default/kustomization.yaml | 36 +++++--- .../manager/kustomization.yaml | 3 +- .../manager/manager.yaml | 10 ++- .../manager/service.yaml | 12 +++ poollet/machinepoollet/addresses/addresses.go | 32 ++++--- .../addresses/addresses_suite_test.go | 27 ++++++ .../addresses/addresses_test.go | 84 +++++++++++++++++++ .../addresses/testdata/addresses.yaml | 5 ++ 8 files changed, 184 insertions(+), 25 deletions(-) create mode 100644 config/machinepoollet-broker/manager/service.yaml create mode 100644 poollet/machinepoollet/addresses/addresses_suite_test.go create mode 100644 poollet/machinepoollet/addresses/addresses_test.go create mode 100644 poollet/machinepoollet/addresses/testdata/addresses.yaml diff --git a/config/machinepoollet-broker/default/kustomization.yaml b/config/machinepoollet-broker/default/kustomization.yaml index 0684259b1..2358df4fd 100644 --- a/config/machinepoollet-broker/default/kustomization.yaml +++ b/config/machinepoollet-broker/default/kustomization.yaml @@ -13,22 +13,38 @@ namePrefix: machinepoollet- # someName: someValue resources: - - ../broker-rbac - - ../manager +- ../broker-rbac +- ../manager # - ../webhook # - ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus patchesStrategicMerge: - - manager_auth_proxy_patch.yaml - - # Mount the controller config file for loading manager configurations - # through a ComponentConfig type - #- manager_config_patch.yaml - - #- manager_webhook_patch.yaml - #- webhookcainjection_patch.yaml +- manager_auth_proxy_patch.yaml + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_patch.yaml + +#- manager_webhook_patch.yaml +#- webhookcainjection_patch.yaml + +replacements: +- source: + kind: Service + group: "" + version: v1 + name: server + fieldPath: metadata.name + targets: + - select: + kind: Deployment + group: apps + version: v1 + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=KUBERNETES_SERVICE_NAME].value #replacements: # - source: diff --git a/config/machinepoollet-broker/manager/kustomization.yaml b/config/machinepoollet-broker/manager/kustomization.yaml index f62d9bd1c..4c8520751 100644 --- a/config/machinepoollet-broker/manager/kustomization.yaml +++ b/config/machinepoollet-broker/manager/kustomization.yaml @@ -1,5 +1,6 @@ resources: - - manager.yaml +- manager.yaml +- service.yaml generatorOptions: disableNameSuffixHash: true diff --git a/config/machinepoollet-broker/manager/manager.yaml b/config/machinepoollet-broker/manager/manager.yaml index 844cc64bd..93d2f385d 100644 --- a/config/machinepoollet-broker/manager/manager.yaml +++ b/config/machinepoollet-broker/manager/manager.yaml @@ -33,10 +33,12 @@ spec: - --leader-elect image: machinepoollet:latest env: - - name: KUBERNETES_POD_IP + - name: KUBERNETES_SERVICE_NAME + value: server + - name: KUBERNETES_POD_NAMESPACE valueFrom: fieldRef: - fieldPath: status.podIP + fieldPath: metadata.namespace name: manager securityContext: allowPrivilegeEscalation: false @@ -62,6 +64,10 @@ spec: volumeMounts: - name: var-run mountPath: /var/run + ports: + - containerPort: 20250 + name: server + protocol: TCP - command: - /machinebroker image: machinebroker:latest diff --git a/config/machinepoollet-broker/manager/service.yaml b/config/machinepoollet-broker/manager/service.yaml new file mode 100644 index 000000000..c1f3f2198 --- /dev/null +++ b/config/machinepoollet-broker/manager/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: server +spec: + type: ClusterIP + selector: + control-plane: controller-manager + ports: + - name: server + port: 20250 + targetPort: server diff --git a/poollet/machinepoollet/addresses/addresses.go b/poollet/machinepoollet/addresses/addresses.go index 73232677f..36200db62 100644 --- a/poollet/machinepoollet/addresses/addresses.go +++ b/poollet/machinepoollet/addresses/addresses.go @@ -16,7 +16,6 @@ package addresses import ( "bytes" - "errors" "fmt" "net" "os" @@ -28,11 +27,18 @@ import ( ) const ( - KubernetesPodIPEnvVar = "KUBERNETES_POD_IP" + KubernetesServiceName = "KUBERNETES_SERVICE_NAME" + KubernetesPodNamespaceEnvVar = "KUBERNETES_POD_NAMESPACE" + KubernetesClusterDomainEnvVar = "KUBERNETES_CLUSTER_DOMAIN" +) + +const ( + DefaultKubernetesClusterDomain = "cluster.local" ) var ( - ErrNotInCluster = errors.New("unable to load in-cluster addresses, KUBERNETES_POD_IP must be defined") + ErrNotInCluster = fmt.Errorf("unable to load in-cluster addresses, %s and %s must be defined", + KubernetesServiceName, KubernetesPodNamespaceEnvVar) ) type GetOptions struct { @@ -115,7 +121,7 @@ func LocalIP() (string, error) { } func IsInCluster() bool { - podIP := os.Getenv(KubernetesPodIPEnvVar) + podIP := os.Getenv(KubernetesServiceName) return podIP != "" } @@ -168,26 +174,28 @@ func Get(opts ...GetOption) ([]computev1alpha1.MachinePoolAddress, error) { } func InCluster() ([]computev1alpha1.MachinePoolAddress, error) { - podIP := os.Getenv(KubernetesPodIPEnvVar) - if podIP == "" { + serviceName := os.Getenv(KubernetesServiceName) + namespace := os.Getenv(KubernetesPodNamespaceEnvVar) + clusterDomain := os.Getenv(KubernetesClusterDomainEnvVar) + + if serviceName == "" || namespace == "" { return nil, ErrNotInCluster } - hostname, err := os.Hostname() - if err != nil { - return nil, fmt.Errorf("error getting hostname: %w", err) + if clusterDomain == "" { + clusterDomain = DefaultKubernetesClusterDomain } - hostname = strings.TrimSpace(hostname) + internalDNS := fmt.Sprintf("%s.%s.svc.%s", serviceName, namespace, clusterDomain) return []computev1alpha1.MachinePoolAddress{ { Type: computev1alpha1.MachinePoolInternalIP, - Address: podIP, + Address: serviceName, }, { Type: computev1alpha1.MachinePoolInternalDNS, - Address: hostname, + Address: internalDNS, }, }, nil } diff --git a/poollet/machinepoollet/addresses/addresses_suite_test.go b/poollet/machinepoollet/addresses/addresses_suite_test.go new file mode 100644 index 000000000..3d61e4d90 --- /dev/null +++ b/poollet/machinepoollet/addresses/addresses_suite_test.go @@ -0,0 +1,27 @@ +// Copyright 2023 OnMetal authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package addresses_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestAddresses(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Addresses Suite") +} diff --git a/poollet/machinepoollet/addresses/addresses_test.go b/poollet/machinepoollet/addresses/addresses_test.go new file mode 100644 index 000000000..7beca04a3 --- /dev/null +++ b/poollet/machinepoollet/addresses/addresses_test.go @@ -0,0 +1,84 @@ +// Copyright 2023 OnMetal authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package addresses_test + +import ( + "os" + + computev1alpha1 "github.com/onmetal/onmetal-api/api/compute/v1alpha1" + . "github.com/onmetal/onmetal-api/poollet/machinepoollet/addresses" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Addresses", func() { + Describe("Get", func() { + BeforeEach(func() { + envVars := []string{ + KubernetesServiceName, + KubernetesPodNamespaceEnvVar, + KubernetesClusterDomainEnvVar, + } + + By("registering cleanup for all relevant env vars") + for _, envVar := range envVars { + DeferCleanup(os.Setenv, envVar, os.Getenv(envVar)) + } + + By("unsetting all relevant env vars") + for _, envVar := range envVars { + Expect(os.Unsetenv(envVar)).To(Succeed()) + } + }) + + It("should return the addresses from the specified file if specified", func() { + addresses, err := Get(&GetOptions{Filename: "./testdata/addresses.yaml"}) + Expect(err).NotTo(HaveOccurred()) + + Expect(addresses).To(Equal([]computev1alpha1.MachinePoolAddress{ + { + Type: computev1alpha1.MachinePoolHostName, + Address: "foo.bar", + }, + { + Type: computev1alpha1.MachinePoolInternalIP, + Address: "10.0.0.1", + }, + })) + }) + + It("should return an error if nothing is specified and the in-cluster env vars are not present", func() { + Expect(os.Setenv(KubernetesServiceName, "10.0.0.1")).To(Succeed()) + _, err := Get() + Expect(err).To(MatchError(ErrNotInCluster)) + }) + + It("should return the values extracted from the in-cluster env vars", func() { + Expect(os.Setenv(KubernetesServiceName, "10.0.0.1")).To(Succeed()) + Expect(os.Setenv(KubernetesPodNamespaceEnvVar, "foo")).To(Succeed()) + + Expect(Get()).To(ConsistOf( + computev1alpha1.MachinePoolAddress{ + Type: computev1alpha1.MachinePoolInternalDNS, + Address: "10.0.0.1.foo.svc.cluster.local", + }, + computev1alpha1.MachinePoolAddress{ + Type: computev1alpha1.MachinePoolInternalIP, + Address: "10.0.0.1", + }, + )) + }) + }) +}) diff --git a/poollet/machinepoollet/addresses/testdata/addresses.yaml b/poollet/machinepoollet/addresses/testdata/addresses.yaml new file mode 100644 index 000000000..e4225d44e --- /dev/null +++ b/poollet/machinepoollet/addresses/testdata/addresses.yaml @@ -0,0 +1,5 @@ +addresses: +- type: Hostname + address: foo.bar +- type: InternalIP + address: 10.0.0.1