Merge pull request #11498 from johngmyers/cloud-statusstore

Subsume StatusStore into fi.Cloud
This commit is contained in:
Kubernetes Prow Robot 2021-05-18 06:29:31 -07:00 committed by GitHub
commit a1e331a46b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 390 additions and 508 deletions

View File

@ -132,7 +132,7 @@ func (c *MockGCECloud) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterSt
} }
// GetApiIngressStatus implements GCECloud::GetApiIngressStatus // GetApiIngressStatus implements GCECloud::GetApiIngressStatus
func (c *MockGCECloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *MockGCECloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return nil, fmt.Errorf("MockGCECloud::GetApiIngressStatus not implemented") return nil, fmt.Errorf("MockGCECloud::GetApiIngressStatus not implemented")
} }

View File

@ -243,8 +243,7 @@ func RunEditCluster(ctx context.Context, f *util.Factory, cmd *cobra.Command, ar
} }
// Retrieve the current status of the cluster. This will eventually be part of the cluster object. // Retrieve the current status of the cluster. This will eventually be part of the cluster object.
statusDiscovery := &commands.CloudDiscoveryStatusStore{} status, err := cloud.FindClusterStatus(oldCluster)
status, err := statusDiscovery.FindClusterStatus(oldCluster)
if err != nil { if err != nil {
return err return err
} }

View File

@ -27,8 +27,8 @@ import (
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
kopsapi "k8s.io/kops/pkg/apis/kops" kopsapi "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/commands"
"k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/pkg/kubeconfig"
"k8s.io/kops/upup/pkg/fi/cloudup"
"k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates" "k8s.io/kubectl/pkg/util/templates"
) )
@ -139,11 +139,15 @@ func RunExportKubecfg(ctx context.Context, f *util.Factory, out io.Writer, optio
return err return err
} }
cloud, err := cloudup.BuildCloud(cluster)
if err != nil {
return err
}
conf, err := kubeconfig.BuildKubecfg( conf, err := kubeconfig.BuildKubecfg(
cluster, cluster,
keyStore, keyStore,
secretStore, secretStore,
&commands.CloudDiscoveryStatusStore{}, cloud,
options.admin, options.admin,
options.user, options.user,
options.internal, options.internal,

View File

@ -27,8 +27,8 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
kopsapi "k8s.io/kops/pkg/apis/kops" kopsapi "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/commands"
"k8s.io/kops/pkg/kopscodecs" "k8s.io/kops/pkg/kopscodecs"
"k8s.io/kops/upup/pkg/fi/cloudup"
"k8s.io/kops/util/pkg/text" "k8s.io/kops/util/pkg/text"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"
cmdutil "k8s.io/kubectl/pkg/cmd/util" cmdutil "k8s.io/kubectl/pkg/cmd/util"
@ -120,8 +120,11 @@ func RunReplace(ctx context.Context, f *util.Factory, cmd *cobra.Command, out io
case *kopsapi.Cluster: case *kopsapi.Cluster:
{ {
// Retrieve the current status of the cluster. This will eventually be part of the cluster object. // Retrieve the current status of the cluster. This will eventually be part of the cluster object.
statusDiscovery := &commands.CloudDiscoveryStatusStore{} cloud, err := cloudup.BuildCloud(v)
status, err := statusDiscovery.FindClusterStatus(v) if err != nil {
return err
}
status, err := cloud.FindClusterStatus(v)
if err != nil { if err != nil {
return err return err
} }

View File

@ -32,7 +32,6 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/commands"
"k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/pkg/kubeconfig"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup" "k8s.io/kops/upup/pkg/fi/cloudup"
@ -318,7 +317,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, clusterName string,
cluster, cluster,
keyStore, keyStore,
secretStore, secretStore,
&commands.CloudDiscoveryStatusStore{}, cloud,
c.admin, c.admin,
c.user, c.user,
c.internal, c.internal,

View File

@ -16,18 +16,6 @@ limitations under the License.
package kops package kops
import (
"k8s.io/klog/v2"
)
// StatusStore abstracts the key status functions; and lets us introduce status gradually
type StatusStore interface {
// FindClusterStatus discovers the status of the cluster, by inspecting the cloud objects
FindClusterStatus(cluster *Cluster) (*ClusterStatus, error)
GetApiIngressStatus(cluster *Cluster) ([]ApiIngressStatus, error)
}
type ClusterStatus struct { type ClusterStatus struct {
// EtcdClusters stores the status for each cluster // EtcdClusters stores the status for each cluster
EtcdClusters []EtcdClusterStatus `json:"etcdClusters,omitempty"` EtcdClusters []EtcdClusterStatus `json:"etcdClusters,omitempty"`
@ -48,35 +36,3 @@ type EtcdMemberStatus struct {
// volumeId is the id of the cloud volume (e.g. the AWS volume id) // volumeId is the id of the cloud volume (e.g. the AWS volume id)
VolumeId string `json:"volumeId,omitempty"` VolumeId string `json:"volumeId,omitempty"`
} }
// ApiIngressStatus represents the status of an ingress point:
// traffic intended for the service should be sent to an ingress point.
type ApiIngressStatus struct {
// IP is set for load-balancer ingress points that are IP based
// (typically GCE or OpenStack load-balancers)
// +optional
IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"`
// Hostname is set for load-balancer ingress points that are DNS based
// (typically AWS load-balancers)
// +optional
Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`
}
// NoopStatusStore is a stub implementation that returns empty status
// It is a temporary hackaround while we introduce status
type NoopStatusStore struct {
}
var _ StatusStore = &NoopStatusStore{}
// FindClusterStatus discovers the status of the cluster, by inspecting the cloud objects
func (s *NoopStatusStore) FindClusterStatus(cluster *Cluster) (*ClusterStatus, error) {
klog.Warningf("FindClusterStatus called on NoopStore")
return nil, nil
}
func (s *NoopStatusStore) GetApiIngressStatus(cluster *Cluster) ([]ApiIngressStatus, error) {
klog.Warningf("GetApiIngressStatus called on NoopStore")
return nil, nil
}

View File

@ -91,7 +91,7 @@ func validateEtcdClusterUpdate(fp *field.Path, obj kops.EtcdClusterSpec, status
fp := fp.Child("etcdMembers").Key(k) fp := fp.Child("etcdMembers").Key(k)
if oldMember, ok := oldMembers[k]; ok { if oldMember, ok := oldMembers[k]; ok {
allErrs = append(allErrs, validateEtcdMemberUpdate(fp, newMember, etcdClusterStatus, oldMember)...) allErrs = append(allErrs, validateEtcdMemberUpdate(fp, newMember, oldMember)...)
} }
} }
} }
@ -99,7 +99,7 @@ func validateEtcdClusterUpdate(fp *field.Path, obj kops.EtcdClusterSpec, status
return allErrs return allErrs
} }
func validateEtcdMemberUpdate(fp *field.Path, obj kops.EtcdMemberSpec, status *kops.EtcdClusterStatus, old kops.EtcdMemberSpec) field.ErrorList { func validateEtcdMemberUpdate(fp *field.Path, obj kops.EtcdMemberSpec, old kops.EtcdMemberSpec) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if obj.Name != old.Name { if obj.Name != old.Name {

View File

@ -183,22 +183,6 @@ func (in *AmazonVPCNetworkingSpec) DeepCopy() *AmazonVPCNetworkingSpec {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApiIngressStatus) DeepCopyInto(out *ApiIngressStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiIngressStatus.
func (in *ApiIngressStatus) DeepCopy() *ApiIngressStatus {
if in == nil {
return nil
}
out := new(ApiIngressStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Assets) DeepCopyInto(out *Assets) { func (in *Assets) DeepCopyInto(out *Assets) {
*out = *in *out = *in
@ -4183,22 +4167,6 @@ func (in *NodeTerminationHandlerConfig) DeepCopy() *NodeTerminationHandlerConfig
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NoopStatusStore) DeepCopyInto(out *NoopStatusStore) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NoopStatusStore.
func (in *NoopStatusStore) DeepCopy() *NoopStatusStore {
if in == nil {
return nil
}
out := new(NoopStatusStore)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OpenstackBlockStorageConfig) DeepCopyInto(out *OpenstackBlockStorageConfig) { func (in *OpenstackBlockStorageConfig) DeepCopyInto(out *OpenstackBlockStorageConfig) {
*out = *in *out = *in

View File

@ -7,7 +7,6 @@ go_library(
"helpers_readwrite.go", "helpers_readwrite.go",
"set_cluster.go", "set_cluster.go",
"set_instancegroups.go", "set_instancegroups.go",
"status_discovery.go",
"version.go", "version.go",
], ],
importpath = "k8s.io/kops/pkg/commands", importpath = "k8s.io/kops/pkg/commands",
@ -21,14 +20,7 @@ go_library(
"//pkg/client/simple:go_default_library", "//pkg/client/simple:go_default_library",
"//pkg/commands/helpers:go_default_library", "//pkg/commands/helpers:go_default_library",
"//pkg/featureflag:go_default_library", "//pkg/featureflag:go_default_library",
"//pkg/resources/digitalocean:go_default_library",
"//upup/pkg/fi/cloudup:go_default_library", "//upup/pkg/fi/cloudup:go_default_library",
"//upup/pkg/fi/cloudup/aliup:go_default_library",
"//upup/pkg/fi/cloudup/awstasks:go_default_library",
"//upup/pkg/fi/cloudup/awsup:go_default_library",
"//upup/pkg/fi/cloudup/azure:go_default_library",
"//upup/pkg/fi/cloudup/gce:go_default_library",
"//upup/pkg/fi/cloudup/openstack:go_default_library",
"//util/pkg/reflectutils:go_default_library", "//util/pkg/reflectutils:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -52,8 +52,7 @@ func UpdateCluster(ctx context.Context, clientset simple.Clientset, cluster *kop
} }
// Retrieve the current status of the cluster. This will eventually be part of the cluster object. // Retrieve the current status of the cluster. This will eventually be part of the cluster object.
statusDiscovery := &CloudDiscoveryStatusStore{} status, err := cloud.FindClusterStatus(cluster)
status, err := statusDiscovery.FindClusterStatus(cluster)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,112 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package commands
import (
"fmt"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/resources/digitalocean"
"k8s.io/kops/upup/pkg/fi/cloudup"
"k8s.io/kops/upup/pkg/fi/cloudup/aliup"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/azure"
"k8s.io/kops/upup/pkg/fi/cloudup/gce"
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
)
// CloudDiscoveryStatusStore implements status.Store by inspecting cloud objects.
// Likely temporary until we validate our status usage
type CloudDiscoveryStatusStore struct {
}
var _ kops.StatusStore = &CloudDiscoveryStatusStore{}
func (s *CloudDiscoveryStatusStore) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) {
cloud, err := cloudup.BuildCloud(cluster)
if err != nil {
return nil, err
}
if aliCloud, ok := cloud.(aliup.ALICloud); ok {
return aliCloud.GetApiIngressStatus(cluster)
}
if gceCloud, ok := cloud.(gce.GCECloud); ok {
return gceCloud.GetApiIngressStatus(cluster)
}
if awsCloud, ok := cloud.(awsup.AWSCloud); ok {
var ingresses []kops.ApiIngressStatus
if lbDnsName, err := awstasks.FindDNSName(awsCloud, cluster); err != nil {
return nil, fmt.Errorf("error finding aws DNSName: %v", err)
} else if lbDnsName != "" {
ingresses = append(ingresses, kops.ApiIngressStatus{Hostname: lbDnsName})
}
return ingresses, nil
}
if azureCloud, ok := cloud.(azure.AzureCloud); ok {
return azureCloud.GetApiIngressStatus(cluster)
}
if osCloud, ok := cloud.(openstack.OpenstackCloud); ok {
return osCloud.GetApiIngressStatus(cluster)
}
if doCloud, ok := cloud.(*digitalocean.Cloud); ok {
return doCloud.GetApiIngressStatus(cluster)
}
return nil, fmt.Errorf("API Ingress Status not implemented for %T", cloud)
}
// FindClusterStatus discovers the status of the cluster, by inspecting the cloud objects
func (s *CloudDiscoveryStatusStore) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {
cloud, err := cloudup.BuildCloud(cluster)
if err != nil {
return nil, err
}
if gceCloud, ok := cloud.(gce.GCECloud); ok {
return gceCloud.FindClusterStatus(cluster)
}
if awsCloud, ok := cloud.(awsup.AWSCloud); ok {
return awsCloud.FindClusterStatus(cluster)
}
if aliCloud, ok := cloud.(aliup.ALICloud); ok {
return aliCloud.FindClusterStatus(cluster)
}
if azureCloud, ok := cloud.(azure.AzureCloud); ok {
return azureCloud.FindClusterStatus(cluster)
}
if osCloud, ok := cloud.(openstack.OpenstackCloud); ok {
return osCloud.FindClusterStatus(cluster)
}
if doCloud, ok := cloud.(*digitalocean.Cloud); ok {
return doCloud.FindClusterStatus(cluster)
}
return nil, fmt.Errorf("etcd Status not implemented for %T", cloud)
}

View File

@ -28,11 +28,14 @@ go_test(
srcs = ["create_kubecfg_test.go"], srcs = ["create_kubecfg_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//dnsprovider/pkg/dnsprovider:go_default_library",
"//pkg/apis/kops:go_default_library", "//pkg/apis/kops:go_default_library",
"//pkg/cloudinstances:go_default_library",
"//pkg/pki:go_default_library", "//pkg/pki:go_default_library",
"//pkg/testutils:go_default_library", "//pkg/testutils:go_default_library",
"//upup/pkg/fi:go_default_library", "//upup/pkg/fi:go_default_library",
"//util/pkg/vfs:go_default_library", "//util/pkg/vfs:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library", "//vendor/github.com/google/go-cmp/cmp:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
], ],
) )

View File

@ -34,7 +34,7 @@ import (
const DefaultKubecfgAdminLifetime = 18 * time.Hour const DefaultKubecfgAdminLifetime = 18 * time.Hour
func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, status kops.StatusStore, admin time.Duration, configUser string, internal bool, kopsStateStore string, useKopsAuthenticationPlugin bool) (*KubeconfigBuilder, error) { func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, cloud fi.Cloud, admin time.Duration, configUser string, internal bool, kopsStateStore string, useKopsAuthenticationPlugin bool) (*KubeconfigBuilder, error) {
clusterName := cluster.ObjectMeta.Name clusterName := cluster.ObjectMeta.Name
var master string var master string
@ -71,7 +71,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se
} }
if useELBName { if useELBName {
ingresses, err := status.GetApiIngressStatus(cluster) ingresses, err := cloud.GetApiIngressStatus(cluster)
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting ingress status: %v", err) return nil, fmt.Errorf("error getting ingress status: %v", err)
} }

View File

@ -21,6 +21,9 @@ import (
"testing" "testing"
"time" "time"
v1 "k8s.io/api/core/v1"
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
"k8s.io/kops/pkg/cloudinstances"
"k8s.io/kops/pkg/testutils" "k8s.io/kops/pkg/testutils"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
@ -34,19 +37,52 @@ const certData = "-----BEGIN CERTIFICATE-----\nMIIC2DCCAcCgAwIBAgIRALJXAkVj964tq
const privatekeyData = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA4JwpEprZ5n8RIEt6jT2lAh+UDgRgx/4px21gjgywQivYHVxH\nAZexVb/E9pBa9Q2G9B1Q7TCO7YsUVRQy4JMDZVt+McFnWVwexnqBYFNcVjkEmDgA\ngvCYGE0P9d/RwRL4KuLHo+u6fv7P0jXMN+CpOxyLhYZZNa0ZOZDHsSiJSQSj9WGF\nGHrbCf0KVDpKieR1uBqHrRO+mLR5zkX2L58m74kjK4dsBhmjeq/7OAoTmiG2QgJ/\nP2IjyhiA2mRqY+hl55lwEUV/0yHYEkJC8LdGkwwZz2eF77aSPGmi/A2CSKgMwDTx\n9m+P7jcpWreYw6NG9BueGoDIve/tgFKwvVFF6QIDAQABAoIBAA0ktjaTfyrAxsTI\nBezb7Zr5NBW55dvuII299cd6MJo+rI/TRYhvUv48kY8IFXp/hyUjzgeDLunxmIf9\n/Zgsoic9Ol44/g45mMduhcGYPzAAeCdcJ5OB9rR9VfDCXyjYLlN8H8iU0734tTqM\n0V13tQ9zdSqkGPZOIcq/kR/pylbOZaQMe97BTlsAnOMSMKDgnftY4122Lq3GYy+t\nvpr+bKVaQZwvkLoSU3rECCaKaghgwCyX7jft9aEkhdJv+KlwbsGY6WErvxOaLWHd\ncuMQjGapY1Fa/4UD00mvrA260NyKfzrp6+P46RrVMwEYRJMIQ8YBAk6N6Hh7dc0G\n8Z6i1m0CgYEA9HeCJR0TSwbIQ1bDXUrzpftHuidG5BnSBtax/ND9qIPhR/FBW5nj\n22nwLc48KkyirlfIULd0ae4qVXJn7wfYcuX/cJMLDmSVtlM5Dzmi/91xRiFgIzx1\nAsbBzaFjISP2HpSgL+e9FtSXaaqeZVrflitVhYKUpI/AKV31qGHf04sCgYEA6zTV\n99Sb49Wdlns5IgsfnXl6ToRttB18lfEKcVfjAM4frnkk06JpFAZeR+9GGKUXZHqs\nz2qcplw4d/moCC6p3rYPBMLXsrGNEUFZqBlgz72QA6BBq3X0Cg1Bc2ZbK5VIzwkg\nST2SSux6ccROfgULmN5ZiLOtdUKNEZpFF3i3qtsCgYADT/s7dYFlatobz3kmMnXK\nsfTu2MllHdRys0YGHu7Q8biDuQkhrJwhxPW0KS83g4JQym+0aEfzh36bWcl+u6R7\nKhKj+9oSf9pndgk345gJz35RbPJYh+EuAHNvzdgCAvK6x1jETWeKf6btj5pF1U1i\nQ4QNIw/QiwIXjWZeubTGsQKBgQCbduLu2rLnlyyAaJZM8DlHZyH2gAXbBZpxqU8T\nt9mtkJDUS/KRiEoYGFV9CqS0aXrayVMsDfXY6B/S/UuZjO5u7LtklDzqOf1aKG3Q\ndGXPKibknqqJYH+bnUNjuYYNerETV57lijMGHuSYCf8vwLn3oxBfERRX61M/DU8Z\nworz/QKBgQDCTJI2+jdXg26XuYUmM4XXfnocfzAXhXBULt1nENcogNf1fcptAVtu\nBAiz4/HipQKqoWVUYmxfgbbLRKKLK0s0lOWKbYdVjhEm/m2ZU8wtXTagNwkIGoyq\nY/C1Lox4f1ROJnCjc/hfcOjcxX5M8A8peecHWlVtUPKTJgxQ7oMKcw==\n-----END RSA PRIVATE KEY-----\n" const privatekeyData = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA4JwpEprZ5n8RIEt6jT2lAh+UDgRgx/4px21gjgywQivYHVxH\nAZexVb/E9pBa9Q2G9B1Q7TCO7YsUVRQy4JMDZVt+McFnWVwexnqBYFNcVjkEmDgA\ngvCYGE0P9d/RwRL4KuLHo+u6fv7P0jXMN+CpOxyLhYZZNa0ZOZDHsSiJSQSj9WGF\nGHrbCf0KVDpKieR1uBqHrRO+mLR5zkX2L58m74kjK4dsBhmjeq/7OAoTmiG2QgJ/\nP2IjyhiA2mRqY+hl55lwEUV/0yHYEkJC8LdGkwwZz2eF77aSPGmi/A2CSKgMwDTx\n9m+P7jcpWreYw6NG9BueGoDIve/tgFKwvVFF6QIDAQABAoIBAA0ktjaTfyrAxsTI\nBezb7Zr5NBW55dvuII299cd6MJo+rI/TRYhvUv48kY8IFXp/hyUjzgeDLunxmIf9\n/Zgsoic9Ol44/g45mMduhcGYPzAAeCdcJ5OB9rR9VfDCXyjYLlN8H8iU0734tTqM\n0V13tQ9zdSqkGPZOIcq/kR/pylbOZaQMe97BTlsAnOMSMKDgnftY4122Lq3GYy+t\nvpr+bKVaQZwvkLoSU3rECCaKaghgwCyX7jft9aEkhdJv+KlwbsGY6WErvxOaLWHd\ncuMQjGapY1Fa/4UD00mvrA260NyKfzrp6+P46RrVMwEYRJMIQ8YBAk6N6Hh7dc0G\n8Z6i1m0CgYEA9HeCJR0TSwbIQ1bDXUrzpftHuidG5BnSBtax/ND9qIPhR/FBW5nj\n22nwLc48KkyirlfIULd0ae4qVXJn7wfYcuX/cJMLDmSVtlM5Dzmi/91xRiFgIzx1\nAsbBzaFjISP2HpSgL+e9FtSXaaqeZVrflitVhYKUpI/AKV31qGHf04sCgYEA6zTV\n99Sb49Wdlns5IgsfnXl6ToRttB18lfEKcVfjAM4frnkk06JpFAZeR+9GGKUXZHqs\nz2qcplw4d/moCC6p3rYPBMLXsrGNEUFZqBlgz72QA6BBq3X0Cg1Bc2ZbK5VIzwkg\nST2SSux6ccROfgULmN5ZiLOtdUKNEZpFF3i3qtsCgYADT/s7dYFlatobz3kmMnXK\nsfTu2MllHdRys0YGHu7Q8biDuQkhrJwhxPW0KS83g4JQym+0aEfzh36bWcl+u6R7\nKhKj+9oSf9pndgk345gJz35RbPJYh+EuAHNvzdgCAvK6x1jETWeKf6btj5pF1U1i\nQ4QNIw/QiwIXjWZeubTGsQKBgQCbduLu2rLnlyyAaJZM8DlHZyH2gAXbBZpxqU8T\nt9mtkJDUS/KRiEoYGFV9CqS0aXrayVMsDfXY6B/S/UuZjO5u7LtklDzqOf1aKG3Q\ndGXPKibknqqJYH+bnUNjuYYNerETV57lijMGHuSYCf8vwLn3oxBfERRX61M/DU8Z\nworz/QKBgQDCTJI2+jdXg26XuYUmM4XXfnocfzAXhXBULt1nENcogNf1fcptAVtu\nBAiz4/HipQKqoWVUYmxfgbbLRKKLK0s0lOWKbYdVjhEm/m2ZU8wtXTagNwkIGoyq\nY/C1Lox4f1ROJnCjc/hfcOjcxX5M8A8peecHWlVtUPKTJgxQ7oMKcw==\n-----END RSA PRIVATE KEY-----\n"
// mock a fake status store. // mock a fake status store.
type fakeStatusStore struct { type fakeStatusCloud struct {
FindClusterStatusFn func(cluster *kops.Cluster) (*kops.ClusterStatus, error) GetApiIngressStatusFn func(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error)
GetApiIngressStatusFn func(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error)
} }
func (f fakeStatusStore) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) { var _ fi.Cloud = &fakeStatusCloud{}
return f.FindClusterStatusFn(cluster)
}
func (f fakeStatusStore) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (f fakeStatusCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return f.GetApiIngressStatusFn(cluster) return f.GetApiIngressStatusFn(cluster)
} }
func (f fakeStatusCloud) ProviderID() kops.CloudProviderID {
panic("not implemented")
}
func (f fakeStatusCloud) DNS() (dnsprovider.Interface, error) {
panic("not implemented")
}
func (f fakeStatusCloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
panic("not implemented")
}
func (f fakeStatusCloud) DeleteInstance(instance *cloudinstances.CloudInstance) error {
panic("not implemented")
}
func (f fakeStatusCloud) DeleteGroup(group *cloudinstances.CloudInstanceGroup) error {
panic("not implemented")
}
func (f fakeStatusCloud) DetachInstance(instance *cloudinstances.CloudInstance) error {
panic("not implemented")
}
func (f fakeStatusCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
panic("not implemented")
}
func (f fakeStatusCloud) Region() string {
panic("not implemented")
}
func (f fakeStatusCloud) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {
panic("not implemented")
}
// mock a fake key store // mock a fake key store
type fakeKeyStore struct { type fakeKeyStore struct {
FindKeypairFn func(name string) (*pki.Certificate, *pki.PrivateKey, bool, error) FindKeypairFn func(name string) (*pki.Certificate, *pki.PrivateKey, bool, error)
@ -110,7 +146,7 @@ func TestBuildKubecfg(t *testing.T) {
type args struct { type args struct {
cluster *kops.Cluster cluster *kops.Cluster
secretStore fi.SecretStore secretStore fi.SecretStore
status fakeStatusStore status fakeStatusCloud
admin time.Duration admin time.Duration
user string user string
internal bool internal bool
@ -135,7 +171,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS with admin", name: "Test Kube Config Data For Public DNS with admin",
args: args{ args: args{
cluster: publicCluster, cluster: publicCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: DefaultKubecfgAdminLifetime, admin: DefaultKubecfgAdminLifetime,
user: "", user: "",
}, },
@ -151,7 +187,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS with admin and secondary NLB port", name: "Test Kube Config Data For Public DNS with admin and secondary NLB port",
args: args{ args: args{
cluster: certNLBCluster, cluster: certNLBCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: DefaultKubecfgAdminLifetime, admin: DefaultKubecfgAdminLifetime,
}, },
want: &KubeconfigBuilder{ want: &KubeconfigBuilder{
@ -166,7 +202,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS with admin and CLB ACM Certificate", name: "Test Kube Config Data For Public DNS with admin and CLB ACM Certificate",
args: args{ args: args{
cluster: certCluster, cluster: certCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: DefaultKubecfgAdminLifetime, admin: DefaultKubecfgAdminLifetime,
}, },
want: &KubeconfigBuilder{ want: &KubeconfigBuilder{
@ -181,7 +217,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS without admin and with ACM certificate", name: "Test Kube Config Data For Public DNS without admin and with ACM certificate",
args: args{ args: args{
cluster: certNLBCluster, cluster: certNLBCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: 0, admin: 0,
}, },
want: &KubeconfigBuilder{ want: &KubeconfigBuilder{
@ -196,7 +232,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS without admin", name: "Test Kube Config Data For Public DNS without admin",
args: args{ args: args{
cluster: publicCluster, cluster: publicCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: 0, admin: 0,
user: "myuser", user: "myuser",
}, },
@ -212,7 +248,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Public DNS with Empty Master Name", name: "Test Kube Config Data For Public DNS with Empty Master Name",
args: args{ args: args{
cluster: emptyMasterPublicNameCluster, cluster: emptyMasterPublicNameCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: 0, admin: 0,
user: "", user: "",
}, },
@ -228,9 +264,9 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Gossip cluster", name: "Test Kube Config Data For Gossip cluster",
args: args{ args: args{
cluster: gossipCluster, cluster: gossipCluster,
status: fakeStatusStore{ status: fakeStatusCloud{
GetApiIngressStatusFn: func(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { GetApiIngressStatusFn: func(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return []kops.ApiIngressStatus{ return []fi.ApiIngressStatus{
{ {
Hostname: "elbHostName", Hostname: "elbHostName",
}, },
@ -250,7 +286,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Public DNS with kops auth plugin", name: "Public DNS with kops auth plugin",
args: args{ args: args{
cluster: publicCluster, cluster: publicCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: 0, admin: 0,
useKopsAuthenticationPlugin: true, useKopsAuthenticationPlugin: true,
}, },
@ -273,7 +309,7 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For internal DNS name with admin", name: "Test Kube Config Data For internal DNS name with admin",
args: args{ args: args{
cluster: publicCluster, cluster: publicCluster,
status: fakeStatusStore{}, status: fakeStatusCloud{},
admin: DefaultKubecfgAdminLifetime, admin: DefaultKubecfgAdminLifetime,
internal: true, internal: true,
}, },
@ -289,9 +325,9 @@ func TestBuildKubecfg(t *testing.T) {
name: "Test Kube Config Data For Gossip cluster with admin and secondary NLB port", name: "Test Kube Config Data For Gossip cluster with admin and secondary NLB port",
args: args{ args: args{
cluster: certGossipNLBCluster, cluster: certGossipNLBCluster,
status: fakeStatusStore{ status: fakeStatusCloud{
GetApiIngressStatusFn: func(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { GetApiIngressStatusFn: func(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return []kops.ApiIngressStatus{ return []fi.ApiIngressStatus{
{ {
Hostname: "nlbHostName", Hostname: "nlbHostName",
}, },

View File

@ -199,8 +199,8 @@ func (c *Cloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
return nil, errors.New("not implemented") return nil, errors.New("not implemented")
} }
func (c *Cloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *Cloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []kops.ApiIngressStatus var ingresses []fi.ApiIngressStatus
if cluster.Spec.MasterPublicName != "" { if cluster.Spec.MasterPublicName != "" {
// Note that this must match Digital Ocean's lb name // Note that this must match Digital Ocean's lb name
klog.V(2).Infof("Querying DO to find Loadbalancers for API (%q)", cluster.Name) klog.V(2).Infof("Querying DO to find Loadbalancers for API (%q)", cluster.Name)
@ -221,7 +221,7 @@ func (c *Cloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressSta
} }
address := lb.IP address := lb.IP
ingresses = append(ingresses, kops.ApiIngressStatus{IP: address}) ingresses = append(ingresses, fi.ApiIngressStatus{IP: address})
return ingresses, nil return ingresses, nil
} }

View File

@ -47,6 +47,11 @@ type Cloud interface {
// Region returns the cloud region bound to the cloud instance. // Region returns the cloud region bound to the cloud instance.
// If the region concept does not apply, returns "". // If the region concept does not apply, returns "".
Region() string Region() string
// FindClusterStatus discovers the status of the cluster, by inspecting the cloud objects
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
GetApiIngressStatus(cluster *kops.Cluster) ([]ApiIngressStatus, error)
} }
type VPCInfo struct { type VPCInfo struct {
@ -63,6 +68,20 @@ type SubnetInfo struct {
CIDR string CIDR string
} }
// ApiIngressStatus represents the status of an ingress point:
// traffic intended for the service should be sent to an ingress point.
type ApiIngressStatus struct {
// IP is set for load-balancer ingress points that are IP based
// (typically GCE or OpenStack load-balancers)
// +optional
IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"`
// Hostname is set for load-balancer ingress points that are DNS based
// (typically AWS load-balancers)
// +optional
Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`
}
// zonesToCloud allows us to infer from certain well-known zones to a cloud // zonesToCloud allows us to infer from certain well-known zones to a cloud
// Note it is safe to "overmap" zones that don't exist: we'll check later if the zones actually exist // Note it is safe to "overmap" zones that don't exist: we'll check later if the zones actually exist
var zonesToCloud = map[string]kops.CloudProviderID{ var zonesToCloud = map[string]kops.CloudProviderID{

View File

@ -70,8 +70,6 @@ type ALICloud interface {
CreateTags(resourceId string, resourceType string, tags map[string]string) error CreateTags(resourceId string, resourceType string, tags map[string]string) error
RemoveTags(resourceId string, resourceType string, tags map[string]string) error RemoveTags(resourceId string, resourceType string, tags map[string]string) error
GetClusterTags() map[string]string GetClusterTags() map[string]string
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error)
} }
type aliCloudImplementation struct { type aliCloudImplementation struct {
@ -342,8 +340,8 @@ func (c *aliCloudImplementation) GetClusterTags() map[string]string {
return c.tags return c.tags
} }
func (c *aliCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *aliCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []kops.ApiIngressStatus var ingresses []fi.ApiIngressStatus
name := "api." + cluster.Name name := "api." + cluster.Name
describeLoadBalancersArgs := &slb.DescribeLoadBalancersArgs{ describeLoadBalancersArgs := &slb.DescribeLoadBalancersArgs{
@ -364,7 +362,7 @@ func (c *aliCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]k
} }
address := responseLoadBalancers[0].Address address := responseLoadBalancers[0].Address
ingresses = append(ingresses, kops.ApiIngressStatus{IP: address}) ingresses = append(ingresses, fi.ApiIngressStatus{IP: address})
return ingresses, nil return ingresses, nil
} }

View File

@ -87,7 +87,6 @@ go_library(
importpath = "k8s.io/kops/upup/pkg/fi/cloudup/awstasks", importpath = "k8s.io/kops/upup/pkg/fi/cloudup/awstasks",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/apis/kops:go_default_library",
"//pkg/diff:go_default_library", "//pkg/diff:go_default_library",
"//pkg/featureflag:go_default_library", "//pkg/featureflag:go_default_library",
"//pkg/pki:go_default_library", "//pkg/pki:go_default_library",

View File

@ -143,7 +143,7 @@ func (e *AutoscalingGroup) Find(c *fi.Context) (*AutoscalingGroup, error) {
} }
} }
if apiLBTask != nil && len(actual.LoadBalancers) > 0 { if apiLBTask != nil && len(actual.LoadBalancers) > 0 {
apiLBDesc, err := FindLoadBalancerByNameTag(c.Cloud.(awsup.AWSCloud), fi.StringValue(apiLBTask.Name)) apiLBDesc, err := c.Cloud.(awsup.AWSCloud).FindELBByNameTag(fi.StringValue(apiLBTask.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -335,7 +335,7 @@ func (v *AutoscalingGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Autos
for _, k := range e.LoadBalancers { for _, k := range e.LoadBalancers {
if k.LoadBalancerName == nil { if k.LoadBalancerName == nil {
lbDesc, err := FindLoadBalancerByNameTag(t.Cloud, fi.StringValue(k.GetName())) lbDesc, err := t.Cloud.FindELBByNameTag(fi.StringValue(k.GetName()))
if err != nil { if err != nil {
return err return err
} }

View File

@ -185,67 +185,6 @@ func findLoadBalancerByAlias(cloud awsup.AWSCloud, alias *route53.AliasTarget) (
return found[0], nil return found[0], nil
} }
func FindLoadBalancerByNameTag(cloud awsup.AWSCloud, findNameTag string) (*elb.LoadBalancerDescription, error) {
// TODO: Any way around this?
klog.V(2).Infof("Listing all ELBs for findLoadBalancerByNameTag")
request := &elb.DescribeLoadBalancersInput{}
// ELB DescribeTags has a limit of 20 names, so we set the page size here to 20 also
request.PageSize = aws.Int64(20)
var found []*elb.LoadBalancerDescription
var innerError error
err := cloud.ELB().DescribeLoadBalancersPages(request, func(p *elb.DescribeLoadBalancersOutput, lastPage bool) bool {
if len(p.LoadBalancerDescriptions) == 0 {
return true
}
// TODO: Filter by cluster?
var names []string
nameToELB := make(map[string]*elb.LoadBalancerDescription)
for _, elb := range p.LoadBalancerDescriptions {
name := aws.StringValue(elb.LoadBalancerName)
nameToELB[name] = elb
names = append(names, name)
}
tagMap, err := describeLoadBalancerTags(cloud, names)
if err != nil {
innerError = err
return false
}
for loadBalancerName, tags := range tagMap {
name, foundNameTag := awsup.FindELBTag(tags, "Name")
if !foundNameTag || name != findNameTag {
continue
}
elb := nameToELB[loadBalancerName]
found = append(found, elb)
}
return true
})
if err != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", err)
}
if innerError != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", innerError)
}
if len(found) == 0 {
return nil, nil
}
if len(found) != 1 {
return nil, fmt.Errorf("Found multiple ELBs with Name %q", findNameTag)
}
return found[0], nil
}
func describeLoadBalancers(cloud awsup.AWSCloud, request *elb.DescribeLoadBalancersInput, filter func(*elb.LoadBalancerDescription) bool) ([]*elb.LoadBalancerDescription, error) { func describeLoadBalancers(cloud awsup.AWSCloud, request *elb.DescribeLoadBalancersInput, filter func(*elb.LoadBalancerDescription) bool) ([]*elb.LoadBalancerDescription, error) {
var found []*elb.LoadBalancerDescription var found []*elb.LoadBalancerDescription
err := cloud.ELB().DescribeLoadBalancersPages(request, func(p *elb.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool) { err := cloud.ELB().DescribeLoadBalancersPages(request, func(p *elb.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool) {
@ -265,26 +204,6 @@ func describeLoadBalancers(cloud awsup.AWSCloud, request *elb.DescribeLoadBalanc
return found, nil return found, nil
} }
func describeLoadBalancerTags(cloud awsup.AWSCloud, loadBalancerNames []string) (map[string][]*elb.Tag, error) {
// TODO: Filter by cluster?
request := &elb.DescribeTagsInput{}
request.LoadBalancerNames = aws.StringSlice(loadBalancerNames)
// TODO: Cache?
klog.V(2).Infof("Querying ELB tags for %s", loadBalancerNames)
response, err := cloud.ELB().DescribeTags(request)
if err != nil {
return nil, err
}
tagMap := make(map[string][]*elb.Tag)
for _, tagset := range response.TagDescriptions {
tagMap[aws.StringValue(tagset.LoadBalancerName)] = tagset.Tags
}
return tagMap, nil
}
func (e *ClassicLoadBalancer) getDNSName() *string { func (e *ClassicLoadBalancer) getDNSName() *string {
return e.DNSName return e.DNSName
} }
@ -296,7 +215,7 @@ func (e *ClassicLoadBalancer) getHostedZoneId() *string {
func (e *ClassicLoadBalancer) Find(c *fi.Context) (*ClassicLoadBalancer, error) { func (e *ClassicLoadBalancer) Find(c *fi.Context) (*ClassicLoadBalancer, error) {
cloud := c.Cloud.(awsup.AWSCloud) cloud := c.Cloud.(awsup.AWSCloud)
lb, err := FindLoadBalancerByNameTag(cloud, fi.StringValue(e.Name)) lb, err := cloud.FindELBByNameTag(fi.StringValue(e.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -315,7 +234,7 @@ func (e *ClassicLoadBalancer) Find(c *fi.Context) (*ClassicLoadBalancer, error)
actual.Lifecycle = e.Lifecycle actual.Lifecycle = e.Lifecycle
actual.ForAPIServer = e.ForAPIServer actual.ForAPIServer = e.ForAPIServer
tagMap, err := describeLoadBalancerTags(cloud, []string{*lb.LoadBalancerName}) tagMap, err := cloud.DescribeELBTags([]string{*lb.LoadBalancerName})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -433,7 +352,7 @@ func (e *ClassicLoadBalancer) IsForAPIServer() bool {
func (e *ClassicLoadBalancer) FindIPAddress(context *fi.Context) (*string, error) { func (e *ClassicLoadBalancer) FindIPAddress(context *fi.Context) (*string, error) {
cloud := context.Cloud.(awsup.AWSCloud) cloud := context.Cloud.(awsup.AWSCloud)
lb, err := FindLoadBalancerByNameTag(cloud, fi.StringValue(e.Name)) lb, err := cloud.FindELBByNameTag(fi.StringValue(e.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -24,7 +24,6 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53" "github.com/aws/aws-sdk-go/service/route53"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup" "k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation" "k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
@ -130,49 +129,6 @@ func (e *DNSName) Find(c *fi.Context) (*DNSName, error) {
return actual, nil return actual, nil
} }
func FindDNSName(awsCloud awsup.AWSCloud, cluster *kops.Cluster) (string, error) {
name := "api." + cluster.Name
lb, err := FindElasticLoadBalancerByNameTag(awsCloud, cluster)
if err != nil {
return "", fmt.Errorf("error looking for AWS ELB: %v", err)
}
if lb == nil {
return "", nil
}
lbDnsName := aws.StringValue(lb.getDNSName())
if lbDnsName == "" {
return "", fmt.Errorf("found ELB %q, but it did not have a DNSName", name)
}
return lbDnsName, nil
}
func FindElasticLoadBalancerByNameTag(awsCloud awsup.AWSCloud, cluster *kops.Cluster) (DNSTarget, error) {
name := "api." + cluster.Name
if cluster.Spec.API == nil || cluster.Spec.API.LoadBalancer == nil {
return nil, nil
}
if cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassClassic {
if lb, err := FindLoadBalancerByNameTag(awsCloud, name); err != nil {
return nil, fmt.Errorf("error looking for AWS ELB: %v", err)
} else if lb != nil {
return &ClassicLoadBalancer{Name: fi.String(name), DNSName: lb.DNSName}, nil
}
} else if cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork {
if lb, err := FindNetworkLoadBalancerByNameTag(awsCloud, name); err != nil {
return nil, fmt.Errorf("error looking for AWS NLB: %v", err)
} else if lb != nil {
return &NetworkLoadBalancer{Name: fi.String(name), DNSName: lb.DNSName}, nil
}
}
return nil, nil
}
func findDNSTarget(cloud awsup.AWSCloud, aliasTarget *route53.AliasTarget, dnsName string, targetDNSName *string) (DNSTarget, error) { func findDNSTarget(cloud awsup.AWSCloud, aliasTarget *route53.AliasTarget, dnsName string, targetDNSName *string) (DNSTarget, error) {
//TODO: I would like to search dnsName for presence of ".elb" or ".nlb" to simply searching, however both nlb and elb have .elb. in the name at present //TODO: I would like to search dnsName for presence of ".elb" or ".nlb" to simply searching, however both nlb and elb have .elb. in the name at present
if ELB, err := findDNSTargetELB(cloud, aliasTarget, dnsName, targetDNSName); err != nil { if ELB, err := findDNSTargetELB(cloud, aliasTarget, dnsName, targetDNSName); err != nil {
@ -198,7 +154,7 @@ func findDNSTargetNLB(cloud awsup.AWSCloud, aliasTarget *route53.AliasTarget, dn
if lb != nil { if lb != nil {
loadBalancerName := aws.StringValue(lb.LoadBalancerName) //TOOD: can we keep these on object loadBalancerName := aws.StringValue(lb.LoadBalancerName) //TOOD: can we keep these on object
loadBalancerArn := aws.StringValue(lb.LoadBalancerArn) //TODO: can we keep these on object loadBalancerArn := aws.StringValue(lb.LoadBalancerArn) //TODO: can we keep these on object
tagMap, err := describeNetworkLoadBalancerTags(cloud, []string{loadBalancerArn}) tagMap, err := cloud.DescribeELBV2Tags([]string{loadBalancerArn})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -220,7 +176,7 @@ func findDNSTargetELB(cloud awsup.AWSCloud, aliasTarget *route53.AliasTarget, dn
} }
if lb != nil { if lb != nil {
loadBalancerName := aws.StringValue(lb.LoadBalancerName) loadBalancerName := aws.StringValue(lb.LoadBalancerName)
tagMap, err := describeLoadBalancerTags(cloud, []string{loadBalancerName}) tagMap, err := cloud.DescribeELBTags([]string{loadBalancerName})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -211,66 +211,6 @@ func findNetworkLoadBalancerByAlias(cloud awsup.AWSCloud, alias *route53.AliasTa
return found[0], nil return found[0], nil
} }
func FindNetworkLoadBalancerByNameTag(cloud awsup.AWSCloud, findNameTag string) (*elbv2.LoadBalancer, error) {
// TODO: Any way around this?
klog.V(2).Infof("Listing all NLBs for findNetworkLoadBalancerByNameTag")
request := &elbv2.DescribeLoadBalancersInput{}
// ELB DescribeTags has a limit of 20 names, so we set the page size here to 20 also
request.PageSize = aws.Int64(20)
var found []*elbv2.LoadBalancer
var innerError error
err := cloud.ELBV2().DescribeLoadBalancersPages(request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) bool {
if len(p.LoadBalancers) == 0 {
return true
}
// TODO: Filter by cluster?
var arns []string
arnToELB := make(map[string]*elbv2.LoadBalancer)
for _, elb := range p.LoadBalancers {
arn := aws.StringValue(elb.LoadBalancerArn)
arnToELB[arn] = elb
arns = append(arns, arn)
}
tagMap, err := describeNetworkLoadBalancerTags(cloud, arns)
if err != nil {
innerError = err
return false
}
for loadBalancerArn, tags := range tagMap {
name, foundNameTag := awsup.FindELBV2Tag(tags, "Name")
if !foundNameTag || name != findNameTag {
continue
}
elb := arnToELB[loadBalancerArn]
found = append(found, elb)
}
return true
})
if err != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", err)
}
if innerError != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", innerError)
}
if len(found) == 0 {
return nil, nil
}
if len(found) != 1 {
return nil, fmt.Errorf("Found multiple NLBs with Name %q", findNameTag)
}
return found[0], nil
}
func describeNetworkLoadBalancers(cloud awsup.AWSCloud, request *elbv2.DescribeLoadBalancersInput, filter func(*elbv2.LoadBalancer) bool) ([]*elbv2.LoadBalancer, error) { func describeNetworkLoadBalancers(cloud awsup.AWSCloud, request *elbv2.DescribeLoadBalancersInput, filter func(*elbv2.LoadBalancer) bool) ([]*elbv2.LoadBalancer, error) {
var found []*elbv2.LoadBalancer var found []*elbv2.LoadBalancer
err := cloud.ELBV2().DescribeLoadBalancersPages(request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool) { err := cloud.ELBV2().DescribeLoadBalancersPages(request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool) {
@ -290,26 +230,6 @@ func describeNetworkLoadBalancers(cloud awsup.AWSCloud, request *elbv2.DescribeL
return found, nil return found, nil
} }
func describeNetworkLoadBalancerTags(cloud awsup.AWSCloud, loadBalancerArns []string) (map[string][]*elbv2.Tag, error) {
// TODO: Filter by cluster?
request := &elbv2.DescribeTagsInput{}
request.ResourceArns = aws.StringSlice(loadBalancerArns)
// TODO: Cache?
klog.V(2).Infof("Querying ELBV2 api for tags for %s", loadBalancerArns)
response, err := cloud.ELBV2().DescribeTags(request)
if err != nil {
return nil, err
}
tagMap := make(map[string][]*elbv2.Tag)
for _, tagset := range response.TagDescriptions {
tagMap[aws.StringValue(tagset.ResourceArn)] = tagset.Tags
}
return tagMap, nil
}
func (e *NetworkLoadBalancer) getDNSName() *string { func (e *NetworkLoadBalancer) getDNSName() *string {
return e.DNSName return e.DNSName
} }
@ -321,7 +241,7 @@ func (e *NetworkLoadBalancer) getHostedZoneId() *string {
func (e *NetworkLoadBalancer) Find(c *fi.Context) (*NetworkLoadBalancer, error) { func (e *NetworkLoadBalancer) Find(c *fi.Context) (*NetworkLoadBalancer, error) {
cloud := c.Cloud.(awsup.AWSCloud) cloud := c.Cloud.(awsup.AWSCloud)
lb, err := FindNetworkLoadBalancerByNameTag(cloud, e.Tags["Name"]) lb, err := cloud.FindELBV2ByNameTag(e.Tags["Name"])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -340,7 +260,7 @@ func (e *NetworkLoadBalancer) Find(c *fi.Context) (*NetworkLoadBalancer, error)
actual.VPC = &VPC{ID: lb.VpcId} actual.VPC = &VPC{ID: lb.VpcId}
actual.Type = lb.Type actual.Type = lb.Type
tagMap, err := describeNetworkLoadBalancerTags(cloud, []string{*loadBalancerArn}) tagMap, err := cloud.DescribeELBV2Tags([]string{*loadBalancerArn})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -488,7 +408,7 @@ func (e *NetworkLoadBalancer) IsForAPIServer() bool {
func (e *NetworkLoadBalancer) FindIPAddress(context *fi.Context) (*string, error) { func (e *NetworkLoadBalancer) FindIPAddress(context *fi.Context) (*string, error) {
cloud := context.Cloud.(awsup.AWSCloud) cloud := context.Cloud.(awsup.AWSCloud)
lb, err := FindNetworkLoadBalancerByNameTag(cloud, e.Tags["Name"]) lb, err := cloud.FindELBV2ByNameTag(e.Tags["Name"])
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -148,6 +148,11 @@ type AWSCloud interface {
RemoveELBTags(loadBalancerName string, tags map[string]string) error RemoveELBTags(loadBalancerName string, tags map[string]string) error
RemoveELBV2Tags(ResourceArn string, tags map[string]string) error RemoveELBV2Tags(ResourceArn string, tags map[string]string) error
FindELBByNameTag(findNameTag string) (*elb.LoadBalancerDescription, error)
DescribeELBTags(loadBalancerNames []string) (map[string][]*elb.Tag, error)
FindELBV2ByNameTag(findNameTag string) (*elbv2.LoadBalancer, error)
DescribeELBV2Tags(loadBalancerNames []string) (map[string][]*elbv2.Tag, error)
// DescribeInstance is a helper that queries for the specified instance by id // DescribeInstance is a helper that queries for the specified instance by id
DescribeInstance(instanceID string) (*ec2.Instance, error) DescribeInstance(instanceID string) (*ec2.Instance, error)
@ -172,9 +177,6 @@ type AWSCloud interface {
// DescribeInstanceType calls ec2.DescribeInstanceType to get information for a particular instance type // DescribeInstanceType calls ec2.DescribeInstanceType to get information for a particular instance type
DescribeInstanceType(instanceType string) (*ec2.InstanceTypeInfo, error) DescribeInstanceType(instanceType string) (*ec2.InstanceTypeInfo, error)
// FindClusterStatus gets the status of the cluster as it exists in AWS, inferred from volumes
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into // AccountInfo returns the AWS account ID and AWS partition that we are deploying into
AccountInfo() (string, string, error) AccountInfo() (string, string, error)
} }
@ -1387,6 +1389,183 @@ func (c *awsCloudImplementation) AddTags(name *string, tags map[string]string) {
} }
} }
func (c *awsCloudImplementation) FindELBByNameTag(findNameTag string) (*elb.LoadBalancerDescription, error) {
return findELBByNameTag(c, findNameTag)
}
func findELBByNameTag(c AWSCloud, findNameTag string) (*elb.LoadBalancerDescription, error) {
// TODO: Any way around this?
klog.V(2).Infof("Listing all ELBs for findLoadBalancerByNameTag")
request := &elb.DescribeLoadBalancersInput{}
// ELB DescribeTags has a limit of 20 names, so we set the page size here to 20 also
request.PageSize = aws.Int64(20)
var found []*elb.LoadBalancerDescription
var innerError error
err := c.ELB().DescribeLoadBalancersPages(request, func(p *elb.DescribeLoadBalancersOutput, lastPage bool) bool {
if len(p.LoadBalancerDescriptions) == 0 {
return true
}
// TODO: Filter by cluster?
var names []string
nameToELB := make(map[string]*elb.LoadBalancerDescription)
for _, elb := range p.LoadBalancerDescriptions {
name := aws.StringValue(elb.LoadBalancerName)
nameToELB[name] = elb
names = append(names, name)
}
tagMap, err := c.DescribeELBTags(names)
if err != nil {
innerError = err
return false
}
for loadBalancerName, tags := range tagMap {
name, foundNameTag := FindELBTag(tags, "Name")
if !foundNameTag || name != findNameTag {
continue
}
elb := nameToELB[loadBalancerName]
found = append(found, elb)
}
return true
})
if err != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", err)
}
if innerError != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", innerError)
}
if len(found) == 0 {
return nil, nil
}
if len(found) != 1 {
return nil, fmt.Errorf("Found multiple ELBs with Name %q", findNameTag)
}
return found[0], nil
}
func (c *awsCloudImplementation) DescribeELBTags(loadBalancerNames []string) (map[string][]*elb.Tag, error) {
return describeELBTags(c, loadBalancerNames)
}
func describeELBTags(c AWSCloud, loadBalancerNames []string) (map[string][]*elb.Tag, error) {
// TODO: Filter by cluster?
request := &elb.DescribeTagsInput{}
request.LoadBalancerNames = aws.StringSlice(loadBalancerNames)
// TODO: Cache?
klog.V(2).Infof("Querying ELB tags for %s", loadBalancerNames)
response, err := c.ELB().DescribeTags(request)
if err != nil {
return nil, err
}
tagMap := make(map[string][]*elb.Tag)
for _, tagset := range response.TagDescriptions {
tagMap[aws.StringValue(tagset.LoadBalancerName)] = tagset.Tags
}
return tagMap, nil
}
func (c *awsCloudImplementation) FindELBV2ByNameTag(findNameTag string) (*elbv2.LoadBalancer, error) {
return findELBV2ByNameTag(c, findNameTag)
}
func findELBV2ByNameTag(c AWSCloud, findNameTag string) (*elbv2.LoadBalancer, error) {
// TODO: Any way around this?
klog.V(2).Infof("Listing all NLBs for findNetworkLoadBalancerByNameTag")
request := &elbv2.DescribeLoadBalancersInput{}
// ELB DescribeTags has a limit of 20 names, so we set the page size here to 20 also
request.PageSize = aws.Int64(20)
var found []*elbv2.LoadBalancer
var innerError error
err := c.ELBV2().DescribeLoadBalancersPages(request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) bool {
if len(p.LoadBalancers) == 0 {
return true
}
// TODO: Filter by cluster?
var arns []string
arnToELB := make(map[string]*elbv2.LoadBalancer)
for _, elb := range p.LoadBalancers {
arn := aws.StringValue(elb.LoadBalancerArn)
arnToELB[arn] = elb
arns = append(arns, arn)
}
tagMap, err := c.DescribeELBV2Tags(arns)
if err != nil {
innerError = err
return false
}
for loadBalancerArn, tags := range tagMap {
name, foundNameTag := FindELBV2Tag(tags, "Name")
if !foundNameTag || name != findNameTag {
continue
}
elb := arnToELB[loadBalancerArn]
found = append(found, elb)
}
return true
})
if err != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", err)
}
if innerError != nil {
return nil, fmt.Errorf("error describing LoadBalancers: %v", innerError)
}
if len(found) == 0 {
return nil, nil
}
if len(found) != 1 {
return nil, fmt.Errorf("Found multiple NLBs with Name %q", findNameTag)
}
return found[0], nil
}
func (c *awsCloudImplementation) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]*elbv2.Tag, error) {
return describeELBV2Tags(c, loadBalancerArns)
}
func describeELBV2Tags(c AWSCloud, loadBalancerArns []string) (map[string][]*elbv2.Tag, error) {
// TODO: Filter by cluster?
request := &elbv2.DescribeTagsInput{}
request.ResourceArns = aws.StringSlice(loadBalancerArns)
// TODO: Cache?
klog.V(2).Infof("Querying ELBV2 api for tags for %s", loadBalancerArns)
response, err := c.ELBV2().DescribeTags(request)
if err != nil {
return nil, err
}
tagMap := make(map[string][]*elbv2.Tag)
for _, tagset := range response.TagDescriptions {
tagMap[aws.StringValue(tagset.ResourceArn)] = tagset.Tags
}
return tagMap, nil
}
func (c *awsCloudImplementation) BuildFilters(name *string) []*ec2.Filter { func (c *awsCloudImplementation) BuildFilters(name *string) []*ec2.Filter {
return buildFilters(c.tags, name) return buildFilters(c.tags, name)
} }
@ -1686,6 +1865,42 @@ func findVPCInfo(c AWSCloud, vpcID string) (*fi.VPCInfo, error) {
return vpcInfo, nil return vpcInfo, nil
} }
func (c *awsCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return getApiIngressStatus(c, cluster)
}
func getApiIngressStatus(c AWSCloud, cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []fi.ApiIngressStatus
if lbDnsName, err := findDNSName(c, cluster); err != nil {
return nil, fmt.Errorf("error finding aws DNSName: %v", err)
} else if lbDnsName != "" {
ingresses = append(ingresses, fi.ApiIngressStatus{Hostname: lbDnsName})
}
return ingresses, nil
}
func findDNSName(c AWSCloud, cluster *kops.Cluster) (string, error) {
name := "api." + cluster.Name
if cluster.Spec.API == nil || cluster.Spec.API.LoadBalancer == nil {
return "", nil
}
if cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassClassic {
if lb, err := c.FindELBByNameTag(name); err != nil {
return "", fmt.Errorf("error looking for AWS ELB: %v", err)
} else if lb != nil {
return aws.StringValue(lb.DNSName), nil
}
} else if cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork {
if lb, err := c.FindELBV2ByNameTag(name); err != nil {
return "", fmt.Errorf("error looking for AWS NLB: %v", err)
} else if lb != nil {
return aws.StringValue(lb.DNSName), nil
}
}
return "", nil
}
// DefaultInstanceType determines an instance type for the specified cluster & instance group // DefaultInstanceType determines an instance type for the specified cluster & instance group
func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) { func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) {
var candidates []string var candidates []string

View File

@ -19,18 +19,19 @@ package awsup
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface"
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface" "github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
"github.com/aws/aws-sdk-go/service/cloudformation" "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/aws/aws-sdk-go/service/elb"
"github.com/aws/aws-sdk-go/service/elb/elbiface" "github.com/aws/aws-sdk-go/service/elb/elbiface"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface" "github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
"github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface"
"github.com/aws/aws-sdk-go/service/iam/iamiface" "github.com/aws/aws-sdk-go/service/iam/iamiface"
"github.com/aws/aws-sdk-go/service/route53/route53iface" "github.com/aws/aws-sdk-go/service/route53/route53iface"
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kops/dnsprovider/pkg/dnsprovider" "k8s.io/kops/dnsprovider/pkg/dnsprovider"
@ -191,6 +192,22 @@ func (c *MockAWSCloud) RemoveELBV2Tags(ResourceArn string, tags map[string]strin
return removeELBV2Tags(c, ResourceArn, tags) return removeELBV2Tags(c, ResourceArn, tags)
} }
func (c *MockAWSCloud) FindELBByNameTag(findNameTag string) (*elb.LoadBalancerDescription, error) {
return findELBByNameTag(c, findNameTag)
}
func (c *MockAWSCloud) DescribeELBTags(loadBalancerNames []string) (map[string][]*elb.Tag, error) {
return describeELBTags(c, loadBalancerNames)
}
func (c *MockAWSCloud) FindELBV2ByNameTag(findNameTag string) (*elbv2.LoadBalancer, error) {
return findELBV2ByNameTag(c, findNameTag)
}
func (c *MockAWSCloud) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]*elbv2.Tag, error) {
return describeELBV2Tags(c, loadBalancerArns)
}
func (c *MockAWSCloud) DescribeInstance(instanceID string) (*ec2.Instance, error) { func (c *MockAWSCloud) DescribeInstance(instanceID string) (*ec2.Instance, error) {
return nil, fmt.Errorf("MockAWSCloud DescribeInstance not implemented") return nil, fmt.Errorf("MockAWSCloud DescribeInstance not implemented")
} }
@ -284,6 +301,10 @@ func (c *MockAWSCloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
return findVPCInfo(c, id) return findVPCInfo(c, id)
} }
func (c *MockAWSCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return getApiIngressStatus(c, cluster)
}
// DefaultInstanceType determines an instance type for the specified cluster & instance group // DefaultInstanceType determines an instance type for the specified cluster & instance group
func (c *MockAWSCloud) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) { func (c *MockAWSCloud) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) {
switch ig.Spec.Role { switch ig.Spec.Role {

View File

@ -42,8 +42,6 @@ type AzureCloud interface {
fi.Cloud fi.Cloud
AddClusterTags(tags map[string]*string) AddClusterTags(tags map[string]*string)
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error)
SubscriptionID() string SubscriptionID() string
ResourceGroup() ResourceGroupsClient ResourceGroup() ResourceGroupsClient
@ -138,8 +136,8 @@ func (c *azureCloudImplementation) AddClusterTags(tags map[string]*string) {
} }
} }
func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []kops.ApiIngressStatus var ingresses []fi.ApiIngressStatus
var rg string = cluster.AzureResourceGroupName() var rg string = cluster.AzureResourceGroupName()
lbSpec := cluster.Spec.API.LoadBalancer lbSpec := cluster.Spec.API.LoadBalancer
@ -167,7 +165,7 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
if i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress == nil { if i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress == nil {
continue continue
} }
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: *i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress, IP: *i.FrontendIPConfigurationPropertiesFormat.PrivateIPAddress,
}) })
case kops.LoadBalancerTypePublic: case kops.LoadBalancerTypePublic:
@ -176,7 +174,7 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.PublicIPAddressPropertiesFormat.IPAddress == nil { i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.PublicIPAddressPropertiesFormat.IPAddress == nil {
continue continue
} }
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: *i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.PublicIPAddressPropertiesFormat.IPAddress, IP: *i.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.PublicIPAddressPropertiesFormat.IPAddress,
}) })
default: default:
@ -213,7 +211,7 @@ func (c *azureCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([
continue continue
} }
for _, i := range *ni.IPConfigurations { for _, i := range *ni.IPConfigurations {
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: *i.PrivateIPAddress, IP: *i.PrivateIPAddress,
}) })
} }

View File

@ -158,7 +158,7 @@ func (c *MockAzureCloud) FindClusterStatus(cluster *kops.Cluster) (*kops.Cluster
} }
// GetApiIngressStatus returns the status of API ingress. // GetApiIngressStatus returns the status of API ingress.
func (c *MockAzureCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *MockAzureCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return nil, nil return nil, nil
} }

View File

@ -45,12 +45,8 @@ type GCECloud interface {
Project() string Project() string
WaitForOp(op *compute.Operation) error WaitForOp(op *compute.Operation) error
GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error)
Labels() map[string]string Labels() map[string]string
// FindClusterStatus gets the status of the cluster as it exists in GCE, inferred from volumes
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
Zones() ([]string, error) Zones() ([]string, error)
// ServiceAccount returns the email for the service account that the instances will run under // ServiceAccount returns the email for the service account that the instances will run under
@ -288,8 +284,8 @@ func (c *gceCloudImplementation) WaitForOp(op *compute.Operation) error {
return WaitForOp(c.compute.srv, op) return WaitForOp(c.compute.srv, op)
} }
func (c *gceCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *gceCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []kops.ApiIngressStatus var ingresses []fi.ApiIngressStatus
// Note that this must match GCEModelContext::NameForForwardingRule // Note that this must match GCEModelContext::NameForForwardingRule
name := SafeObjectName("api", cluster.ObjectMeta.Name) name := SafeObjectName("api", cluster.ObjectMeta.Name)
@ -309,7 +305,7 @@ func (c *gceCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]k
return nil, fmt.Errorf("found forward rule %q, but it did not have an IPAddress", name) return nil, fmt.Errorf("found forward rule %q, but it did not have an IPAddress", name)
} }
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: forwardingRule.IPAddress, IP: forwardingRule.IPAddress,
}) })
} }

View File

@ -79,6 +79,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/kops:go_default_library", "//pkg/apis/kops:go_default_library",
"//upup/pkg/fi:go_default_library",
"//vendor/github.com/gophercloud/gophercloud:go_default_library", "//vendor/github.com/gophercloud/gophercloud:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library",

View File

@ -264,10 +264,6 @@ type OpenstackCloud interface {
// DeleteLB will delete loadbalancer // DeleteLB will delete loadbalancer
DeleteLB(lbID string, opt loadbalancers.DeleteOpts) error DeleteLB(lbID string, opt loadbalancers.DeleteOpts) error
GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error)
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
// DefaultInstanceType determines a suitable instance type for the specified instance group // DefaultInstanceType determines a suitable instance type for the specified instance group
DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error)
@ -664,11 +660,11 @@ type Address struct {
Addr string Addr string
} }
func (c *openstackCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *openstackCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return getApiIngressStatus(c, cluster) return getApiIngressStatus(c, cluster)
} }
func getApiIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func getApiIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
if cluster.Spec.CloudConfig.Openstack.Loadbalancer != nil { if cluster.Spec.CloudConfig.Openstack.Loadbalancer != nil {
return getLoadBalancerIngressStatus(c, cluster) return getLoadBalancerIngressStatus(c, cluster)
} else { } else {
@ -676,8 +672,8 @@ func getApiIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]kops.ApiIng
} }
} }
func getLoadBalancerIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func getLoadBalancerIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []kops.ApiIngressStatus var ingresses []fi.ApiIngressStatus
if cluster.Spec.MasterPublicName != "" { if cluster.Spec.MasterPublicName != "" {
// Note that this must match OpenstackModel lb name // Note that this must match OpenstackModel lb name
klog.V(2).Infof("Querying Openstack to find Loadbalancers for API (%q)", cluster.Name) klog.V(2).Infof("Querying Openstack to find Loadbalancers for API (%q)", cluster.Name)
@ -697,7 +693,7 @@ func getLoadBalancerIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]ko
} }
for _, fip := range fips { for _, fip := range fips {
if fip.PortID == lb.VipPortID { if fip.PortID == lb.VipPortID {
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: fip.FloatingIP, IP: fip.FloatingIP,
}) })
} }
@ -707,7 +703,7 @@ func getLoadBalancerIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]ko
return ingresses, nil return ingresses, nil
} }
func getIPIngressStatus(c OpenstackCloud, cluster *kops.Cluster) (ingresses []kops.ApiIngressStatus, err error) { func getIPIngressStatus(c OpenstackCloud, cluster *kops.Cluster) (ingresses []fi.ApiIngressStatus, err error) {
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) { done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
instances, err := c.ListInstances(servers.ListOpts{}) instances, err := c.ListInstances(servers.ListOpts{})
if err != nil { if err != nil {
@ -725,7 +721,7 @@ func getIPIngressStatus(c OpenstackCloud, cluster *kops.Cluster) (ingresses []ko
if err != nil { if err != nil {
return false, fmt.Errorf("failed to get interface address: %v", err) return false, fmt.Errorf("failed to get interface address: %v", err)
} }
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: address, IP: address,
}) })
} else { } else {
@ -734,7 +730,7 @@ func getIPIngressStatus(c OpenstackCloud, cluster *kops.Cluster) (ingresses []ko
return false, err return false, err
} }
for _, ip := range ips { for _, ip := range ips {
ingresses = append(ingresses, kops.ApiIngressStatus{ ingresses = append(ingresses, fi.ApiIngressStatus{
IP: fi.StringValue(ip), IP: fi.StringValue(ip),
}) })
} }

View File

@ -31,6 +31,7 @@ import (
l3floatingips "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" l3floatingips "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
) )
func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) { func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
@ -41,7 +42,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
l3FloatingIPs []l3floatingips.FloatingIP l3FloatingIPs []l3floatingips.FloatingIP
instances serverList instances serverList
cloudFloatingEnabled bool cloudFloatingEnabled bool
expectedAPIIngress []kops.ApiIngressStatus expectedAPIIngress []fi.ApiIngressStatus
expectedError error expectedError error
}{ }{
{ {
@ -74,7 +75,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
FloatingIP: "8.8.8.8", FloatingIP: "8.8.8.8",
}, },
}, },
expectedAPIIngress: []kops.ApiIngressStatus{ expectedAPIIngress: []fi.ApiIngressStatus{
{ {
IP: "8.8.8.8", IP: "8.8.8.8",
}, },
@ -122,7 +123,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
FloatingIP: "9.9.9.9", FloatingIP: "9.9.9.9",
}, },
}, },
expectedAPIIngress: []kops.ApiIngressStatus{ expectedAPIIngress: []fi.ApiIngressStatus{
{IP: "8.8.8.8"}, {IP: "8.8.8.8"},
}, },
}, },
@ -200,7 +201,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
}, },
}, },
}, },
expectedAPIIngress: []kops.ApiIngressStatus{ expectedAPIIngress: []fi.ApiIngressStatus{
{IP: "1.2.3.4"}, {IP: "1.2.3.4"},
{IP: "2.3.4.5"}, {IP: "2.3.4.5"},
{IP: "3.4.5.6"}, {IP: "3.4.5.6"},
@ -273,7 +274,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
}, },
}, },
cloudFloatingEnabled: true, cloudFloatingEnabled: true,
expectedAPIIngress: []kops.ApiIngressStatus{ expectedAPIIngress: []fi.ApiIngressStatus{
{IP: "1.2.3.4"}, {IP: "1.2.3.4"},
{IP: "4.5.6.7"}, {IP: "4.5.6.7"},
{IP: "40.50.60.70"}, {IP: "40.50.60.70"},
@ -390,7 +391,7 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) {
} }
} }
type sortByIP []kops.ApiIngressStatus type sortByIP []fi.ApiIngressStatus
// Len is the number of elements in the collection. // Len is the number of elements in the collection.
func (s sortByIP) Len() int { func (s sortByIP) Len() int {

View File

@ -303,7 +303,7 @@ func (c *MockCloud) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatu
func (c *MockCloud) FindNetworkBySubnetID(subnetID string) (*networks.Network, error) { func (c *MockCloud) FindNetworkBySubnetID(subnetID string) (*networks.Network, error) {
return findNetworkBySubnetID(c, subnetID) return findNetworkBySubnetID(c, subnetID)
} }
func (c *MockCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiIngressStatus, error) { func (c *MockCloud) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
return getApiIngressStatus(c, cluster) return getApiIngressStatus(c, cluster)
} }
func (c *MockCloud) GetCloudTags() map[string]string { func (c *MockCloud) GetCloudTags() map[string]string {

View File

@ -353,8 +353,7 @@ func (e *Elastigroup) Find(c *fi.Context) (*Elastigroup, error) {
if e.LoadBalancer != nil && if e.LoadBalancer != nil &&
fi.StringValue(name) != fi.StringValue(e.LoadBalancer.Name) { fi.StringValue(name) != fi.StringValue(e.LoadBalancer.Name) {
nlb, err := awstasks.FindNetworkLoadBalancerByNameTag( nlb, err := cloud.FindELBV2ByNameTag(fi.StringValue(e.LoadBalancer.Name))
cloud, fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -362,8 +361,7 @@ func (e *Elastigroup) Find(c *fi.Context) (*Elastigroup, error) {
actual.LoadBalancer = e.LoadBalancer actual.LoadBalancer = e.LoadBalancer
} }
elb, err := awstasks.FindLoadBalancerByNameTag( elb, err := cloud.FindELBByNameTag(fi.StringValue(e.LoadBalancer.Name))
cloud, fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -642,7 +640,7 @@ func (_ *Elastigroup) create(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
// Load balancer. // Load balancer.
{ {
if e.LoadBalancer != nil { if e.LoadBalancer != nil {
elb, err := awstasks.FindLoadBalancerByNameTag(cloud, fi.StringValue(e.LoadBalancer.Name)) elb, err := cloud.FindELBByNameTag(fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return err return err
} }
@ -659,7 +657,7 @@ func (_ *Elastigroup) create(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
//TODO: Verify using NLB functionality //TODO: Verify using NLB functionality
//TODO: Consider using DNSTarget Interface and adding .getLoadBalancerName() .getLoadBalancerArn //TODO: Consider using DNSTarget Interface and adding .getLoadBalancerName() .getLoadBalancerArn
nlb, err := awstasks.FindNetworkLoadBalancerByNameTag(cloud, fi.StringValue(e.LoadBalancer.Name)) nlb, err := cloud.FindELBV2ByNameTag(fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return err return err
} }
@ -1159,8 +1157,7 @@ func (_ *Elastigroup) update(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
var name, typ *string var name, typ *string
var lb interface{} var lb interface{}
lb, err = awstasks.FindLoadBalancerByNameTag( lb, err = cloud.FindELBByNameTag(fi.StringValue(e.LoadBalancer.Name))
cloud, fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return fmt.Errorf("spotinst: error looking for aws/elb: %v", err) return fmt.Errorf("spotinst: error looking for aws/elb: %v", err)
} }
@ -1168,8 +1165,7 @@ func (_ *Elastigroup) update(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
typ = fi.String("CLASSIC") typ = fi.String("CLASSIC")
name = lb.(*elb.LoadBalancerDescription).LoadBalancerName name = lb.(*elb.LoadBalancerDescription).LoadBalancerName
} else { } else {
lb, err = awstasks.FindNetworkLoadBalancerByNameTag( lb, err = cloud.FindELBV2ByNameTag(fi.StringValue(e.LoadBalancer.Name))
cloud, fi.StringValue(e.LoadBalancer.Name))
if err != nil { if err != nil {
return fmt.Errorf("spotinst: error looking for aws/nlb: %v", err) return fmt.Errorf("spotinst: error looking for aws/nlb: %v", err)
} }