github.com/kubernetes-incubator/kube-aws@v0.16.4/pkg/api/api_endpoint_lb.go (about) 1 package api 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 // DefaultRecordSetTTL is the default value for the loadBalancer.recordSetTTL key 9 const DefaultRecordSetTTL = 300 10 11 // APIEndpointLB is a set of an ELB and relevant settings and resources to serve a Kubernetes API hosted by controller nodes 12 type APIEndpointLB struct { 13 // APIAccessAllowedSourceCIDRs is network ranges of sources you'd like Kubernetes API accesses to be allowed from, in CIDR notation 14 APIAccessAllowedSourceCIDRs CIDRRanges `yaml:"apiAccessAllowedSourceCIDRs,omitempty"` 15 // Identifier specifies an existing load-balancer used for load-balancing controller nodes and serving this endpoint 16 Identifier Identifier `yaml:",inline"` 17 // Managed is set to true when want to create an ELB for this API endpoint. It is false by default i.e. considered to be false if nil 18 Managed *bool `yaml:"managed,omitempty"` 19 // Subnets contains all the subnets assigned to this load-balancer. Specified only when this load balancer is not reused but managed one 20 SubnetReferences []SubnetReference `yaml:"subnets,omitempty"` 21 // PrivateSpecified determines the resulting load balancer uses an internal elb for an endpoint 22 PrivateSpecified *bool `yaml:"private,omitempty"` 23 // RecordSetManaged represents if the user wants kube-aws not to create a record set for this API load balancer 24 // i.e. the user wants to configure Route53 or one's own DNS oneself 25 RecordSetManaged *bool `yaml:"recordSetManaged,omitempty"` 26 // RecordSetTTLSpecified is the TTL for the record set to this load balancer. Defaults to 300 if nil 27 RecordSetTTLSpecified *int `yaml:"recordSetTTL,omitempty"` 28 // HostedZone is where the resulting Alias record is created for an endpoint 29 HostedZone HostedZone `yaml:"hostedZone,omitempty"` 30 //// SecurityGroups contains extra security groups must be associated to the lb serving API requests from clients 31 //SecurityGroups []SecurityGroup 32 // SecurityGroupIds represents SGs associated to this LB. Required when APIAccessAllowedSourceCIDRs is explicitly set to empty 33 SecurityGroupIds []string `yaml:"securityGroupIds"` 34 // Load balancer type. It is 'classic' by default, but can be changed to 'network' 35 Type *string `yaml:"type,omitempty"` 36 } 37 38 // UnmarshalYAML unmarshals YAML data to an APIEndpointLB object with defaults 39 // This doesn't work due to a go-yaml issue described in http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/ 40 // And that's why we need to implement `func (e APIEndpointLB) RecordSetTTL() int` for defaulting. 41 // TODO Migrate to ghodss/yaml 42 func (e *APIEndpointLB) UnmarshalYAML(unmarshal func(interface{}) error) error { 43 ttl := DefaultRecordSetTTL 44 type t APIEndpointLB 45 work := t(APIEndpointLB{ 46 RecordSetTTLSpecified: &ttl, 47 APIAccessAllowedSourceCIDRs: DefaultCIDRRanges(), 48 }) 49 if err := unmarshal(&work); err != nil { 50 return fmt.Errorf("failed to parse API endpoint LB config: %v", err) 51 } 52 *e = APIEndpointLB(work) 53 return nil 54 } 55 56 // ManageELB returns true if an ELB should be managed by kube-aws 57 func (e APIEndpointLB) ManageELB() bool { 58 return e.managedELBImplied() || (e.Managed != nil && *e.Managed) 59 } 60 61 // ClassicLoadBalancer returns true if the load balancer is a classic ELB 62 func (e APIEndpointLB) ClassicLoadBalancer() bool { 63 return e.Type == nil || *e.Type == "classic" 64 } 65 66 // LoadBalancerV2 returns true if the load balancer is a ELBV2 load balancer (only network load balancer is supported for now) 67 func (e APIEndpointLB) LoadBalancerV2() bool { 68 return e.Type != nil && *e.Type != "classic" 69 } 70 71 // NetworkLoadBalancer returns true if the load balancer is a ELBV2 network load balancer 72 func (e APIEndpointLB) NetworkLoadBalancer() bool { 73 return e.Type != nil && *e.Type == "network" 74 } 75 76 // ManageELBRecordSet returns true if kube-aws should create a record set for the ELB 77 func (e APIEndpointLB) ManageELBRecordSet() bool { 78 return e.HostedZone.HasIdentifier() 79 } 80 81 // ManageSecurityGroup returns true if kube-aws should create a security group for this ELB 82 func (e APIEndpointLB) ManageSecurityGroup() bool { 83 return !e.NetworkLoadBalancer() && len(e.APIAccessAllowedSourceCIDRs) > 0 84 } 85 86 // Validate returns an error when there's any user error in the settings of the `loadBalancer` field 87 func (e APIEndpointLB) Validate() error { 88 if e.Identifier.HasIdentifier() { 89 if e.PrivateSpecified != nil || !e.ClassicLoadBalancer() || len(e.SubnetReferences) > 0 || e.HostedZone.HasIdentifier() { 90 return errors.New("type, private, subnets, hostedZone must be omitted when id is specified to reuse an existing ELB") 91 } 92 93 return nil 94 } 95 96 if e.Managed != nil && !*e.Managed { 97 if e.RecordSetTTL() != DefaultRecordSetTTL { 98 return errors.New("recordSetTTL should not be modified when an API endpoint LB is not managed by kube-aws") 99 } 100 101 if e.HostedZone.HasIdentifier() { 102 return errors.New("hostedZone.id should not be specified when an API endpoint LB is not managed by kube-aws") 103 } 104 105 if e.Type != nil && len(*e.Type) > 0 { 106 return errors.New("type should not be specified when an API endpoint LB is not managed by kube-aws") 107 } 108 109 return nil 110 } 111 112 if e.HostedZone.HasIdentifier() { 113 if e.RecordSetManaged != nil && !*e.RecordSetManaged { 114 return errors.New("hostedZone.id must be omitted when you want kube-aws not to touch Route53") 115 } 116 117 if e.RecordSetTTL() < 1 { 118 return errors.New("recordSetTTL must be at least 1 second") 119 } 120 } else { 121 if e.RecordSetManaged == nil || *e.RecordSetManaged { 122 return errors.New("missing hostedZone.id: hostedZone.id is required when `recordSetManaged` is set to true. If you do want to configure DNS yourself, set it to true") 123 } 124 125 if e.RecordSetTTL() != DefaultRecordSetTTL { 126 return errors.New( 127 "recordSetTTL should not be modified when hostedZone id is nil", 128 ) 129 } 130 } 131 132 if e.ClassicLoadBalancer() && e.ManageELB() && len(e.APIAccessAllowedSourceCIDRs) == 0 && len(e.SecurityGroupIds) == 0 { 133 return errors.New("either apiAccessAllowedSourceCIDRs or securityGroupIds must be present. Try not to explicitly empty apiAccessAllowedSourceCIDRs or set one or more securityGroupIDs") 134 } 135 136 if !e.NetworkLoadBalancer() && !e.ClassicLoadBalancer() { 137 return errors.New("load balancer type must be either 'classic' or 'network'") 138 } 139 140 if e.NetworkLoadBalancer() { 141 if len(e.SecurityGroupIds) > 0 { 142 return errors.New("cannot specify security group IDs for a network load balancer") 143 } 144 } 145 146 return nil 147 } 148 149 func (e APIEndpointLB) managedELBImplied() bool { 150 return len(e.SubnetReferences) > 0 || 151 e.explicitlyPrivate() || 152 e.explicitlyPublic() || 153 e.HostedZone.HasIdentifier() || 154 len(e.SecurityGroupIds) > 0 || 155 e.RecordSetManaged != nil 156 } 157 158 func (e APIEndpointLB) explicitlyPrivate() bool { 159 return e.PrivateSpecified != nil && *e.PrivateSpecified 160 } 161 162 func (e APIEndpointLB) explicitlyPublic() bool { 163 return e.PrivateSpecified != nil && !*e.PrivateSpecified 164 } 165 166 // RecordSetTTL is the TTL for the record set to this load balancer. Defaults to 300 if `recordSetTTL` is omitted/set to nil 167 func (e APIEndpointLB) RecordSetTTL() int { 168 if e.RecordSetTTLSpecified != nil { 169 return *e.RecordSetTTLSpecified 170 } 171 return DefaultRecordSetTTL 172 } 173 174 // Private returns true when this LB is a private one i.e. the `private` field is explicitly set to true 175 func (e APIEndpointLB) Private() bool { 176 return e.explicitlyPrivate() 177 }