v1alpha3: Move API-related settings under API

This commit is contained in:
John Gardiner Myers 2022-11-06 22:32:26 -08:00
parent 6132c8d9e2
commit 5fca16aa30
54 changed files with 517 additions and 484 deletions

View File

@ -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 {

View File

@ -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 != "" {

View File

@ -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"},
})
}

View File

@ -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

View File

@ -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{}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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{}

View File

@ -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{}

View File

@ -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

View File

@ -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)

View File

@ -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"))
}

View File

@ -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,

View File

@ -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 {

View File

@ -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)

View File

@ -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",
},
},
},
},

View File

@ -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{

View File

@ -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)

View File

@ -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"
}

View File

@ -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)),

View File

@ -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},

View File

@ -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"),

View File

@ -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{

View File

@ -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,
},

View File

@ -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
}

View File

@ -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

View File

@ -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"},
})

View File

@ -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,
})
}

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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{

View File

@ -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

View File

@ -39,6 +39,7 @@ kind: Cluster
metadata:
creationTimestamp: null
spec:
api: {}
cloudProvider: {}
kubeControllerManager: {}
kubelet: {}

View File

@ -11,6 +11,9 @@ spec:
- manifest: s3://somebucket/example.yaml
api:
dns: {}
loadBalancer:
class: Network
type: Public
authorization:
alwaysAllow: {}
channel: stable

View File

@ -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: {}

View File

@ -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: {}

View File

@ -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:

View File

@ -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:

View File

@ -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: {}

View File

@ -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: {}

View File

@ -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: {}

View File

@ -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: {}

View File

@ -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 {

View File

@ -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,

View File

@ -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,
})
}

View File

@ -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",

View File

@ -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{}

View File

@ -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)

View File

@ -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{},

View File

@ -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{