mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 23:49:37 -05:00
Deploy Konnectivity
This commit is contained in:
parent
15592e8f3f
commit
7163c161b6
@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- GCP: Support for higher end N2D standard (128 & 224 vCPUs), *high-mem* and *high-cpu* VMs
|
- GCP: Support for higher end N2D standard (128 & 224 vCPUs), *high-mem* and *high-cpu* VMs
|
||||||
- Add `constellation upgrade` to update node images in Constellation.
|
- Add `constellation upgrade` to update node images in Constellation.
|
||||||
- Add cilium v1.12.1 with strict mode v2
|
- Add cilium v1.12.1 with strict mode v2
|
||||||
|
- Konnectivity is now deployed for secure API server to node/pod/service communication.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
<!-- For changes in existing functionality. -->
|
<!-- For changes in existing functionality. -->
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -34,10 +33,8 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/cloud/vmtype"
|
"github.com/edgelesssys/constellation/internal/cloud/vmtype"
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"github.com/edgelesssys/constellation/internal/iproute"
|
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"github.com/edgelesssys/constellation/internal/oid"
|
||||||
"github.com/edgelesssys/constellation/internal/role"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
@ -107,9 +104,6 @@ func main() {
|
|||||||
)
|
)
|
||||||
openTPM = vtpm.OpenVTPM
|
openTPM = vtpm.OpenVTPM
|
||||||
fs = afero.NewOsFs()
|
fs = afero.NewOsFs()
|
||||||
if err := setLoadbalancerRoute(ctx, metadata); err != nil {
|
|
||||||
log.With(zap.Error(err)).Fatalf("Failed to set loadbalancer route")
|
|
||||||
}
|
|
||||||
log.Infof("Added load balancer IP to routing table")
|
log.Infof("Added load balancer IP to routing table")
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
pcrs, err := vtpm.GetSelectedPCRs(vtpm.OpenVTPM, vtpm.AzurePCRSelection)
|
pcrs, err := vtpm.GetSelectedPCRs(vtpm.OpenVTPM, vtpm.AzurePCRSelection)
|
||||||
@ -181,22 +175,3 @@ func main() {
|
|||||||
|
|
||||||
run(issuer, openTPM, fileHandler, clusterInitJoiner, metadataAPI, bindIP, bindPort, log, cloudLogger)
|
run(issuer, openTPM, fileHandler, clusterInitJoiner, metadataAPI, bindIP, bindPort, log, cloudLogger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLoadbalancerRoute(ctx context.Context, meta metadataAPI) error {
|
|
||||||
self, err := meta.Self(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if self.Role != role.ControlPlane {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
endpoint, err := meta.GetLoadBalancerEndpoint(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ip, _, err := net.SplitHostPort(endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return iproute.AddToLocalRoutingTable(ctx, ip)
|
|
||||||
}
|
|
||||||
|
37
bootstrapper/internal/certificate/certificate.go
Normal file
37
bootstrapper/internal/certificate/certificate.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package certificate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetCertificateRequest returns a certificate request and matching private key.
|
||||||
|
func GetCertificateRequest(csrTemplate *x509.CertificateRequest) (certificateRequest []byte, privateKey []byte, err error) {
|
||||||
|
privK, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
keyBytes, err := x509.MarshalECPrivateKey(privK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
keyPem := pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
Bytes: keyBytes,
|
||||||
|
})
|
||||||
|
certificateRequest, err = x509.CreateCertificateRequest(rand.Reader, csrTemplate, privK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificateRequest, keyPem, nil
|
||||||
|
}
|
@ -7,14 +7,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package kubelet
|
package kubelet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/pem"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/bootstrapper/internal/certificate"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,18 +24,6 @@ const (
|
|||||||
|
|
||||||
// GetCertificateRequest returns a certificate request and macthing private key for the kubelet.
|
// GetCertificateRequest returns a certificate request and macthing private key for the kubelet.
|
||||||
func GetCertificateRequest(nodeName string, ips []net.IP) (certificateRequest []byte, privateKey []byte, err error) {
|
func GetCertificateRequest(nodeName string, ips []net.IP) (certificateRequest []byte, privateKey []byte, err error) {
|
||||||
privK, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
keyBytes, err := x509.MarshalECPrivateKey(privK)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
kubeletKey := pem.EncodeToMemory(&pem.Block{
|
|
||||||
Type: "EC PRIVATE KEY",
|
|
||||||
Bytes: keyBytes,
|
|
||||||
})
|
|
||||||
csrTemplate := &x509.CertificateRequest{
|
csrTemplate := &x509.CertificateRequest{
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
Organization: []string{constants.NodesGroup},
|
Organization: []string{constants.NodesGroup},
|
||||||
@ -46,10 +31,5 @@ func GetCertificateRequest(nodeName string, ips []net.IP) (certificateRequest []
|
|||||||
},
|
},
|
||||||
IPAddresses: ips,
|
IPAddresses: ips,
|
||||||
}
|
}
|
||||||
certificateRequest, err = x509.CreateCertificateRequest(rand.Reader, csrTemplate, privK)
|
return certificate.GetCertificateRequest(csrTemplate)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return certificateRequest, kubeletKey, nil
|
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ func (c *CoreOSConfiguration) InitConfiguration(externalCloudProvider bool, k8sV
|
|||||||
"audit-log-maxbackup": "10", // CIS benchmark - Default value of Rancher
|
"audit-log-maxbackup": "10", // CIS benchmark - Default value of Rancher
|
||||||
"audit-log-maxsize": "100", // CIS benchmark - Default value of Rancher
|
"audit-log-maxsize": "100", // CIS benchmark - Default value of Rancher
|
||||||
"profiling": "false", // CIS benchmark
|
"profiling": "false", // CIS benchmark
|
||||||
|
"egress-selector-config-file": "/etc/kubernetes/egress-selector-configuration.yaml",
|
||||||
"kubelet-certificate-authority": filepath.Join(
|
"kubelet-certificate-authority": filepath.Join(
|
||||||
kubeconstants.KubernetesDir,
|
kubeconstants.KubernetesDir,
|
||||||
kubeconstants.DefaultCertificateDir,
|
kubeconstants.DefaultCertificateDir,
|
||||||
@ -101,6 +102,20 @@ func (c *CoreOSConfiguration) InitConfiguration(externalCloudProvider bool, k8sV
|
|||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
PathType: corev1.HostPathFile,
|
PathType: corev1.HostPathFile,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "egress-config",
|
||||||
|
HostPath: "/etc/kubernetes/egress-selector-configuration.yaml",
|
||||||
|
MountPath: "/etc/kubernetes/egress-selector-configuration.yaml",
|
||||||
|
ReadOnly: true,
|
||||||
|
PathType: corev1.HostPathFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "konnectivity-uds",
|
||||||
|
HostPath: "/etc/kubernetes/konnectivity-server",
|
||||||
|
MountPath: "/etc/kubernetes/konnectivity-server",
|
||||||
|
ReadOnly: false,
|
||||||
|
PathType: corev1.HostPathDirectoryOrCreate,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CertSANs: []string{"127.0.0.1"},
|
CertSANs: []string{"127.0.0.1"},
|
||||||
@ -133,6 +148,7 @@ func (c *CoreOSConfiguration) InitConfiguration(externalCloudProvider bool, k8sV
|
|||||||
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
"TLS_RSA_WITH_AES_128_GCM_SHA256",
|
"TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
}, // CIS benchmark
|
}, // CIS benchmark
|
||||||
|
StaticPodPath: "/etc/kubernetes/manifests",
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
APIVersion: kubeletconf.SchemeGroupVersion.String(),
|
APIVersion: kubeletconf.SchemeGroupVersion.String(),
|
||||||
Kind: "KubeletConfiguration",
|
Kind: "KubeletConfiguration",
|
||||||
|
@ -0,0 +1,380 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resources
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/bootstrapper/internal/certificate"
|
||||||
|
"github.com/edgelesssys/constellation/internal/kubernetes"
|
||||||
|
"github.com/edgelesssys/constellation/internal/versions"
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/apiserver/pkg/apis/apiserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KonnectivityCertificateFilename is the path to the kubelets certificate.
|
||||||
|
KonnectivityCertificateFilename = "/etc/kubernetes/konnectivity.crt"
|
||||||
|
// KonnectivityKeyFilename is the path to the kubelets private key.
|
||||||
|
KonnectivityKeyFilename = "/etc/kubernetes/konnectivity.key"
|
||||||
|
)
|
||||||
|
|
||||||
|
type konnectivityAgents struct {
|
||||||
|
DaemonSet appsv1.DaemonSet
|
||||||
|
ClusterRoleBinding rbacv1.ClusterRoleBinding
|
||||||
|
ServiceAccount corev1.ServiceAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
type konnectivityServerStaticPod struct {
|
||||||
|
StaticPod corev1.Pod
|
||||||
|
}
|
||||||
|
|
||||||
|
type egressSelectorConfiguration struct {
|
||||||
|
EgressSelectorConfiguration apiserver.EgressSelectorConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKonnectivityAgents(konnectivityServerAddress string) *konnectivityAgents {
|
||||||
|
return &konnectivityAgents{
|
||||||
|
DaemonSet: appsv1.DaemonSet{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "DaemonSet",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "konnectivity-agent",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"k8s-app": "konnectivity-agent",
|
||||||
|
"addonmanager.kubernetes.io/mode": "Reconcile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: appsv1.DaemonSetSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"k8s-app": "konnectivity-agent",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"k8s-app": "konnectivity-agent",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
PriorityClassName: "system-cluster-critical",
|
||||||
|
Tolerations: []corev1.Toleration{
|
||||||
|
{
|
||||||
|
Key: "node-role.kubernetes.io/master",
|
||||||
|
Operator: corev1.TolerationOpExists,
|
||||||
|
Effect: corev1.TaintEffectNoSchedule,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "node-role.kubernetes.io/control-plane",
|
||||||
|
Operator: corev1.TolerationOpExists,
|
||||||
|
Effect: corev1.TaintEffectNoSchedule,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "CriticalAddonsOnly",
|
||||||
|
Operator: corev1.TolerationOpExists,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "node.kubernetes.io/not-ready",
|
||||||
|
Operator: corev1.TolerationOpExists,
|
||||||
|
Effect: corev1.TaintEffectNoExecute,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Name: "konnectivity-agent",
|
||||||
|
Image: versions.KonnectivityAgentImage,
|
||||||
|
Command: []string{
|
||||||
|
"/proxy-agent",
|
||||||
|
},
|
||||||
|
Args: []string{
|
||||||
|
"--logtostderr=true",
|
||||||
|
"--proxy-server-host=" + konnectivityServerAddress,
|
||||||
|
"--ca-cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt",
|
||||||
|
"--proxy-server-port=8132",
|
||||||
|
"--admin-server-port=8133",
|
||||||
|
"--health-server-port=8134",
|
||||||
|
"--service-account-token-path=/var/run/secrets/tokens/konnectivity-agent-token",
|
||||||
|
"--agent-identifiers=host=$(HOST_IP)",
|
||||||
|
// we will be able to avoid constant polling when either one is done:
|
||||||
|
// https://github.com/kubernetes-sigs/apiserver-network-proxy/issues/358
|
||||||
|
// https://github.com/kubernetes-sigs/apiserver-network-proxy/issues/273
|
||||||
|
"--sync-forever=true",
|
||||||
|
// Ensure stable connection to the konnectivity server.
|
||||||
|
"--keepalive-time=60s",
|
||||||
|
"--sync-interval=1s",
|
||||||
|
"--sync-interval-cap=3s",
|
||||||
|
"--probe-interval=1s",
|
||||||
|
"--v=3",
|
||||||
|
},
|
||||||
|
Env: []corev1.EnvVar{
|
||||||
|
{
|
||||||
|
Name: "HOST_IP",
|
||||||
|
ValueFrom: &corev1.EnvVarSource{
|
||||||
|
FieldRef: &corev1.ObjectFieldSelector{
|
||||||
|
APIVersion: "v1",
|
||||||
|
FieldPath: "status.hostIP",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VolumeMounts: []corev1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "konnectivity-agent-token",
|
||||||
|
MountPath: "/var/run/secrets/tokens",
|
||||||
|
ReadOnly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
LivenessProbe: &corev1.Probe{
|
||||||
|
ProbeHandler: corev1.ProbeHandler{
|
||||||
|
HTTPGet: &corev1.HTTPGetAction{
|
||||||
|
Path: "/healthz",
|
||||||
|
Port: intstr.FromInt(8134),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InitialDelaySeconds: 15,
|
||||||
|
TimeoutSeconds: 15,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ServiceAccountName: "konnectivity-agent",
|
||||||
|
Volumes: []corev1.Volume{
|
||||||
|
{
|
||||||
|
Name: "konnectivity-agent-token",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
Projected: &corev1.ProjectedVolumeSource{
|
||||||
|
Sources: []corev1.VolumeProjection{
|
||||||
|
{
|
||||||
|
ServiceAccountToken: &corev1.ServiceAccountTokenProjection{
|
||||||
|
Audience: "system:konnectivity-server",
|
||||||
|
Path: "konnectivity-agent-token",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ClusterRoleBinding: rbacv1.ClusterRoleBinding{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||||
|
Kind: "ClusterRoleBinding",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "system:konnectivity-server",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"kubernetes.io/cluster-service": "true",
|
||||||
|
"addonmanager.kubernetes.io/mode": "Reconcile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RoleRef: rbacv1.RoleRef{
|
||||||
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
|
Kind: "ClusterRole",
|
||||||
|
Name: "system:auth-delegator",
|
||||||
|
},
|
||||||
|
Subjects: []rbacv1.Subject{
|
||||||
|
{
|
||||||
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
|
Kind: "User",
|
||||||
|
Name: "system:konnectivity-server",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ServiceAccount: corev1.ServiceAccount{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "ServiceAccount",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "konnectivity-agent",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"kubernetes.io/cluster-service": "true",
|
||||||
|
"addonmanager.kubernetes.io/mode": "Reconcile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKonnectivityServerStaticPod() *konnectivityServerStaticPod {
|
||||||
|
udsHostPathType := corev1.HostPathDirectoryOrCreate
|
||||||
|
return &konnectivityServerStaticPod{
|
||||||
|
StaticPod: corev1.Pod{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "Pod",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "konnectivity-server",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
PriorityClassName: "system-cluster-critical",
|
||||||
|
HostNetwork: true,
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Name: "konnectivity-server-container",
|
||||||
|
Image: versions.KonnectivityServerImage,
|
||||||
|
Command: []string{"/proxy-server"},
|
||||||
|
Args: []string{
|
||||||
|
"--logtostderr=true",
|
||||||
|
// This needs to be consistent with the value set in egressSelectorConfiguration.
|
||||||
|
"--uds-name=/etc/kubernetes/konnectivity-server/konnectivity-server.socket",
|
||||||
|
// The following two lines assume the Konnectivity server is
|
||||||
|
// deployed on the same machine as the apiserver, and the certs and
|
||||||
|
// key of the API Server are at the specified location.
|
||||||
|
"--cluster-cert=/etc/kubernetes/pki/apiserver.crt",
|
||||||
|
"--cluster-key=/etc/kubernetes/pki/apiserver.key",
|
||||||
|
// This needs to be consistent with the value set in egressSelectorConfiguration.
|
||||||
|
"--mode=grpc",
|
||||||
|
"--server-port=0",
|
||||||
|
"--agent-port=8132",
|
||||||
|
"--admin-port=8133",
|
||||||
|
"--health-port=8134",
|
||||||
|
"--v=5",
|
||||||
|
"--agent-namespace=kube-system",
|
||||||
|
"--agent-service-account=konnectivity-agent",
|
||||||
|
"--kubeconfig=/etc/kubernetes/konnectivity-server.conf",
|
||||||
|
"--authentication-audience=system:konnectivity-server",
|
||||||
|
"--proxy-strategies=destHost",
|
||||||
|
},
|
||||||
|
LivenessProbe: &corev1.Probe{
|
||||||
|
ProbeHandler: corev1.ProbeHandler{
|
||||||
|
HTTPGet: &corev1.HTTPGetAction{
|
||||||
|
Path: "/healthz",
|
||||||
|
Port: intstr.FromInt(8134),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InitialDelaySeconds: 30,
|
||||||
|
TimeoutSeconds: 60,
|
||||||
|
},
|
||||||
|
Ports: []corev1.ContainerPort{
|
||||||
|
{
|
||||||
|
Name: "agent-port",
|
||||||
|
ContainerPort: 8132,
|
||||||
|
HostPort: 8132,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "admin-port",
|
||||||
|
ContainerPort: 8133,
|
||||||
|
HostPort: 8133,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "health-port",
|
||||||
|
ContainerPort: 8134,
|
||||||
|
HostPort: 8134,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VolumeMounts: []corev1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "k8s-certs",
|
||||||
|
MountPath: "/etc/kubernetes/pki",
|
||||||
|
ReadOnly: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
MountPath: "/etc/kubernetes/konnectivity-server.conf",
|
||||||
|
ReadOnly: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "konnectivity-uds",
|
||||||
|
MountPath: "/etc/kubernetes/konnectivity-server",
|
||||||
|
ReadOnly: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Volumes: []corev1.Volume{
|
||||||
|
{
|
||||||
|
Name: "k8s-certs",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
HostPath: &corev1.HostPathVolumeSource{
|
||||||
|
Path: "/etc/kubernetes/pki",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
HostPath: &corev1.HostPathVolumeSource{
|
||||||
|
Path: "/etc/kubernetes/konnectivity-server.conf",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "konnectivity-uds",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
HostPath: &corev1.HostPathVolumeSource{
|
||||||
|
Path: "/etc/kubernetes/konnectivity-server",
|
||||||
|
Type: &udsHostPathType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEgressSelectorConfiguration() *egressSelectorConfiguration {
|
||||||
|
return &egressSelectorConfiguration{
|
||||||
|
EgressSelectorConfiguration: apiserver.EgressSelectorConfiguration{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "apiserver.k8s.io/v1beta1",
|
||||||
|
Kind: "EgressSelectorConfiguration",
|
||||||
|
},
|
||||||
|
EgressSelections: []apiserver.EgressSelection{
|
||||||
|
{
|
||||||
|
Name: "cluster",
|
||||||
|
Connection: apiserver.Connection{
|
||||||
|
ProxyProtocol: "GRPC",
|
||||||
|
Transport: &apiserver.Transport{
|
||||||
|
UDS: &apiserver.UDSTransport{
|
||||||
|
UDSName: "/etc/kubernetes/konnectivity-server/konnectivity-server.socket",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *konnectivityAgents) Marshal() ([]byte, error) {
|
||||||
|
return kubernetes.MarshalK8SResources(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *konnectivityServerStaticPod) Marshal() ([]byte, error) {
|
||||||
|
return kubernetes.MarshalK8SResources(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *egressSelectorConfiguration) Marshal() ([]byte, error) {
|
||||||
|
return kubernetes.MarshalK8SResources(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCertificateRequest returns a certificate request and matching private key for the konnectivity server.
|
||||||
|
func GetKonnectivityCertificateRequest() (certificateRequest []byte, privateKey []byte, err error) {
|
||||||
|
csrTemplate := &x509.CertificateRequest{
|
||||||
|
Subject: pkix.Name{
|
||||||
|
CommonName: "system:konnectivity-server",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return certificate.GetCertificateRequest(csrTemplate)
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Edgeless Systems GmbH
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package resources
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/internal/kubernetes"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKonnectivityMarshalUnmarshal(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
kmsDepl := NewKonnectivityAgents("192.168.2.1")
|
||||||
|
data, err := kmsDepl.Marshal()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
var recreated konnectivityAgents
|
||||||
|
require.NoError(kubernetes.UnmarshalK8SResources(data, &recreated))
|
||||||
|
assert.Equal(kmsDepl, &recreated)
|
||||||
|
}
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi/resources"
|
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi/resources"
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/kubernetes"
|
"github.com/edgelesssys/constellation/internal/kubernetes"
|
||||||
|
"github.com/edgelesssys/constellation/internal/role"
|
||||||
kubeconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/internal/crypto"
|
"github.com/edgelesssys/constellation/internal/crypto"
|
||||||
@ -130,7 +131,7 @@ func (k *KubernetesUtil) InstallComponents(ctx context.Context, version versions
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (k *KubernetesUtil) InitCluster(
|
func (k *KubernetesUtil) InitCluster(
|
||||||
ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, log *logger.Logger,
|
ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, log *logger.Logger,
|
||||||
) error {
|
) error {
|
||||||
// TODO: audit policy should be user input
|
// TODO: audit policy should be user input
|
||||||
auditPolicy, err := resources.NewDefaultAuditPolicy().Marshal()
|
auditPolicy, err := resources.NewDefaultAuditPolicy().Marshal()
|
||||||
@ -180,6 +181,11 @@ func (k *KubernetesUtil) InitCluster(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Infof("Preparing node for Konnectivity")
|
||||||
|
if err := k.prepareControlPlaneForKonnectivity(ctx, controlPlaneEndpoint); err != nil {
|
||||||
|
return fmt.Errorf("setup konnectivity: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the cluster
|
// initialize the cluster
|
||||||
log.Infof("Initializing the cluster using kubeadm init")
|
log.Infof("Initializing the cluster using kubeadm init")
|
||||||
cmd = exec.CommandContext(ctx, kubeadmPath, "init", "-v=5", "--skip-phases=preflight,certs,addon/kube-proxy", "--config", initConfigFile.Name())
|
cmd = exec.CommandContext(ctx, kubeadmPath, "init", "-v=5", "--skip-phases=preflight,certs,addon/kube-proxy", "--config", initConfigFile.Name())
|
||||||
@ -195,6 +201,64 @@ func (k *KubernetesUtil) InitCluster(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *KubernetesUtil) prepareControlPlaneForKonnectivity(ctx context.Context, loadBalancerEndpoint string) error {
|
||||||
|
if !strings.Contains(loadBalancerEndpoint, ":") {
|
||||||
|
loadBalancerEndpoint = net.JoinHostPort(loadBalancerEndpoint, strconv.Itoa(constants.KubernetesPort))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll("/etc/kubernetes/manifests", os.ModePerm); err != nil {
|
||||||
|
return fmt.Errorf("creating static pods directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
konnectivityServerYaml, err := resources.NewKonnectivityServerStaticPod().Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("generating konnectivity server static pod: %w", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile("/etc/kubernetes/manifests/konnectivity-server.yaml", konnectivityServerYaml, 0o644); err != nil {
|
||||||
|
return fmt.Errorf("writing konnectivity server pod: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
egressConfigYaml, err := resources.NewEgressSelectorConfiguration().Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("generating egress selector configuration: %w", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile("/etc/kubernetes/egress-selector-configuration.yaml", egressConfigYaml, 0o644); err != nil {
|
||||||
|
return fmt.Errorf("writing egress selector config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := k.createSignedKonnectivityCert(); err != nil {
|
||||||
|
return fmt.Errorf("generating konnectivity server certificate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if out, err := exec.CommandContext(ctx, kubectlPath, "config", "set-credentials", "--kubeconfig", "/etc/kubernetes/konnectivity-server.conf", "system:konnectivity-server",
|
||||||
|
"--client-certificate", "/etc/kubernetes/konnectivity.crt", "--client-key", "/etc/kubernetes/konnectivity.key", "--embed-certs=true").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("konnectivity kubeconfig set-credentials: %w, %s", err, string(out))
|
||||||
|
}
|
||||||
|
if out, err := exec.CommandContext(ctx, kubectlPath, "--kubeconfig", "/etc/kubernetes/konnectivity-server.conf", "config", "set-cluster", "kubernetes", "--server", "https://"+loadBalancerEndpoint,
|
||||||
|
"--certificate-authority", "/etc/kubernetes/pki/ca.crt", "--embed-certs=true").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("konnectivity kubeconfig set-cluster: %w, %s", err, string(out))
|
||||||
|
}
|
||||||
|
if out, err := exec.CommandContext(ctx, kubectlPath, "--kubeconfig", "/etc/kubernetes/konnectivity-server.conf", "config", "set-context", "system:konnectivity-server@kubernetes",
|
||||||
|
"--cluster", "kubernetes", "--user", "system:konnectivity-server").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("konnectivity kubeconfig set-context: %w, %s", err, string(out))
|
||||||
|
}
|
||||||
|
if out, err := exec.CommandContext(ctx, kubectlPath, "--kubeconfig", "/etc/kubernetes/konnectivity-server.conf", "config", "use-context", "system:konnectivity-server@kubernetes").CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("konnectivity kubeconfig use-context: %w, %s", err, string(out))
|
||||||
|
}
|
||||||
|
// cleanup
|
||||||
|
if err := os.Remove("/etc/kubernetes/konnectivity.crt"); err != nil {
|
||||||
|
return fmt.Errorf("removing konnectivity certificate: %w", err)
|
||||||
|
}
|
||||||
|
if err := os.Remove("/etc/kubernetes/konnectivity.key"); err != nil {
|
||||||
|
return fmt.Errorf("removing konnectivity key: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *KubernetesUtil) SetupKonnectivity(kubectl Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error {
|
||||||
|
return kubectl.Apply(konnectivityAgentsDaemonSet, true)
|
||||||
|
}
|
||||||
|
|
||||||
func (k *KubernetesUtil) SetupHelmDeployments(ctx context.Context, kubectl Client, helmDeployments []byte, in SetupPodNetworkInput, log *logger.Logger) error {
|
func (k *KubernetesUtil) SetupHelmDeployments(ctx context.Context, kubectl Client, helmDeployments []byte, in SetupPodNetworkInput, log *logger.Logger) error {
|
||||||
var helmDeploy helm.Deployments
|
var helmDeploy helm.Deployments
|
||||||
if err := json.Unmarshal(helmDeployments, &helmDeploy); err != nil {
|
if err := json.Unmarshal(helmDeployments, &helmDeploy); err != nil {
|
||||||
@ -450,7 +514,7 @@ func (k *KubernetesUtil) SetupNodeOperator(ctx context.Context, kubectl Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JoinCluster joins existing Kubernetes cluster using kubeadm join.
|
// JoinCluster joins existing Kubernetes cluster using kubeadm join.
|
||||||
func (k *KubernetesUtil) JoinCluster(ctx context.Context, joinConfig []byte, log *logger.Logger) error {
|
func (k *KubernetesUtil) JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error {
|
||||||
// TODO: audit policy should be user input
|
// TODO: audit policy should be user input
|
||||||
auditPolicy, err := resources.NewDefaultAuditPolicy().Marshal()
|
auditPolicy, err := resources.NewDefaultAuditPolicy().Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -469,6 +533,13 @@ func (k *KubernetesUtil) JoinCluster(ctx context.Context, joinConfig []byte, log
|
|||||||
return fmt.Errorf("writing kubeadm init yaml config %v: %w", joinConfigFile.Name(), err)
|
return fmt.Errorf("writing kubeadm init yaml config %v: %w", joinConfigFile.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peerRole == role.ControlPlane {
|
||||||
|
log.Infof("Prep Init Kubernetes cluster")
|
||||||
|
if err := k.prepareControlPlaneForKonnectivity(ctx, controlPlaneEndpoint); err != nil {
|
||||||
|
return fmt.Errorf("setup konnectivity: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// run `kubeadm join` to join a worker node to an existing Kubernetes cluster
|
// run `kubeadm join` to join a worker node to an existing Kubernetes cluster
|
||||||
cmd := exec.CommandContext(ctx, kubeadmPath, "join", "-v=5", "--config", joinConfigFile.Name())
|
cmd := exec.CommandContext(ctx, kubeadmPath, "join", "-v=5", "--config", joinConfigFile.Name())
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
@ -497,6 +568,7 @@ func (k *KubernetesUtil) StartKubelet() error {
|
|||||||
// createSignedKubeletCert manually creates a Kubernetes CA signed kubelet certificate for the bootstrapper node.
|
// createSignedKubeletCert manually creates a Kubernetes CA signed kubelet certificate for the bootstrapper node.
|
||||||
// This is necessary because this node does not request a certificate from the join service.
|
// This is necessary because this node does not request a certificate from the join service.
|
||||||
func (k *KubernetesUtil) createSignedKubeletCert(nodeName string, ips []net.IP) error {
|
func (k *KubernetesUtil) createSignedKubeletCert(nodeName string, ips []net.IP) error {
|
||||||
|
// Create CSR
|
||||||
certRequestRaw, kubeletKey, err := kubelet.GetCertificateRequest(nodeName, ips)
|
certRequestRaw, kubeletKey, err := kubelet.GetCertificateRequest(nodeName, ips)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -505,48 +577,12 @@ func (k *KubernetesUtil) createSignedKubeletCert(nodeName string, ips []net.IP)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
parentCertRaw, err := k.file.Read(filepath.Join(
|
|
||||||
kubeconstants.KubernetesDir,
|
|
||||||
kubeconstants.DefaultCertificateDir,
|
|
||||||
kubeconstants.CACertName,
|
|
||||||
))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
parentCert, err := crypto.PemToX509Cert(parentCertRaw)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
parentKeyRaw, err := k.file.Read(filepath.Join(
|
|
||||||
kubeconstants.KubernetesDir,
|
|
||||||
kubeconstants.DefaultCertificateDir,
|
|
||||||
kubeconstants.CAKeyName,
|
|
||||||
))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
parentKeyPEM, _ := pem.Decode(parentKeyRaw)
|
|
||||||
var parentKey any
|
|
||||||
switch parentKeyPEM.Type {
|
|
||||||
case "EC PRIVATE KEY":
|
|
||||||
parentKey, err = x509.ParseECPrivateKey(parentKeyPEM.Bytes)
|
|
||||||
case "RSA PRIVATE KEY":
|
|
||||||
parentKey, err = x509.ParsePKCS1PrivateKey(parentKeyPEM.Bytes)
|
|
||||||
case "PRIVATE KEY":
|
|
||||||
parentKey, err = x509.ParsePKCS8PrivateKey(parentKeyPEM.Bytes)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unsupported key type %q", parentKeyPEM.Type)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
certRequest, err := x509.ParseCertificateRequest(certRequestRaw)
|
certRequest, err := x509.ParseCertificateRequest(certRequestRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare certificate signing
|
||||||
serialNumber, err := crypto.GenerateCertificateSerialNumber()
|
serialNumber, err := crypto.GenerateCertificateSerialNumber()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -570,10 +606,18 @@ func (k *KubernetesUtil) createSignedKubeletCert(nodeName string, ips []net.IP)
|
|||||||
IPAddresses: certRequest.IPAddresses,
|
IPAddresses: certRequest.IPAddresses,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parentCert, parentKey, err := k.getKubernetesCACertAndKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the certificate
|
||||||
certRaw, err := x509.CreateCertificate(rand.Reader, certTmpl, parentCert, certRequest.PublicKey, parentKey)
|
certRaw, err := x509.CreateCertificate(rand.Reader, certTmpl, parentCert, certRequest.PublicKey, parentKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the certificate
|
||||||
kubeletCert := pem.EncodeToMemory(&pem.Block{
|
kubeletCert := pem.EncodeToMemory(&pem.Block{
|
||||||
Type: "CERTIFICATE",
|
Type: "CERTIFICATE",
|
||||||
Bytes: certRaw,
|
Bytes: certRaw,
|
||||||
@ -581,3 +625,97 @@ func (k *KubernetesUtil) createSignedKubeletCert(nodeName string, ips []net.IP)
|
|||||||
|
|
||||||
return k.file.Write(kubelet.CertificateFilename, kubeletCert, file.OptMkdirAll)
|
return k.file.Write(kubelet.CertificateFilename, kubeletCert, file.OptMkdirAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createSignedKonnectivityCert manually creates a Kubernetes CA signed certificate for the Konnectivity server.
|
||||||
|
func (k *KubernetesUtil) createSignedKonnectivityCert() error {
|
||||||
|
// Create CSR
|
||||||
|
certRequestRaw, keyPem, err := resources.GetKonnectivityCertificateRequest()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := k.file.Write(resources.KonnectivityKeyFilename, keyPem, file.OptMkdirAll); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
certRequest, err := x509.ParseCertificateRequest(certRequestRaw)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare certificate signing
|
||||||
|
serialNumber, err := crypto.GenerateCertificateSerialNumber()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
// Create the kubelet certificate
|
||||||
|
// For a reference on the certificate fields, see: https://kubernetes.io/docs/setup/best-practices/certificates/
|
||||||
|
certTmpl := &x509.Certificate{
|
||||||
|
SerialNumber: serialNumber,
|
||||||
|
NotBefore: now.Add(-2 * time.Hour),
|
||||||
|
NotAfter: now.Add(24 * 365 * time.Hour),
|
||||||
|
Subject: certRequest.Subject,
|
||||||
|
}
|
||||||
|
|
||||||
|
parentCert, parentKey, err := k.getKubernetesCACertAndKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the certificate
|
||||||
|
certRaw, err := x509.CreateCertificate(rand.Reader, certTmpl, parentCert, certRequest.PublicKey, parentKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the certificate
|
||||||
|
konnectivityCert := pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "CERTIFICATE",
|
||||||
|
Bytes: certRaw,
|
||||||
|
})
|
||||||
|
|
||||||
|
return k.file.Write(resources.KonnectivityCertificateFilename, konnectivityCert, file.OptMkdirAll)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getKubernetesCACertAndKey returns the Kubernetes CA certificate and key.
|
||||||
|
// The key of type `any` can be consumed by `x509.CreateCertificate()`.
|
||||||
|
func (k *KubernetesUtil) getKubernetesCACertAndKey() (*x509.Certificate, any, error) {
|
||||||
|
parentCertRaw, err := k.file.Read(filepath.Join(
|
||||||
|
kubeconstants.KubernetesDir,
|
||||||
|
kubeconstants.DefaultCertificateDir,
|
||||||
|
kubeconstants.CACertName,
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
parentCert, err := crypto.PemToX509Cert(parentCertRaw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
parentKeyRaw, err := k.file.Read(filepath.Join(
|
||||||
|
kubeconstants.KubernetesDir,
|
||||||
|
kubeconstants.DefaultCertificateDir,
|
||||||
|
kubeconstants.CAKeyName,
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
parentKeyPEM, _ := pem.Decode(parentKeyRaw)
|
||||||
|
var parentKey any
|
||||||
|
switch parentKeyPEM.Type {
|
||||||
|
case "EC PRIVATE KEY":
|
||||||
|
parentKey, err = x509.ParseECPrivateKey(parentKeyPEM.Bytes)
|
||||||
|
case "RSA PRIVATE KEY":
|
||||||
|
parentKey, err = x509.ParsePKCS1PrivateKey(parentKeyPEM.Bytes)
|
||||||
|
case "PRIVATE KEY":
|
||||||
|
parentKey, err = x509.ParsePKCS8PrivateKey(parentKeyPEM.Bytes)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unsupported key type %q", parentKeyPEM.Type)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return parentCert, parentKey, nil
|
||||||
|
}
|
||||||
|
@ -13,19 +13,21 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi"
|
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi"
|
||||||
"github.com/edgelesssys/constellation/internal/kubernetes"
|
"github.com/edgelesssys/constellation/internal/kubernetes"
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
|
"github.com/edgelesssys/constellation/internal/role"
|
||||||
"github.com/edgelesssys/constellation/internal/versions"
|
"github.com/edgelesssys/constellation/internal/versions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type clusterUtil interface {
|
type clusterUtil interface {
|
||||||
InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error
|
InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error
|
||||||
InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, log *logger.Logger) error
|
InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, log *logger.Logger) error
|
||||||
JoinCluster(ctx context.Context, joinConfig []byte, log *logger.Logger) error
|
JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error
|
||||||
SetupHelmDeployments(ctx context.Context, client k8sapi.Client, helmDeployments []byte, in k8sapi.SetupPodNetworkInput, log *logger.Logger) error
|
SetupHelmDeployments(ctx context.Context, client k8sapi.Client, helmDeployments []byte, in k8sapi.SetupPodNetworkInput, log *logger.Logger) error
|
||||||
SetupAccessManager(kubectl k8sapi.Client, sshUsers kubernetes.Marshaler) error
|
SetupAccessManager(kubectl k8sapi.Client, sshUsers kubernetes.Marshaler) error
|
||||||
SetupAutoscaling(kubectl k8sapi.Client, clusterAutoscalerConfiguration kubernetes.Marshaler, secrets kubernetes.Marshaler) error
|
SetupAutoscaling(kubectl k8sapi.Client, clusterAutoscalerConfiguration kubernetes.Marshaler, secrets kubernetes.Marshaler) error
|
||||||
SetupJoinService(kubectl k8sapi.Client, joinServiceConfiguration kubernetes.Marshaler) error
|
SetupJoinService(kubectl k8sapi.Client, joinServiceConfiguration kubernetes.Marshaler) error
|
||||||
SetupCloudControllerManager(kubectl k8sapi.Client, cloudControllerManagerConfiguration kubernetes.Marshaler, configMaps kubernetes.Marshaler, secrets kubernetes.Marshaler) error
|
SetupCloudControllerManager(kubectl k8sapi.Client, cloudControllerManagerConfiguration kubernetes.Marshaler, configMaps kubernetes.Marshaler, secrets kubernetes.Marshaler) error
|
||||||
SetupCloudNodeManager(kubectl k8sapi.Client, cloudNodeManagerConfiguration kubernetes.Marshaler) error
|
SetupCloudNodeManager(kubectl k8sapi.Client, cloudNodeManagerConfiguration kubernetes.Marshaler) error
|
||||||
|
SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error
|
||||||
SetupKMS(kubectl k8sapi.Client, kmsConfiguration kubernetes.Marshaler) error
|
SetupKMS(kubectl k8sapi.Client, kmsConfiguration kubernetes.Marshaler) error
|
||||||
SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error
|
SetupVerificationService(kubectl k8sapi.Client, verificationServiceConfiguration kubernetes.Marshaler) error
|
||||||
SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgentConfiguration kubernetes.Marshaler) error
|
SetupGCPGuestAgent(kubectl k8sapi.Client, gcpGuestAgentConfiguration kubernetes.Marshaler) error
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi/resources"
|
"github.com/edgelesssys/constellation/bootstrapper/internal/kubernetes/k8sapi/resources"
|
||||||
"github.com/edgelesssys/constellation/internal/cloud/metadata"
|
"github.com/edgelesssys/constellation/internal/cloud/metadata"
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/iproute"
|
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/internal/role"
|
"github.com/edgelesssys/constellation/internal/role"
|
||||||
"github.com/edgelesssys/constellation/internal/versions"
|
"github.com/edgelesssys/constellation/internal/versions"
|
||||||
@ -156,7 +155,7 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
return nil, fmt.Errorf("encoding kubeadm init configuration as YAML: %w", err)
|
return nil, fmt.Errorf("encoding kubeadm init configuration as YAML: %w", err)
|
||||||
}
|
}
|
||||||
log.Infof("Initializing Kubernetes cluster")
|
log.Infof("Initializing Kubernetes cluster")
|
||||||
if err := k.clusterUtil.InitCluster(ctx, initConfigYAML, nodeName, validIPs, log); err != nil {
|
if err := k.clusterUtil.InitCluster(ctx, initConfigYAML, nodeName, validIPs, controlPlaneEndpoint, log); err != nil {
|
||||||
return nil, fmt.Errorf("kubeadm init: %w", err)
|
return nil, fmt.Errorf("kubeadm init: %w", err)
|
||||||
}
|
}
|
||||||
kubeConfig, err := k.GetKubeconfig()
|
kubeConfig, err := k.GetKubeconfig()
|
||||||
@ -178,6 +177,19 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
return nil, fmt.Errorf("setting up pod network: %w", err)
|
return nil, fmt.Errorf("setting up pod network: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var controlPlaneIP string
|
||||||
|
if strings.Contains(controlPlaneEndpoint, ":") {
|
||||||
|
controlPlaneIP, _, err = net.SplitHostPort(controlPlaneEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parsing control plane endpoint: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
controlPlaneIP = controlPlaneEndpoint
|
||||||
|
}
|
||||||
|
if err = k.clusterUtil.SetupKonnectivity(k.client, resources.NewKonnectivityAgents(controlPlaneIP)); err != nil {
|
||||||
|
return nil, fmt.Errorf("setting up konnectivity: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
kms := resources.NewKMSDeployment(k.cloudProvider, kmsConfig)
|
kms := resources.NewKMSDeployment(k.cloudProvider, kmsConfig)
|
||||||
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
|
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
|
||||||
return nil, fmt.Errorf("setting up kms: %w", err)
|
return nil, fmt.Errorf("setting up kms: %w", err)
|
||||||
@ -277,19 +289,7 @@ func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTo
|
|||||||
zap.String("nodeIP", nodeInternalIP),
|
zap.String("nodeIP", nodeInternalIP),
|
||||||
).Infof("Setting information for node")
|
).Infof("Setting information for node")
|
||||||
|
|
||||||
// Step 2: Remove load balancer from local routing table on GCP.
|
// Step 2: configure kubeadm join config
|
||||||
if k.cloudProvider == "gcp" {
|
|
||||||
ip, _, err := net.SplitHostPort(loadbalancerEndpoint)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("parsing load balancer IP: %w", err)
|
|
||||||
}
|
|
||||||
if err := iproute.RemoveFromLocalRoutingTable(ctx, ip); err != nil {
|
|
||||||
return fmt.Errorf("removing load balancer IP from routing table: %w", err)
|
|
||||||
}
|
|
||||||
log.Infof("Removed load balancer IP from routing table")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: configure kubeadm join config
|
|
||||||
joinConfig := k.configProvider.JoinConfiguration(k.cloudControllerManager.Supported())
|
joinConfig := k.configProvider.JoinConfiguration(k.cloudControllerManager.Supported())
|
||||||
joinConfig.SetAPIServerEndpoint(args.APIServerEndpoint)
|
joinConfig.SetAPIServerEndpoint(args.APIServerEndpoint)
|
||||||
joinConfig.SetToken(args.Token)
|
joinConfig.SetToken(args.Token)
|
||||||
@ -305,7 +305,7 @@ func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTo
|
|||||||
return fmt.Errorf("encoding kubeadm join configuration as YAML: %w", err)
|
return fmt.Errorf("encoding kubeadm join configuration as YAML: %w", err)
|
||||||
}
|
}
|
||||||
log.With(zap.String("apiServerEndpoint", args.APIServerEndpoint)).Infof("Joining Kubernetes cluster")
|
log.With(zap.String("apiServerEndpoint", args.APIServerEndpoint)).Infof("Joining Kubernetes cluster")
|
||||||
if err := k.clusterUtil.JoinCluster(ctx, joinConfigYAML, log); err != nil {
|
if err := k.clusterUtil.JoinCluster(ctx, joinConfigYAML, peerRole, loadbalancerEndpoint, log); err != nil {
|
||||||
return fmt.Errorf("joining cluster: %v; %w ", string(joinConfigYAML), err)
|
return fmt.Errorf("joining cluster: %v; %w ", string(joinConfigYAML), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +263,18 @@ func TestInitCluster(t *testing.T) {
|
|||||||
wantErr: true,
|
wantErr: true,
|
||||||
k8sVersion: versions.Default,
|
k8sVersion: versions.Default,
|
||||||
},
|
},
|
||||||
|
"kubeadm init fails when setting up konnectivity": {
|
||||||
|
clusterUtil: stubClusterUtil{setupKonnectivityError: someErr},
|
||||||
|
kubeconfigReader: &stubKubeconfigReader{
|
||||||
|
Kubeconfig: []byte("someKubeconfig"),
|
||||||
|
},
|
||||||
|
providerMetadata: &stubProviderMetadata{SupportedResp: false},
|
||||||
|
CloudControllerManager: &stubCloudControllerManager{},
|
||||||
|
CloudNodeManager: &stubCloudNodeManager{SupportedResp: false},
|
||||||
|
ClusterAutoscaler: &stubClusterAutoscaler{},
|
||||||
|
wantErr: true,
|
||||||
|
k8sVersion: versions.Default,
|
||||||
|
},
|
||||||
"kubeadm init fails when setting up verification service": {
|
"kubeadm init fails when setting up verification service": {
|
||||||
clusterUtil: stubClusterUtil{setupVerificationServiceErr: someErr},
|
clusterUtil: stubClusterUtil{setupVerificationServiceErr: someErr},
|
||||||
kubeconfigReader: &stubKubeconfigReader{
|
kubeconfigReader: &stubKubeconfigReader{
|
||||||
@ -522,6 +534,7 @@ type stubClusterUtil struct {
|
|||||||
setupJoinServiceError error
|
setupJoinServiceError error
|
||||||
setupCloudControllerManagerError error
|
setupCloudControllerManagerError error
|
||||||
setupCloudNodeManagerError error
|
setupCloudNodeManagerError error
|
||||||
|
setupKonnectivityError error
|
||||||
setupKMSError error
|
setupKMSError error
|
||||||
setupAccessManagerError error
|
setupAccessManagerError error
|
||||||
setupVerificationServiceErr error
|
setupVerificationServiceErr error
|
||||||
@ -536,11 +549,15 @@ type stubClusterUtil struct {
|
|||||||
joinConfigs [][]byte
|
joinConfigs [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *stubClusterUtil) SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error {
|
||||||
|
return s.setupKonnectivityError
|
||||||
|
}
|
||||||
|
|
||||||
func (s *stubClusterUtil) InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error {
|
func (s *stubClusterUtil) InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error {
|
||||||
return s.installComponentsErr
|
return s.installComponentsErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubClusterUtil) InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, log *logger.Logger) error {
|
func (s *stubClusterUtil) InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, log *logger.Logger) error {
|
||||||
s.initConfigs = append(s.initConfigs, initConfig)
|
s.initConfigs = append(s.initConfigs, initConfig)
|
||||||
return s.initClusterErr
|
return s.initClusterErr
|
||||||
}
|
}
|
||||||
@ -593,7 +610,7 @@ func (s *stubClusterUtil) SetupNodeOperator(ctx context.Context, kubectl k8sapi.
|
|||||||
return s.setupNodeOperatorErr
|
return s.setupNodeOperatorErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubClusterUtil) JoinCluster(ctx context.Context, joinConfig []byte, log *logger.Logger) error {
|
func (s *stubClusterUtil) JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error {
|
||||||
s.joinConfigs = append(s.joinConfigs, joinConfig)
|
s.joinConfigs = append(s.joinConfigs, joinConfig)
|
||||||
return s.joinClusterErr
|
return s.joinClusterErr
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ const (
|
|||||||
verifyHealthProbeName = "verifyHealthProbe"
|
verifyHealthProbeName = "verifyHealthProbe"
|
||||||
coordHealthProbeName = "coordHealthProbe"
|
coordHealthProbeName = "coordHealthProbe"
|
||||||
debugdHealthProbeName = "debugdHealthProbe"
|
debugdHealthProbeName = "debugdHealthProbe"
|
||||||
|
konnectivityHealthProbeName = "konnectivityHealthProbe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Azure returns a Azure representation of LoadBalancer.
|
// Azure returns a Azure representation of LoadBalancer.
|
||||||
@ -86,6 +87,13 @@ func (l LoadBalancer) Azure() armnetwork.LoadBalancer {
|
|||||||
Port: to.Ptr[int32](constants.DebugdPort),
|
Port: to.Ptr[int32](constants.DebugdPort),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: to.Ptr(konnectivityHealthProbeName),
|
||||||
|
Properties: &armnetwork.ProbePropertiesFormat{
|
||||||
|
Protocol: to.Ptr(armnetwork.ProbeProtocolTCP),
|
||||||
|
Port: to.Ptr[int32](constants.KonnectivityPort),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
LoadBalancingRules: []*armnetwork.LoadBalancingRule{
|
LoadBalancingRules: []*armnetwork.LoadBalancingRule{
|
||||||
{
|
{
|
||||||
@ -175,6 +183,35 @@ func (l LoadBalancer) Azure() armnetwork.LoadBalancer {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: to.Ptr("konnectivityLoadBalancerRule"),
|
||||||
|
Properties: &armnetwork.LoadBalancingRulePropertiesFormat{
|
||||||
|
FrontendIPConfiguration: &armnetwork.SubResource{
|
||||||
|
ID: to.Ptr("/subscriptions/" + l.Subscription +
|
||||||
|
"/resourceGroups/" + l.ResourceGroup +
|
||||||
|
"/providers/Microsoft.Network/loadBalancers/" + l.Name +
|
||||||
|
"/frontendIPConfigurations/" + frontEndIPConfigName),
|
||||||
|
},
|
||||||
|
FrontendPort: to.Ptr[int32](constants.KonnectivityPort),
|
||||||
|
BackendPort: to.Ptr[int32](constants.KonnectivityPort),
|
||||||
|
Protocol: to.Ptr(armnetwork.TransportProtocolTCP),
|
||||||
|
Probe: &armnetwork.SubResource{
|
||||||
|
ID: to.Ptr("/subscriptions/" + l.Subscription +
|
||||||
|
"/resourceGroups/" + l.ResourceGroup +
|
||||||
|
"/providers/Microsoft.Network/loadBalancers/" + l.Name +
|
||||||
|
"/probes/" + konnectivityHealthProbeName),
|
||||||
|
},
|
||||||
|
DisableOutboundSnat: to.Ptr(true),
|
||||||
|
BackendAddressPools: []*armnetwork.SubResource{
|
||||||
|
{
|
||||||
|
ID: to.Ptr("/subscriptions/" + l.Subscription +
|
||||||
|
"/resourceGroups/" + l.ResourceGroup +
|
||||||
|
"/providers/Microsoft.Network/loadBalancers/" + l.Name +
|
||||||
|
"/backendAddressPools/" + backEndAddressPoolControlPlaneName),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
OutboundRules: []*armnetwork.OutboundRule{
|
OutboundRules: []*armnetwork.OutboundRule{
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ func TestCreator(t *testing.T) {
|
|||||||
GCPSubnetwork: "subnetwork",
|
GCPSubnetwork: "subnetwork",
|
||||||
GCPLoadbalancers: []string{"kube-lb", "boot-lb", "verify-lb"},
|
GCPLoadbalancers: []string{"kube-lb", "boot-lb", "verify-lb"},
|
||||||
GCPFirewalls: []string{
|
GCPFirewalls: []string{
|
||||||
"bootstrapper", "ssh", "nodeport", "kubernetes",
|
"bootstrapper", "ssh", "nodeport", "kubernetes", "konnectivity",
|
||||||
"allow-cluster-internal-tcp", "allow-cluster-internal-udp", "allow-cluster-internal-icmp",
|
"allow-cluster-internal-tcp", "allow-cluster-internal-udp", "allow-cluster-internal-icmp",
|
||||||
"allow-node-internal-tcp", "allow-node-internal-udp", "allow-node-internal-icmp",
|
"allow-node-internal-tcp", "allow-node-internal-udp", "allow-node-internal-icmp",
|
||||||
},
|
},
|
||||||
|
@ -49,29 +49,37 @@ type firewallsAPI interface {
|
|||||||
|
|
||||||
type forwardingRulesAPI interface {
|
type forwardingRulesAPI interface {
|
||||||
Close() error
|
Close() error
|
||||||
Delete(ctx context.Context, req *computepb.DeleteForwardingRuleRequest,
|
Delete(ctx context.Context, req *computepb.DeleteGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
Insert(ctx context.Context, req *computepb.InsertForwardingRuleRequest,
|
Insert(ctx context.Context, req *computepb.InsertGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
Get(ctx context.Context, req *computepb.GetForwardingRuleRequest,
|
Get(ctx context.Context, req *computepb.GetGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption) (*computepb.ForwardingRule, error)
|
opts ...gax.CallOption) (*computepb.ForwardingRule, error)
|
||||||
SetLabels(ctx context.Context, req *computepb.SetLabelsForwardingRuleRequest,
|
SetLabels(ctx context.Context, req *computepb.SetLabelsGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type backendServicesAPI interface {
|
type backendServicesAPI interface {
|
||||||
Close() error
|
Close() error
|
||||||
Delete(ctx context.Context, req *computepb.DeleteRegionBackendServiceRequest,
|
Delete(ctx context.Context, req *computepb.DeleteBackendServiceRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
Insert(ctx context.Context, req *computepb.InsertRegionBackendServiceRequest,
|
Insert(ctx context.Context, req *computepb.InsertBackendServiceRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type healthChecksAPI interface {
|
type healthChecksAPI interface {
|
||||||
Close() error
|
Close() error
|
||||||
Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckRequest,
|
Delete(ctx context.Context, req *computepb.DeleteHealthCheckRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckRequest,
|
Insert(ctx context.Context, req *computepb.InsertHealthCheckRequest,
|
||||||
|
opts ...gax.CallOption) (Operation, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type targetTCPProxiesAPI interface {
|
||||||
|
Close() error
|
||||||
|
Delete(ctx context.Context, req *computepb.DeleteTargetTcpProxyRequest,
|
||||||
|
opts ...gax.CallOption) (Operation, error)
|
||||||
|
Insert(ctx context.Context, req *computepb.InsertTargetTcpProxyRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,11 +137,11 @@ type projectsAPI interface {
|
|||||||
|
|
||||||
type addressesAPI interface {
|
type addressesAPI interface {
|
||||||
Close() error
|
Close() error
|
||||||
Insert(ctx context.Context, req *computepb.InsertAddressRequest,
|
Insert(ctx context.Context, req *computepb.InsertGlobalAddressRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
Get(ctx context.Context, req *computepb.GetAddressRequest,
|
Get(ctx context.Context, req *computepb.GetGlobalAddressRequest,
|
||||||
opts ...gax.CallOption) (*computepb.Address, error)
|
opts ...gax.CallOption) (*computepb.Address, error)
|
||||||
Delete(ctx context.Context, req *computepb.DeleteAddressRequest,
|
Delete(ctx context.Context, req *computepb.DeleteGlobalAddressRequest,
|
||||||
opts ...gax.CallOption) (Operation, error)
|
opts ...gax.CallOption) (Operation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ func (a stubBackendServicesAPI) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubBackendServicesAPI) Insert(ctx context.Context, req *computepb.InsertRegionBackendServiceRequest,
|
func (a stubBackendServicesAPI) Insert(ctx context.Context, req *computepb.InsertBackendServiceRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.insertErr != nil {
|
if a.insertErr != nil {
|
||||||
@ -240,12 +240,46 @@ func (a stubBackendServicesAPI) Insert(ctx context.Context, req *computepb.Inser
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubBackendServicesAPI) Delete(ctx context.Context, req *computepb.DeleteRegionBackendServiceRequest,
|
func (a stubBackendServicesAPI) Delete(ctx context.Context, req *computepb.DeleteBackendServiceRequest,
|
||||||
|
opts ...gax.CallOption,
|
||||||
|
) (Operation, error) {
|
||||||
|
if a.deleteErr != nil {
|
||||||
|
return nil, a.deleteErr
|
||||||
|
}
|
||||||
|
return &stubOperation{
|
||||||
|
&computepb.Operation{
|
||||||
|
Name: proto.String("name"),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type stubTargetTCPProxiesAPI struct {
|
||||||
|
insertErr error
|
||||||
|
deleteErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a stubTargetTCPProxiesAPI) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a stubTargetTCPProxiesAPI) Insert(ctx context.Context, req *computepb.InsertTargetTcpProxyRequest,
|
||||||
|
opts ...gax.CallOption,
|
||||||
|
) (Operation, error) {
|
||||||
|
if a.insertErr != nil {
|
||||||
|
return nil, a.insertErr
|
||||||
|
}
|
||||||
|
return &stubOperation{
|
||||||
|
&computepb.Operation{
|
||||||
|
Name: proto.String("name"),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a stubTargetTCPProxiesAPI) Delete(ctx context.Context, req *computepb.DeleteTargetTcpProxyRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.deleteErr != nil {
|
if a.deleteErr != nil {
|
||||||
@ -254,7 +288,6 @@ func (a stubBackendServicesAPI) Delete(ctx context.Context, req *computepb.Delet
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -271,7 +304,7 @@ func (a stubForwardingRulesAPI) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubForwardingRulesAPI) Insert(ctx context.Context, req *computepb.InsertForwardingRuleRequest,
|
func (a stubForwardingRulesAPI) Insert(ctx context.Context, req *computepb.InsertGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.insertErr != nil {
|
if a.insertErr != nil {
|
||||||
@ -280,12 +313,11 @@ func (a stubForwardingRulesAPI) Insert(ctx context.Context, req *computepb.Inser
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubForwardingRulesAPI) Delete(ctx context.Context, req *computepb.DeleteForwardingRuleRequest,
|
func (a stubForwardingRulesAPI) Delete(ctx context.Context, req *computepb.DeleteGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.deleteErr != nil {
|
if a.deleteErr != nil {
|
||||||
@ -294,12 +326,11 @@ func (a stubForwardingRulesAPI) Delete(ctx context.Context, req *computepb.Delet
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubForwardingRulesAPI) Get(ctx context.Context, req *computepb.GetForwardingRuleRequest,
|
func (a stubForwardingRulesAPI) Get(ctx context.Context, req *computepb.GetGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (*computepb.ForwardingRule, error) {
|
) (*computepb.ForwardingRule, error) {
|
||||||
if a.getErr != nil {
|
if a.getErr != nil {
|
||||||
@ -308,7 +339,7 @@ func (a stubForwardingRulesAPI) Get(ctx context.Context, req *computepb.GetForwa
|
|||||||
return a.forwardingRule, nil
|
return a.forwardingRule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubForwardingRulesAPI) SetLabels(ctx context.Context, req *computepb.SetLabelsForwardingRuleRequest,
|
func (a stubForwardingRulesAPI) SetLabels(ctx context.Context, req *computepb.SetLabelsGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.deleteErr != nil {
|
if a.deleteErr != nil {
|
||||||
@ -317,7 +348,6 @@ func (a stubForwardingRulesAPI) SetLabels(ctx context.Context, req *computepb.Se
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -331,7 +361,7 @@ func (a stubHealthChecksAPI) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubHealthChecksAPI) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckRequest,
|
func (a stubHealthChecksAPI) Insert(ctx context.Context, req *computepb.InsertHealthCheckRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.insertErr != nil {
|
if a.insertErr != nil {
|
||||||
@ -340,12 +370,11 @@ func (a stubHealthChecksAPI) Insert(ctx context.Context, req *computepb.InsertRe
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubHealthChecksAPI) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckRequest,
|
func (a stubHealthChecksAPI) Delete(ctx context.Context, req *computepb.DeleteHealthCheckRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.deleteErr != nil {
|
if a.deleteErr != nil {
|
||||||
@ -354,7 +383,6 @@ func (a stubHealthChecksAPI) Delete(ctx context.Context, req *computepb.DeleteRe
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -511,7 +539,7 @@ type stubAddressesAPI struct {
|
|||||||
deleteErr error
|
deleteErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubAddressesAPI) Insert(context.Context, *computepb.InsertAddressRequest,
|
func (a stubAddressesAPI) Insert(context.Context, *computepb.InsertGlobalAddressRequest,
|
||||||
...gax.CallOption,
|
...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.insertErr != nil {
|
if a.insertErr != nil {
|
||||||
@ -520,18 +548,17 @@ func (a stubAddressesAPI) Insert(context.Context, *computepb.InsertAddressReques
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubAddressesAPI) Get(ctx context.Context, req *computepb.GetAddressRequest,
|
func (a stubAddressesAPI) Get(ctx context.Context, req *computepb.GetGlobalAddressRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (*computepb.Address, error) {
|
) (*computepb.Address, error) {
|
||||||
return &computepb.Address{Address: a.getAddr}, a.getErr
|
return &computepb.Address{Address: a.getAddr}, a.getErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a stubAddressesAPI) Delete(context.Context, *computepb.DeleteAddressRequest,
|
func (a stubAddressesAPI) Delete(context.Context, *computepb.DeleteGlobalAddressRequest,
|
||||||
...gax.CallOption,
|
...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
if a.deleteErr != nil {
|
if a.deleteErr != nil {
|
||||||
@ -540,7 +567,6 @@ func (a stubAddressesAPI) Delete(context.Context, *computepb.DeleteAddressReques
|
|||||||
return &stubOperation{
|
return &stubOperation{
|
||||||
&computepb.Operation{
|
&computepb.Operation{
|
||||||
Name: proto.String("name"),
|
Name: proto.String("name"),
|
||||||
Region: proto.String("region"),
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ type Client struct {
|
|||||||
forwardingRulesAPI
|
forwardingRulesAPI
|
||||||
backendServicesAPI
|
backendServicesAPI
|
||||||
healthChecksAPI
|
healthChecksAPI
|
||||||
|
targetTCPProxiesAPI
|
||||||
instanceTemplateAPI
|
instanceTemplateAPI
|
||||||
instanceGroupManagersAPI
|
instanceGroupManagersAPI
|
||||||
iamAPI
|
iamAPI
|
||||||
@ -109,25 +110,31 @@ func NewFromDefault(ctx context.Context) (*Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closers = append(closers, subnetAPI)
|
closers = append(closers, subnetAPI)
|
||||||
forwardingRulesAPI, err := compute.NewForwardingRulesRESTClient(ctx)
|
forwardingRulesAPI, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = closeAll(closers)
|
_ = closeAll(closers)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closers = append(closers, forwardingRulesAPI)
|
closers = append(closers, forwardingRulesAPI)
|
||||||
backendServicesAPI, err := compute.NewRegionBackendServicesRESTClient(ctx)
|
backendServicesAPI, err := compute.NewBackendServicesRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = closeAll(closers)
|
_ = closeAll(closers)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closers = append(closers, backendServicesAPI)
|
closers = append(closers, backendServicesAPI)
|
||||||
|
targetTCPProxiesAPI, err := compute.NewTargetTcpProxiesRESTClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
_ = closeAll(closers)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
closers = append(closers, targetTCPProxiesAPI)
|
||||||
targetPoolsAPI, err := compute.NewTargetPoolsRESTClient(ctx)
|
targetPoolsAPI, err := compute.NewTargetPoolsRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = closeAll(closers)
|
_ = closeAll(closers)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closers = append(closers, targetPoolsAPI)
|
closers = append(closers, targetPoolsAPI)
|
||||||
healthChecksAPI, err := compute.NewRegionHealthChecksRESTClient(ctx)
|
healthChecksAPI, err := compute.NewHealthChecksRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = closeAll(closers)
|
_ = closeAll(closers)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -157,7 +164,7 @@ func NewFromDefault(ctx context.Context) (*Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
closers = append(closers, projectsAPI)
|
closers = append(closers, projectsAPI)
|
||||||
addressesAPI, err := compute.NewAddressesRESTClient(ctx)
|
addressesAPI, err := compute.NewGlobalAddressesRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = closeAll(closers)
|
_ = closeAll(closers)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -173,6 +180,7 @@ func NewFromDefault(ctx context.Context) (*Client, error) {
|
|||||||
firewallsAPI: &firewallsClient{fwAPI},
|
firewallsAPI: &firewallsClient{fwAPI},
|
||||||
forwardingRulesAPI: &forwardingRulesClient{forwardingRulesAPI},
|
forwardingRulesAPI: &forwardingRulesClient{forwardingRulesAPI},
|
||||||
backendServicesAPI: &backendServicesClient{backendServicesAPI},
|
backendServicesAPI: &backendServicesClient{backendServicesAPI},
|
||||||
|
targetTCPProxiesAPI: &targetTCPProxiesClient{targetTCPProxiesAPI},
|
||||||
healthChecksAPI: &healthChecksClient{healthChecksAPI},
|
healthChecksAPI: &healthChecksClient{healthChecksAPI},
|
||||||
instanceTemplateAPI: &instanceTemplateClient{templAPI},
|
instanceTemplateAPI: &instanceTemplateClient{templAPI},
|
||||||
instanceGroupManagersAPI: &instanceGroupManagersClient{groupAPI},
|
instanceGroupManagersAPI: &instanceGroupManagersClient{groupAPI},
|
||||||
@ -282,6 +290,7 @@ func (c *Client) SetState(stat state.ConstellationState) {
|
|||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
}
|
}
|
||||||
c.loadbalancers = append(c.loadbalancers, lb)
|
c.loadbalancers = append(c.loadbalancers, lb)
|
||||||
}
|
}
|
||||||
|
@ -53,75 +53,95 @@ func (c *firewallsClient) Insert(ctx context.Context, req *computepb.InsertFirew
|
|||||||
}
|
}
|
||||||
|
|
||||||
type forwardingRulesClient struct {
|
type forwardingRulesClient struct {
|
||||||
*compute.ForwardingRulesClient
|
*compute.GlobalForwardingRulesClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) Close() error {
|
func (c *forwardingRulesClient) Close() error {
|
||||||
return c.ForwardingRulesClient.Close()
|
return c.GlobalForwardingRulesClient.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) Delete(ctx context.Context, req *computepb.DeleteForwardingRuleRequest,
|
func (c *forwardingRulesClient) Delete(ctx context.Context, req *computepb.DeleteGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.ForwardingRulesClient.Delete(ctx, req)
|
return c.GlobalForwardingRulesClient.Delete(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) Insert(ctx context.Context, req *computepb.InsertForwardingRuleRequest,
|
func (c *forwardingRulesClient) Insert(ctx context.Context, req *computepb.InsertGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.ForwardingRulesClient.Insert(ctx, req)
|
return c.GlobalForwardingRulesClient.Insert(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) Get(ctx context.Context, req *computepb.GetForwardingRuleRequest,
|
func (c *forwardingRulesClient) Get(ctx context.Context, req *computepb.GetGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (*computepb.ForwardingRule, error) {
|
) (*computepb.ForwardingRule, error) {
|
||||||
return c.ForwardingRulesClient.Get(ctx, req)
|
return c.GlobalForwardingRulesClient.Get(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsForwardingRuleRequest,
|
func (c *forwardingRulesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsGlobalForwardingRuleRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.ForwardingRulesClient.SetLabels(ctx, req)
|
return c.GlobalForwardingRulesClient.SetLabels(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type backendServicesClient struct {
|
type backendServicesClient struct {
|
||||||
*compute.RegionBackendServicesClient
|
*compute.BackendServicesClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *backendServicesClient) Close() error {
|
func (c *backendServicesClient) Close() error {
|
||||||
return c.RegionBackendServicesClient.Close()
|
return c.BackendServicesClient.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *backendServicesClient) Insert(ctx context.Context, req *computepb.InsertRegionBackendServiceRequest,
|
func (c *backendServicesClient) Insert(ctx context.Context, req *computepb.InsertBackendServiceRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.RegionBackendServicesClient.Insert(ctx, req)
|
return c.BackendServicesClient.Insert(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *backendServicesClient) Delete(ctx context.Context, req *computepb.DeleteRegionBackendServiceRequest,
|
func (c *backendServicesClient) Delete(ctx context.Context, req *computepb.DeleteBackendServiceRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.RegionBackendServicesClient.Delete(ctx, req)
|
return c.BackendServicesClient.Delete(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
type targetTCPProxiesClient struct {
|
||||||
|
*compute.TargetTcpProxiesClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *targetTCPProxiesClient) Close() error {
|
||||||
|
return c.TargetTcpProxiesClient.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *targetTCPProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetTcpProxyRequest,
|
||||||
|
opts ...gax.CallOption,
|
||||||
|
) (Operation, error) {
|
||||||
|
return c.TargetTcpProxiesClient.Delete(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *targetTCPProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetTcpProxyRequest,
|
||||||
|
opts ...gax.CallOption,
|
||||||
|
) (Operation, error) {
|
||||||
|
return c.TargetTcpProxiesClient.Insert(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type healthChecksClient struct {
|
type healthChecksClient struct {
|
||||||
*compute.RegionHealthChecksClient
|
*compute.HealthChecksClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *healthChecksClient) Close() error {
|
func (c *healthChecksClient) Close() error {
|
||||||
return c.RegionHealthChecksClient.Close()
|
return c.HealthChecksClient.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *healthChecksClient) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckRequest,
|
func (c *healthChecksClient) Delete(ctx context.Context, req *computepb.DeleteHealthCheckRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.RegionHealthChecksClient.Delete(ctx, req)
|
return c.HealthChecksClient.Delete(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *healthChecksClient) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckRequest,
|
func (c *healthChecksClient) Insert(ctx context.Context, req *computepb.InsertHealthCheckRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.RegionHealthChecksClient.Insert(ctx, req)
|
return c.HealthChecksClient.Insert(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type networksClient struct {
|
type networksClient struct {
|
||||||
@ -257,21 +277,21 @@ func (c *projectsClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPoli
|
|||||||
}
|
}
|
||||||
|
|
||||||
type addressesClient struct {
|
type addressesClient struct {
|
||||||
*compute.AddressesClient
|
*compute.GlobalAddressesClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *addressesClient) Insert(ctx context.Context, req *computepb.InsertAddressRequest,
|
func (c *addressesClient) Insert(ctx context.Context, req *computepb.InsertGlobalAddressRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.AddressesClient.Insert(ctx, req)
|
return c.GlobalAddressesClient.Insert(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *addressesClient) Delete(ctx context.Context, req *computepb.DeleteAddressRequest,
|
func (c *addressesClient) Delete(ctx context.Context, req *computepb.DeleteGlobalAddressRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) (Operation, error) {
|
) (Operation, error) {
|
||||||
return c.AddressesClient.Delete(ctx, req)
|
return c.GlobalAddressesClient.Delete(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *addressesClient) Close() error {
|
func (c *addressesClient) Close() error {
|
||||||
return c.AddressesClient.Close()
|
return c.GlobalAddressesClient.Close()
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput
|
|||||||
{Name: proto.String("debugd"), Port: proto.Int32(constants.DebugdPort)},
|
{Name: proto.String("debugd"), Port: proto.Int32(constants.DebugdPort)},
|
||||||
{Name: proto.String("bootstrapper"), Port: proto.Int32(constants.BootstrapperPort)},
|
{Name: proto.String("bootstrapper"), Port: proto.Int32(constants.BootstrapperPort)},
|
||||||
{Name: proto.String("verify"), Port: proto.Int32(constants.VerifyServiceNodePortGRPC)},
|
{Name: proto.String("verify"), Port: proto.Int32(constants.VerifyServiceNodePortGRPC)},
|
||||||
|
{Name: proto.String("konnectivity"), Port: proto.Int32(constants.KonnectivityPort)},
|
||||||
},
|
},
|
||||||
Template: c.controlPlaneTemplate,
|
Template: c.controlPlaneTemplate,
|
||||||
UID: c.uid,
|
UID: c.uid,
|
||||||
|
@ -32,6 +32,7 @@ type loadBalancer struct {
|
|||||||
hasHealthCheck bool
|
hasHealthCheck bool
|
||||||
hasBackendService bool
|
hasBackendService bool
|
||||||
hasForwardingRules bool
|
hasForwardingRules bool
|
||||||
|
hasTargetTCPProxy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateLoadBalancers creates all necessary load balancers.
|
// CreateLoadBalancers creates all necessary load balancers.
|
||||||
@ -69,6 +70,14 @@ func (c *Client) CreateLoadBalancers(ctx context.Context, isDebugCluster bool) e
|
|||||||
healthCheck: computepb.HealthCheck_TCP,
|
healthCheck: computepb.HealthCheck_TCP,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
c.loadbalancers = append(c.loadbalancers, &loadBalancer{
|
||||||
|
name: c.buildResourceName("konnectivity"),
|
||||||
|
ip: c.loadbalancerIPname,
|
||||||
|
frontendPort: constants.KonnectivityPort,
|
||||||
|
backendPortName: "konnectivity",
|
||||||
|
healthCheck: computepb.HealthCheck_TCP,
|
||||||
|
})
|
||||||
|
|
||||||
// Only create when the debug cluster flag is set in the Constellation config
|
// Only create when the debug cluster flag is set in the Constellation config
|
||||||
if isDebugCluster {
|
if isDebugCluster {
|
||||||
c.loadbalancers = append(c.loadbalancers, &loadBalancer{
|
c.loadbalancers = append(c.loadbalancers, &loadBalancer{
|
||||||
@ -107,6 +116,9 @@ func (c *Client) createLoadBalancer(ctx context.Context, lb *loadBalancer) error
|
|||||||
if err := c.createBackendService(ctx, lb); err != nil {
|
if err := c.createBackendService(ctx, lb); err != nil {
|
||||||
return fmt.Errorf("creating backend services: %w", err)
|
return fmt.Errorf("creating backend services: %w", err)
|
||||||
}
|
}
|
||||||
|
if err := c.createTargetTCPProxy(ctx, lb); err != nil {
|
||||||
|
return fmt.Errorf("creating target TCP proxies: %w", err)
|
||||||
|
}
|
||||||
if err := c.createForwardingRules(ctx, lb); err != nil {
|
if err := c.createForwardingRules(ctx, lb); err != nil {
|
||||||
return fmt.Errorf("creating forwarding rules: %w", err)
|
return fmt.Errorf("creating forwarding rules: %w", err)
|
||||||
}
|
}
|
||||||
@ -114,9 +126,8 @@ func (c *Client) createLoadBalancer(ctx context.Context, lb *loadBalancer) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createHealthCheck(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) createHealthCheck(ctx context.Context, lb *loadBalancer) error {
|
||||||
req := &computepb.InsertRegionHealthCheckRequest{
|
req := &computepb.InsertHealthCheckRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
HealthCheckResource: &computepb.HealthCheck{
|
HealthCheckResource: &computepb.HealthCheck{
|
||||||
Name: proto.String(lb.name),
|
Name: proto.String(lb.name),
|
||||||
Type: proto.String(computepb.HealthCheck_Type_name[int32(lb.healthCheck)]),
|
Type: proto.String(computepb.HealthCheck_Type_name[int32(lb.healthCheck)]),
|
||||||
@ -144,18 +155,17 @@ func (c *Client) createHealthCheck(ctx context.Context, lb *loadBalancer) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createBackendService(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) createBackendService(ctx context.Context, lb *loadBalancer) error {
|
||||||
req := &computepb.InsertRegionBackendServiceRequest{
|
req := &computepb.InsertBackendServiceRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
BackendServiceResource: &computepb.BackendService{
|
BackendServiceResource: &computepb.BackendService{
|
||||||
Name: proto.String(lb.name),
|
Name: proto.String(lb.name),
|
||||||
Protocol: proto.String(computepb.BackendService_Protocol_name[int32(computepb.BackendService_TCP)]),
|
Protocol: proto.String(computepb.BackendService_Protocol_name[int32(computepb.BackendService_TCP)]),
|
||||||
LoadBalancingScheme: proto.String(computepb.BackendService_LoadBalancingScheme_name[int32(computepb.BackendService_EXTERNAL)]),
|
LoadBalancingScheme: proto.String(computepb.BackendService_LoadBalancingScheme_name[int32(computepb.BackendService_EXTERNAL)]),
|
||||||
HealthChecks: []string{c.resourceURI(scopeRegion, "healthChecks", lb.name)},
|
HealthChecks: []string{c.resourceURI(scopeGlobal, "healthChecks", lb.name)},
|
||||||
PortName: proto.String(lb.backendPortName),
|
PortName: proto.String(lb.backendPortName),
|
||||||
Backends: []*computepb.Backend{
|
Backends: []*computepb.Backend{
|
||||||
{
|
{
|
||||||
BalancingMode: proto.String(computepb.Backend_BalancingMode_name[int32(computepb.Backend_CONNECTION)]),
|
BalancingMode: proto.String(computepb.Backend_BalancingMode_name[int32(computepb.Backend_UTILIZATION)]),
|
||||||
Group: proto.String(c.resourceURI(scopeZone, "instanceGroups", c.controlPlaneInstanceGroup)),
|
Group: proto.String(c.resourceURI(scopeZone, "instanceGroups", c.controlPlaneInstanceGroup)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -175,16 +185,16 @@ func (c *Client) createBackendService(ctx context.Context, lb *loadBalancer) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createForwardingRules(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) createForwardingRules(ctx context.Context, lb *loadBalancer) error {
|
||||||
req := &computepb.InsertForwardingRuleRequest{
|
req := &computepb.InsertGlobalForwardingRuleRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
ForwardingRuleResource: &computepb.ForwardingRule{
|
ForwardingRuleResource: &computepb.ForwardingRule{
|
||||||
Name: proto.String(lb.name),
|
Name: proto.String(lb.name),
|
||||||
IPAddress: proto.String(c.resourceURI(scopeRegion, "addresses", c.loadbalancerIPname)),
|
IPAddress: proto.String(c.resourceURI(scopeGlobal, "addresses", c.loadbalancerIPname)),
|
||||||
IPProtocol: proto.String(computepb.ForwardingRule_IPProtocolEnum_name[int32(computepb.ForwardingRule_TCP)]),
|
IPProtocol: proto.String(computepb.ForwardingRule_IPProtocolEnum_name[int32(computepb.ForwardingRule_TCP)]),
|
||||||
LoadBalancingScheme: proto.String(computepb.ForwardingRule_LoadBalancingScheme_name[int32(computepb.ForwardingRule_EXTERNAL)]),
|
LoadBalancingScheme: proto.String(computepb.ForwardingRule_LoadBalancingScheme_name[int32(computepb.ForwardingRule_EXTERNAL)]),
|
||||||
Ports: []string{strconv.Itoa(lb.frontendPort)},
|
PortRange: proto.String(strconv.Itoa(lb.frontendPort)),
|
||||||
BackendService: proto.String(c.resourceURI(scopeRegion, "backendServices", lb.name)),
|
|
||||||
|
Target: proto.String(c.resourceURI(scopeGlobal, "targetTcpProxies", lb.name)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
resp, err := c.forwardingRulesAPI.Insert(ctx, req)
|
resp, err := c.forwardingRulesAPI.Insert(ctx, req)
|
||||||
@ -205,9 +215,8 @@ func (c *Client) createForwardingRules(ctx context.Context, lb *loadBalancer) er
|
|||||||
|
|
||||||
// labelLoadBalancer labels a load balancer (its forwarding rules) so that it can be found by applications in the cluster.
|
// labelLoadBalancer labels a load balancer (its forwarding rules) so that it can be found by applications in the cluster.
|
||||||
func (c *Client) labelLoadBalancer(ctx context.Context, name string) error {
|
func (c *Client) labelLoadBalancer(ctx context.Context, name string) error {
|
||||||
forwardingRule, err := c.forwardingRulesAPI.Get(ctx, &computepb.GetForwardingRuleRequest{
|
forwardingRule, err := c.forwardingRulesAPI.Get(ctx, &computepb.GetGlobalForwardingRuleRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
ForwardingRule: name,
|
ForwardingRule: name,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -217,11 +226,10 @@ func (c *Client) labelLoadBalancer(ctx context.Context, name string) error {
|
|||||||
return fmt.Errorf("forwarding rule %s has no label fingerprint", name)
|
return fmt.Errorf("forwarding rule %s has no label fingerprint", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.forwardingRulesAPI.SetLabels(ctx, &computepb.SetLabelsForwardingRuleRequest{
|
resp, err := c.forwardingRulesAPI.SetLabels(ctx, &computepb.SetLabelsGlobalForwardingRuleRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
Resource: name,
|
Resource: name,
|
||||||
RegionSetLabelsRequestResource: &computepb.RegionSetLabelsRequest{
|
GlobalSetLabelsRequestResource: &computepb.GlobalSetLabelsRequest{
|
||||||
Labels: map[string]string{"constellation-uid": c.uid},
|
Labels: map[string]string{"constellation-uid": c.uid},
|
||||||
LabelFingerprint: forwardingRule.LabelFingerprint,
|
LabelFingerprint: forwardingRule.LabelFingerprint,
|
||||||
},
|
},
|
||||||
@ -233,6 +241,26 @@ func (c *Client) labelLoadBalancer(ctx context.Context, name string) error {
|
|||||||
return c.waitForOperations(ctx, []Operation{resp})
|
return c.waitForOperations(ctx, []Operation{resp})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) createTargetTCPProxy(ctx context.Context, lb *loadBalancer) error {
|
||||||
|
req := &computepb.InsertTargetTcpProxyRequest{
|
||||||
|
Project: c.project,
|
||||||
|
TargetTcpProxyResource: &computepb.TargetTcpProxy{
|
||||||
|
Name: proto.String(lb.name),
|
||||||
|
Service: proto.String(c.resourceURI(scopeGlobal, "backendServices", lb.name)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resp, err := c.targetTCPProxiesAPI.Insert(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("inserting target tcp proxy: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.waitForOperations(ctx, []Operation{resp}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lb.hasTargetTCPProxy = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TerminateLoadBalancers terminates all load balancers.
|
// TerminateLoadBalancers terminates all load balancers.
|
||||||
func (c *Client) TerminateLoadBalancers(ctx context.Context) error {
|
func (c *Client) TerminateLoadBalancers(ctx context.Context) error {
|
||||||
errC := make(chan error)
|
errC := make(chan error)
|
||||||
@ -276,6 +304,12 @@ func (c *Client) terminateLoadBalancer(ctx context.Context, lb *loadBalancer) er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lb.hasTargetTCPProxy {
|
||||||
|
if err := c.terminateTargetTCPProxy(ctx, lb); err != nil {
|
||||||
|
return fmt.Errorf("terminating target tcp proxy: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if lb.hasBackendService {
|
if lb.hasBackendService {
|
||||||
if err := c.terminateBackendService(ctx, lb); err != nil {
|
if err := c.terminateBackendService(ctx, lb); err != nil {
|
||||||
return fmt.Errorf("terminating backend services: %w", err)
|
return fmt.Errorf("terminating backend services: %w", err)
|
||||||
@ -293,9 +327,8 @@ func (c *Client) terminateLoadBalancer(ctx context.Context, lb *loadBalancer) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) terminateForwadingRules(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) terminateForwadingRules(ctx context.Context, lb *loadBalancer) error {
|
||||||
resp, err := c.forwardingRulesAPI.Delete(ctx, &computepb.DeleteForwardingRuleRequest{
|
resp, err := c.forwardingRulesAPI.Delete(ctx, &computepb.DeleteGlobalForwardingRuleRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
ForwardingRule: lb.name,
|
ForwardingRule: lb.name,
|
||||||
})
|
})
|
||||||
if isNotFoundError(err) {
|
if isNotFoundError(err) {
|
||||||
@ -314,10 +347,30 @@ func (c *Client) terminateForwadingRules(ctx context.Context, lb *loadBalancer)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) terminateBackendService(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) terminateTargetTCPProxy(ctx context.Context, lb *loadBalancer) error {
|
||||||
resp, err := c.backendServicesAPI.Delete(ctx, &computepb.DeleteRegionBackendServiceRequest{
|
resp, err := c.targetTCPProxiesAPI.Delete(ctx, &computepb.DeleteTargetTcpProxyRequest{
|
||||||
|
Project: c.project,
|
||||||
|
TargetTcpProxy: lb.name,
|
||||||
|
})
|
||||||
|
if isNotFoundError(err) {
|
||||||
|
lb.hasTargetTCPProxy = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("deleting target tcp proxy: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.waitForOperations(ctx, []Operation{resp}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
lb.hasTargetTCPProxy = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) terminateBackendService(ctx context.Context, lb *loadBalancer) error {
|
||||||
|
resp, err := c.backendServicesAPI.Delete(ctx, &computepb.DeleteBackendServiceRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
BackendService: lb.name,
|
BackendService: lb.name,
|
||||||
})
|
})
|
||||||
if isNotFoundError(err) {
|
if isNotFoundError(err) {
|
||||||
@ -337,9 +390,8 @@ func (c *Client) terminateBackendService(ctx context.Context, lb *loadBalancer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) terminateHealthCheck(ctx context.Context, lb *loadBalancer) error {
|
func (c *Client) terminateHealthCheck(ctx context.Context, lb *loadBalancer) error {
|
||||||
resp, err := c.healthChecksAPI.Delete(ctx, &computepb.DeleteRegionHealthCheckRequest{
|
resp, err := c.healthChecksAPI.Delete(ctx, &computepb.DeleteHealthCheckRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
HealthCheck: lb.name,
|
HealthCheck: lb.name,
|
||||||
})
|
})
|
||||||
if isNotFoundError(err) {
|
if isNotFoundError(err) {
|
||||||
@ -360,9 +412,8 @@ func (c *Client) terminateHealthCheck(ctx context.Context, lb *loadBalancer) err
|
|||||||
|
|
||||||
func (c *Client) createIPAddr(ctx context.Context) error {
|
func (c *Client) createIPAddr(ctx context.Context) error {
|
||||||
ipName := c.buildResourceName()
|
ipName := c.buildResourceName()
|
||||||
insertReq := &computepb.InsertAddressRequest{
|
insertReq := &computepb.InsertGlobalAddressRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
AddressResource: &computepb.Address{
|
AddressResource: &computepb.Address{
|
||||||
Name: proto.String(ipName),
|
Name: proto.String(ipName),
|
||||||
},
|
},
|
||||||
@ -376,9 +427,8 @@ func (c *Client) createIPAddr(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
c.loadbalancerIPname = ipName
|
c.loadbalancerIPname = ipName
|
||||||
|
|
||||||
getReq := &computepb.GetAddressRequest{
|
getReq := &computepb.GetGlobalAddressRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
Address: c.loadbalancerIPname,
|
Address: c.loadbalancerIPname,
|
||||||
}
|
}
|
||||||
addr, err := c.addressesAPI.Get(ctx, getReq)
|
addr, err := c.addressesAPI.Get(ctx, getReq)
|
||||||
@ -398,9 +448,8 @@ func (c *Client) deleteIPAddr(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &computepb.DeleteAddressRequest{
|
req := &computepb.DeleteGlobalAddressRequest{
|
||||||
Project: c.project,
|
Project: c.project,
|
||||||
Region: c.region,
|
|
||||||
Address: c.loadbalancerIPname,
|
Address: c.loadbalancerIPname,
|
||||||
}
|
}
|
||||||
op, err := c.addressesAPI.Delete(ctx, req)
|
op, err := c.addressesAPI.Delete(ctx, req)
|
||||||
|
@ -27,8 +27,9 @@ func TestCreateLoadBalancers(t *testing.T) {
|
|||||||
addrAPI addressesAPI
|
addrAPI addressesAPI
|
||||||
healthAPI healthChecksAPI
|
healthAPI healthChecksAPI
|
||||||
backendAPI backendServicesAPI
|
backendAPI backendServicesAPI
|
||||||
|
proxyAPI targetTCPProxiesAPI
|
||||||
forwardAPI forwardingRulesAPI
|
forwardAPI forwardingRulesAPI
|
||||||
opRegAPI operationRegionAPI
|
operationAPI operationGlobalAPI
|
||||||
isDebugCluster bool
|
isDebugCluster bool
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
@ -36,31 +37,44 @@ func TestCreateLoadBalancers(t *testing.T) {
|
|||||||
addrAPI: &stubAddressesAPI{getAddr: proto.String("192.0.2.1")},
|
addrAPI: &stubAddressesAPI{getAddr: proto.String("192.0.2.1")},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{},
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
proxyAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
||||||
opRegAPI: stubOperationRegionAPI{},
|
operationAPI: stubOperationGlobalAPI{},
|
||||||
},
|
},
|
||||||
"successful create (debug cluster)": {
|
"successful create (debug cluster)": {
|
||||||
addrAPI: &stubAddressesAPI{getAddr: proto.String("192.0.2.1")},
|
addrAPI: &stubAddressesAPI{getAddr: proto.String("192.0.2.1")},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{},
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
proxyAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
||||||
opRegAPI: stubOperationRegionAPI{},
|
operationAPI: stubOperationGlobalAPI{},
|
||||||
isDebugCluster: true,
|
isDebugCluster: true,
|
||||||
},
|
},
|
||||||
"createIPAddr fails": {
|
"createIPAddr fails": {
|
||||||
addrAPI: &stubAddressesAPI{insertErr: someErr},
|
addrAPI: &stubAddressesAPI{insertErr: someErr},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{},
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
proxyAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
||||||
opRegAPI: stubOperationRegionAPI{},
|
operationAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"createLB fails": {
|
"createLB fails": {
|
||||||
addrAPI: &stubAddressesAPI{},
|
addrAPI: &stubAddressesAPI{},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{insertErr: someErr},
|
backendAPI: &stubBackendServicesAPI{insertErr: someErr},
|
||||||
|
proxyAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
||||||
opRegAPI: stubOperationRegionAPI{},
|
operationAPI: stubOperationGlobalAPI{},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
"createTcpProxy fails": {
|
||||||
|
addrAPI: &stubAddressesAPI{getAddr: proto.String("192.0.2.1")},
|
||||||
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
proxyAPI: &stubTargetTCPProxiesAPI{insertErr: someErr},
|
||||||
|
forwardAPI: &stubForwardingRulesAPI{forwardingRule: forwardingRule},
|
||||||
|
operationAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -76,10 +90,11 @@ func TestCreateLoadBalancers(t *testing.T) {
|
|||||||
name: "name",
|
name: "name",
|
||||||
uid: "uid",
|
uid: "uid",
|
||||||
addressesAPI: tc.addrAPI,
|
addressesAPI: tc.addrAPI,
|
||||||
|
targetTCPProxiesAPI: tc.proxyAPI,
|
||||||
healthChecksAPI: tc.healthAPI,
|
healthChecksAPI: tc.healthAPI,
|
||||||
backendServicesAPI: tc.backendAPI,
|
backendServicesAPI: tc.backendAPI,
|
||||||
forwardingRulesAPI: tc.forwardAPI,
|
forwardingRulesAPI: tc.forwardAPI,
|
||||||
operationRegionAPI: tc.opRegAPI,
|
operationGlobalAPI: tc.operationAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.CreateLoadBalancers(ctx, tc.isDebugCluster)
|
err := client.CreateLoadBalancers(ctx, tc.isDebugCluster)
|
||||||
@ -104,10 +119,10 @@ func TestCreateLoadBalancers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.isDebugCluster {
|
if tc.isDebugCluster {
|
||||||
assert.Equal(4, len(client.loadbalancers))
|
assert.Equal(5, len(client.loadbalancers))
|
||||||
assert.True(foundDebugdLB, "debugd loadbalancer not found in debug-mode")
|
assert.True(foundDebugdLB, "debugd loadbalancer not found in debug-mode")
|
||||||
} else {
|
} else {
|
||||||
assert.Equal(3, len(client.loadbalancers))
|
assert.Equal(4, len(client.loadbalancers))
|
||||||
assert.False(foundDebugdLB, "debugd loadbalancer found in non-debug mode")
|
assert.False(foundDebugdLB, "debugd loadbalancer found in non-debug mode")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -117,23 +132,26 @@ func TestCreateLoadBalancers(t *testing.T) {
|
|||||||
func TestCreateLoadBalancer(t *testing.T) {
|
func TestCreateLoadBalancer(t *testing.T) {
|
||||||
someErr := errors.New("failed")
|
someErr := errors.New("failed")
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
operationRegionAPI operationRegionAPI
|
operationGlobalAPI operationGlobalAPI
|
||||||
healthChecksAPI healthChecksAPI
|
healthChecksAPI healthChecksAPI
|
||||||
backendServicesAPI backendServicesAPI
|
backendServicesAPI backendServicesAPI
|
||||||
forwardingRulesAPI forwardingRulesAPI
|
forwardingRulesAPI forwardingRulesAPI
|
||||||
|
targetTCPProxiesAPI targetTCPProxiesAPI
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantLB *loadBalancer
|
wantLB *loadBalancer
|
||||||
}{
|
}{
|
||||||
"successful create": {
|
"successful create": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
frontendPort: 1234,
|
frontendPort: 1234,
|
||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
},
|
},
|
||||||
@ -141,14 +159,16 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
"successful create with label": {
|
"successful create with label": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
frontendPort: 1234,
|
frontendPort: 1234,
|
||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
label: true,
|
label: true,
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
},
|
},
|
||||||
@ -156,8 +176,9 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
"CreateLoadBalancer fails when getting forwarding rule": {
|
"CreateLoadBalancer fails when getting forwarding rule": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{getErr: someErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{getErr: someErr},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
@ -165,6 +186,7 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
label: true,
|
label: true,
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
},
|
},
|
||||||
@ -172,8 +194,9 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
"CreateLoadBalancer fails when label fingerprint is missing": {
|
"CreateLoadBalancer fails when label fingerprint is missing": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{}},
|
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{}},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
@ -181,6 +204,7 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
label: true,
|
label: true,
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
},
|
},
|
||||||
@ -188,23 +212,26 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
"CreateLoadBalancer fails when creating health check": {
|
"CreateLoadBalancer fails when creating health check": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{insertErr: someErr},
|
healthChecksAPI: stubHealthChecksAPI{insertErr: someErr},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
frontendPort: 1234,
|
frontendPort: 1234,
|
||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
hasHealthCheck: false,
|
hasHealthCheck: false,
|
||||||
|
hasTargetTCPProxy: false,
|
||||||
hasBackendService: false,
|
hasBackendService: false,
|
||||||
hasForwardingRules: false,
|
hasForwardingRules: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"CreateLoadBalancer fails when creating backend service": {
|
"CreateLoadBalancer fails when creating backend service": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{insertErr: someErr},
|
backendServicesAPI: stubBackendServicesAPI{insertErr: someErr},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
@ -212,14 +239,33 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
backendPortName: "testport",
|
backendPortName: "testport",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: false,
|
hasBackendService: false,
|
||||||
|
hasTargetTCPProxy: false,
|
||||||
hasForwardingRules: false,
|
hasForwardingRules: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"CreateLoadBalancer fails when creating forwarding rule": {
|
"CreateLoadBalancer fails when creating forwarding rule": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{insertErr: someErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{insertErr: someErr},
|
||||||
operationRegionAPI: stubOperationRegionAPI{},
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
|
wantErr: true,
|
||||||
|
wantLB: &loadBalancer{
|
||||||
|
name: "name",
|
||||||
|
frontendPort: 1234,
|
||||||
|
backendPortName: "testport",
|
||||||
|
hasHealthCheck: true,
|
||||||
|
hasBackendService: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
|
hasForwardingRules: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"CreateLoadBalancer fails when creating target proxy rule": {
|
||||||
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{insertErr: someErr},
|
||||||
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
|
operationGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
@ -233,8 +279,9 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
"CreateLoadBalancer fails when waiting on operation": {
|
"CreateLoadBalancer fails when waiting on operation": {
|
||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
forwardingRulesAPI: stubForwardingRulesAPI{forwardingRule: &compute.ForwardingRule{LabelFingerprint: proto.String("fingerprint")}},
|
||||||
operationRegionAPI: stubOperationRegionAPI{waitErr: someErr},
|
operationGlobalAPI: stubOperationGlobalAPI{waitErr: someErr},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
@ -259,8 +306,9 @@ func TestCreateLoadBalancer(t *testing.T) {
|
|||||||
uid: "uid",
|
uid: "uid",
|
||||||
backendServicesAPI: tc.backendServicesAPI,
|
backendServicesAPI: tc.backendServicesAPI,
|
||||||
forwardingRulesAPI: tc.forwardingRulesAPI,
|
forwardingRulesAPI: tc.forwardingRulesAPI,
|
||||||
|
targetTCPProxiesAPI: tc.targetTCPProxiesAPI,
|
||||||
healthChecksAPI: tc.healthChecksAPI,
|
healthChecksAPI: tc.healthChecksAPI,
|
||||||
operationRegionAPI: tc.operationRegionAPI,
|
operationGlobalAPI: tc.operationGlobalAPI,
|
||||||
}
|
}
|
||||||
lb := &loadBalancer{
|
lb := &loadBalancer{
|
||||||
name: tc.wantLB.name,
|
name: tc.wantLB.name,
|
||||||
@ -289,6 +337,7 @@ func TestTerminateLoadbalancers(t *testing.T) {
|
|||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,31 +346,35 @@ func TestTerminateLoadbalancers(t *testing.T) {
|
|||||||
addrAPI addressesAPI
|
addrAPI addressesAPI
|
||||||
healthAPI healthChecksAPI
|
healthAPI healthChecksAPI
|
||||||
backendAPI backendServicesAPI
|
backendAPI backendServicesAPI
|
||||||
|
targetAPI targetTCPProxiesAPI
|
||||||
forwardAPI forwardingRulesAPI
|
forwardAPI forwardingRulesAPI
|
||||||
opRegionAPI operationRegionAPI
|
opGlobalAPI operationGlobalAPI
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"successful terminate": {
|
"successful terminate": {
|
||||||
addrAPI: &stubAddressesAPI{},
|
addrAPI: &stubAddressesAPI{},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{},
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
targetAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{},
|
forwardAPI: &stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
},
|
},
|
||||||
"deleteIPAddr fails": {
|
"deleteIPAddr fails": {
|
||||||
addrAPI: &stubAddressesAPI{deleteErr: someErr},
|
addrAPI: &stubAddressesAPI{deleteErr: someErr},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{},
|
backendAPI: &stubBackendServicesAPI{},
|
||||||
|
targetAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{},
|
forwardAPI: &stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"deleteLB fails": {
|
"deleteLB fails": {
|
||||||
addrAPI: &stubAddressesAPI{},
|
addrAPI: &stubAddressesAPI{},
|
||||||
healthAPI: &stubHealthChecksAPI{},
|
healthAPI: &stubHealthChecksAPI{},
|
||||||
backendAPI: &stubBackendServicesAPI{deleteErr: someErr},
|
backendAPI: &stubBackendServicesAPI{deleteErr: someErr},
|
||||||
|
targetAPI: &stubTargetTCPProxiesAPI{},
|
||||||
forwardAPI: &stubForwardingRulesAPI{},
|
forwardAPI: &stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -339,8 +392,9 @@ func TestTerminateLoadbalancers(t *testing.T) {
|
|||||||
addressesAPI: tc.addrAPI,
|
addressesAPI: tc.addrAPI,
|
||||||
healthChecksAPI: tc.healthAPI,
|
healthChecksAPI: tc.healthAPI,
|
||||||
backendServicesAPI: tc.backendAPI,
|
backendServicesAPI: tc.backendAPI,
|
||||||
|
targetTCPProxiesAPI: tc.targetAPI,
|
||||||
forwardingRulesAPI: tc.forwardAPI,
|
forwardingRulesAPI: tc.forwardAPI,
|
||||||
operationRegionAPI: tc.opRegionAPI,
|
operationGlobalAPI: tc.opGlobalAPI,
|
||||||
loadbalancerIPname: "loadbalancerIPid",
|
loadbalancerIPname: "loadbalancerIPid",
|
||||||
loadbalancers: []*loadBalancer{
|
loadbalancers: []*loadBalancer{
|
||||||
newRunningLB(),
|
newRunningLB(),
|
||||||
@ -369,6 +423,7 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
return &loadBalancer{
|
return &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
}
|
}
|
||||||
@ -376,9 +431,10 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
lb *loadBalancer
|
lb *loadBalancer
|
||||||
opRegionAPI operationRegionAPI
|
opGlobalAPI operationGlobalAPI
|
||||||
healthChecksAPI healthChecksAPI
|
healthChecksAPI healthChecksAPI
|
||||||
backendServicesAPI backendServicesAPI
|
backendServicesAPI backendServicesAPI
|
||||||
|
targetTCPProxiesAPI targetTCPProxiesAPI
|
||||||
forwardingRulesAPI forwardingRulesAPI
|
forwardingRulesAPI forwardingRulesAPI
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantLB *loadBalancer
|
wantLB *loadBalancer
|
||||||
@ -388,7 +444,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"terminate partially created loadbalancer": {
|
"terminate partially created loadbalancer": {
|
||||||
@ -401,7 +458,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"terminate partially created loadbalancer 2": {
|
"terminate partially created loadbalancer 2": {
|
||||||
@ -414,7 +472,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{deleteErr: someErr},
|
backendServicesAPI: stubBackendServicesAPI{deleteErr: someErr},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"no-op for nil loadbalancer": {
|
"no-op for nil loadbalancer": {
|
||||||
@ -425,7 +484,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{deleteErr: notFoundErr},
|
healthChecksAPI: stubHealthChecksAPI{deleteErr: notFoundErr},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"backend service not found": {
|
"backend service not found": {
|
||||||
@ -433,7 +493,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{deleteErr: notFoundErr},
|
backendServicesAPI: stubBackendServicesAPI{deleteErr: notFoundErr},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"forwarding rules not found": {
|
"forwarding rules not found": {
|
||||||
@ -441,7 +502,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: notFoundErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: notFoundErr},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantLB: &loadBalancer{},
|
wantLB: &loadBalancer{},
|
||||||
},
|
},
|
||||||
"fails for loadbalancer without name": {
|
"fails for loadbalancer without name": {
|
||||||
@ -454,13 +516,15 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{deleteErr: someErr},
|
healthChecksAPI: stubHealthChecksAPI{deleteErr: someErr},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: false,
|
hasBackendService: false,
|
||||||
hasForwardingRules: false,
|
hasForwardingRules: false,
|
||||||
|
hasTargetTCPProxy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fails when deleting backend service": {
|
"fails when deleting backend service": {
|
||||||
@ -468,13 +532,15 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{deleteErr: someErr},
|
backendServicesAPI: stubBackendServicesAPI{deleteErr: someErr},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: false,
|
hasForwardingRules: false,
|
||||||
|
hasTargetTCPProxy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fails when deleting forwarding rule": {
|
"fails when deleting forwarding rule": {
|
||||||
@ -482,13 +548,31 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
forwardingRulesAPI: stubForwardingRulesAPI{deleteErr: someErr},
|
||||||
opRegionAPI: stubOperationRegionAPI{},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fails when deleting tcp proxy rule": {
|
||||||
|
lb: newRunningLB(),
|
||||||
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{deleteErr: someErr},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{},
|
||||||
|
wantErr: true,
|
||||||
|
wantLB: &loadBalancer{
|
||||||
|
name: "name",
|
||||||
|
hasHealthCheck: true,
|
||||||
|
hasBackendService: true,
|
||||||
|
hasForwardingRules: false,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fails when waiting on operation": {
|
"fails when waiting on operation": {
|
||||||
@ -496,13 +580,15 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
healthChecksAPI: stubHealthChecksAPI{},
|
healthChecksAPI: stubHealthChecksAPI{},
|
||||||
backendServicesAPI: stubBackendServicesAPI{},
|
backendServicesAPI: stubBackendServicesAPI{},
|
||||||
forwardingRulesAPI: stubForwardingRulesAPI{},
|
forwardingRulesAPI: stubForwardingRulesAPI{},
|
||||||
opRegionAPI: stubOperationRegionAPI{waitErr: someErr},
|
targetTCPProxiesAPI: stubTargetTCPProxiesAPI{},
|
||||||
|
opGlobalAPI: stubOperationGlobalAPI{waitErr: someErr},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
wantLB: &loadBalancer{
|
wantLB: &loadBalancer{
|
||||||
name: "name",
|
name: "name",
|
||||||
hasHealthCheck: true,
|
hasHealthCheck: true,
|
||||||
hasBackendService: true,
|
hasBackendService: true,
|
||||||
hasForwardingRules: true,
|
hasForwardingRules: true,
|
||||||
|
hasTargetTCPProxy: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -520,7 +606,8 @@ func TestTerminateLoadBalancer(t *testing.T) {
|
|||||||
backendServicesAPI: tc.backendServicesAPI,
|
backendServicesAPI: tc.backendServicesAPI,
|
||||||
forwardingRulesAPI: tc.forwardingRulesAPI,
|
forwardingRulesAPI: tc.forwardingRulesAPI,
|
||||||
healthChecksAPI: tc.healthChecksAPI,
|
healthChecksAPI: tc.healthChecksAPI,
|
||||||
operationRegionAPI: tc.opRegionAPI,
|
targetTCPProxiesAPI: tc.targetTCPProxiesAPI,
|
||||||
|
operationGlobalAPI: tc.opGlobalAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.terminateLoadBalancer(ctx, tc.lb)
|
err := client.terminateLoadBalancer(ctx, tc.lb)
|
||||||
@ -541,31 +628,31 @@ func TestCreateIPAddr(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
addrAPI addressesAPI
|
addrAPI addressesAPI
|
||||||
opAPI operationRegionAPI
|
opAPI operationGlobalAPI
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"successful create": {
|
"successful create": {
|
||||||
addrAPI: stubAddressesAPI{getAddr: proto.String("test-ip")},
|
addrAPI: stubAddressesAPI{getAddr: proto.String("test-ip")},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
},
|
},
|
||||||
"insert fails": {
|
"insert fails": {
|
||||||
addrAPI: stubAddressesAPI{insertErr: someErr},
|
addrAPI: stubAddressesAPI{insertErr: someErr},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"get fails": {
|
"get fails": {
|
||||||
addrAPI: stubAddressesAPI{getErr: someErr},
|
addrAPI: stubAddressesAPI{getErr: someErr},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"get address nil": {
|
"get address nil": {
|
||||||
addrAPI: stubAddressesAPI{getAddr: nil},
|
addrAPI: stubAddressesAPI{getAddr: nil},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"wait fails": {
|
"wait fails": {
|
||||||
addrAPI: stubAddressesAPI{},
|
addrAPI: stubAddressesAPI{},
|
||||||
opAPI: stubOperationRegionAPI{waitErr: someErr},
|
opAPI: stubOperationGlobalAPI{waitErr: someErr},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -581,7 +668,7 @@ func TestCreateIPAddr(t *testing.T) {
|
|||||||
name: "name",
|
name: "name",
|
||||||
uid: "uid",
|
uid: "uid",
|
||||||
addressesAPI: tc.addrAPI,
|
addressesAPI: tc.addrAPI,
|
||||||
operationRegionAPI: tc.opAPI,
|
operationGlobalAPI: tc.opAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.createIPAddr(ctx)
|
err := client.createIPAddr(ctx)
|
||||||
@ -603,33 +690,33 @@ func TestDeleteIPAddr(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
addrAPI addressesAPI
|
addrAPI addressesAPI
|
||||||
opAPI operationRegionAPI
|
opAPI operationGlobalAPI
|
||||||
addrID string
|
addrID string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"successful delete": {
|
"successful delete": {
|
||||||
addrAPI: stubAddressesAPI{},
|
addrAPI: stubAddressesAPI{},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
addrID: "name",
|
addrID: "name",
|
||||||
},
|
},
|
||||||
"not found": {
|
"not found": {
|
||||||
addrAPI: stubAddressesAPI{deleteErr: notFoundErr},
|
addrAPI: stubAddressesAPI{deleteErr: notFoundErr},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
addrID: "name",
|
addrID: "name",
|
||||||
},
|
},
|
||||||
"empty is no-op": {
|
"empty is no-op": {
|
||||||
addrAPI: stubAddressesAPI{},
|
addrAPI: stubAddressesAPI{},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
},
|
},
|
||||||
"delete fails": {
|
"delete fails": {
|
||||||
addrAPI: stubAddressesAPI{deleteErr: someErr},
|
addrAPI: stubAddressesAPI{deleteErr: someErr},
|
||||||
opAPI: stubOperationRegionAPI{},
|
opAPI: stubOperationGlobalAPI{},
|
||||||
addrID: "name",
|
addrID: "name",
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"wait fails": {
|
"wait fails": {
|
||||||
addrAPI: stubAddressesAPI{},
|
addrAPI: stubAddressesAPI{},
|
||||||
opAPI: stubOperationRegionAPI{waitErr: someErr},
|
opAPI: stubOperationGlobalAPI{waitErr: someErr},
|
||||||
addrID: "name",
|
addrID: "name",
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
@ -646,7 +733,7 @@ func TestDeleteIPAddr(t *testing.T) {
|
|||||||
name: "name",
|
name: "name",
|
||||||
uid: "uid",
|
uid: "uid",
|
||||||
addressesAPI: tc.addrAPI,
|
addressesAPI: tc.addrAPI,
|
||||||
operationRegionAPI: tc.opAPI,
|
operationGlobalAPI: tc.opAPI,
|
||||||
loadbalancerIPname: tc.addrID,
|
loadbalancerIPname: tc.addrID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,7 @@ import (
|
|||||||
platform "github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
platform "github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
||||||
"github.com/edgelesssys/constellation/internal/deploy/user"
|
"github.com/edgelesssys/constellation/internal/deploy/user"
|
||||||
"github.com/edgelesssys/constellation/internal/iproute"
|
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/internal/role"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,9 +67,6 @@ func main() {
|
|||||||
log.Fatalf("%s", err)
|
log.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
fetcher = gcpFetcher
|
fetcher = gcpFetcher
|
||||||
if err := setLoadbalancerRoute(ctx, fetcher); err != nil {
|
|
||||||
log.Errorf("adding load balancer IP to local routing table: %s", err)
|
|
||||||
}
|
|
||||||
log.Infof("Added load balancer IP to local routing table")
|
log.Infof("Added load balancer IP to local routing table")
|
||||||
case platform.QEMU:
|
case platform.QEMU:
|
||||||
fetcher = cloudprovider.NewQEMU()
|
fetcher = cloudprovider.NewQEMU()
|
||||||
@ -108,18 +103,3 @@ func writeDebugBanner(log *logger.Logger) {
|
|||||||
log.Infof("Unable to print to /dev/ttyS0: %v", err)
|
log.Infof("Unable to print to /dev/ttyS0: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLoadbalancerRoute(ctx context.Context, fetcher metadata.Fetcher) error {
|
|
||||||
ownRole, err := fetcher.Role(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if ownRole != role.ControlPlane {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ip, err := fetcher.DiscoverLoadbalancerIP(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return iproute.AddToLocalRoutingTable(ctx, ip)
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,7 @@ type subnetworkAPI interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type forwardingRulesAPI interface {
|
type forwardingRulesAPI interface {
|
||||||
List(ctx context.Context, req *computepb.ListForwardingRulesRequest, opts ...gax.CallOption) ForwardingRuleIterator
|
List(ctx context.Context, req *computepb.ListGlobalForwardingRulesRequest, opts ...gax.CallOption) ForwardingRuleIterator
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func NewClient(ctx context.Context) (*Client, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
forwardingRulesAPI, err := compute.NewForwardingRulesRESTClient(ctx)
|
forwardingRulesAPI, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -222,20 +222,14 @@ func (c *Client) RetrieveSubnetworkAliasCIDR(ctx context.Context, project, zone,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveLoadBalancerEndpoint returns the endpoint of the load balancer with the constellation-uid tag.
|
// RetrieveLoadBalancerEndpoint returns the endpoint of the load balancer with the constellation-uid tag.
|
||||||
func (c *Client) RetrieveLoadBalancerEndpoint(ctx context.Context, project, zone string) (string, error) {
|
func (c *Client) RetrieveLoadBalancerEndpoint(ctx context.Context, project string) (string, error) {
|
||||||
uid, err := c.UID()
|
uid, err := c.UID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
region := zoneFromRegionRegex.FindString(zone)
|
req := &computepb.ListGlobalForwardingRulesRequest{
|
||||||
if region == "" {
|
|
||||||
return "", fmt.Errorf("invalid zone %s", zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
req := &computepb.ListForwardingRulesRequest{
|
|
||||||
Project: project,
|
Project: project,
|
||||||
Region: region,
|
|
||||||
}
|
}
|
||||||
iter := c.forwardingRulesAPI.List(ctx, req)
|
iter := c.forwardingRulesAPI.List(ctx, req)
|
||||||
for {
|
for {
|
||||||
@ -247,10 +241,11 @@ func (c *Client) RetrieveLoadBalancerEndpoint(ctx context.Context, project, zone
|
|||||||
return "", fmt.Errorf("retrieving load balancer IP failed: %w", err)
|
return "", fmt.Errorf("retrieving load balancer IP failed: %w", err)
|
||||||
}
|
}
|
||||||
if resp.Labels["constellation-uid"] == uid {
|
if resp.Labels["constellation-uid"] == uid {
|
||||||
if len(resp.Ports) == 0 {
|
if resp.PortRange == nil {
|
||||||
return "", errors.New("load balancer with searched UID has no ports")
|
return "", errors.New("load balancer with searched UID has no ports")
|
||||||
}
|
}
|
||||||
return net.JoinHostPort(*resp.IPAddress, resp.Ports[0]), nil
|
portRange := strings.Split(*resp.PortRange, "-")
|
||||||
|
return net.JoinHostPort(*resp.IPAddress, portRange[0]), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +796,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
|
|||||||
rules: []*computepb.ForwardingRule{
|
rules: []*computepb.ForwardingRule{
|
||||||
{
|
{
|
||||||
IPAddress: proto.String(loadBalancerIP),
|
IPAddress: proto.String(loadBalancerIP),
|
||||||
Ports: []string{"100"},
|
PortRange: proto.String("100-100"),
|
||||||
Labels: map[string]string{"constellation-uid": uid},
|
Labels: map[string]string{"constellation-uid": uid},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -811,7 +811,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
|
|||||||
rules: []*computepb.ForwardingRule{
|
rules: []*computepb.ForwardingRule{
|
||||||
{
|
{
|
||||||
IPAddress: proto.String(loadBalancerIP),
|
IPAddress: proto.String(loadBalancerIP),
|
||||||
Ports: []string{"100"},
|
PortRange: proto.String("100-100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -825,7 +825,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
|
|||||||
rules: []*computepb.ForwardingRule{
|
rules: []*computepb.ForwardingRule{
|
||||||
{
|
{
|
||||||
IPAddress: proto.String(loadBalancerIP),
|
IPAddress: proto.String(loadBalancerIP),
|
||||||
Ports: []string{"100"},
|
PortRange: proto.String("100-100"),
|
||||||
Labels: map[string]string{"constellation-uid": uid},
|
Labels: map[string]string{"constellation-uid": uid},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -855,7 +855,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
|
|||||||
rules: []*computepb.ForwardingRule{
|
rules: []*computepb.ForwardingRule{
|
||||||
{
|
{
|
||||||
IPAddress: proto.String(loadBalancerIP),
|
IPAddress: proto.String(loadBalancerIP),
|
||||||
Ports: []string{"100"},
|
PortRange: proto.String("100-100"),
|
||||||
Labels: map[string]string{"constellation-uid": uid},
|
Labels: map[string]string{"constellation-uid": uid},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -870,7 +870,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
|
|||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
client := Client{forwardingRulesAPI: tc.stubForwardingRulesClient, metadataAPI: tc.stubMetadataClient}
|
client := Client{forwardingRulesAPI: tc.stubForwardingRulesClient, metadataAPI: tc.stubMetadataClient}
|
||||||
aliasCIDR, err := client.RetrieveLoadBalancerEndpoint(context.Background(), "project", "us-central1-a")
|
aliasCIDR, err := client.RetrieveLoadBalancerEndpoint(context.Background(), "project")
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
@ -1038,7 +1038,7 @@ type stubForwardingRulesClient struct {
|
|||||||
CloseErr error
|
CloseErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s stubForwardingRulesClient) List(ctx context.Context, req *computepb.ListForwardingRulesRequest, opts ...gax.CallOption) ForwardingRuleIterator {
|
func (s stubForwardingRulesClient) List(ctx context.Context, req *computepb.ListGlobalForwardingRulesRequest, opts ...gax.CallOption) ForwardingRuleIterator {
|
||||||
return s.ForwardingRuleIterator
|
return s.ForwardingRuleIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ type API interface {
|
|||||||
// RetrieveSubnetworkAliasCIDR retrieves the subnetwork CIDR of the current instance.
|
// RetrieveSubnetworkAliasCIDR retrieves the subnetwork CIDR of the current instance.
|
||||||
RetrieveSubnetworkAliasCIDR(ctx context.Context, project, zone, instanceName string) (string, error)
|
RetrieveSubnetworkAliasCIDR(ctx context.Context, project, zone, instanceName string) (string, error)
|
||||||
// RetrieveLoadBalancerEndpoint retrieves the load balancer endpoint of the current instance.
|
// RetrieveLoadBalancerEndpoint retrieves the load balancer endpoint of the current instance.
|
||||||
RetrieveLoadBalancerEndpoint(ctx context.Context, project, zone string) (string, error)
|
RetrieveLoadBalancerEndpoint(ctx context.Context, project string) (string, error)
|
||||||
// SetInstanceMetadata sets metadata key: value of the instance specified by project, zone and instanceName.
|
// SetInstanceMetadata sets metadata key: value of the instance specified by project, zone and instanceName.
|
||||||
SetInstanceMetadata(ctx context.Context, project, zone, instanceName, key, value string) error
|
SetInstanceMetadata(ctx context.Context, project, zone, instanceName, key, value string) error
|
||||||
// UnsetInstanceMetadata removes a metadata key-value pair of the instance specified by project, zone and instanceName.
|
// UnsetInstanceMetadata removes a metadata key-value pair of the instance specified by project, zone and instanceName.
|
||||||
@ -123,11 +123,7 @@ func (m *Metadata) GetLoadBalancerEndpoint(ctx context.Context) (string, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
zone, err := m.api.RetrieveZone()
|
return m.api.RetrieveLoadBalancerEndpoint(ctx, project)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return m.api.RetrieveLoadBalancerEndpoint(ctx, project, zone)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UID retrieves the UID of the constellation.
|
// UID retrieves the UID of the constellation.
|
||||||
|
@ -293,7 +293,7 @@ func (s *stubGCPClient) RetrieveInstanceName() (string, error) {
|
|||||||
return s.instanceName, s.retrieveInstanceNameErr
|
return s.instanceName, s.retrieveInstanceNameErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubGCPClient) RetrieveLoadBalancerEndpoint(ctx context.Context, project, zone string) (string, error) {
|
func (s *stubGCPClient) RetrieveLoadBalancerEndpoint(ctx context.Context, project string) (string, error) {
|
||||||
return s.loadBalancerIP, s.retrieveLoadBalancerErr
|
return s.loadBalancerIP, s.retrieveLoadBalancerErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,17 +50,17 @@ func (c *subnetworkClient) Get(ctx context.Context, req *computepb.GetSubnetwork
|
|||||||
}
|
}
|
||||||
|
|
||||||
type forwardingRulesClient struct {
|
type forwardingRulesClient struct {
|
||||||
*compute.ForwardingRulesClient
|
*compute.GlobalForwardingRulesClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) Close() error {
|
func (c *forwardingRulesClient) Close() error {
|
||||||
return c.ForwardingRulesClient.Close()
|
return c.GlobalForwardingRulesClient.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *forwardingRulesClient) List(ctx context.Context, req *computepb.ListForwardingRulesRequest,
|
func (c *forwardingRulesClient) List(ctx context.Context, req *computepb.ListGlobalForwardingRulesRequest,
|
||||||
opts ...gax.CallOption,
|
opts ...gax.CallOption,
|
||||||
) ForwardingRuleIterator {
|
) ForwardingRuleIterator {
|
||||||
return c.ForwardingRulesClient.List(ctx, req)
|
return c.GlobalForwardingRulesClient.List(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type metadataClient struct{}
|
type metadataClient struct{}
|
||||||
|
@ -47,6 +47,7 @@ const (
|
|||||||
SSHPort = 22
|
SSHPort = 22
|
||||||
NVMEOverTCPPort = 8009
|
NVMEOverTCPPort = 8009
|
||||||
DebugdPort = 4000
|
DebugdPort = 4000
|
||||||
|
KonnectivityPort = 8132
|
||||||
// Default NodePort Range
|
// Default NodePort Range
|
||||||
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||||
NodePortFrom = 30000
|
NodePortFrom = 30000
|
||||||
|
@ -42,6 +42,13 @@ var (
|
|||||||
IPRange: "0.0.0.0/0",
|
IPRange: "0.0.0.0/0",
|
||||||
FromPort: KubernetesPort,
|
FromPort: KubernetesPort,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "konnectivity",
|
||||||
|
Description: "konnectivity",
|
||||||
|
Protocol: "tcp",
|
||||||
|
IPRange: "0.0.0.0/0",
|
||||||
|
FromPort: KonnectivityPort,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// IngressRulesDebug is the default set of ingress rules for a Constellation cluster with debug mode.
|
// IngressRulesDebug is the default set of ingress rules for a Constellation cluster with debug mode.
|
||||||
|
@ -36,6 +36,11 @@ func ServiceIsUnavailable(err error) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retry if GCP proxy LB isn't fully available yet
|
||||||
|
if strings.HasPrefix(statusErr.Message(), `connection error: desc = "transport: authentication handshake failed: EOF"`) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// ideally we would check the error type directly, but grpc only provides a string
|
// ideally we would check the error type directly, but grpc only provides a string
|
||||||
return !strings.HasPrefix(statusErr.Message(), `connection error: desc = "transport: authentication handshake failed`)
|
return !strings.HasPrefix(statusErr.Message(), `connection error: desc = "transport: authentication handshake failed`)
|
||||||
}
|
}
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) Edgeless Systems GmbH
|
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package iproute
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddToLocalRoutingTable adds the IP to the local routing table.
|
|
||||||
func AddToLocalRoutingTable(ctx context.Context, ip string) error {
|
|
||||||
return manipulateLocalRoutingTable(ctx, "add", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveFromLocalRoutingTable removes the IPfrom the local routing table.
|
|
||||||
func RemoveFromLocalRoutingTable(ctx context.Context, ip string) error {
|
|
||||||
return manipulateLocalRoutingTable(ctx, "del", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
func manipulateLocalRoutingTable(ctx context.Context, action string, ip string) error {
|
|
||||||
// https://github.com/GoogleCloudPlatform/guest-agent/blob/792fce795218633bcbde505fb3457a0b24f26d37/google_guest_agent/addresses.go#L179
|
|
||||||
if !strings.Contains(ip, "/") {
|
|
||||||
ip = ip + "/32"
|
|
||||||
}
|
|
||||||
|
|
||||||
args := []string{"route", action, "to", "local", ip, "scope", "host", "dev", "ens3", "proto", "66"}
|
|
||||||
_, err := exec.CommandContext(ctx, "ip", args...).Output()
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var exitErr *exec.ExitError
|
|
||||||
if !errors.As(err, &exitErr) {
|
|
||||||
return fmt.Errorf("ip route %s: %w", action, err)
|
|
||||||
}
|
|
||||||
if exitErr.ExitCode() == 2 {
|
|
||||||
// "RTNETLINK answers: File exists" or "RTNETLINK answers: No such process"
|
|
||||||
//
|
|
||||||
// Ignore, expected in case of adding an existing route or deleting a route
|
|
||||||
// that does not exist.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("ip route %s (code %v) with: %s", action, exitErr.ExitCode(), exitErr.Stderr)
|
|
||||||
}
|
|
@ -43,6 +43,8 @@ func IsPreviewK8sVersion(version ValidK8sVersion) bool {
|
|||||||
const (
|
const (
|
||||||
// Constellation images.
|
// Constellation images.
|
||||||
// These images are built in a way that they support all versions currently listed in VersionConfigs.
|
// These images are built in a way that they support all versions currently listed in VersionConfigs.
|
||||||
|
KonnectivityAgentImage = "us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent:v0.0.32"
|
||||||
|
KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.0.32"
|
||||||
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v0.0.2-0.20220905091720-bd6c6ce836af"
|
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v0.0.2-0.20220905091720-bd6c6ce836af"
|
||||||
AccessManagerImage = "ghcr.io/edgelesssys/constellation/access-manager:v0.0.1"
|
AccessManagerImage = "ghcr.io/edgelesssys/constellation/access-manager:v0.0.1"
|
||||||
KmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:v0.0.2-0.20220831181049-47d4c9e30423"
|
KmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:v0.0.2-0.20220831181049-47d4c9e30423"
|
||||||
|
Loading…
Reference in New Issue
Block a user