From 5fca16aa30d59e4349f8a2b535fdf1fa6b45500c Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 6 Nov 2022 22:32:26 -0800 Subject: [PATCH] v1alpha3: Move API-related settings under API --- cmd/kops/create_cluster.go | 2 +- cmd/kops/update_cluster.go | 2 +- nodeup/pkg/model/etc_hosts.go | 4 +- nodeup/pkg/model/kube_apiserver.go | 18 +- pkg/apis/kops/cluster.go | 24 +-- pkg/apis/kops/v1alpha2/cluster.go | 18 +- pkg/apis/kops/v1alpha2/conversion.go | 18 ++ pkg/apis/kops/v1alpha2/defaults.go | 18 +- .../kops/v1alpha2/zz_generated.conversion.go | 164 +++++++++--------- .../kops/v1alpha2/zz_generated.deepcopy.go | 69 ++++---- pkg/apis/kops/v1alpha3/cluster.go | 29 ++-- pkg/apis/kops/v1alpha3/defaults.go | 6 +- .../kops/v1alpha3/zz_generated.conversion.go | 160 ++++++++--------- .../kops/v1alpha3/zz_generated.deepcopy.go | 78 ++++----- pkg/apis/kops/validation/aws.go | 14 +- pkg/apis/kops/validation/aws_test.go | 2 +- pkg/apis/kops/validation/validation.go | 4 +- pkg/apis/kops/zz_generated.deepcopy.go | 78 ++++----- pkg/commands/set_cluster_test.go | 8 +- pkg/commands/unset_cluster_test.go | 12 +- pkg/kubeconfig/create_kubecfg.go | 8 +- pkg/kubeconfig/create_kubecfg_test.go | 6 +- pkg/model/awsmodel/api_loadbalancer.go | 6 +- pkg/model/awsmodel/autoscalinggroup_test.go | 2 +- pkg/model/awsmodel/dns.go | 8 +- pkg/model/awsmodel/external_access.go | 4 +- pkg/model/azuremodel/testing.go | 2 +- pkg/model/components/discovery.go | 6 +- pkg/model/context.go | 5 +- pkg/model/gcemodel/api_loadbalancer.go | 2 +- pkg/model/gcemodel/external_access.go | 4 +- pkg/model/hetznermodel/firewall.go | 2 +- pkg/model/openstackmodel/firewall.go | 14 +- pkg/model/openstackmodel/servergroup.go | 8 +- pkg/model/openstackmodel/servergroup_test.go | 60 +++++-- pkg/testutils/cluster.go | 4 +- tests/codecs/componentconfig_test.go | 1 + .../integration/conversion/aws/v1alpha2.yaml | 3 + .../integration/conversion/aws/v1alpha3.yaml | 13 +- .../conversion/azure/v1alpha3.yaml | 10 +- .../conversion/canal/v1alpha3.yaml | 10 +- .../conversion/cilium/v1alpha3.yaml | 10 +- tests/integration/conversion/do/v1alpha3.yaml | 10 +- .../integration/conversion/gce/v1alpha3.yaml | 10 +- .../conversion/minimal/v1alpha3.yaml | 10 +- .../conversion/openstack/v1alpha3.yaml | 10 +- upup/pkg/fi/cloudup/awsup/aws_cloud.go | 2 +- upup/pkg/fi/cloudup/defaults.go | 6 +- upup/pkg/fi/cloudup/dns.go | 8 +- upup/pkg/fi/cloudup/dns_test.go | 8 +- upup/pkg/fi/cloudup/new_cluster.go | 5 +- upup/pkg/fi/cloudup/openstack/cloud.go | 4 +- upup/pkg/fi/cloudup/openstack/cloud_test.go | 8 +- upup/pkg/fi/cloudup/populate_cluster_spec.go | 4 +- 54 files changed, 517 insertions(+), 484 deletions(-) diff --git a/cmd/kops/create_cluster.go b/cmd/kops/create_cluster.go index 6aa82731eb..af7cb98302 100644 --- a/cmd/kops/create_cluster.go +++ b/cmd/kops/create_cluster.go @@ -605,7 +605,7 @@ func RunCreateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Cr } if c.MasterPublicName != "" { - cluster.Spec.MasterPublicName = c.MasterPublicName + cluster.Spec.API.PublicName = c.MasterPublicName } if err := commands.UnsetClusterFields(c.Unsets, cluster); err != nil { diff --git a/cmd/kops/update_cluster.go b/cmd/kops/update_cluster.go index da3ec15113..acb978779a 100644 --- a/cmd/kops/update_cluster.go +++ b/cmd/kops/update_cluster.go @@ -393,7 +393,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Up fmt.Fprintf(sb, " * validate cluster: kops validate cluster --wait 10m\n") fmt.Fprintf(sb, " * list nodes: kubectl get nodes --show-labels\n") if !usesBastion(applyCmd.InstanceGroups) { - fmt.Fprintf(sb, " * ssh to the master: ssh -i ~/.ssh/id_rsa ubuntu@%s\n", cluster.Spec.MasterPublicName) + fmt.Fprintf(sb, " * ssh to the master: ssh -i ~/.ssh/id_rsa ubuntu@%s\n", cluster.Spec.API.PublicName) } else { bastionPublicName := findBastionPublicName(cluster) if bastionPublicName != "" { diff --git a/nodeup/pkg/model/etc_hosts.go b/nodeup/pkg/model/etc_hosts.go index 07567c01c0..573aad94d8 100644 --- a/nodeup/pkg/model/etc_hosts.go +++ b/nodeup/pkg/model/etc_hosts.go @@ -40,9 +40,9 @@ func (b *EtcHostsBuilder) Build(c *fi.ModelBuilderContext) error { Hostname: b.Cluster.APIInternalName(), Addresses: []string{"127.0.0.1"}, }) - if b.Cluster.Spec.MasterPublicName != "" { + if b.Cluster.Spec.API.PublicName != "" { task.Records = append(task.Records, nodetasks.HostRecord{ - Hostname: b.Cluster.Spec.MasterPublicName, + Hostname: b.Cluster.Spec.API.PublicName, Addresses: []string{"127.0.0.1"}, }) } diff --git a/nodeup/pkg/model/kube_apiserver.go b/nodeup/pkg/model/kube_apiserver.go index 4b5de83740..4f8c346eeb 100644 --- a/nodeup/pkg/model/kube_apiserver.go +++ b/nodeup/pkg/model/kube_apiserver.go @@ -367,11 +367,11 @@ func (b *KubeAPIServerBuilder) writeServerCertificate(c *fi.ModelBuilderContext, } // Names specified in the cluster spec - if b.Cluster.Spec.MasterPublicName != "" { - alternateNames = append(alternateNames, b.Cluster.Spec.MasterPublicName) + if b.Cluster.Spec.API.PublicName != "" { + alternateNames = append(alternateNames, b.Cluster.Spec.API.PublicName) } alternateNames = append(alternateNames, b.Cluster.APIInternalName()) - alternateNames = append(alternateNames, b.Cluster.Spec.AdditionalSANs...) + alternateNames = append(alternateNames, b.Cluster.Spec.API.AdditionalSANs...) // Load balancer IPs passed in through NodeupConfig alternateNames = append(alternateNames, b.NodeupConfig.ApiserverAdditionalIPs...) @@ -732,14 +732,12 @@ func (b *KubeAPIServerBuilder) buildAnnotations() map[string]string { return annotations } - if b.Cluster.Spec.API != nil { - if b.Cluster.Spec.API.LoadBalancer == nil || !b.Cluster.Spec.API.LoadBalancer.UseForInternalAPI { - annotations["dns.alpha.kubernetes.io/internal"] = b.Cluster.APIInternalName() - } + if b.Cluster.Spec.API.LoadBalancer == nil || !b.Cluster.Spec.API.LoadBalancer.UseForInternalAPI { + annotations["dns.alpha.kubernetes.io/internal"] = b.Cluster.APIInternalName() + } - if b.Cluster.Spec.API.DNS != nil && b.Cluster.Spec.MasterPublicName != "" { - annotations["dns.alpha.kubernetes.io/external"] = b.Cluster.Spec.MasterPublicName - } + if b.Cluster.Spec.API.DNS != nil && b.Cluster.Spec.API.PublicName != "" { + annotations["dns.alpha.kubernetes.io/external"] = b.Cluster.Spec.API.PublicName } return annotations diff --git a/pkg/apis/kops/cluster.go b/pkg/apis/kops/cluster.go index 7c9abf8376..4099442f1c 100644 --- a/pkg/apis/kops/cluster.go +++ b/pkg/apis/kops/cluster.go @@ -70,8 +70,6 @@ type ClusterSpec struct { KubernetesVersion string `json:"kubernetesVersion,omitempty"` // Configuration of subnets we are targeting Subnets []ClusterSubnetSpec `json:"subnets,omitempty"` - // MasterPublicName is the external DNS name for the master nodes - MasterPublicName string `json:"masterPublicName,omitempty"` // NetworkCIDR is the CIDR used for the AWS VPC / DO/ GCE Network, or otherwise allocated to k8s // This is a real CIDR, not the internal k8s network // On AWS, it maps to the VPC CIDR. It is not required on GCE. @@ -102,8 +100,6 @@ type ClusterSpec struct { DNSZone string `json:"dnsZone,omitempty"` // DNSControllerGossipConfig for the cluster assuming the use of gossip DNS DNSControllerGossipConfig *DNSControllerGossipConfig `json:"dnsControllerGossipConfig,omitempty"` - // AdditionalSANs adds additional Subject Alternate Names to apiserver cert that kops generates - AdditionalSANs []string `json:"additionalSANs,omitempty"` // ClusterDNSDomain is the suffix we use for internal DNS names (normally cluster.local) ClusterDNSDomain string `json:"clusterDNSDomain,omitempty"` // ServiceClusterIPRange is the CIDR, from the internal network, where we allocate IPs for services @@ -121,8 +117,6 @@ type ClusterSpec struct { EgressProxy *EgressProxySpec `json:"egressProxy,omitempty"` // SSHKeyName specifies a preexisting SSH key to use SSHKeyName *string `json:"sshKeyName,omitempty"` - // KubernetesAPIAccess is a list of the CIDRs that can access the Kubernetes API endpoint (master HTTPS) - KubernetesAPIAccess []string `json:"kubernetesAPIAccess,omitempty"` // IsolateMasters determines whether we should lock down masters so that they are not on the pod network. // true is the kube-up behaviour, but it is very surprising: it means that daemonsets only work on the master // if they have hostNetwork=true. @@ -176,8 +170,8 @@ type ClusterSpec struct { // Networking configuration Networking *NetworkingSpec `json:"networking,omitempty"` - // API field controls how the API is exposed outside the cluster - API *AccessSpec `json:"api,omitempty"` + // API controls how the Kubernetes API is exposed. + API APISpec `json:"api,omitempty"` // Authentication field controls how the cluster is configured for authentication Authentication *AuthenticationSpec `json:"authentication,omitempty"` // Authorization field controls how the cluster is configured for authorization @@ -450,12 +444,18 @@ type RBACAuthorizationSpec struct{} type AlwaysAllowAuthorizationSpec struct{} -// AccessSpec provides configuration details related to kubeapi dns and ELB access -type AccessSpec struct { - // DNS will be used to provide config on kube-apiserver ELB DNS +// APISpec provides configuration details related to the Kubernetes API. +type APISpec struct { + // DNS will be used to provide configuration for the Kubernetes API's DNS server. DNS *DNSAccessSpec `json:"dns,omitempty"` - // LoadBalancer is the configuration for the kube-apiserver ELB + // LoadBalancer is the configuration for the Kubernetes API load balancer. LoadBalancer *LoadBalancerAccessSpec `json:"loadBalancer,omitempty"` + // PublicName is the external DNS name for the Kubernetes API. + PublicName string `json:"publicName,omitempty"` + // AdditionalSANs adds additional Subject Alternate Names to the Kubernetes API certificate. + AdditionalSANs []string `json:"additionalSANs,omitempty"` + // Access is a list of the CIDRs that can access the Kubernetes API endpoint. + Access []string `json:"access,omitempty"` } type DNSAccessSpec struct{} diff --git a/pkg/apis/kops/v1alpha2/cluster.go b/pkg/apis/kops/v1alpha2/cluster.go index 3a67ef258a..57dbeab6cd 100644 --- a/pkg/apis/kops/v1alpha2/cluster.go +++ b/pkg/apis/kops/v1alpha2/cluster.go @@ -71,6 +71,7 @@ type ClusterSpec struct { // +k8s:conversion-gen=false Project string `json:"project,omitempty"` // MasterPublicName is the external DNS name for the master nodes + // +k8s:conversion-gen=false MasterPublicName string `json:"masterPublicName,omitempty"` // MasterInternalName is unused. // +k8s:conversion-gen=false @@ -105,6 +106,7 @@ type ClusterSpec struct { // DNSControllerGossipConfig for the cluster assuming the use of gossip DNS DNSControllerGossipConfig *DNSControllerGossipConfig `json:"dnsControllerGossipConfig,omitempty"` // AdditionalSANs adds additional Subject Alternate Names to apiserver cert that kops generates + // +k8s:conversion-gen=false AdditionalSANs []string `json:"additionalSans,omitempty"` // ClusterDNSDomain is the suffix we use for internal DNS names (normally cluster.local) ClusterDNSDomain string `json:"clusterDNSDomain,omitempty"` @@ -127,6 +129,7 @@ type ClusterSpec struct { SSHKeyName *string `json:"sshKeyName,omitempty"` // KubernetesAPIAccess determines the permitted access to the API endpoints (master HTTPS) // Currently only a single CIDR is supported (though a richer grammar could be added in future) + // +k8s:conversion-gen=false KubernetesAPIAccess []string `json:"kubernetesApiAccess,omitempty"` // IsolateMasters determines whether we should lock down masters so that they are not on the pod network. // true is the kube-up behaviour, but it is very surprising: it means that daemonsets only work on the master @@ -182,7 +185,9 @@ type ClusterSpec struct { // Networking configuration Networking *NetworkingSpec `json:"networking,omitempty"` // API field controls how the API is exposed outside the cluster - API *AccessSpec `json:"api,omitempty"` + // +k8s:conversion-gen=false + LegacyAPI *APISpec `json:"api,omitempty"` + API APISpec `json:"-"` // Authentication field controls how the cluster is configured for authentication Authentication *AuthenticationSpec `json:"authentication,omitempty"` // Authorization field controls how the cluster is configured for authorization @@ -418,15 +423,18 @@ type RBACAuthorizationSpec struct{} type AlwaysAllowAuthorizationSpec struct{} -// AccessSpec provides configuration details related to kubeapi dns and ELB access -type AccessSpec struct { +// APISpec provides configuration details related to kubeapi dns and ELB access +type APISpec struct { // DNS will be used to provide config on kube-apiserver ELB DNS DNS *DNSAccessSpec `json:"dns,omitempty"` // LoadBalancer is the configuration for the kube-apiserver ELB - LoadBalancer *LoadBalancerAccessSpec `json:"loadBalancer,omitempty"` + LoadBalancer *LoadBalancerAccessSpec `json:"loadBalancer,omitempty"` + PublicName string `json:"-"` + AdditionalSANs []string `json:"-"` + Access []string `json:"-"` } -func (s *AccessSpec) IsEmpty() bool { +func (s *APISpec) IsEmpty() bool { return s.DNS == nil && s.LoadBalancer == nil } diff --git a/pkg/apis/kops/v1alpha2/conversion.go b/pkg/apis/kops/v1alpha2/conversion.go index 4f2d5a0742..4623ec1d4d 100644 --- a/pkg/apis/kops/v1alpha2/conversion.go +++ b/pkg/apis/kops/v1alpha2/conversion.go @@ -75,6 +75,11 @@ func Convert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *kops if err := autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in, out, s); err != nil { return err } + if in.LegacyAPI != nil { + if err := autoConvert_v1alpha2_APISpec_To_kops_APISpec(in.LegacyAPI, &out.API, s); err != nil { + return err + } + } switch kops.CloudProviderID(in.LegacyCloudProvider) { case kops.CloudProviderAWS: out.CloudProvider.AWS = &kops.AWSSpec{} @@ -122,6 +127,9 @@ func Convert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *kops out.Hooks[i].Enabled = values.Bool(!*hook.Enabled) } } + out.API.PublicName = in.MasterPublicName + out.API.AdditionalSANs = in.AdditionalSANs + out.API.Access = in.KubernetesAPIAccess return nil } @@ -129,6 +137,13 @@ func Convert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, out if err := autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in, out, s); err != nil { return err } + out.LegacyAPI = &APISpec{} + if err := autoConvert_kops_APISpec_To_v1alpha2_APISpec(&in.API, out.LegacyAPI, s); err != nil { + return err + } + if out.API.IsEmpty() { + out.LegacyAPI = nil + } out.LegacyCloudProvider = string(in.GetCloudProvider()) switch kops.CloudProviderID(out.LegacyCloudProvider) { case kops.CloudProviderAzure: @@ -162,6 +177,9 @@ func Convert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, out out.Hooks[i].Enabled = values.Bool(!*hook.Enabled) } } + out.MasterPublicName = in.API.PublicName + out.AdditionalSANs = in.API.AdditionalSANs + out.KubernetesAPIAccess = in.API.Access return nil } diff --git a/pkg/apis/kops/v1alpha2/defaults.go b/pkg/apis/kops/v1alpha2/defaults.go index 0363989e04..111ddd2053 100644 --- a/pkg/apis/kops/v1alpha2/defaults.go +++ b/pkg/apis/kops/v1alpha2/defaults.go @@ -51,31 +51,31 @@ func SetDefaults_ClusterSpec(obj *ClusterSpec) { } if obj.LegacyCloudProvider != "openstack" { - if obj.API == nil { - obj.API = &AccessSpec{} + if obj.LegacyAPI == nil { + obj.LegacyAPI = &APISpec{} } - if obj.API.IsEmpty() { + if obj.LegacyAPI.IsEmpty() { switch obj.Topology.ControlPlane { case TopologyPublic: - obj.API.DNS = &DNSAccessSpec{} + obj.LegacyAPI.DNS = &DNSAccessSpec{} case TopologyPrivate: - obj.API.LoadBalancer = &LoadBalancerAccessSpec{} + obj.LegacyAPI.LoadBalancer = &LoadBalancerAccessSpec{} default: klog.Infof("unknown master topology type: %q", obj.Topology.ControlPlane) } } - if obj.API.LoadBalancer != nil && obj.API.LoadBalancer.Type == "" { - obj.API.LoadBalancer.Type = LoadBalancerTypePublic + if obj.LegacyAPI.LoadBalancer != nil && obj.LegacyAPI.LoadBalancer.Type == "" { + obj.LegacyAPI.LoadBalancer.Type = LoadBalancerTypePublic } } - if obj.API.LoadBalancer != nil && obj.API.LoadBalancer.Class == "" && obj.LegacyCloudProvider == "aws" { - obj.API.LoadBalancer.Class = LoadBalancerClassClassic + if obj.LegacyAPI.LoadBalancer != nil && obj.LegacyAPI.LoadBalancer.Class == "" && obj.LegacyCloudProvider == "aws" { + obj.LegacyAPI.LoadBalancer.Class = LoadBalancerClassClassic } if obj.Authorization == nil { diff --git a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go index d7badbef3a..56eaf3a013 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go @@ -34,6 +34,16 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*APISpec)(nil), (*kops.APISpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_APISpec_To_kops_APISpec(a.(*APISpec), b.(*kops.APISpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.APISpec)(nil), (*APISpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_APISpec_To_v1alpha2_APISpec(a.(*kops.APISpec), b.(*APISpec), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*AWSAuthenticationIdentityMappingSpec)(nil), (*kops.AWSAuthenticationIdentityMappingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_AWSAuthenticationIdentityMappingSpec_To_kops_AWSAuthenticationIdentityMappingSpec(a.(*AWSAuthenticationIdentityMappingSpec), b.(*kops.AWSAuthenticationIdentityMappingSpec), scope) }); err != nil { @@ -104,16 +114,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*AccessSpec)(nil), (*kops.AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha2_AccessSpec_To_kops_AccessSpec(a.(*AccessSpec), b.(*kops.AccessSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*kops.AccessSpec)(nil), (*AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_kops_AccessSpec_To_v1alpha2_AccessSpec(a.(*kops.AccessSpec), b.(*AccessSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*AddonSpec)(nil), (*kops.AddonSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_AddonSpec_To_kops_AddonSpec(a.(*AddonSpec), b.(*kops.AddonSpec), scope) }); err != nil { @@ -1237,6 +1237,66 @@ func RegisterConversions(s *runtime.Scheme) error { return nil } +func autoConvert_v1alpha2_APISpec_To_kops_APISpec(in *APISpec, out *kops.APISpec, s conversion.Scope) error { + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(kops.DNSAccessSpec) + if err := Convert_v1alpha2_DNSAccessSpec_To_kops_DNSAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.DNS = nil + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(kops.LoadBalancerAccessSpec) + if err := Convert_v1alpha2_LoadBalancerAccessSpec_To_kops_LoadBalancerAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.LoadBalancer = nil + } + out.PublicName = in.PublicName + out.AdditionalSANs = in.AdditionalSANs + out.Access = in.Access + return nil +} + +// Convert_v1alpha2_APISpec_To_kops_APISpec is an autogenerated conversion function. +func Convert_v1alpha2_APISpec_To_kops_APISpec(in *APISpec, out *kops.APISpec, s conversion.Scope) error { + return autoConvert_v1alpha2_APISpec_To_kops_APISpec(in, out, s) +} + +func autoConvert_kops_APISpec_To_v1alpha2_APISpec(in *kops.APISpec, out *APISpec, s conversion.Scope) error { + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSAccessSpec) + if err := Convert_kops_DNSAccessSpec_To_v1alpha2_DNSAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.DNS = nil + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancerAccessSpec) + if err := Convert_kops_LoadBalancerAccessSpec_To_v1alpha2_LoadBalancerAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.LoadBalancer = nil + } + out.PublicName = in.PublicName + out.AdditionalSANs = in.AdditionalSANs + out.Access = in.Access + return nil +} + +// Convert_kops_APISpec_To_v1alpha2_APISpec is an autogenerated conversion function. +func Convert_kops_APISpec_To_v1alpha2_APISpec(in *kops.APISpec, out *APISpec, s conversion.Scope) error { + return autoConvert_kops_APISpec_To_v1alpha2_APISpec(in, out, s) +} + func autoConvert_v1alpha2_AWSAuthenticationIdentityMappingSpec_To_kops_AWSAuthenticationIdentityMappingSpec(in *AWSAuthenticationIdentityMappingSpec, out *kops.AWSAuthenticationIdentityMappingSpec, s conversion.Scope) error { out.ARN = in.ARN out.Username = in.Username @@ -1439,60 +1499,6 @@ func Convert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(in *kops.AccessLogSpec return autoConvert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(in, out, s) } -func autoConvert_v1alpha2_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error { - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(kops.DNSAccessSpec) - if err := Convert_v1alpha2_DNSAccessSpec_To_kops_DNSAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.DNS = nil - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(kops.LoadBalancerAccessSpec) - if err := Convert_v1alpha2_LoadBalancerAccessSpec_To_kops_LoadBalancerAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.LoadBalancer = nil - } - return nil -} - -// Convert_v1alpha2_AccessSpec_To_kops_AccessSpec is an autogenerated conversion function. -func Convert_v1alpha2_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error { - return autoConvert_v1alpha2_AccessSpec_To_kops_AccessSpec(in, out, s) -} - -func autoConvert_kops_AccessSpec_To_v1alpha2_AccessSpec(in *kops.AccessSpec, out *AccessSpec, s conversion.Scope) error { - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNSAccessSpec) - if err := Convert_kops_DNSAccessSpec_To_v1alpha2_DNSAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.DNS = nil - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancerAccessSpec) - if err := Convert_kops_LoadBalancerAccessSpec_To_v1alpha2_LoadBalancerAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.LoadBalancer = nil - } - return nil -} - -// Convert_kops_AccessSpec_To_v1alpha2_AccessSpec is an autogenerated conversion function. -func Convert_kops_AccessSpec_To_v1alpha2_AccessSpec(in *kops.AccessSpec, out *AccessSpec, s conversion.Scope) error { - return autoConvert_kops_AccessSpec_To_v1alpha2_AccessSpec(in, out, s) -} - func autoConvert_v1alpha2_AddonSpec_To_kops_AddonSpec(in *AddonSpec, out *kops.AddonSpec, s conversion.Scope) error { out.Manifest = in.Manifest return nil @@ -2445,7 +2451,7 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * out.Subnets = nil } // INFO: in.Project opted out of conversion generation - out.MasterPublicName = in.MasterPublicName + // INFO: in.MasterPublicName opted out of conversion generation // INFO: in.MasterInternalName opted out of conversion generation out.NetworkCIDR = in.NetworkCIDR out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs @@ -2472,7 +2478,7 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * } else { out.DNSControllerGossipConfig = nil } - out.AdditionalSANs = in.AdditionalSANs + // INFO: in.AdditionalSANs opted out of conversion generation out.ClusterDNSDomain = in.ClusterDNSDomain out.ServiceClusterIPRange = in.ServiceClusterIPRange out.PodCIDR = in.PodCIDR @@ -2489,7 +2495,7 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * out.EgressProxy = nil } out.SSHKeyName = in.SSHKeyName - out.KubernetesAPIAccess = in.KubernetesAPIAccess + // INFO: in.KubernetesAPIAccess opted out of conversion generation out.IsolateMasters = in.IsolateMasters out.UpdatePolicy = in.UpdatePolicy out.ExternalPolicies = in.ExternalPolicies @@ -2687,14 +2693,9 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * } else { out.Networking = nil } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(kops.AccessSpec) - if err := Convert_v1alpha2_AccessSpec_To_kops_AccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.API = nil + // INFO: in.LegacyAPI opted out of conversion generation + if err := Convert_v1alpha2_APISpec_To_kops_APISpec(&in.API, &out.API, s); err != nil { + return err } if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication @@ -2869,7 +2870,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, } else { out.Subnets = nil } - out.MasterPublicName = in.MasterPublicName out.NetworkCIDR = in.NetworkCIDR out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs out.NetworkID = in.NetworkID @@ -2895,7 +2895,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, } else { out.DNSControllerGossipConfig = nil } - out.AdditionalSANs = in.AdditionalSANs out.ClusterDNSDomain = in.ClusterDNSDomain out.ServiceClusterIPRange = in.ServiceClusterIPRange out.PodCIDR = in.PodCIDR @@ -2912,7 +2911,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, out.EgressProxy = nil } out.SSHKeyName = in.SSHKeyName - out.KubernetesAPIAccess = in.KubernetesAPIAccess out.IsolateMasters = in.IsolateMasters out.UpdatePolicy = in.UpdatePolicy out.ExternalPolicies = in.ExternalPolicies @@ -3110,14 +3108,8 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec, } else { out.Networking = nil } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(AccessSpec) - if err := Convert_kops_AccessSpec_To_v1alpha2_AccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.API = nil + if err := Convert_kops_APISpec_To_v1alpha2_APISpec(&in.API, &out.API, s); err != nil { + return err } if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication diff --git a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go index 1a2b8b015b..278cd9ab5f 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go @@ -28,6 +28,42 @@ import ( intstr "k8s.io/apimachinery/pkg/util/intstr" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APISpec) DeepCopyInto(out *APISpec) { + *out = *in + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSAccessSpec) + **out = **in + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancerAccessSpec) + (*in).DeepCopyInto(*out) + } + if in.AdditionalSANs != nil { + in, out := &in.AdditionalSANs, &out.AdditionalSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Access != nil { + in, out := &in.Access, &out.Access + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APISpec. +func (in *APISpec) DeepCopy() *APISpec { + if in == nil { + return nil + } + out := new(APISpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AWSAuthenticationIdentityMappingSpec) DeepCopyInto(out *AWSAuthenticationIdentityMappingSpec) { *out = *in @@ -224,32 +260,6 @@ func (in *AccessLogSpec) DeepCopy() *AccessLogSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AccessSpec) DeepCopyInto(out *AccessSpec) { - *out = *in - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNSAccessSpec) - **out = **in - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancerAccessSpec) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessSpec. -func (in *AccessSpec) DeepCopy() *AccessSpec { - if in == nil { - return nil - } - out := new(AccessSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AddonSpec) DeepCopyInto(out *AddonSpec) { *out = *in @@ -1256,11 +1266,12 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(NetworkingSpec) (*in).DeepCopyInto(*out) } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(AccessSpec) + if in.LegacyAPI != nil { + in, out := &in.LegacyAPI, &out.LegacyAPI + *out = new(APISpec) (*in).DeepCopyInto(*out) } + in.API.DeepCopyInto(&out.API) if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication *out = new(AuthenticationSpec) diff --git a/pkg/apis/kops/v1alpha3/cluster.go b/pkg/apis/kops/v1alpha3/cluster.go index 1a8a7fe6a6..2f68b41332 100644 --- a/pkg/apis/kops/v1alpha3/cluster.go +++ b/pkg/apis/kops/v1alpha3/cluster.go @@ -66,8 +66,6 @@ type ClusterSpec struct { KubernetesVersion string `json:"kubernetesVersion,omitempty"` // Configuration of subnets we are targeting Subnets []ClusterSubnetSpec `json:"subnets,omitempty"` - // MasterPublicName is the external DNS name for the master nodes - MasterPublicName string `json:"masterPublicName,omitempty"` // NetworkCIDR is the CIDR used for the AWS VPC / GCE Network, or otherwise allocated to k8s // This is a real CIDR, not the internal k8s network // On AWS, it maps to the VPC CIDR. It is not required on GCE. @@ -97,8 +95,6 @@ type ClusterSpec struct { DNSZone string `json:"dnsZone,omitempty"` // DNSControllerGossipConfig for the cluster assuming the use of gossip DNS DNSControllerGossipConfig *DNSControllerGossipConfig `json:"dnsControllerGossipConfig,omitempty"` - // AdditionalSANs adds additional Subject Alternate Names to apiserver cert that kops generates - AdditionalSANs []string `json:"additionalSANs,omitempty"` // ClusterDNSDomain is the suffix we use for internal DNS names (normally cluster.local) ClusterDNSDomain string `json:"clusterDNSDomain,omitempty"` // ServiceClusterIPRange is the CIDR, from the internal network, where we allocate IPs for services @@ -118,9 +114,6 @@ type ClusterSpec struct { EgressProxy *EgressProxySpec `json:"egressProxy,omitempty"` // SSHKeyName specifies a preexisting SSH key to use SSHKeyName *string `json:"sshKeyName,omitempty"` - // KubernetesAPIAccess determines the permitted access to the API endpoints (master HTTPS) - // Currently only a single CIDR is supported (though a richer grammar could be added in future) - KubernetesAPIAccess []string `json:"kubernetesAPIAccess,omitempty"` // IsolateMasters determines whether we should lock down masters so that they are not on the pod network. // true is the kube-up behaviour, but it is very surprising: it means that daemonsets only work on the master // if they have hostNetwork=true. @@ -174,8 +167,8 @@ type ClusterSpec struct { // Networking configuration Networking *NetworkingSpec `json:"networking,omitempty"` - // API field controls how the API is exposed outside the cluster - API *AccessSpec `json:"api,omitempty"` + // API controls how the Kubernetes API is exposed. + API APISpec `json:"api,omitempty"` // Authentication field controls how the cluster is configured for authentication Authentication *AuthenticationSpec `json:"authentication,omitempty"` // Authorization field controls how the cluster is configured for authorization @@ -421,16 +414,18 @@ type RBACAuthorizationSpec struct{} type AlwaysAllowAuthorizationSpec struct{} -// AccessSpec provides configuration details related to kubeapi dns and ELB access -type AccessSpec struct { - // DNS will be used to provide config on kube-apiserver ELB DNS +// APISpec provides configuration details related to the Kubernetes API. +type APISpec struct { + // DNS will be used to provide configuration for the Kubernetes API's DNS server. DNS *DNSAccessSpec `json:"dns,omitempty"` - // LoadBalancer is the configuration for the kube-apiserver ELB + // LoadBalancer is the configuration for the Kubernetes API load balancer. LoadBalancer *LoadBalancerAccessSpec `json:"loadBalancer,omitempty"` -} - -func (s *AccessSpec) IsEmpty() bool { - return s.DNS == nil && s.LoadBalancer == nil + // PublicName is the external DNS name for the Kubernetes API. + PublicName string `json:"publicName,omitempty"` + // AdditionalSANs adds additional Subject Alternate Names to the Kubernetes API certificate. + AdditionalSANs []string `json:"additionalSANs,omitempty"` + // Access is a list of the CIDRs that can access the Kubernetes API endpoint. + Access []string `json:"access,omitempty"` } type DNSAccessSpec struct{} diff --git a/pkg/apis/kops/v1alpha3/defaults.go b/pkg/apis/kops/v1alpha3/defaults.go index 13267dfb43..dec28740da 100644 --- a/pkg/apis/kops/v1alpha3/defaults.go +++ b/pkg/apis/kops/v1alpha3/defaults.go @@ -47,11 +47,7 @@ func SetDefaults_ClusterSpec(obj *ClusterSpec) { } if obj.CloudProvider.Openstack == nil { - if obj.API == nil { - obj.API = &AccessSpec{} - } - - if obj.API.IsEmpty() { + if obj.API.DNS == nil && obj.API.LoadBalancer == nil { switch obj.Topology.ControlPlane { case TopologyPublic: obj.API.DNS = &DNSAccessSpec{} diff --git a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go index aad7e3c888..725473a2a5 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go @@ -34,6 +34,16 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*APISpec)(nil), (*kops.APISpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_APISpec_To_kops_APISpec(a.(*APISpec), b.(*kops.APISpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kops.APISpec)(nil), (*APISpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kops_APISpec_To_v1alpha3_APISpec(a.(*kops.APISpec), b.(*APISpec), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*AWSAuthenticationIdentityMappingSpec)(nil), (*kops.AWSAuthenticationIdentityMappingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_AWSAuthenticationIdentityMappingSpec_To_kops_AWSAuthenticationIdentityMappingSpec(a.(*AWSAuthenticationIdentityMappingSpec), b.(*kops.AWSAuthenticationIdentityMappingSpec), scope) }); err != nil { @@ -114,16 +124,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*AccessSpec)(nil), (*kops.AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha3_AccessSpec_To_kops_AccessSpec(a.(*AccessSpec), b.(*kops.AccessSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*kops.AccessSpec)(nil), (*AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_kops_AccessSpec_To_v1alpha3_AccessSpec(a.(*kops.AccessSpec), b.(*AccessSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*AddonSpec)(nil), (*kops.AddonSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_AddonSpec_To_kops_AddonSpec(a.(*AddonSpec), b.(*kops.AddonSpec), scope) }); err != nil { @@ -1247,6 +1247,66 @@ func RegisterConversions(s *runtime.Scheme) error { return nil } +func autoConvert_v1alpha3_APISpec_To_kops_APISpec(in *APISpec, out *kops.APISpec, s conversion.Scope) error { + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(kops.DNSAccessSpec) + if err := Convert_v1alpha3_DNSAccessSpec_To_kops_DNSAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.DNS = nil + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(kops.LoadBalancerAccessSpec) + if err := Convert_v1alpha3_LoadBalancerAccessSpec_To_kops_LoadBalancerAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.LoadBalancer = nil + } + out.PublicName = in.PublicName + out.AdditionalSANs = in.AdditionalSANs + out.Access = in.Access + return nil +} + +// Convert_v1alpha3_APISpec_To_kops_APISpec is an autogenerated conversion function. +func Convert_v1alpha3_APISpec_To_kops_APISpec(in *APISpec, out *kops.APISpec, s conversion.Scope) error { + return autoConvert_v1alpha3_APISpec_To_kops_APISpec(in, out, s) +} + +func autoConvert_kops_APISpec_To_v1alpha3_APISpec(in *kops.APISpec, out *APISpec, s conversion.Scope) error { + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSAccessSpec) + if err := Convert_kops_DNSAccessSpec_To_v1alpha3_DNSAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.DNS = nil + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancerAccessSpec) + if err := Convert_kops_LoadBalancerAccessSpec_To_v1alpha3_LoadBalancerAccessSpec(*in, *out, s); err != nil { + return err + } + } else { + out.LoadBalancer = nil + } + out.PublicName = in.PublicName + out.AdditionalSANs = in.AdditionalSANs + out.Access = in.Access + return nil +} + +// Convert_kops_APISpec_To_v1alpha3_APISpec is an autogenerated conversion function. +func Convert_kops_APISpec_To_v1alpha3_APISpec(in *kops.APISpec, out *APISpec, s conversion.Scope) error { + return autoConvert_kops_APISpec_To_v1alpha3_APISpec(in, out, s) +} + func autoConvert_v1alpha3_AWSAuthenticationIdentityMappingSpec_To_kops_AWSAuthenticationIdentityMappingSpec(in *AWSAuthenticationIdentityMappingSpec, out *kops.AWSAuthenticationIdentityMappingSpec, s conversion.Scope) error { out.ARN = in.ARN out.Username = in.Username @@ -1467,60 +1527,6 @@ func Convert_kops_AccessLogSpec_To_v1alpha3_AccessLogSpec(in *kops.AccessLogSpec return autoConvert_kops_AccessLogSpec_To_v1alpha3_AccessLogSpec(in, out, s) } -func autoConvert_v1alpha3_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error { - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(kops.DNSAccessSpec) - if err := Convert_v1alpha3_DNSAccessSpec_To_kops_DNSAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.DNS = nil - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(kops.LoadBalancerAccessSpec) - if err := Convert_v1alpha3_LoadBalancerAccessSpec_To_kops_LoadBalancerAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.LoadBalancer = nil - } - return nil -} - -// Convert_v1alpha3_AccessSpec_To_kops_AccessSpec is an autogenerated conversion function. -func Convert_v1alpha3_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error { - return autoConvert_v1alpha3_AccessSpec_To_kops_AccessSpec(in, out, s) -} - -func autoConvert_kops_AccessSpec_To_v1alpha3_AccessSpec(in *kops.AccessSpec, out *AccessSpec, s conversion.Scope) error { - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNSAccessSpec) - if err := Convert_kops_DNSAccessSpec_To_v1alpha3_DNSAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.DNS = nil - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancerAccessSpec) - if err := Convert_kops_LoadBalancerAccessSpec_To_v1alpha3_LoadBalancerAccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.LoadBalancer = nil - } - return nil -} - -// Convert_kops_AccessSpec_To_v1alpha3_AccessSpec is an autogenerated conversion function. -func Convert_kops_AccessSpec_To_v1alpha3_AccessSpec(in *kops.AccessSpec, out *AccessSpec, s conversion.Scope) error { - return autoConvert_kops_AccessSpec_To_v1alpha3_AccessSpec(in, out, s) -} - func autoConvert_v1alpha3_AddonSpec_To_kops_AddonSpec(in *AddonSpec, out *kops.AddonSpec, s conversion.Scope) error { out.Manifest = in.Manifest return nil @@ -2554,7 +2560,6 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * } else { out.Subnets = nil } - out.MasterPublicName = in.MasterPublicName out.NetworkCIDR = in.NetworkCIDR out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs out.NetworkID = in.NetworkID @@ -2580,7 +2585,6 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * } else { out.DNSControllerGossipConfig = nil } - out.AdditionalSANs = in.AdditionalSANs out.ClusterDNSDomain = in.ClusterDNSDomain out.ServiceClusterIPRange = in.ServiceClusterIPRange out.PodCIDR = in.PodCIDR @@ -2597,7 +2601,6 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * out.EgressProxy = nil } out.SSHKeyName = in.SSHKeyName - out.KubernetesAPIAccess = in.KubernetesAPIAccess out.IsolateMasters = in.IsolateMasters out.UpdatePolicy = in.UpdatePolicy out.ExternalPolicies = in.ExternalPolicies @@ -2795,14 +2798,8 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out * } else { out.Networking = nil } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(kops.AccessSpec) - if err := Convert_v1alpha3_AccessSpec_To_kops_AccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.API = nil + if err := Convert_v1alpha3_APISpec_To_kops_APISpec(&in.API, &out.API, s); err != nil { + return err } if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication @@ -2976,7 +2973,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec, } else { out.Subnets = nil } - out.MasterPublicName = in.MasterPublicName out.NetworkCIDR = in.NetworkCIDR out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs out.NetworkID = in.NetworkID @@ -3002,7 +2998,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec, } else { out.DNSControllerGossipConfig = nil } - out.AdditionalSANs = in.AdditionalSANs out.ClusterDNSDomain = in.ClusterDNSDomain out.ServiceClusterIPRange = in.ServiceClusterIPRange out.PodCIDR = in.PodCIDR @@ -3019,7 +3014,6 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec, out.EgressProxy = nil } out.SSHKeyName = in.SSHKeyName - out.KubernetesAPIAccess = in.KubernetesAPIAccess out.IsolateMasters = in.IsolateMasters out.UpdatePolicy = in.UpdatePolicy out.ExternalPolicies = in.ExternalPolicies @@ -3217,14 +3211,8 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec, } else { out.Networking = nil } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(AccessSpec) - if err := Convert_kops_AccessSpec_To_v1alpha3_AccessSpec(*in, *out, s); err != nil { - return err - } - } else { - out.API = nil + if err := Convert_kops_APISpec_To_v1alpha3_APISpec(&in.API, &out.API, s); err != nil { + return err } if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication diff --git a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go index edc4b7f188..d3455a2871 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go @@ -29,6 +29,42 @@ import ( kops "k8s.io/kops/pkg/apis/kops" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APISpec) DeepCopyInto(out *APISpec) { + *out = *in + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSAccessSpec) + **out = **in + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancerAccessSpec) + (*in).DeepCopyInto(*out) + } + if in.AdditionalSANs != nil { + in, out := &in.AdditionalSANs, &out.AdditionalSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Access != nil { + in, out := &in.Access, &out.Access + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APISpec. +func (in *APISpec) DeepCopy() *APISpec { + if in == nil { + return nil + } + out := new(APISpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AWSAuthenticationIdentityMappingSpec) DeepCopyInto(out *AWSAuthenticationIdentityMappingSpec) { *out = *in @@ -241,32 +277,6 @@ func (in *AccessLogSpec) DeepCopy() *AccessLogSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AccessSpec) DeepCopyInto(out *AccessSpec) { - *out = *in - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNSAccessSpec) - **out = **in - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancerAccessSpec) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessSpec. -func (in *AccessSpec) DeepCopy() *AccessSpec { - if in == nil { - return nil - } - out := new(AccessSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AddonSpec) DeepCopyInto(out *AddonSpec) { *out = *in @@ -1035,11 +1045,6 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(DNSControllerGossipConfig) (*in).DeepCopyInto(*out) } - if in.AdditionalSANs != nil { - in, out := &in.AdditionalSANs, &out.AdditionalSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.SSHAccess != nil { in, out := &in.SSHAccess, &out.SSHAccess *out = make([]string, len(*in)) @@ -1060,11 +1065,6 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(string) **out = **in } - if in.KubernetesAPIAccess != nil { - in, out := &in.KubernetesAPIAccess, &out.KubernetesAPIAccess - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.IsolateMasters != nil { in, out := &in.IsolateMasters, &out.IsolateMasters *out = new(bool) @@ -1214,11 +1214,7 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(NetworkingSpec) (*in).DeepCopyInto(*out) } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(AccessSpec) - (*in).DeepCopyInto(*out) - } + in.API.DeepCopyInto(&out.API) if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication *out = new(AuthenticationSpec) diff --git a/pkg/apis/kops/validation/aws.go b/pkg/apis/kops/validation/aws.go index 824881fa59..1872da7d3a 100644 --- a/pkg/apis/kops/validation/aws.go +++ b/pkg/apis/kops/validation/aws.go @@ -35,13 +35,11 @@ import ( func awsValidateCluster(c *kops.Cluster) field.ErrorList { allErrs := field.ErrorList{} - if c.Spec.API != nil { - if c.Spec.API.LoadBalancer != nil { - allErrs = append(allErrs, awsValidateAdditionalSecurityGroups(field.NewPath("spec", "api", "loadBalancer", "additionalSecurityGroups"), c.Spec.API.LoadBalancer.AdditionalSecurityGroups)...) - allErrs = append(allErrs, awsValidateSSLPolicy(field.NewPath("spec", "api", "loadBalancer", "sslPolicy"), c.Spec.API.LoadBalancer)...) - allErrs = append(allErrs, awsValidateLoadBalancerSubnets(field.NewPath("spec", "api", "loadBalancer", "subnets"), c.Spec)...) - allErrs = append(allErrs, awsValidateTopologyDNS(field.NewPath("spec", "api", "loadBalancer", "type"), c)...) - } + if c.Spec.API.LoadBalancer != nil { + allErrs = append(allErrs, awsValidateAdditionalSecurityGroups(field.NewPath("spec", "api", "loadBalancer", "additionalSecurityGroups"), c.Spec.API.LoadBalancer.AdditionalSecurityGroups)...) + allErrs = append(allErrs, awsValidateSSLPolicy(field.NewPath("spec", "api", "loadBalancer", "sslPolicy"), c.Spec.API.LoadBalancer)...) + allErrs = append(allErrs, awsValidateLoadBalancerSubnets(field.NewPath("spec", "api", "loadBalancer", "subnets"), c.Spec)...) + allErrs = append(allErrs, awsValidateTopologyDNS(field.NewPath("spec", "api", "loadBalancer", "type"), c)...) } allErrs = append(allErrs, awsValidateExternalCloudControllerManager(c)...) @@ -277,7 +275,7 @@ func awsValidateMixedInstancesPolicy(path *field.Path, spec *kops.MixedInstances func awsValidateTopologyDNS(fieldPath *field.Path, c *kops.Cluster) field.ErrorList { allErrs := field.ErrorList{} - if c.UsesNoneDNS() && c.Spec.API != nil && c.Spec.API.LoadBalancer != nil && c.Spec.API.LoadBalancer.Class != kops.LoadBalancerClassNetwork { + if c.UsesNoneDNS() && c.Spec.API.LoadBalancer != nil && c.Spec.API.LoadBalancer.Class != kops.LoadBalancerClassNetwork { allErrs = append(allErrs, field.Forbidden(fieldPath, "topology.dns.type=none requires Network Load Balancer")) } diff --git a/pkg/apis/kops/validation/aws_test.go b/pkg/apis/kops/validation/aws_test.go index 034a134161..85a6b5e1ba 100644 --- a/pkg/apis/kops/validation/aws_test.go +++ b/pkg/apis/kops/validation/aws_test.go @@ -571,7 +571,7 @@ func TestLoadBalancerSubnets(t *testing.T) { for _, test := range tests { cluster := kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{ Class: kops.LoadBalancerClassNetwork, Type: kops.LoadBalancerTypeInternal, diff --git a/pkg/apis/kops/validation/validation.go b/pkg/apis/kops/validation/validation.go index 40a3d2c03c..26e6a34630 100644 --- a/pkg/apis/kops/validation/validation.go +++ b/pkg/apis/kops/validation/validation.go @@ -94,7 +94,7 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie } // KubernetesAPIAccess - for i, cidr := range spec.KubernetesAPIAccess { + for i, cidr := range spec.API.Access { if strings.HasPrefix(cidr, "pl-") { if spec.GetCloudProvider() != kops.CloudProviderAWS { allErrs = append(allErrs, field.Invalid(fieldPath.Child("kubernetesAPIAccess").Index(i), cidr, "Prefix List ID only supported for AWS")) @@ -243,7 +243,7 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie allErrs = append(allErrs, validateRollingUpdate(spec.RollingUpdate, fieldPath.Child("rollingUpdate"), false)...) } - if spec.API != nil && spec.API.LoadBalancer != nil { + if spec.API.LoadBalancer != nil { lbSpec := spec.API.LoadBalancer lbPath := fieldPath.Child("api", "loadBalancer") if spec.GetCloudProvider() == kops.CloudProviderAWS { diff --git a/pkg/apis/kops/zz_generated.deepcopy.go b/pkg/apis/kops/zz_generated.deepcopy.go index 9eae6ec8a3..07f48879fc 100644 --- a/pkg/apis/kops/zz_generated.deepcopy.go +++ b/pkg/apis/kops/zz_generated.deepcopy.go @@ -28,6 +28,42 @@ import ( intstr "k8s.io/apimachinery/pkg/util/intstr" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APISpec) DeepCopyInto(out *APISpec) { + *out = *in + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSAccessSpec) + **out = **in + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancerAccessSpec) + (*in).DeepCopyInto(*out) + } + if in.AdditionalSANs != nil { + in, out := &in.AdditionalSANs, &out.AdditionalSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Access != nil { + in, out := &in.Access, &out.Access + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APISpec. +func (in *APISpec) DeepCopy() *APISpec { + if in == nil { + return nil + } + out := new(APISpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AWSAuthenticationIdentityMappingSpec) DeepCopyInto(out *AWSAuthenticationIdentityMappingSpec) { *out = *in @@ -240,32 +276,6 @@ func (in *AccessLogSpec) DeepCopy() *AccessLogSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AccessSpec) DeepCopyInto(out *AccessSpec) { - *out = *in - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNSAccessSpec) - **out = **in - } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancerAccessSpec) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessSpec. -func (in *AccessSpec) DeepCopy() *AccessSpec { - if in == nil { - return nil - } - out := new(AccessSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AddonSpec) DeepCopyInto(out *AddonSpec) { *out = *in @@ -1132,11 +1142,6 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(DNSControllerGossipConfig) (*in).DeepCopyInto(*out) } - if in.AdditionalSANs != nil { - in, out := &in.AdditionalSANs, &out.AdditionalSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.SSHAccess != nil { in, out := &in.SSHAccess, &out.SSHAccess *out = make([]string, len(*in)) @@ -1157,11 +1162,6 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(string) **out = **in } - if in.KubernetesAPIAccess != nil { - in, out := &in.KubernetesAPIAccess, &out.KubernetesAPIAccess - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.IsolateMasters != nil { in, out := &in.IsolateMasters, &out.IsolateMasters *out = new(bool) @@ -1311,11 +1311,7 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = new(NetworkingSpec) (*in).DeepCopyInto(*out) } - if in.API != nil { - in, out := &in.API, &out.API - *out = new(AccessSpec) - (*in).DeepCopyInto(*out) - } + in.API.DeepCopyInto(&out.API) if in.Authentication != nil { in, out := &in.Authentication, &out.Authentication *out = new(AuthenticationSpec) diff --git a/pkg/commands/set_cluster_test.go b/pkg/commands/set_cluster_test.go index 7f1b75f657..cf042cca3c 100644 --- a/pkg/commands/set_cluster_test.go +++ b/pkg/commands/set_cluster_test.go @@ -71,7 +71,7 @@ func TestSetClusterFields(t *testing.T) { }, Output: kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ DNS: &kops.DNSAccessSpec{}, }, }, @@ -116,10 +116,12 @@ func TestSetClusterFields(t *testing.T) { }, }, { - Fields: []string{"spec.masterPublicName=api.example.com"}, + Fields: []string{"spec.api.publicName=api.example.com"}, Output: kops.Cluster{ Spec: kops.ClusterSpec{ - MasterPublicName: "api.example.com", + API: kops.APISpec{ + PublicName: "api.example.com", + }, }, }, }, diff --git a/pkg/commands/unset_cluster_test.go b/pkg/commands/unset_cluster_test.go index 096246f447..db1ff0ef6a 100644 --- a/pkg/commands/unset_cluster_test.go +++ b/pkg/commands/unset_cluster_test.go @@ -68,15 +68,13 @@ func TestUnsetClusterFields(t *testing.T) { }, Input: kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ DNS: &kops.DNSAccessSpec{}, }, }, }, Output: kops.Cluster{ - Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{}, - }, + Spec: kops.ClusterSpec{}, }, }, { @@ -136,10 +134,12 @@ func TestUnsetClusterFields(t *testing.T) { }, }, { - Fields: []string{"spec.masterPublicName"}, + Fields: []string{"spec.api.publicName"}, Input: kops.Cluster{ Spec: kops.ClusterSpec{ - MasterPublicName: "api.example.com", + API: kops.APISpec{ + PublicName: "api.example.com", + }, }, }, Output: kops.Cluster{ diff --git a/pkg/kubeconfig/create_kubecfg.go b/pkg/kubeconfig/create_kubecfg.go index 7047ea8cd8..ffabe67aa0 100644 --- a/pkg/kubeconfig/create_kubecfg.go +++ b/pkg/kubeconfig/create_kubecfg.go @@ -39,7 +39,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se if internal { master = cluster.APIInternalName() } else { - master = cluster.Spec.MasterPublicName + master = cluster.Spec.API.PublicName if master == "" { master = "api." + clusterName } @@ -65,7 +65,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se // We differentiate using the heuristic that if we have an internal ELB // we are likely connected directly to the VPC. privateDNS := cluster.Spec.Topology != nil && cluster.Spec.Topology.DNS == kops.DNSTypePrivate - internalELB := cluster.Spec.API != nil && cluster.Spec.API.LoadBalancer != nil && cluster.Spec.API.LoadBalancer.Type == kops.LoadBalancerTypeInternal + internalELB := cluster.Spec.API.LoadBalancer != nil && cluster.Spec.API.LoadBalancer.Type == kops.LoadBalancerTypeInternal if privateDNS && !internalELB { useELBName = true } @@ -100,7 +100,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se b := NewKubeconfigBuilder() // Use the secondary load balancer port if a certificate is on the primary listener - if admin != 0 && cluster.Spec.API != nil && cluster.Spec.API.LoadBalancer != nil && cluster.Spec.API.LoadBalancer.SSLCertificate != "" && cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork { + if admin != 0 && cluster.Spec.API.LoadBalancer != nil && cluster.Spec.API.LoadBalancer.SSLCertificate != "" && cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork { server = server + ":8443" } @@ -109,7 +109,7 @@ func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.Se // add the CA Cert to the kubeconfig only if we didn't specify a certificate for the LB // or if we're using admin credentials and the secondary port - if cluster.Spec.API == nil || cluster.Spec.API.LoadBalancer == nil || cluster.Spec.API.LoadBalancer.SSLCertificate == "" || cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork || internal { + if cluster.Spec.API.LoadBalancer == nil || cluster.Spec.API.LoadBalancer.SSLCertificate == "" || cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassNetwork || internal { keySet, err := keyStore.FindKeyset(fi.CertificateIDCA) if err != nil { return nil, fmt.Errorf("error fetching CA keypair: %v", err) diff --git a/pkg/kubeconfig/create_kubecfg_test.go b/pkg/kubeconfig/create_kubecfg_test.go index 2bf050c092..2cb85ad834 100644 --- a/pkg/kubeconfig/create_kubecfg_test.go +++ b/pkg/kubeconfig/create_kubecfg_test.go @@ -119,11 +119,9 @@ func (f fakeKeyStore) MirrorTo(basedir vfs.Path) error { // build a generic minimal cluster func buildMinimalCluster(clusterName string, masterPublicName string, lbCert bool, nlb bool) *kops.Cluster { cluster := testutils.BuildMinimalCluster(clusterName) - cluster.Spec.MasterPublicName = masterPublicName + cluster.Spec.API.PublicName = masterPublicName cluster.Spec.KubernetesVersion = "1.24.0" - cluster.Spec.API = &kops.AccessSpec{ - LoadBalancer: &kops.LoadBalancerAccessSpec{}, - } + cluster.Spec.API.LoadBalancer = &kops.LoadBalancerAccessSpec{} if lbCert { cluster.Spec.API.LoadBalancer.SSLCertificate = "cert-arn" } diff --git a/pkg/model/awsmodel/api_loadbalancer.go b/pkg/model/awsmodel/api_loadbalancer.go index 89d3f96366..df00c4a844 100644 --- a/pkg/model/awsmodel/api_loadbalancer.go +++ b/pkg/model/awsmodel/api_loadbalancer.go @@ -397,7 +397,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error { // Allow traffic into the ELB from KubernetesAPIAccess CIDRs if b.APILoadBalancerClass() == kops.LoadBalancerClassClassic { - for _, cidr := range b.Cluster.Spec.KubernetesAPIAccess { + for _, cidr := range b.Cluster.Spec.API.Access { { t := &awstasks.SecurityGroupRule{ Name: fi.PtrTo("https-api-elb-" + cidr), @@ -442,7 +442,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error { } if b.APILoadBalancerClass() == kops.LoadBalancerClassNetwork { - for _, cidr := range b.Cluster.Spec.KubernetesAPIAccess { + for _, cidr := range b.Cluster.Spec.API.Access { for _, masterGroup := range masterGroups { { t := &awstasks.SecurityGroupRule{ @@ -485,7 +485,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error { c.AddTask(t) } - if b.Cluster.Spec.API != nil && b.Cluster.Spec.API.LoadBalancer != nil && b.Cluster.Spec.API.LoadBalancer.SSLCertificate != "" { + if b.Cluster.Spec.API.LoadBalancer != nil && b.Cluster.Spec.API.LoadBalancer.SSLCertificate != "" { // Allow access to masters on secondary port through NLB t := &awstasks.SecurityGroupRule{ Name: fi.PtrTo(fmt.Sprintf("tcp-api-%s", cidr)), diff --git a/pkg/model/awsmodel/autoscalinggroup_test.go b/pkg/model/awsmodel/autoscalinggroup_test.go index 35bf02ffe6..24ad47adda 100644 --- a/pkg/model/awsmodel/autoscalinggroup_test.go +++ b/pkg/model/awsmodel/autoscalinggroup_test.go @@ -119,7 +119,7 @@ func TestAPIServerAdditionalSecurityGroupsWithNLB(t *testing.T) { const sgIDAPIServer = "sg-01234567890abcdef" cluster := buildMinimalCluster() - cluster.Spec.API = &kops.AccessSpec{ + cluster.Spec.API = kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{ Class: kops.LoadBalancerClassNetwork, AdditionalSecurityGroups: []string{sgIDAPIServer}, diff --git a/pkg/model/awsmodel/dns.go b/pkg/model/awsmodel/dns.go index 497d59274a..3cd4602aa2 100644 --- a/pkg/model/awsmodel/dns.go +++ b/pkg/model/awsmodel/dns.go @@ -100,8 +100,8 @@ func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error { } c.AddTask(&awstasks.DNSName{ - Name: fi.PtrTo(b.Cluster.Spec.MasterPublicName), - ResourceName: fi.PtrTo(b.Cluster.Spec.MasterPublicName), + Name: fi.PtrTo(b.Cluster.Spec.API.PublicName), + ResourceName: fi.PtrTo(b.Cluster.Spec.API.PublicName), Lifecycle: b.Lifecycle, Zone: b.LinkToDNSZone(), ResourceType: fi.PtrTo("A"), @@ -109,8 +109,8 @@ func (b *DNSModelBuilder) Build(c *fi.ModelBuilderContext) error { }) if b.UseIPv6ForAPI() { c.AddTask(&awstasks.DNSName{ - Name: fi.PtrTo(b.Cluster.Spec.MasterPublicName + "-AAAA"), - ResourceName: fi.PtrTo(b.Cluster.Spec.MasterPublicName), + Name: fi.PtrTo(b.Cluster.Spec.API.PublicName + "-AAAA"), + ResourceName: fi.PtrTo(b.Cluster.Spec.API.PublicName), Lifecycle: b.Lifecycle, Zone: b.LinkToDNSZone(), ResourceType: fi.PtrTo("AAAA"), diff --git a/pkg/model/awsmodel/external_access.go b/pkg/model/awsmodel/external_access.go index 148d95be98..38d09e7258 100644 --- a/pkg/model/awsmodel/external_access.go +++ b/pkg/model/awsmodel/external_access.go @@ -35,7 +35,7 @@ type ExternalAccessModelBuilder struct { var _ fi.ModelBuilder = &ExternalAccessModelBuilder{} func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error { - if len(b.Cluster.Spec.KubernetesAPIAccess) == 0 { + if len(b.Cluster.Spec.API.Access) == 0 { klog.Warningf("KubernetesAPIAccess is empty") } @@ -131,7 +131,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error { // We need to open security groups directly to the master nodes (instead of via the ELB) // HTTPS to the master is allowed (for API access) - for _, apiAccess := range b.Cluster.Spec.KubernetesAPIAccess { + for _, apiAccess := range b.Cluster.Spec.API.Access { for _, masterGroup := range masterGroups { suffix := masterGroup.Suffix t := &awstasks.SecurityGroupRule{ diff --git a/pkg/model/azuremodel/testing.go b/pkg/model/azuremodel/testing.go index cab648b951..d7edf412cb 100644 --- a/pkg/model/azuremodel/testing.go +++ b/pkg/model/azuremodel/testing.go @@ -44,7 +44,7 @@ func newTestCluster() *kops.Cluster { Name: "testcluster.test.com", }, Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{ Type: kops.LoadBalancerTypeInternal, }, diff --git a/pkg/model/components/discovery.go b/pkg/model/components/discovery.go index bcdc9a1b71..11f660b877 100644 --- a/pkg/model/components/discovery.go +++ b/pkg/model/components/discovery.go @@ -71,8 +71,8 @@ func (b *DiscoveryOptionsBuilder) BuildOptions(o interface{}) error { return fmt.Errorf("locationStore=%q is of unexpected type %T", store, base) } } else { - if supportsPublicJWKS(clusterSpec) && clusterSpec.MasterPublicName != "" { - serviceAccountIssuer = "https://" + clusterSpec.MasterPublicName + if supportsPublicJWKS(clusterSpec) && clusterSpec.API.PublicName != "" { + serviceAccountIssuer = "https://" + clusterSpec.API.PublicName } else { serviceAccountIssuer = "https://api.internal." + b.ClusterName } @@ -89,7 +89,7 @@ func supportsPublicJWKS(clusterSpec *kops.ClusterSpec) bool { if !fi.ValueOf(clusterSpec.KubeAPIServer.AnonymousAuth) { return false } - for _, cidr := range clusterSpec.KubernetesAPIAccess { + for _, cidr := range clusterSpec.API.Access { if cidr == "0.0.0.0/0" || cidr == "::/0" { return true } diff --git a/pkg/model/context.go b/pkg/model/context.go index cebe06b0f1..40892465f5 100644 --- a/pkg/model/context.go +++ b/pkg/model/context.go @@ -270,9 +270,6 @@ func (b *KopsModelContext) UsesSSHBastion() bool { // UseLoadBalancerForAPI checks if we are using a load balancer for the kubeapi func (b *KopsModelContext) UseLoadBalancerForAPI() bool { - if b.Cluster.Spec.API == nil { - return false - } return b.Cluster.Spec.API.LoadBalancer != nil } @@ -286,7 +283,7 @@ func (b *KopsModelContext) UseLoadBalancerForInternalAPI() bool { // APILoadBalancerClass returns which type of load balancer to use for the api func (b *KopsModelContext) APILoadBalancerClass() kops.LoadBalancerClass { - if b.Cluster.Spec.API != nil && b.Cluster.Spec.API.LoadBalancer != nil { + if b.Cluster.Spec.API.LoadBalancer != nil { return b.Cluster.Spec.API.LoadBalancer.Class } return kops.LoadBalancerClassClassic diff --git a/pkg/model/gcemodel/api_loadbalancer.go b/pkg/model/gcemodel/api_loadbalancer.go index 6b2a105335..d10e63d56d 100644 --- a/pkg/model/gcemodel/api_loadbalancer.go +++ b/pkg/model/gcemodel/api_loadbalancer.go @@ -91,7 +91,7 @@ func createPublicLB(b *APILoadBalancerBuilder, c *fi.ModelBuilderContext) error b.AddFirewallRulesTasks(c, "https-api", &gcetasks.FirewallRule{ Lifecycle: b.Lifecycle, Network: network, - SourceRanges: b.Cluster.Spec.KubernetesAPIAccess, + SourceRanges: b.Cluster.Spec.API.Access, TargetTags: []string{b.GCETagForRole(kops.InstanceGroupRoleMaster)}, Allowed: []string{"tcp:443"}, }) diff --git a/pkg/model/gcemodel/external_access.go b/pkg/model/gcemodel/external_access.go index 8f3297a3bd..b247ea0a88 100644 --- a/pkg/model/gcemodel/external_access.go +++ b/pkg/model/gcemodel/external_access.go @@ -34,7 +34,7 @@ var _ fi.ModelBuilder = &ExternalAccessModelBuilder{} func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error { klog.Warningf("TODO: Harmonize gcemodel ExternalAccessModelBuilder with awsmodel") - if len(b.Cluster.Spec.KubernetesAPIAccess) == 0 { + if len(b.Cluster.Spec.API.Access) == 0 { klog.Warningf("KubernetesAPIAccess is empty") } @@ -109,7 +109,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error { Lifecycle: b.Lifecycle, TargetTags: []string{b.GCETagForRole(kops.InstanceGroupRoleMaster)}, Allowed: []string{"tcp:443"}, - SourceRanges: b.Cluster.Spec.KubernetesAPIAccess, + SourceRanges: b.Cluster.Spec.API.Access, Network: network, }) } diff --git a/pkg/model/hetznermodel/firewall.go b/pkg/model/hetznermodel/firewall.go index 2daf485139..b3c4674274 100644 --- a/pkg/model/hetznermodel/firewall.go +++ b/pkg/model/hetznermodel/firewall.go @@ -90,7 +90,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error { if !b.UseLoadBalancerForAPI() { var apiAccess []net.IPNet - for _, cidr := range b.Cluster.Spec.KubernetesAPIAccess { + for _, cidr := range b.Cluster.Spec.API.Access { _, ipNet, err := net.ParseCIDR(cidr) if err != nil { return err diff --git a/pkg/model/openstackmodel/firewall.go b/pkg/model/openstackmodel/firewall.go index 1259dc48ac..419f2344f6 100644 --- a/pkg/model/openstackmodel/firewall.go +++ b/pkg/model/openstackmodel/firewall.go @@ -233,7 +233,7 @@ func (b *FirewallModelBuilder) addNodePortRules(c *fi.ModelBuilderContext, sgMap func (b *FirewallModelBuilder) addHTTPSRules(c *fi.ModelBuilderContext, sgMap map[string]*openstacktasks.SecurityGroup, useVIPACL bool) error { masterName := b.SecurityGroupName(kops.InstanceGroupRoleMaster) nodeName := b.SecurityGroupName(kops.InstanceGroupRoleNode) - lbSGName := b.Cluster.Spec.MasterPublicName + lbSGName := b.Cluster.Spec.API.PublicName lbSG := sgMap[lbSGName] masterSG := sgMap[masterName] nodeSG := sgMap[nodeName] @@ -254,7 +254,7 @@ func (b *FirewallModelBuilder) addHTTPSRules(c *fi.ModelBuilderContext, sgMap ma if b.UseLoadBalancerForAPI() { if !useVIPACL { // Allow API Access to the lb sg - for _, apiAccess := range b.Cluster.Spec.KubernetesAPIAccess { + for _, apiAccess := range b.Cluster.Spec.API.Access { etherType := IPV4 if !net.IsIPv4CIDRString(apiAccess) { etherType = IPV6 @@ -276,7 +276,7 @@ func (b *FirewallModelBuilder) addHTTPSRules(c *fi.ModelBuilderContext, sgMap ma // FIXME: Octavia port traffic appears to be denied though its port is in lbSG if b.usesOctavia() { if b.getOctaviaProvider() == "ovn" { - for _, apiAccess := range b.Cluster.Spec.KubernetesAPIAccess { + for _, apiAccess := range b.Cluster.Spec.API.Access { etherType := IPV4 if !net.IsIPv4CIDRString(apiAccess) { etherType = IPV6 @@ -306,7 +306,7 @@ func (b *FirewallModelBuilder) addHTTPSRules(c *fi.ModelBuilderContext, sgMap ma } else { // Allow the masters to receive connections from KubernetesAPIAccess - for _, apiAccess := range b.Cluster.Spec.KubernetesAPIAccess { + for _, apiAccess := range b.Cluster.Spec.API.Access { etherType := IPV4 if !net.IsIPv4CIDRString(apiAccess) { etherType = IPV6 @@ -581,7 +581,7 @@ func (b *FirewallModelBuilder) getExistingRules(sgMap map[string]*openstacktasks func (b *FirewallModelBuilder) addDefaultEgress(c *fi.ModelBuilderContext, sgMap map[string]*openstacktasks.SecurityGroup, useVIPACL bool) { for name, sg := range sgMap { - if useVIPACL && name == b.Cluster.Spec.MasterPublicName { + if useVIPACL && name == b.Cluster.Spec.API.PublicName { continue } t := &openstacktasks.SecurityGroupRule{ @@ -618,7 +618,7 @@ func (b *FirewallModelBuilder) Build(c *fi.ModelBuilderContext) error { useVIPACL = true } sg := &openstacktasks.SecurityGroup{ - Name: s(b.Cluster.Spec.MasterPublicName), + Name: s(b.Cluster.Spec.API.PublicName), Lifecycle: b.Lifecycle, RemoveExtraRules: []string{"port=443"}, } @@ -626,7 +626,7 @@ func (b *FirewallModelBuilder) Build(c *fi.ModelBuilderContext) error { sg.RemoveGroup = true } c.AddTask(sg) - sgMap[b.Cluster.Spec.MasterPublicName] = sg + sgMap[b.Cluster.Spec.API.PublicName] = sg for _, role := range roles { // Create Security Group for Role diff --git a/pkg/model/openstackmodel/servergroup.go b/pkg/model/openstackmodel/servergroup.go index 9b989453ff..abae24f318 100644 --- a/pkg/model/openstackmodel/servergroup.go +++ b/pkg/model/openstackmodel/servergroup.go @@ -106,7 +106,7 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg * securityGroups = append(securityGroups, b.LinkToSecurityGroup(securityGroupName)) if b.Cluster.Spec.CloudProvider.Openstack.Loadbalancer == nil && ig.Spec.Role == kops.InstanceGroupRoleMaster { - securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName)) + securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.API.PublicName)) } r := strings.NewReplacer("_", "-", ".", "-") @@ -285,14 +285,14 @@ func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error { return fmt.Errorf("could not find subnet for master loadbalancer") } lbTask := &openstacktasks.LB{ - Name: fi.PtrTo(b.Cluster.Spec.MasterPublicName), + Name: fi.PtrTo(b.Cluster.Spec.API.PublicName), Subnet: fi.PtrTo(lbSubnetName), Lifecycle: b.Lifecycle, } useVIPACL := b.UseVIPACL() if !useVIPACL { - lbTask.SecurityGroup = b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName) + lbTask.SecurityGroup = b.LinkToSecurityGroup(b.Cluster.Spec.API.PublicName) } c.AddTask(lbTask) @@ -323,7 +323,7 @@ func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error { if useVIPACL { var AllowedCIDRs []string // currently kOps openstack supports only ipv4 addresses - for _, CIDR := range b.Cluster.Spec.KubernetesAPIAccess { + for _, CIDR := range b.Cluster.Spec.API.Access { if net.IsIPv4CIDRString(CIDR) { AllowedCIDRs = append(AllowedCIDRs, CIDR) } diff --git a/pkg/model/openstackmodel/servergroup_test.go b/pkg/model/openstackmodel/servergroup_test.go index f76c8217ca..e986f1db2f 100644 --- a/pkg/model/openstackmodel/servergroup_test.go +++ b/pkg/model/openstackmodel/servergroup_test.go @@ -49,7 +49,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -107,7 +109,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -193,7 +197,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -315,7 +321,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "tom-software-dev-playground-real33-k8s-local", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -373,7 +381,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Loadbalancer: &kops.OpenstackLoadbalancerConfig{}, @@ -502,7 +512,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -621,7 +633,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -703,7 +717,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -763,7 +779,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Router: &kops.OpenstackRouter{ @@ -849,7 +867,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -893,7 +913,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -939,7 +961,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -983,7 +1007,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -1027,7 +1053,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ @@ -1071,7 +1099,9 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { Name: "cluster", }, Spec: kops.ClusterSpec{ - MasterPublicName: "master-public-name", + API: kops.APISpec{ + PublicName: "master-public-name", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Metadata: &kops.OpenstackMetadata{ diff --git a/pkg/testutils/cluster.go b/pkg/testutils/cluster.go index bdb4ad8705..e64d775545 100644 --- a/pkg/testutils/cluster.go +++ b/pkg/testutils/cluster.go @@ -36,8 +36,8 @@ func BuildMinimalCluster(clusterName string) *kops.Cluster { c.Spec.ContainerRuntime = "containerd" c.Spec.Containerd = &kops.ContainerdConfig{} - c.Spec.MasterPublicName = fmt.Sprintf("api.%v", clusterName) - c.Spec.KubernetesAPIAccess = []string{"0.0.0.0/0"} + c.Spec.API.PublicName = fmt.Sprintf("api.%v", clusterName) + c.Spec.API.Access = []string{"0.0.0.0/0"} c.Spec.SSHAccess = []string{"0.0.0.0/0"} // Default to public topology diff --git a/tests/codecs/componentconfig_test.go b/tests/codecs/componentconfig_test.go index 9cfabb0deb..3b1cd590e9 100644 --- a/tests/codecs/componentconfig_test.go +++ b/tests/codecs/componentconfig_test.go @@ -39,6 +39,7 @@ kind: Cluster metadata: creationTimestamp: null spec: + api: {} cloudProvider: {} kubeControllerManager: {} kubelet: {} diff --git a/tests/integration/conversion/aws/v1alpha2.yaml b/tests/integration/conversion/aws/v1alpha2.yaml index 7fb0392eff..bd0b2b49d5 100644 --- a/tests/integration/conversion/aws/v1alpha2.yaml +++ b/tests/integration/conversion/aws/v1alpha2.yaml @@ -11,6 +11,9 @@ spec: - manifest: s3://somebucket/example.yaml api: dns: {} + loadBalancer: + class: Network + type: Public authorization: alwaysAllow: {} channel: stable diff --git a/tests/integration/conversion/aws/v1alpha3.yaml b/tests/integration/conversion/aws/v1alpha3.yaml index c4012df076..a31637ba6b 100644 --- a/tests/integration/conversion/aws/v1alpha3.yaml +++ b/tests/integration/conversion/aws/v1alpha3.yaml @@ -4,12 +4,18 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com addons: - manifest: s3://somebucket/example.yaml api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + loadBalancer: + class: Network + type: Public + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -38,10 +44,7 @@ spec: - enabled: true name: hookEnabled iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/tests/integration/conversion/azure/v1alpha3.yaml b/tests/integration/conversion/azure/v1alpha3.yaml index 88924167a7..66b0a2aeed 100644 --- a/tests/integration/conversion/azure/v1alpha3.yaml +++ b/tests/integration/conversion/azure/v1alpha3.yaml @@ -4,10 +4,13 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -34,10 +37,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/tests/integration/conversion/canal/v1alpha3.yaml b/tests/integration/conversion/canal/v1alpha3.yaml index 867d0d2b9e..35e1d4951f 100644 --- a/tests/integration/conversion/canal/v1alpha3.yaml +++ b/tests/integration/conversion/canal/v1alpha3.yaml @@ -4,12 +4,15 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com addons: - manifest: s3://somebucket/example.yaml api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -30,10 +33,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: canal: diff --git a/tests/integration/conversion/cilium/v1alpha3.yaml b/tests/integration/conversion/cilium/v1alpha3.yaml index a932054cdc..8d05ce776d 100644 --- a/tests/integration/conversion/cilium/v1alpha3.yaml +++ b/tests/integration/conversion/cilium/v1alpha3.yaml @@ -4,12 +4,15 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com addons: - manifest: s3://somebucket/example.yaml api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -30,10 +33,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: cilium: diff --git a/tests/integration/conversion/do/v1alpha3.yaml b/tests/integration/conversion/do/v1alpha3.yaml index 4d4f88c729..519840499c 100644 --- a/tests/integration/conversion/do/v1alpha3.yaml +++ b/tests/integration/conversion/do/v1alpha3.yaml @@ -4,10 +4,13 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -28,10 +31,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/tests/integration/conversion/gce/v1alpha3.yaml b/tests/integration/conversion/gce/v1alpha3.yaml index bb805c51e5..c16c810f6a 100644 --- a/tests/integration/conversion/gce/v1alpha3.yaml +++ b/tests/integration/conversion/gce/v1alpha3.yaml @@ -4,10 +4,13 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -29,10 +32,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/tests/integration/conversion/minimal/v1alpha3.yaml b/tests/integration/conversion/minimal/v1alpha3.yaml index 70226e51e2..7014b950b1 100644 --- a/tests/integration/conversion/minimal/v1alpha3.yaml +++ b/tests/integration/conversion/minimal/v1alpha3.yaml @@ -4,12 +4,15 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com addons: - manifest: s3://somebucket/example.yaml api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -30,10 +33,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/tests/integration/conversion/openstack/v1alpha3.yaml b/tests/integration/conversion/openstack/v1alpha3.yaml index 472c3a8eb8..a769995f13 100644 --- a/tests/integration/conversion/openstack/v1alpha3.yaml +++ b/tests/integration/conversion/openstack/v1alpha3.yaml @@ -4,10 +4,13 @@ metadata: creationTimestamp: "2016-12-10T22:42:27Z" name: minimal.example.com spec: - additionalSANs: - - proxy.api.minimal.example.com api: + access: + - 0.0.0.0/0 + additionalSANs: + - proxy.api.minimal.example.com dns: {} + publicName: api.minimal.example.com authorization: alwaysAllow: {} channel: stable @@ -43,10 +46,7 @@ spec: memoryRequest: 100Mi name: events iam: {} - kubernetesAPIAccess: - - 0.0.0.0/0 kubernetesVersion: v1.21.0 - masterPublicName: api.minimal.example.com networkCIDR: 172.20.0.0/16 networking: kubenet: {} diff --git a/upup/pkg/fi/cloudup/awsup/aws_cloud.go b/upup/pkg/fi/cloudup/awsup/aws_cloud.go index 29079c6b90..22e19ebd07 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/aws_cloud.go @@ -2279,7 +2279,7 @@ func getApiIngressStatus(c AWSCloud, cluster *kops.Cluster) ([]fi.ApiIngressStat func findDNSName(c AWSCloud, cluster *kops.Cluster) (string, error) { name := "api." + cluster.Name - if cluster.Spec.API == nil || cluster.Spec.API.LoadBalancer == nil { + if cluster.Spec.API.LoadBalancer == nil { return "", nil } if cluster.Spec.API.LoadBalancer.Class == kops.LoadBalancerClassClassic { diff --git a/upup/pkg/fi/cloudup/defaults.go b/upup/pkg/fi/cloudup/defaults.go index 36e7f4c937..82bd561017 100644 --- a/upup/pkg/fi/cloudup/defaults.go +++ b/upup/pkg/fi/cloudup/defaults.go @@ -107,8 +107,8 @@ func PerformAssignments(c *kops.Cluster, cloud fi.Cloud) error { } // TODO: Unclear this should be here - it isn't too hard to change - if c.UsesPublicDNS() && c.Spec.MasterPublicName == "" && c.ObjectMeta.Name != "" { - c.Spec.MasterPublicName = "api." + c.ObjectMeta.Name + if c.UsesPublicDNS() && c.Spec.API.PublicName == "" && c.ObjectMeta.Name != "" { + c.Spec.API.PublicName = "api." + c.ObjectMeta.Name } // We only assign subnet CIDRs on AWS, OpenStack, and Azure. @@ -201,7 +201,7 @@ func assignProxy(cluster *kops.Cluster) (*kops.EgressProxySpec, error) { "127.0.0.1", "localhost", cluster.Spec.ClusterDNSDomain, // TODO we may want this for public loadbalancers - cluster.Spec.MasterPublicName, + cluster.Spec.API.PublicName, cluster.ObjectMeta.Name, firstIP, cluster.Spec.NonMasqueradeCIDR, diff --git a/upup/pkg/fi/cloudup/dns.go b/upup/pkg/fi/cloudup/dns.go index 419a839a51..5436460e28 100644 --- a/upup/pkg/fi/cloudup/dns.go +++ b/upup/pkg/fi/cloudup/dns.go @@ -249,17 +249,17 @@ func buildPrecreateDNSHostnames(cluster *kops.Cluster) []recordKey { internalType = rrstype.AAAA } - hasAPILoadbalancer := cluster.Spec.API != nil && cluster.Spec.API.LoadBalancer != nil + hasAPILoadbalancer := cluster.Spec.API.LoadBalancer != nil useLBForInternalAPI := hasAPILoadbalancer && cluster.Spec.API.LoadBalancer.UseForInternalAPI - if cluster.Spec.MasterPublicName != "" && !hasAPILoadbalancer { + if cluster.Spec.API.PublicName != "" && !hasAPILoadbalancer { recordKeys = append(recordKeys, recordKey{ - hostname: cluster.Spec.MasterPublicName, + hostname: cluster.Spec.API.PublicName, rrsType: rrstype.A, }) if internalType != rrstype.A { recordKeys = append(recordKeys, recordKey{ - hostname: cluster.Spec.MasterPublicName, + hostname: cluster.Spec.API.PublicName, rrsType: internalType, }) } diff --git a/upup/pkg/fi/cloudup/dns_test.go b/upup/pkg/fi/cloudup/dns_test.go index b8ae2ee6a1..b960a77558 100644 --- a/upup/pkg/fi/cloudup/dns_test.go +++ b/upup/pkg/fi/cloudup/dns_test.go @@ -52,7 +52,7 @@ func TestPrecreateDNSNames(t *testing.T) { { cluster: &kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{}, }, }, @@ -64,7 +64,7 @@ func TestPrecreateDNSNames(t *testing.T) { { cluster: &kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{}, }, NonMasqueradeCIDR: "::/0", @@ -77,7 +77,7 @@ func TestPrecreateDNSNames(t *testing.T) { { cluster: &kops.Cluster{ Spec: kops.ClusterSpec{ - API: &kops.AccessSpec{ + API: kops.APISpec{ LoadBalancer: &kops.LoadBalancerAccessSpec{ UseForInternalAPI: true, }, @@ -124,7 +124,7 @@ func TestPrecreateDNSNames(t *testing.T) { cluster := g.cluster cluster.ObjectMeta.Name = "cluster1.example.com" - cluster.Spec.MasterPublicName = "api." + cluster.ObjectMeta.Name + cluster.Spec.API.PublicName = "api." + cluster.ObjectMeta.Name cluster.Spec.EtcdClusters = []kops.EtcdClusterSpec{ { Name: "main", diff --git a/upup/pkg/fi/cloudup/new_cluster.go b/upup/pkg/fi/cloudup/new_cluster.go index 0224df390e..3779abd6db 100644 --- a/upup/pkg/fi/cloudup/new_cluster.go +++ b/upup/pkg/fi/cloudup/new_cluster.go @@ -240,7 +240,7 @@ func NewCluster(opt *NewClusterOptions, clientset simple.Clientset) (*NewCluster if len(opt.AdminAccess) == 0 { opt.AdminAccess = []string{"0.0.0.0/0", "::/0"} } - cluster.Spec.KubernetesAPIAccess = opt.AdminAccess + cluster.Spec.API.Access = opt.AdminAccess if len(opt.SSHAccess) != 0 { cluster.Spec.SSHAccess = opt.SSHAccess } else { @@ -1302,14 +1302,13 @@ func setupTopology(opt *NewClusterOptions, cluster *api.Cluster, allZones sets.S func setupAPI(opt *NewClusterOptions, cluster *api.Cluster) error { // Populate the API access, so that it can be discoverable klog.Infof(" Cloud Provider ID = %s", cluster.Spec.GetCloudProvider()) - cluster.Spec.API = &api.AccessSpec{} if cluster.Spec.GetCloudProvider() == api.CloudProviderOpenstack { initializeOpenstackAPI(opt, cluster) } else if cluster.Spec.GetCloudProvider() == api.CloudProviderAzure { // Do nothing to disable the use of loadbalancer for the k8s API server. // TODO(kenji): Remove this condition once we support the loadbalancer // in pkg/model/azuremodel/api_loadbalancer.go. - cluster.Spec.API = nil + cluster.Spec.API.LoadBalancer = nil return nil } else if opt.APILoadBalancerType != "" || opt.APISSLCertificate != "" { cluster.Spec.API.LoadBalancer = &api.LoadBalancerAccessSpec{} diff --git a/upup/pkg/fi/cloudup/openstack/cloud.go b/upup/pkg/fi/cloudup/openstack/cloud.go index 7d2b456bed..98c9a78825 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud.go +++ b/upup/pkg/fi/cloudup/openstack/cloud.go @@ -693,11 +693,11 @@ func getApiIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]fi.ApiIngre func getLoadBalancerIngressStatus(c OpenstackCloud, cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) { var ingresses []fi.ApiIngressStatus - if cluster.Spec.MasterPublicName != "" { + if cluster.Spec.API.PublicName != "" { // Note that this must match OpenstackModel lb name klog.V(2).Infof("Querying Openstack to find Loadbalancers for API (%q)", cluster.Name) lbList, err := c.ListLBs(loadbalancers.ListOpts{ - Name: cluster.Spec.MasterPublicName, + Name: cluster.Spec.API.PublicName, }) if err != nil { return ingresses, fmt.Errorf("GetApiIngressStatus: Failed to list openstack loadbalancers: %v", err) diff --git a/upup/pkg/fi/cloudup/openstack/cloud_test.go b/upup/pkg/fi/cloudup/openstack/cloud_test.go index 1d645b89bb..30ffd996c8 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud_test.go +++ b/upup/pkg/fi/cloudup/openstack/cloud_test.go @@ -49,7 +49,9 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) { desc: "Loadbalancer configured master public name set", cluster: &kops.Cluster{ Spec: kops.ClusterSpec{ - MasterPublicName: "master.k8s.local", + API: kops.APISpec{ + PublicName: "master.k8s.local", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Loadbalancer: &kops.OpenstackLoadbalancerConfig{}, @@ -85,7 +87,9 @@ func Test_OpenstackCloud_GetApiIngressStatus(t *testing.T) { desc: "Loadbalancer configured master public name set multiple IPs match", cluster: &kops.Cluster{ Spec: kops.ClusterSpec{ - MasterPublicName: "master.k8s.local", + API: kops.APISpec{ + PublicName: "master.k8s.local", + }, CloudProvider: kops.CloudProviderSpec{ Openstack: &kops.OpenstackSpec{ Loadbalancer: &kops.OpenstackLoadbalancerConfig{}, diff --git a/upup/pkg/fi/cloudup/populate_cluster_spec.go b/upup/pkg/fi/cloudup/populate_cluster_spec.go index f34aab8e01..785ce97f7d 100644 --- a/upup/pkg/fi/cloudup/populate_cluster_spec.go +++ b/upup/pkg/fi/cloudup/populate_cluster_spec.go @@ -241,8 +241,8 @@ func (c *populateClusterSpec) run(clientset simple.Clientset) error { } if !cluster.UsesNoneDNS() { - if cluster.Spec.DNSZone != "" && cluster.Spec.MasterPublicName == "" { - cluster.Spec.MasterPublicName = "api." + cluster.Name + if cluster.Spec.DNSZone != "" && cluster.Spec.API.PublicName == "" { + cluster.Spec.API.PublicName = "api." + cluster.Name } if cluster.Spec.ExternalDNS == nil { cluster.Spec.ExternalDNS = &kopsapi.ExternalDNSConfig{