IdleTimeout configurable from editcluster

This commit is contained in:
alok87 2016-12-04 16:31:03 +05:30
parent 0ab99a432f
commit 66d2e4791d
11 changed files with 80 additions and 11 deletions

View File

@ -417,6 +417,7 @@ func RunCreateCluster(f *util.Factory, cmd *cobra.Command, args []string, out io
return fmt.Errorf("Invalid topology %s.", c.Topology) return fmt.Errorf("Invalid topology %s.", c.Topology)
} }
cluster.Spec.Topology.Bastion.MachineType = cloudup.DefaultBastionMachineType(cluster) cluster.Spec.Topology.Bastion.MachineType = cloudup.DefaultBastionMachineType(cluster)
cluster.Spec.Topology.Bastion.IdleTimeout = cloudup.DefaultBastionIdleTimeout(cluster)
sshPublicKeys := make(map[string][]byte) sshPublicKeys := make(map[string][]byte)
if c.SSHPublicKey != "" { if c.SSHPublicKey != "" {

View File

@ -13,11 +13,12 @@ Note: Bastion will get setup for the cluster(by default) only when `--topology="
Instance types in AWS comprise varying combinations of CPU, memory, storage, and networking capacity and give you the flexibility to choose the appropriate mix of resources for your applications. Instance types in AWS comprise varying combinations of CPU, memory, storage, and networking capacity and give you the flexibility to choose the appropriate mix of resources for your applications.
- Bastion Instance type can be modified using `kops edit cluster` - **Defaults** to `t2.medium`
- Defaults to `t2.medium` - **Configure:** Bastion Instance type can be modified using `kops edit cluster`
#### TODO: add the example below for configuration
``` ```
topology:
bastion:
MachineType: c4.large
``` ```
[More information](https://aws.amazon.com/ec2/instance-types/) [More information](https://aws.amazon.com/ec2/instance-types/)
@ -27,18 +28,25 @@ Instance types in AWS comprise varying combinations of CPU, memory, storage, and
To turn on/off bastion host setup completely. To turn on/off bastion host setup completely.
- **Defaults** to `false` if the topology selected is `public` - **Defaults** to `false` if the topology selected is `public`
- **Defaults** to `true` if the topology selected is `private` - **Defaults** to `true` if the topology selected is `private`
- **Configure:**
``` ```
kops create cluster --bastion=[true|false] kops create cluster --bastion=[true|false]
```
OR using `kops edit cluster`
```
topology:
bastion:
Enable: true
``` ```
### Reach bastion from outside of vpc using a name ### Reach bastion from outside of vpc using a name
- **Default:** CNAME for the bastion is only created when the user explicitly define it using `kops edit cluster` - **Default:** CNAME for the bastion is only created when the user explicitly define it using `kops edit cluster`
- **Configure:** Bastion friendly CNAME can be configured using `kops edit cluster` - **Configure:** Bastion friendly CNAME can be configured using `kops edit cluster`
#### TODO: add the example below for configuration
``` ```
topology:
bastion:
PublicName: jumper
``` ```
### High idle timeout for bastion ASG's ELB. (Configurable LoadBalancer Attributes) ### High idle timeout for bastion ASG's ELB. (Configurable LoadBalancer Attributes)
@ -46,9 +54,10 @@ To turn on/off bastion host setup completely.
By default, elastic load balancing sets the idle timeout to `60` seconds. By default, elastic load balancing sets the idle timeout to `60` seconds.
- **Default:** Bastion ELB in kops will have `120` seconds as their default timeout. - **Default:** Bastion ELB in kops will have `120` seconds as their default timeout.
- **Configure:** This value can be configured using `kops edit cluster` - **Configure:** This value can be configured using `kops edit cluster`
#### TODO: add the example below for configuration
``` ```
topology:
bastion:
IdleTimeOut: 75
``` ```
[More information](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-idle-timeout.html) [More information](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-idle-timeout.html)

View File

@ -23,4 +23,6 @@ type BastionSpec struct {
Enable bool `json:"Enable,omitempty"` Enable bool `json:"Enable,omitempty"`
MachineType string `json:"MachineType,omitempty"` MachineType string `json:"MachineType,omitempty"`
PublicName string `json:"Name,omitempty"` PublicName string `json:"Name,omitempty"`
// Bastion's Loadbalancer idle timeout
IdleTimeout int `json:"IdleTimeout,omitempty"`
} }

View File

@ -554,3 +554,6 @@ func (c *Cluster) GetBastionMachineType() string {
func (c *Cluster) GetBastionPublicName() string { func (c *Cluster) GetBastionPublicName() string {
return c.Spec.Topology.Bastion.PublicName return c.Spec.Topology.Bastion.PublicName
} }
func (c *Cluster) GetBastionIdleTimeout() int {
return c.Spec.Topology.Bastion.IdleTimeout
}

View File

@ -23,4 +23,6 @@ type BastionSpec struct {
Enable bool `json:"Enable,omitempty"` Enable bool `json:"Enable,omitempty"`
MachineType string `json:"MachineType,omitempty"` MachineType string `json:"MachineType,omitempty"`
PublicName string `json:"Name,omitempty"` PublicName string `json:"Name,omitempty"`
// Bastion's Loadbalancer idle timeout
IdleTimeout int `json:"IdleTimeout,omitempty"`
} }

View File

@ -307,3 +307,6 @@ func (c *Cluster) GetBastionMachineType() string {
func (c *Cluster) GetBastionPublicName() string { func (c *Cluster) GetBastionPublicName() string {
return c.Spec.Topology.Bastion.PublicName return c.Spec.Topology.Bastion.PublicName
} }
func (c *Cluster) GetBastionIdleTimeout() int {
return c.Spec.Topology.Bastion.IdleTimeout
}

View File

@ -327,6 +327,9 @@ func (c *Cluster) Validate(strict bool) error {
if c.Spec.Topology.Bastion.MachineType == "" { if c.Spec.Topology.Bastion.MachineType == "" {
return fmt.Errorf("Bastion MachineType can not be empty") return fmt.Errorf("Bastion MachineType can not be empty")
} }
if c.Spec.Topology.Bastion.IdleTimeout <= 0 {
return fmt.Errorf("Bastion IdleTimeout should be greater than zero")
}
} }
// Etcd // Etcd

View File

@ -93,7 +93,7 @@ loadBalancerAttributes/bastion.{{ ClusterName }}:
connectionSettings: loadBalancerConnectionSettings/bastion.{{ ClusterName }} connectionSettings: loadBalancerConnectionSettings/bastion.{{ ClusterName }}
loadBalancerConnectionSettings/bastion.{{ ClusterName }}: loadBalancerConnectionSettings/bastion.{{ ClusterName }}:
loadBalancer: loadBalancer/bastion.{{ ClusterName }} loadBalancer: loadBalancer/bastion.{{ ClusterName }}
idleTimeout: 120 idleTimeout: {{ GetBastionIdleTimeout }}
# --------------------------------------------------------------- # ---------------------------------------------------------------
# ASG - The Bastion itself # ASG - The Bastion itself
# #

View File

@ -40,6 +40,10 @@ const DefaultMasterMachineTypeGCE = "n1-standard-1"
const DefaultBastionMachineTypeAWS = "t2.medium" const DefaultBastionMachineTypeAWS = "t2.medium"
const DefaultBastionMasterMachineTypeGCE = "n1-standard-1" const DefaultBastionMasterMachineTypeGCE = "n1-standard-1"
// Default LoadBalancing IdleTimeout for bastion hosts
const DefaultBastionIdleTimeoutAWS = 120
const DefaultBastionIdleTimeoutGCE = 120
// PopulateInstanceGroupSpec sets default values in the InstanceGroup // PopulateInstanceGroupSpec sets default values in the InstanceGroup
// The InstanceGroup is simpler than the cluster spec, so we just populate in place (like the rest of k8s) // The InstanceGroup is simpler than the cluster spec, so we just populate in place (like the rest of k8s)
func PopulateInstanceGroupSpec(cluster *api.Cluster, input *api.InstanceGroup, channel *api.Channel) (*api.InstanceGroup, error) { func PopulateInstanceGroupSpec(cluster *api.Cluster, input *api.InstanceGroup, channel *api.Channel) (*api.InstanceGroup, error) {
@ -172,6 +176,19 @@ func DefaultBastionMachineType(cluster *api.Cluster) string {
} }
} }
// defaultIdleTimeout returns the default Idletimeout for bastion loadbalancer, based on the cloudprovider
func DefaultBastionIdleTimeout(cluster *api.Cluster) int {
switch fi.CloudProviderID(cluster.Spec.CloudProvider) {
case fi.CloudProviderAWS:
return DefaultBastionIdleTimeoutAWS
case fi.CloudProviderGCE:
return DefaultBastionIdleTimeoutGCE
default:
glog.V(2).Infof("Cannot set default IdleTimeout for CloudProvider=%q", cluster.Spec.CloudProvider)
return 0
}
}
// defaultImage returns the default Image, based on the cloudprovider // defaultImage returns the default Image, based on the cloudprovider
func defaultImage(cluster *api.Cluster, channel *api.Channel) string { func defaultImage(cluster *api.Cluster, channel *api.Channel) string {
if channel != nil { if channel != nil {

View File

@ -336,6 +336,26 @@ func TestPopulateCluster_BastionMachineTypeInvalidNil_Required(t *testing.T) {
expectErrorFromPopulateCluster(t, c, "Bastion") expectErrorFromPopulateCluster(t, c, "Bastion")
} }
func TestPopulateCluster_BastionIdleTimeoutInvalidNil_Required(t *testing.T) {
c := buildMinimalCluster()
c.Spec.Topology.Masters = api.TopologyPrivate
c.Spec.Topology.Nodes = api.TopologyPrivate
c.Spec.Topology.Bastion.Enable = true
c.Spec.Topology.Bastion.MachineType = "t2.small"
c.Spec.Topology.Bastion.IdleTimeout = 0
expectErrorFromPopulateCluster(t, c, "Bastion")
}
func TestPopulateCluster_BastionIdleTimeoutInvalidNegative_Required(t *testing.T) {
c := buildMinimalCluster()
c.Spec.Topology.Masters = api.TopologyPrivate
c.Spec.Topology.Nodes = api.TopologyPrivate
c.Spec.Topology.Bastion.Enable = true
c.Spec.Topology.Bastion.MachineType = "t2.small"
c.Spec.Topology.Bastion.IdleTimeout = -1
expectErrorFromPopulateCluster(t, c, "Bastion")
}
func expectErrorFromPopulateCluster(t *testing.T, c *api.Cluster, message string) { func expectErrorFromPopulateCluster(t *testing.T, c *api.Cluster, message string) {
_, err := PopulateClusterSpec(c) _, err := PopulateClusterSpec(c)
if err == nil { if err == nil {

View File

@ -98,6 +98,7 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap) {
dest["WithBastion"] = tf.WithBastion dest["WithBastion"] = tf.WithBastion
dest["GetBastionImageId"] = tf.GetBastionImageId dest["GetBastionImageId"] = tf.GetBastionImageId
dest["GetBastionMachineType"] = tf.GetBastionMachineType dest["GetBastionMachineType"] = tf.GetBastionMachineType
dest["GetBastionIdleTimeout"] = tf.GetBastionIdleTimeout
dest["GetBastionZone"] = tf.GetBastionZone dest["GetBastionZone"] = tf.GetBastionZone
dest["GetELBName32"] = tf.GetELBName32 dest["GetELBName32"] = tf.GetELBName32
dest["IsBastionDNS"] = tf.IsBastionDNS dest["IsBastionDNS"] = tf.IsBastionDNS
@ -222,6 +223,14 @@ func (tf *TemplateFunctions) GetBastionMachineType() (string, error) {
return defaultMachineType, nil return defaultMachineType, nil
} }
func (tf *TemplateFunctions) GetBastionIdleTimeout() (int, error) {
timeout := tf.cluster.GetBastionIdleTimeout()
if timeout <= 0 {
return 0, fmt.Errorf("IdleTimeout for Bastion can not be negative")
}
return timeout, nil
}
// Will attempt to calculate a meaningful name for an ELB given a prefix // Will attempt to calculate a meaningful name for an ELB given a prefix
// Will never return a string longer than 32 chars // Will never return a string longer than 32 chars
func (tf *TemplateFunctions) GetELBName32(prefix string) (string, error) { func (tf *TemplateFunctions) GetELBName32(prefix string) (string, error) {