mirror of https://github.com/kubernetes/kops.git
refactoring to use cloud based GetGroups
This commit is contained in:
parent
2f12a3e521
commit
a431eb3e43
|
@ -109,7 +109,11 @@ func NewCmdDeleteInstanceGroup(f *util.Factory, out io.Writer) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// RunDeleteInstanceGroup runs the deletion of an instance group
|
||||
func RunDeleteInstanceGroup(f *util.Factory, out io.Writer, options *DeleteInstanceGroupOptions) error {
|
||||
|
||||
// TODO make this drain and validate the ig?
|
||||
// TODO implement drain and validate logic
|
||||
groupName := options.GroupName
|
||||
if groupName == "" {
|
||||
return fmt.Errorf("GroupName is required")
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/pkg/featureflag"
|
||||
"k8s.io/kops/pkg/instancegroups"
|
||||
"k8s.io/kops/pkg/pretty"
|
||||
|
@ -274,32 +275,32 @@ func RunRollingUpdateCluster(f *util.Factory, out io.Writer, options *RollingUpd
|
|||
return err
|
||||
}
|
||||
|
||||
groups, err := instancegroups.FindCloudInstanceGroups(cloud, cluster, instanceGroups, warnUnmatched, nodes)
|
||||
groups, err := cloud.GetCloudGroups(cluster, instanceGroups, warnUnmatched, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
t := &tables.Table{}
|
||||
t.AddColumn("NAME", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
t.AddColumn("NAME", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return r.InstanceGroup.ObjectMeta.Name
|
||||
})
|
||||
t.AddColumn("STATUS", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
t.AddColumn("STATUS", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return r.Status
|
||||
})
|
||||
t.AddColumn("NEEDUPDATE", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
t.AddColumn("NEEDUPDATE", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(len(r.NeedUpdate))
|
||||
})
|
||||
t.AddColumn("READY", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
t.AddColumn("READY", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(len(r.Ready))
|
||||
})
|
||||
t.AddColumn("MIN", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(r.MinSize())
|
||||
t.AddColumn("MIN", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(r.MinSize)
|
||||
})
|
||||
t.AddColumn("MAX", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(r.MaxSize())
|
||||
t.AddColumn("MAX", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
return strconv.Itoa(r.MaxSize)
|
||||
})
|
||||
t.AddColumn("NODES", func(r *instancegroups.CloudInstanceGroup) string {
|
||||
t.AddColumn("NODES", func(r *cloudinstances.CloudInstanceGroup) string {
|
||||
var nodes []*v1.Node
|
||||
for _, i := range r.Ready {
|
||||
if i.Node != nil {
|
||||
|
@ -313,7 +314,7 @@ func RunRollingUpdateCluster(f *util.Factory, out io.Writer, options *RollingUpd
|
|||
}
|
||||
return strconv.Itoa(len(nodes))
|
||||
})
|
||||
var l []*instancegroups.CloudInstanceGroup
|
||||
var l []*cloudinstances.CloudInstanceGroup
|
||||
for _, v := range groups {
|
||||
l = append(l, v)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha2
|
|||
k8s.io/kops/pkg/client/clientset_generated/internalclientset/typed/kops/v1alpha2/fake
|
||||
k8s.io/kops/pkg/client/simple
|
||||
k8s.io/kops/pkg/client/simple/vfsclientset
|
||||
k8s.io/kops/pkg/cloudinstances
|
||||
k8s.io/kops/pkg/diff
|
||||
k8s.io/kops/pkg/dns
|
||||
k8s.io/kops/pkg/edit
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cloudinstances
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
)
|
||||
|
||||
// CloudInstanceGroup is the cloud backing of InstanceGroup.
|
||||
type CloudInstanceGroup struct {
|
||||
InstanceGroup *api.InstanceGroup
|
||||
GroupName string
|
||||
GroupTemplateName string
|
||||
Status string
|
||||
Ready []*CloudInstanceMember
|
||||
NeedUpdate []*CloudInstanceMember
|
||||
MinSize int
|
||||
MaxSize int
|
||||
}
|
||||
|
||||
// CloudInstanceGroupInstance describes an instances in a CloudInstanceGroup group.
|
||||
type CloudInstanceMember struct {
|
||||
ID *string
|
||||
Node *v1.Node
|
||||
}
|
||||
|
||||
// NewCloudInstanceGroup creates a CloudInstanceGroup and validates its initial values.
|
||||
func NewCloudInstanceGroup(groupName string, groupTemplateName string, ig *api.InstanceGroup, minSize int, maxSize int) (*CloudInstanceGroup, error) {
|
||||
if groupName == "" {
|
||||
return nil, fmt.Errorf("group name for cloud instance group must be set")
|
||||
}
|
||||
if groupTemplateName == "" {
|
||||
return nil, fmt.Errorf("group template name for cloud instance group must be set")
|
||||
}
|
||||
if ig == nil {
|
||||
return nil, fmt.Errorf("kops instance group for cloud instance group must be set")
|
||||
}
|
||||
|
||||
if minSize < 0 {
|
||||
return nil, fmt.Errorf("cloud instance group min size must be zero or greater")
|
||||
}
|
||||
if maxSize < 0 {
|
||||
return nil, fmt.Errorf("cloud instance group max size must be zero or greater")
|
||||
}
|
||||
|
||||
cg := &CloudInstanceGroup{
|
||||
GroupName: groupName,
|
||||
GroupTemplateName: groupTemplateName,
|
||||
InstanceGroup: ig,
|
||||
MinSize: minSize,
|
||||
MaxSize: maxSize,
|
||||
}
|
||||
|
||||
return cg, nil
|
||||
}
|
||||
|
||||
// NewCloudInstanceMember creates a new CloudInstanceGroupMember
|
||||
func (c *CloudInstanceGroup) NewCloudInstanceMember(instanceId *string, newGroupName string, currentGroupName string, nodeMap map[string]*v1.Node) error {
|
||||
if instanceId == nil {
|
||||
return fmt.Errorf("instance id for cloud instance member cannot be nil")
|
||||
}
|
||||
cm := &CloudInstanceMember{
|
||||
ID: instanceId,
|
||||
}
|
||||
id := *instanceId
|
||||
node := nodeMap[id]
|
||||
if node != nil {
|
||||
cm.Node = node
|
||||
} else {
|
||||
glog.V(8).Infof("unable to find node for instance: %s", id)
|
||||
}
|
||||
|
||||
if newGroupName == currentGroupName {
|
||||
c.Ready = append(c.Ready, cm)
|
||||
} else {
|
||||
c.NeedUpdate = append(c.NeedUpdate, cm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkIsReady sets the CloudInstanceGroup status for Ready or NeedsUpdate
|
||||
func (c *CloudInstanceGroup) MarkIsReady() {
|
||||
if len(c.NeedUpdate) == 0 {
|
||||
c.Status = "Ready"
|
||||
} else {
|
||||
c.Status = "NeedsUpdate"
|
||||
}
|
||||
}
|
||||
|
||||
// GetNodeMap returns a list of nodes keyed by there external id
|
||||
func GetNodeMap(nodes []v1.Node) map[string]*v1.Node {
|
||||
nodeMap := make(map[string]*v1.Node)
|
||||
for i := range nodes {
|
||||
node := &nodes[i]
|
||||
nodeMap[node.Spec.ExternalID] = node
|
||||
}
|
||||
|
||||
return nodeMap
|
||||
}
|
||||
|
||||
// GetInstanceGroup filters a list of instancegroups for recognized cloud groups
|
||||
func GetInstanceGroup(name string, clusterName string, instancegroups []*api.InstanceGroup) (*api.InstanceGroup, error) {
|
||||
var instancegroup *api.InstanceGroup
|
||||
for _, g := range instancegroups {
|
||||
var groupName string
|
||||
switch g.Spec.Role {
|
||||
case api.InstanceGroupRoleMaster:
|
||||
groupName = g.ObjectMeta.Name + ".masters." + clusterName
|
||||
case api.InstanceGroupRoleNode:
|
||||
groupName = g.ObjectMeta.Name + "." + clusterName
|
||||
case api.InstanceGroupRoleBastion:
|
||||
groupName = g.ObjectMeta.Name + "." + clusterName
|
||||
default:
|
||||
glog.Warningf("Ignoring InstanceGroup of unknown role %q", g.Spec.Role)
|
||||
continue
|
||||
}
|
||||
|
||||
if name == groupName {
|
||||
if instancegroup != nil {
|
||||
return nil, fmt.Errorf("found multiple instance groups matching ASG %q", groupName)
|
||||
}
|
||||
instancegroup = g
|
||||
}
|
||||
}
|
||||
|
||||
return instancegroup, nil
|
||||
}
|
|
@ -32,28 +32,32 @@ type DeleteInstanceGroup struct {
|
|||
Clientset simple.Clientset
|
||||
}
|
||||
|
||||
func (c *DeleteInstanceGroup) DeleteInstanceGroup(group *api.InstanceGroup) error {
|
||||
groups, err := FindCloudInstanceGroups(c.Cloud, c.Cluster, []*api.InstanceGroup{group}, false, nil)
|
||||
// DeleteInstanceGroup deletes a cloud instance group
|
||||
func (d *DeleteInstanceGroup) DeleteInstanceGroup(group *api.InstanceGroup) error {
|
||||
|
||||
groups, err := d.Cloud.GetCloudGroups(d.Cluster, []*api.InstanceGroup{group}, false, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding CloudInstanceGroups: %v", err)
|
||||
}
|
||||
|
||||
// TODO should we drain nodes and validate the cluster?
|
||||
cig := groups[group.ObjectMeta.Name]
|
||||
if cig == nil {
|
||||
glog.Warningf("AutoScalingGroup %q not found in cloud - skipping delete", group.ObjectMeta.Name)
|
||||
} else {
|
||||
if len(groups) != 1 {
|
||||
return fmt.Errorf("Multiple InstanceGroup resources found in cloud")
|
||||
return fmt.Errorf("multiple InstanceGroup resources found in cloud")
|
||||
}
|
||||
|
||||
glog.Infof("Deleting AutoScalingGroup %q", group.ObjectMeta.Name)
|
||||
|
||||
err = cig.Delete(c.Cloud)
|
||||
err = d.Cloud.DeleteGroup(cig.GroupName, cig.GroupTemplateName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting cloud resources for InstanceGroup: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = c.Clientset.InstanceGroupsFor(c.Cluster).Delete(group.ObjectMeta.Name, nil)
|
||||
err = d.Clientset.InstanceGroupsFor(d.Cluster).Delete(group.ObjectMeta.Name, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -21,141 +21,48 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/autoscaling"
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/pkg/featureflag"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/pkg/validation"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
// FindCloudInstanceGroups joins data from the cloud and the instance groups into a map that can be used for updates.
|
||||
func FindCloudInstanceGroups(cloud fi.Cloud, cluster *api.Cluster, instancegroups []*api.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*CloudInstanceGroup, error) {
|
||||
awsCloud := cloud.(awsup.AWSCloud)
|
||||
// RollingUpdateInstanceGroup is the AWS ASG backing an InstanceGroup.
|
||||
type RollingUpdateInstanceGroup struct {
|
||||
// Cloud is the kops cloud provider
|
||||
Cloud fi.Cloud
|
||||
// CloudGroup is the kops cloud provider groups
|
||||
CloudGroup *cloudinstances.CloudInstanceGroup
|
||||
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
|
||||
tags := awsCloud.Tags()
|
||||
|
||||
asgs, err := resources.FindAutoscalingGroups(awsCloud, tags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeMap := make(map[string]*v1.Node)
|
||||
for i := range nodes {
|
||||
node := &nodes[i]
|
||||
awsID := node.Spec.ExternalID
|
||||
nodeMap[awsID] = node
|
||||
}
|
||||
|
||||
for _, asg := range asgs {
|
||||
name := aws.StringValue(asg.AutoScalingGroupName)
|
||||
var instancegroup *api.InstanceGroup
|
||||
for _, g := range instancegroups {
|
||||
var asgName string
|
||||
switch g.Spec.Role {
|
||||
case api.InstanceGroupRoleMaster:
|
||||
asgName = g.ObjectMeta.Name + ".masters." + cluster.ObjectMeta.Name
|
||||
case api.InstanceGroupRoleNode:
|
||||
asgName = g.ObjectMeta.Name + "." + cluster.ObjectMeta.Name
|
||||
case api.InstanceGroupRoleBastion:
|
||||
asgName = g.ObjectMeta.Name + "." + cluster.ObjectMeta.Name
|
||||
default:
|
||||
glog.Warningf("Ignoring InstanceGroup of unknown role %q", g.Spec.Role)
|
||||
continue
|
||||
}
|
||||
|
||||
if name == asgName {
|
||||
if instancegroup != nil {
|
||||
return nil, fmt.Errorf("Found multiple instance groups matching ASG %q", asgName)
|
||||
}
|
||||
instancegroup = g
|
||||
}
|
||||
}
|
||||
if instancegroup == nil {
|
||||
if warnUnmatched {
|
||||
glog.Warningf("Found ASG with no corresponding instance group %q", name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
group := buildCloudInstanceGroup(instancegroup, asg, nodeMap)
|
||||
groups[instancegroup.ObjectMeta.Name] = group
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
// TODO should remove the need to have rollingupdate struct and add:
|
||||
// TODO - the kubernetes client
|
||||
// TODO - the cluster name
|
||||
// TODO - the client config
|
||||
// TODO - fail on validate
|
||||
// TODO - fail on drain
|
||||
// TODO - cloudonly
|
||||
}
|
||||
|
||||
|
||||
|
||||
// CloudInstanceGroup is the AWS ASG backing an InstanceGroup.
|
||||
type CloudInstanceGroup struct {
|
||||
InstanceGroup *api.InstanceGroup
|
||||
ASGName string
|
||||
Status string
|
||||
Ready []*CloudInstanceGroupInstance
|
||||
NeedUpdate []*CloudInstanceGroupInstance
|
||||
|
||||
asg *autoscaling.Group
|
||||
}
|
||||
|
||||
func buildCloudInstanceGroup(ig *api.InstanceGroup, g *autoscaling.Group, nodeMap map[string]*v1.Node) *CloudInstanceGroup {
|
||||
n := &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(g.AutoScalingGroupName),
|
||||
InstanceGroup: ig,
|
||||
asg: g,
|
||||
// NewRollingUpdateInstanceGroup create a new struct
|
||||
func NewRollingUpdateInstanceGroup(cloud fi.Cloud, cloudGroup *cloudinstances.CloudInstanceGroup) (*RollingUpdateInstanceGroup, error) {
|
||||
if cloud == nil {
|
||||
return nil, fmt.Errorf("cloud provider is required")
|
||||
}
|
||||
if cloudGroup == nil {
|
||||
return nil, fmt.Errorf("cloud group is required")
|
||||
}
|
||||
|
||||
readyLaunchConfigurationName := aws.StringValue(g.LaunchConfigurationName)
|
||||
// TODO check more values in cloudGroup that they are set properly
|
||||
|
||||
for _, i := range g.Instances {
|
||||
c := &CloudInstanceGroupInstance{ASGInstance: i}
|
||||
|
||||
node := nodeMap[aws.StringValue(i.InstanceId)]
|
||||
if node != nil {
|
||||
c.Node = node
|
||||
}
|
||||
|
||||
if readyLaunchConfigurationName == aws.StringValue(i.LaunchConfigurationName) {
|
||||
n.Ready = append(n.Ready, c)
|
||||
} else {
|
||||
n.NeedUpdate = append(n.NeedUpdate, c)
|
||||
}
|
||||
}
|
||||
|
||||
if len(n.NeedUpdate) == 0 {
|
||||
n.Status = "Ready"
|
||||
} else {
|
||||
n.Status = "NeedsUpdate"
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// CloudInstanceGroupInstance describes an instance in an autoscaling group.
|
||||
type CloudInstanceGroupInstance struct {
|
||||
ASGInstance *autoscaling.Instance
|
||||
Node *v1.Node
|
||||
}
|
||||
|
||||
func (n *CloudInstanceGroup) String() string {
|
||||
return "CloudInstanceGroup:" + n.ASGName
|
||||
}
|
||||
|
||||
func (c *CloudInstanceGroup) MinSize() int {
|
||||
return int(aws.Int64Value(c.asg.MinSize))
|
||||
}
|
||||
|
||||
func (c *CloudInstanceGroup) MaxSize() int {
|
||||
return int(aws.Int64Value(c.asg.MaxSize))
|
||||
return &RollingUpdateInstanceGroup{
|
||||
Cloud: cloud,
|
||||
CloudGroup: cloudGroup,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TODO: Temporarily increase size of ASG?
|
||||
|
@ -163,7 +70,7 @@ func (c *CloudInstanceGroup) MaxSize() int {
|
|||
// TODO: Batch termination, like a rolling-update
|
||||
|
||||
// RollingUpdate performs a rolling update on a list of ec2 instances.
|
||||
func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, isBastion bool, t time.Duration) (err error) {
|
||||
func (r *RollingUpdateInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, isBastion bool, t time.Duration) (err error) {
|
||||
|
||||
// we should not get here, but hey I am going to check.
|
||||
if rollingUpdateData == nil {
|
||||
|
@ -179,11 +86,9 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
return fmt.Errorf("rollingUpdate is missing the InstanceGroupList")
|
||||
}
|
||||
|
||||
c := rollingUpdateData.Cloud
|
||||
|
||||
update := n.NeedUpdate
|
||||
update := r.CloudGroup.NeedUpdate
|
||||
if rollingUpdateData.Force {
|
||||
update = append(update, n.Ready...)
|
||||
update = append(update, r.CloudGroup.Ready...)
|
||||
}
|
||||
|
||||
if len(update) == 0 {
|
||||
|
@ -195,7 +100,7 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
} else if rollingUpdateData.CloudOnly {
|
||||
glog.V(3).Info("Not validating cluster as validation is turned off via the cloud-only flag.")
|
||||
} else if featureflag.DrainAndValidateRollingUpdate.Enabled() {
|
||||
if err = n.ValidateCluster(rollingUpdateData, instanceGroupList); err != nil {
|
||||
if err = r.ValidateCluster(rollingUpdateData, instanceGroupList); err != nil {
|
||||
if rollingUpdateData.FailOnValidate {
|
||||
return fmt.Errorf("error validating cluster: %v", err)
|
||||
} else {
|
||||
|
@ -207,7 +112,7 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
|
||||
for _, u := range update {
|
||||
|
||||
instanceId := aws.StringValue(u.ASGInstance.InstanceId)
|
||||
instanceId := fi.StringValue(u.ID)
|
||||
|
||||
nodeName := ""
|
||||
if u.Node != nil {
|
||||
|
@ -215,7 +120,7 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
}
|
||||
|
||||
if isBastion {
|
||||
if err = n.DeleteInstance(u, instanceId, nodeName, c); err != nil {
|
||||
if err = r.DeleteInstance(u); err != nil {
|
||||
glog.Errorf("Error deleting aws instance %q: %v", instanceId, err)
|
||||
return err
|
||||
}
|
||||
|
@ -233,9 +138,9 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
if u.Node != nil {
|
||||
glog.Infof("Draining the node: %q.", nodeName)
|
||||
|
||||
if err = n.DrainNode(u, rollingUpdateData); err != nil {
|
||||
if err = r.DrainNode(u, rollingUpdateData); err != nil {
|
||||
if rollingUpdateData.FailOnDrainError {
|
||||
return fmt.Errorf("Failed to drain node %q: %v", nodeName, err)
|
||||
return fmt.Errorf("failed to drain node %q: %v", nodeName, err)
|
||||
} else {
|
||||
glog.Infof("Ignoring error draining node %q: %v", nodeName, err)
|
||||
}
|
||||
|
@ -245,7 +150,7 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
}
|
||||
}
|
||||
|
||||
if err = n.DeleteInstance(u, instanceId, nodeName, c); err != nil {
|
||||
if err = r.DeleteInstance(u); err != nil {
|
||||
glog.Errorf("Error deleting aws instance %q, node %q: %v", instanceId, nodeName, err)
|
||||
return err
|
||||
}
|
||||
|
@ -262,7 +167,7 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
|
||||
glog.Infof("Validating the cluster.")
|
||||
|
||||
if err = n.ValidateClusterWithDuration(rollingUpdateData, instanceGroupList, t); err != nil {
|
||||
if err = r.ValidateClusterWithDuration(rollingUpdateData, instanceGroupList, t); err != nil {
|
||||
|
||||
if rollingUpdateData.FailOnValidate {
|
||||
glog.Errorf("Cluster did not validate within the set duration of %q, you can retry, and maybe extend the duration", t)
|
||||
|
@ -278,12 +183,12 @@ func (n *CloudInstanceGroup) RollingUpdate(rollingUpdateData *RollingUpdateClust
|
|||
}
|
||||
|
||||
// ValidateClusterWithDuration runs validation.ValidateCluster until either we get positive result or the timeout expires
|
||||
func (n *CloudInstanceGroup) ValidateClusterWithDuration(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, duration time.Duration) error {
|
||||
func (r *RollingUpdateInstanceGroup) ValidateClusterWithDuration(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, duration time.Duration) error {
|
||||
// TODO should we expose this to the UI?
|
||||
tickDuration := 30 * time.Second
|
||||
// Try to validate cluster at least once, this will handle durations that are lower
|
||||
// than our tick time
|
||||
if n.tryValidateCluster(rollingUpdateData, instanceGroupList, duration, tickDuration) {
|
||||
if r.tryValidateCluster(rollingUpdateData, instanceGroupList, duration, tickDuration) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -297,7 +202,7 @@ func (n *CloudInstanceGroup) ValidateClusterWithDuration(rollingUpdateData *Roll
|
|||
return fmt.Errorf("cluster did not validate within a duation of %q", duration)
|
||||
case <-tick:
|
||||
// Got a tick, validate cluster
|
||||
if n.tryValidateCluster(rollingUpdateData, instanceGroupList, duration, tickDuration) {
|
||||
if r.tryValidateCluster(rollingUpdateData, instanceGroupList, duration, tickDuration) {
|
||||
return nil
|
||||
}
|
||||
// ValidateCluster didn't work yet, so let's try again
|
||||
|
@ -306,7 +211,7 @@ func (n *CloudInstanceGroup) ValidateClusterWithDuration(rollingUpdateData *Roll
|
|||
}
|
||||
}
|
||||
|
||||
func (n *CloudInstanceGroup) tryValidateCluster(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, duration time.Duration, tickDuration time.Duration) bool {
|
||||
func (r *RollingUpdateInstanceGroup) tryValidateCluster(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList, duration time.Duration, tickDuration time.Duration) bool {
|
||||
if _, err := validation.ValidateCluster(rollingUpdateData.ClusterName, instanceGroupList, rollingUpdateData.K8sClient); err != nil {
|
||||
glog.Infof("Cluster did not validate, will try again in %q util duration %q expires: %v.", tickDuration, duration, err)
|
||||
return false
|
||||
|
@ -317,7 +222,7 @@ func (n *CloudInstanceGroup) tryValidateCluster(rollingUpdateData *RollingUpdate
|
|||
}
|
||||
|
||||
// ValidateCluster runs our validation methods on the K8s Cluster.
|
||||
func (n *CloudInstanceGroup) ValidateCluster(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList) error {
|
||||
func (r *RollingUpdateInstanceGroup) ValidateCluster(rollingUpdateData *RollingUpdateCluster, instanceGroupList *api.InstanceGroupList) error {
|
||||
|
||||
if _, err := validation.ValidateCluster(rollingUpdateData.ClusterName, instanceGroupList, rollingUpdateData.K8sClient); err != nil {
|
||||
return fmt.Errorf("cluster %q did not pass validation: %v", rollingUpdateData.ClusterName, err)
|
||||
|
@ -328,19 +233,21 @@ func (n *CloudInstanceGroup) ValidateCluster(rollingUpdateData *RollingUpdateClu
|
|||
}
|
||||
|
||||
// DeleteInstance deletes an Cloud Instance.
|
||||
func (n *CloudInstanceGroup) DeleteInstance(u *CloudInstanceGroupInstance, instanceId string, nodeName string, c fi.Cloud) error {
|
||||
func (r *RollingUpdateInstanceGroup) DeleteInstance(u *cloudinstances.CloudInstanceMember) error {
|
||||
|
||||
if nodeName != "" {
|
||||
glog.Infof("Stopping instance %q, node %q, in AWS ASG %q.", instanceId, nodeName, n.ASGName)
|
||||
id := fi.StringValue(u.ID)
|
||||
|
||||
if u.Node != nil {
|
||||
glog.Infof("Stopping instance %q, node %q, in group %q.", id, u.Node.Name, r.CloudGroup.GroupName)
|
||||
} else {
|
||||
glog.Infof("Stopping instance %q, in AWS ASG %q.", instanceId, n.asg.AutoScalingGroupName)
|
||||
glog.Infof("Stopping instance %q, in group %q.", fi.StringValue(u.ID), r.CloudGroup.GroupName)
|
||||
}
|
||||
|
||||
if err := c.DeleteInstance(u.ASGInstance.InstanceId); err != nil {
|
||||
if nodeName != "" {
|
||||
return fmt.Errorf("error deleting instance %q, node %q: %v", instanceId, nodeName, err)
|
||||
if err := r.Cloud.DeleteInstance(u.ID); err != nil {
|
||||
if u.Node.Name != "" {
|
||||
return fmt.Errorf("error deleting instance %q, node %q: %v", id, u.Node.Name, err)
|
||||
}
|
||||
return fmt.Errorf("error deleting instance %q: %v", instanceId, err)
|
||||
return fmt.Errorf("error deleting instance %q: %v", id, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -348,9 +255,13 @@ func (n *CloudInstanceGroup) DeleteInstance(u *CloudInstanceGroupInstance, insta
|
|||
}
|
||||
|
||||
// DrainNode drains a K8s node.
|
||||
func (n *CloudInstanceGroup) DrainNode(u *CloudInstanceGroupInstance, rollingUpdateData *RollingUpdateCluster) error {
|
||||
func (r *RollingUpdateInstanceGroup) DrainNode(u *cloudinstances.CloudInstanceMember, rollingUpdateData *RollingUpdateCluster) error {
|
||||
if rollingUpdateData.ClientConfig == nil {
|
||||
return fmt.Errorf("ClientConfig not set")
|
||||
return fmt.Errorf("clientConfig not set")
|
||||
}
|
||||
|
||||
if u.Node.Name == "" {
|
||||
return fmt.Errorf("node name not set")
|
||||
}
|
||||
f := cmdutil.NewFactory(rollingUpdateData.ClientConfig)
|
||||
|
||||
|
@ -395,8 +306,16 @@ func (n *CloudInstanceGroup) DrainNode(u *CloudInstanceGroupInstance, rollingUpd
|
|||
}
|
||||
|
||||
// Delete and CloudInstanceGroups
|
||||
func (g *CloudInstanceGroup) Delete(cloud fi.Cloud) error {
|
||||
|
||||
func (r *RollingUpdateInstanceGroup) Delete() error {
|
||||
if r.CloudGroup == nil {
|
||||
return fmt.Errorf("group has to be set")
|
||||
}
|
||||
if r.CloudGroup.GroupName == "" {
|
||||
return fmt.Errorf("group name has to be set")
|
||||
}
|
||||
if r.CloudGroup.GroupTemplateName == "" {
|
||||
return fmt.Errorf("group template name has to be set")
|
||||
}
|
||||
// TODO: Leaving func in place in order to cordon nd drain nodes
|
||||
return cloud.DeleteGroup(*g.asg.AutoScalingGroupName, *g.asg.LaunchConfigurationName)
|
||||
return r.Cloud.DeleteGroup(r.CloudGroup.GroupName, r.CloudGroup.GroupTemplateName)
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
api "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
|
@ -48,7 +49,7 @@ type RollingUpdateCluster struct {
|
|||
}
|
||||
|
||||
// RollingUpdate performs a rolling update on a K8s Cluster.
|
||||
func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*CloudInstanceGroup, instanceGroups *api.InstanceGroupList) error {
|
||||
func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*cloudinstances.CloudInstanceGroup, instanceGroups *api.InstanceGroupList) error {
|
||||
if len(groups) == 0 {
|
||||
glog.Infof("Cloud Instance Group length is zero. Not doing a rolling-update.")
|
||||
return nil
|
||||
|
@ -57,9 +58,9 @@ func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*CloudInstanceGro
|
|||
var resultsMutex sync.Mutex
|
||||
results := make(map[string]error)
|
||||
|
||||
masterGroups := make(map[string]*CloudInstanceGroup)
|
||||
nodeGroups := make(map[string]*CloudInstanceGroup)
|
||||
bastionGroups := make(map[string]*CloudInstanceGroup)
|
||||
masterGroups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
nodeGroups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
bastionGroups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
for k, group := range groups {
|
||||
switch group.InstanceGroup.Spec.Role {
|
||||
case api.InstanceGroupRoleNode:
|
||||
|
@ -79,14 +80,17 @@ func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*CloudInstanceGro
|
|||
|
||||
for k, bastionGroup := range bastionGroups {
|
||||
wg.Add(1)
|
||||
go func(k string, group *CloudInstanceGroup) {
|
||||
go func(k string, group *cloudinstances.CloudInstanceGroup) {
|
||||
resultsMutex.Lock()
|
||||
results[k] = fmt.Errorf("function panic bastions")
|
||||
resultsMutex.Unlock()
|
||||
|
||||
defer wg.Done()
|
||||
|
||||
err := group.RollingUpdate(c, instanceGroups, true, c.BastionInterval)
|
||||
g, err := NewRollingUpdateInstanceGroup(c.Cloud, group)
|
||||
if err == nil {
|
||||
err = g.RollingUpdate(c, instanceGroups, true, c.BastionInterval)
|
||||
}
|
||||
|
||||
resultsMutex.Lock()
|
||||
results[k] = err
|
||||
|
@ -116,7 +120,10 @@ func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*CloudInstanceGro
|
|||
defer wg.Done()
|
||||
|
||||
for k, group := range masterGroups {
|
||||
err := group.RollingUpdate(c, instanceGroups, false, c.MasterInterval)
|
||||
g, err := NewRollingUpdateInstanceGroup(c.Cloud, group)
|
||||
if err == nil {
|
||||
err = g.RollingUpdate(c, instanceGroups, false, c.MasterInterval)
|
||||
}
|
||||
|
||||
resultsMutex.Lock()
|
||||
results[k] = err
|
||||
|
@ -151,7 +158,10 @@ func (c *RollingUpdateCluster) RollingUpdate(groups map[string]*CloudInstanceGro
|
|||
defer wg.Done()
|
||||
|
||||
for k, group := range nodeGroups {
|
||||
err := group.RollingUpdate(c, instanceGroups, false, c.NodeInterval)
|
||||
g, err := NewRollingUpdateInstanceGroup(c.Cloud, group)
|
||||
if err == nil {
|
||||
err = g.RollingUpdate(c, instanceGroups, false, c.NodeInterval)
|
||||
}
|
||||
|
||||
resultsMutex.Lock()
|
||||
results[k] = err
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/cloudmock/aws/mockautoscaling"
|
||||
kopsapi "k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
|
||||
)
|
||||
|
||||
|
@ -97,10 +98,10 @@ func TestRollingUpdateAllNeedUpdate(t *testing.T) {
|
|||
setUpCloud(c)
|
||||
|
||||
asgGroups, _ := cloud.Autoscaling().DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{})
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
groups["node-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[0],
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
groups["node-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[0].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-1",
|
||||
|
@ -109,39 +110,31 @@ func TestRollingUpdateAllNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1a"),
|
||||
},
|
||||
ID: aws.String("node-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1b"),
|
||||
},
|
||||
ID: aws.String("node-1b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
NeedUpdate: []*CloudInstanceGroupInstance{
|
||||
NeedUpdate: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1a"),
|
||||
},
|
||||
ID: aws.String("node-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1b"),
|
||||
},
|
||||
ID: aws.String("node-1b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["node-2"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[1],
|
||||
groups["node-2"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[1].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-2",
|
||||
|
@ -150,39 +143,31 @@ func TestRollingUpdateAllNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2a"),
|
||||
},
|
||||
ID: aws.String("node-2a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2b"),
|
||||
},
|
||||
ID: aws.String("node-2b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
NeedUpdate: []*CloudInstanceGroupInstance{
|
||||
NeedUpdate: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2a"),
|
||||
},
|
||||
ID: aws.String("node-2a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2b"),
|
||||
},
|
||||
ID: aws.String("node-2b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["master-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[2],
|
||||
groups["master-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[2].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "master-1",
|
||||
|
@ -191,27 +176,23 @@ func TestRollingUpdateAllNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleMaster,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("master-1a"),
|
||||
},
|
||||
ID: aws.String("master-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
NeedUpdate: []*CloudInstanceGroupInstance{
|
||||
NeedUpdate: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("master-1a"),
|
||||
},
|
||||
ID: aws.String("master-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["bastion-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[3],
|
||||
groups["bastion-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[3].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "bastion-1",
|
||||
|
@ -220,19 +201,15 @@ func TestRollingUpdateAllNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleBastion,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("bastion-1a"),
|
||||
},
|
||||
ID: aws.String("bastion-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
NeedUpdate: []*CloudInstanceGroupInstance{
|
||||
NeedUpdate: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("bastion-1a"),
|
||||
},
|
||||
ID: aws.String("bastion-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
|
@ -271,10 +248,10 @@ func TestRollingUpdateNoneNeedUpdate(t *testing.T) {
|
|||
|
||||
asgGroups, _ := cloud.Autoscaling().DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{})
|
||||
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
groups["node-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[0],
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
groups["node-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[0].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-1",
|
||||
|
@ -283,25 +260,21 @@ func TestRollingUpdateNoneNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1a"),
|
||||
},
|
||||
ID: aws.String("node-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1b"),
|
||||
},
|
||||
ID: aws.String("node-1b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["node-2"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[1],
|
||||
groups["node-2"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[1].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-2",
|
||||
|
@ -310,25 +283,21 @@ func TestRollingUpdateNoneNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2a"),
|
||||
},
|
||||
ID: aws.String("node-2a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2b"),
|
||||
},
|
||||
ID: aws.String("node-2b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["master-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[2],
|
||||
groups["master-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[2].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "master-1",
|
||||
|
@ -337,19 +306,17 @@ func TestRollingUpdateNoneNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleMaster,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("master-1a"),
|
||||
},
|
||||
ID: aws.String("master-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["bastion-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[3],
|
||||
groups["bastion-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[3].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "bastion-1",
|
||||
|
@ -358,11 +325,9 @@ func TestRollingUpdateNoneNeedUpdate(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleBastion,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("bastion-1a"),
|
||||
},
|
||||
ID: aws.String("bastion-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
|
@ -429,10 +394,10 @@ func TestRollingUpdateNoneNeedUpdateWithForce(t *testing.T) {
|
|||
|
||||
asgGroups, _ := cloud.Autoscaling().DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{})
|
||||
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
groups["node-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[0],
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
groups["node-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[0].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-1",
|
||||
|
@ -441,25 +406,21 @@ func TestRollingUpdateNoneNeedUpdateWithForce(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1a"),
|
||||
},
|
||||
ID: aws.String("node-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1b"),
|
||||
},
|
||||
ID: aws.String("node-1b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["node-2"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[1],
|
||||
groups["node-2"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[1].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-2",
|
||||
|
@ -468,25 +429,21 @@ func TestRollingUpdateNoneNeedUpdateWithForce(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2a"),
|
||||
},
|
||||
ID: aws.String("node-2a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2b"),
|
||||
},
|
||||
ID: aws.String("node-2b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["master-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[2],
|
||||
groups["master-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[2].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "master-1",
|
||||
|
@ -495,19 +452,17 @@ func TestRollingUpdateNoneNeedUpdateWithForce(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleMaster,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("master-1a"),
|
||||
},
|
||||
ID: aws.String("master-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["bastion-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[3],
|
||||
groups["bastion-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[3].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "bastion-1",
|
||||
|
@ -516,11 +471,9 @@ func TestRollingUpdateNoneNeedUpdateWithForce(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleBastion,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("bastion-1a"),
|
||||
},
|
||||
ID: aws.String("bastion-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
|
@ -557,7 +510,7 @@ func TestRollingUpdateEmptyGroup(t *testing.T) {
|
|||
setUpCloud(c)
|
||||
|
||||
asgGroups, _ := cloud.Autoscaling().DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{})
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
|
||||
err := c.RollingUpdate(groups, &kopsapi.InstanceGroupList{})
|
||||
if err != nil {
|
||||
|
@ -620,10 +573,10 @@ func TestRollingUpdateUnknownRole(t *testing.T) {
|
|||
|
||||
asgGroups, _ := cloud.Autoscaling().DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{})
|
||||
|
||||
groups := make(map[string]*CloudInstanceGroup)
|
||||
groups["node-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[0],
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
groups["node-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[0].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[0].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-1",
|
||||
|
@ -632,25 +585,21 @@ func TestRollingUpdateUnknownRole(t *testing.T) {
|
|||
Role: "Unknown",
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1a"),
|
||||
},
|
||||
ID: aws.String("node-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-1b"),
|
||||
},
|
||||
ID: aws.String("node-1b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["node-2"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[1],
|
||||
groups["node-2"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[1].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[1].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "node-2",
|
||||
|
@ -659,25 +608,21 @@ func TestRollingUpdateUnknownRole(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleNode,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2a"),
|
||||
},
|
||||
ID: aws.String("node-2a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("node-2b"),
|
||||
},
|
||||
ID: aws.String("node-2b"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["master-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[2],
|
||||
groups["master-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[2].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[2].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "master-1",
|
||||
|
@ -686,19 +631,17 @@ func TestRollingUpdateUnknownRole(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleMaster,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("master-1a"),
|
||||
},
|
||||
ID: aws.String("master-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
groups["bastion-1"] = &CloudInstanceGroup{
|
||||
ASGName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
asg: asgGroups.AutoScalingGroups[3],
|
||||
groups["bastion-1"] = &cloudinstances.CloudInstanceGroup{
|
||||
GroupName: aws.StringValue(asgGroups.AutoScalingGroups[3].AutoScalingGroupName),
|
||||
GroupTemplateName: aws.StringValue(asgGroups.AutoScalingGroups[3].LaunchConfigurationName),
|
||||
InstanceGroup: &kopsapi.InstanceGroup{
|
||||
ObjectMeta: v1meta.ObjectMeta{
|
||||
Name: "bastion-1",
|
||||
|
@ -707,11 +650,9 @@ func TestRollingUpdateUnknownRole(t *testing.T) {
|
|||
Role: kopsapi.InstanceGroupRoleBastion,
|
||||
},
|
||||
},
|
||||
Ready: []*CloudInstanceGroupInstance{
|
||||
Ready: []*cloudinstances.CloudInstanceMember{
|
||||
{
|
||||
ASGInstance: &autoscaling.Instance{
|
||||
InstanceId: aws.String("bastion-1a"),
|
||||
},
|
||||
ID: aws.String("bastion-1a"),
|
||||
Node: &v1.Node{},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/pkg/resources/digitalocean/dns"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
|
@ -81,21 +82,21 @@ func NewCloud(region string) (*Cloud, error) {
|
|||
}
|
||||
|
||||
// GetCloudGroups is not implemented yet, that needs to return the instances and groups that back a kops cluster.
|
||||
func (c *Cloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *Cloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
glog.V(8).Infof("digitalocean cloud provider GetCloudGroups not implemented yet")
|
||||
return nil, fmt.Errorf("digital ocean cloud provider does not support getting cloud groups at this time.")
|
||||
return nil, fmt.Errorf("digital ocean cloud provider does not support getting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteGroup is not implemented yet, is a func that needs to delete a DO instance group.
|
||||
func (c *Cloud) DeleteGroup(name string, template string) error {
|
||||
glog.V(8).Infof("digitalocean cloud provider DeleteGroup not implemented yet")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud groups at this time.")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteInstance is not implemented yet, is func needs to delete a DO instance.
|
||||
func (c *Cloud) DeleteInstance(id *string) error {
|
||||
glog.V(8).Infof("digitalocean cloud provider DeleteInstance not implemented yet")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud instances at this time.")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud instances at this time")
|
||||
}
|
||||
|
||||
// ProviderID returns the kops api identifier for DigitalOcean cloud provider
|
||||
|
|
|
@ -19,6 +19,7 @@ package fi
|
|||
import (
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
)
|
||||
|
||||
|
@ -37,7 +38,7 @@ type Cloud interface {
|
|||
DeleteGroup(name string, template string) error
|
||||
|
||||
// GetCloudGroups returns a map of cloud instances that back a kops cluster
|
||||
GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*CloudGroup, error)
|
||||
GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error)
|
||||
}
|
||||
|
||||
type VPCInfo struct {
|
||||
|
@ -54,24 +55,6 @@ type SubnetInfo struct {
|
|||
CIDR string
|
||||
}
|
||||
|
||||
// CloudInstanceGroup is the cloud backing of InstanceGroup.
|
||||
type CloudGroup struct {
|
||||
InstanceGroup *kops.InstanceGroup
|
||||
GroupName string
|
||||
GroupTemplateName string
|
||||
Status string
|
||||
Ready []*CloudGroupInstance
|
||||
NeedUpdate []*CloudGroupInstance
|
||||
MinSize int
|
||||
MaxSize int
|
||||
}
|
||||
|
||||
// CloudInstanceGroupInstance describes an instance in an autoscaling group.
|
||||
type CloudGroupInstance struct {
|
||||
ID *string
|
||||
Node *v1.Node
|
||||
}
|
||||
|
||||
// zonesToCloud allows us to infer from certain well-known zones to a cloud
|
||||
// Note it is safe to "overmap" zones that don't exist: we'll check later if the zones actually exist
|
||||
var zonesToCloud = map[string]kops.CloudProviderID{
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
dnsproviderroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53"
|
||||
|
@ -286,9 +287,11 @@ func (c *awsCloudImplementation) DeleteInstance(id *string) error {
|
|||
|
||||
// TODO not used yet, as this requires a major refactor of rolling-update code, slowly but surely
|
||||
|
||||
// GetCloudGroups returns a groups of instanaces that back a kops instance groups
|
||||
func (c *awsCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
var groups map[string]*fi.CloudGroup
|
||||
// GetCloudGroups returns a groups of instances that back a kops instance groups
|
||||
func (c *awsCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
nodeMap := cloudinstances.GetNodeMap(nodes)
|
||||
|
||||
groups := make(map[string]*cloudinstances.CloudInstanceGroup)
|
||||
asgs, err := c.FindAutoscalingGroups()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find autoscale groups: %v", err)
|
||||
|
@ -296,27 +299,9 @@ func (c *awsCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instanceg
|
|||
|
||||
for _, asg := range asgs {
|
||||
name := aws.StringValue(asg.AutoScalingGroupName)
|
||||
var instancegroup *kops.InstanceGroup
|
||||
for _, g := range instancegroups {
|
||||
var asgName string
|
||||
switch g.Spec.Role {
|
||||
case kops.InstanceGroupRoleMaster:
|
||||
asgName = g.ObjectMeta.Name + ".masters." + cluster.ObjectMeta.Name
|
||||
case kops.InstanceGroupRoleNode:
|
||||
asgName = g.ObjectMeta.Name + "." + cluster.ObjectMeta.Name
|
||||
case kops.InstanceGroupRoleBastion:
|
||||
asgName = g.ObjectMeta.Name + "." + cluster.ObjectMeta.Name
|
||||
default:
|
||||
glog.Warningf("Ignoring InstanceGroup of unknown role %q", g.Spec.Role)
|
||||
continue
|
||||
}
|
||||
|
||||
if name == asgName {
|
||||
if instancegroup != nil {
|
||||
return nil, fmt.Errorf("Found multiple instance groups matching ASG %q", asgName)
|
||||
}
|
||||
instancegroup = g
|
||||
}
|
||||
instancegroup, err := cloudinstances.GetInstanceGroup(name, cluster.ObjectMeta.Name, instancegroups)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting instance group for ASG %q", name)
|
||||
}
|
||||
if instancegroup == nil {
|
||||
if warnUnmatched {
|
||||
|
@ -325,7 +310,10 @@ func (c *awsCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instanceg
|
|||
continue
|
||||
}
|
||||
|
||||
groups[instancegroup.ObjectMeta.Name] = c.awsBuildCloudInstanceGroup(instancegroup, asg, nodeMap)
|
||||
groups[instancegroup.ObjectMeta.Name], err = c.awsBuildCloudInstanceGroup(instancegroup, asg, nodeMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting cloud instance group %q: %v", instancegroup.ObjectMeta.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
|
@ -418,40 +406,23 @@ func MatchesAsgTags(tags map[string]string, actual []*autoscaling.TagDescription
|
|||
return true
|
||||
}
|
||||
|
||||
func (c *awsCloudImplementation) awsBuildCloudInstanceGroup(ig *kops.InstanceGroup, g *autoscaling.Group, nodeMap map[string]*v1.Node) *fi.CloudGroup {
|
||||
|
||||
n := &fi.CloudGroup{
|
||||
GroupName: aws.StringValue(g.AutoScalingGroupName),
|
||||
InstanceGroup: ig,
|
||||
GroupTemplateName: aws.StringValue(g.LaunchConfigurationName),
|
||||
func (c *awsCloudImplementation) awsBuildCloudInstanceGroup(ig *kops.InstanceGroup, g *autoscaling.Group, nodeMap map[string]*v1.Node) (*cloudinstances.CloudInstanceGroup, error) {
|
||||
newLaunchConfigName := aws.StringValue(g.LaunchConfigurationName)
|
||||
n, err := cloudinstances.NewCloudInstanceGroup(aws.StringValue(g.AutoScalingGroupName), newLaunchConfigName, ig, int(aws.Int64Value(g.MinSize)), int(aws.Int64Value(g.MaxSize)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating cloud instance group: %v", err)
|
||||
}
|
||||
|
||||
readyLaunchConfigurationName := aws.StringValue(g.LaunchConfigurationName)
|
||||
|
||||
for _, i := range g.Instances {
|
||||
c := &fi.CloudGroupInstance{
|
||||
ID: i.InstanceId,
|
||||
}
|
||||
|
||||
node := nodeMap[aws.StringValue(i.InstanceId)]
|
||||
if node != nil {
|
||||
c.Node = node
|
||||
}
|
||||
|
||||
if readyLaunchConfigurationName == aws.StringValue(i.LaunchConfigurationName) {
|
||||
n.Ready = append(n.Ready, c)
|
||||
} else {
|
||||
n.NeedUpdate = append(n.NeedUpdate, c)
|
||||
err = n.NewCloudInstanceMember(i.InstanceId, newLaunchConfigName, aws.StringValue(i.LaunchConfigurationName), nodeMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating cloud instance group member: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(n.NeedUpdate) == 0 {
|
||||
n.Status = "Ready"
|
||||
} else {
|
||||
n.Status = "NeedsUpdate"
|
||||
}
|
||||
n.MarkIsReady()
|
||||
|
||||
return n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (c *awsCloudImplementation) Tags() map[string]string {
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
dnsproviderroute53 "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/aws/route53"
|
||||
|
@ -116,7 +117,7 @@ func (c *MockAWSCloud) DeleteInstance(id *string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *MockAWSCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *MockAWSCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
return nil, fmt.Errorf("not implemented yet")
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
)
|
||||
|
@ -51,21 +52,21 @@ func (c *Cloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
|
|||
|
||||
// GetCloudGroups is not implemented yet, that needs to return the instances and groups that back a kops cluster.
|
||||
// Baremetal may not support this.
|
||||
func (c *Cloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *Cloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
glog.V(8).Infof("baremetal cloud GetCloudGroups not implemented yet")
|
||||
return nil, fmt.Errorf("baremetal provider does not support getting cloud groups at this time.")
|
||||
return nil, fmt.Errorf("baremetal provider does not support getting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteGroup is not implemented yet, is a func that needs to delete a DO instance group.
|
||||
// Baremetal may not support this.
|
||||
func (c *Cloud) DeleteGroup(name string, template string) error {
|
||||
glog.V(8).Infof("digitalocean cloud provider DeleteGroup not implemented yet")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud groups at this time.")
|
||||
return fmt.Errorf("digital ocean cloud provider does not support deleting cloud groups at this time")
|
||||
}
|
||||
|
||||
//DeleteInstance is not implemented yet, is func needs to delete a DO instance.
|
||||
//Baremetal may not support this.
|
||||
func (c *Cloud) DeleteInstance(id *string) error {
|
||||
glog.V(8).Infof("baremetal cloud provider DeleteInstance not implemented yet")
|
||||
return fmt.Errorf("baremetal cloud provider does not support deleting cloud instances at this time.")
|
||||
return fmt.Errorf("baremetal cloud provider does not support deleting cloud instances at this time")
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"google.golang.org/api/storage/v1"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns"
|
||||
|
@ -220,19 +221,19 @@ func (c *gceCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]k
|
|||
// DeleteGroup deletes a cloud of instances controlled by an Instance Group Manager
|
||||
func (c *gceCloudImplementation) DeleteGroup(name string, template string) error {
|
||||
glog.V(8).Infof("gce cloud provider DeleteGroup not implemented yet")
|
||||
return fmt.Errorf("gce cloud provider does not support deleting cloud groups at this time.")
|
||||
return fmt.Errorf("gce cloud provider does not support deleting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteInstance deletes a GCE instance
|
||||
func (c *gceCloudImplementation) DeleteInstance(id *string) error {
|
||||
glog.V(8).Infof("gce cloud provider DeleteInstance not implemented yet")
|
||||
return fmt.Errorf("gce cloud provider does not support deleting cloud instances at this time.")
|
||||
return fmt.Errorf("gce cloud provider does not support deleting cloud instances at this time")
|
||||
}
|
||||
|
||||
// GetCloudGroups returns a map of CloudGroup that backs a list of instance groups
|
||||
func (c *gceCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *gceCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
glog.V(8).Infof("gce cloud provider GetCloudGroups not implemented yet")
|
||||
return nil, fmt.Errorf("gce cloud provider does not support getting cloud groups at this time.")
|
||||
return nil, fmt.Errorf("gce cloud provider does not support getting cloud groups at this time")
|
||||
}
|
||||
|
||||
// FindInstanceTemplates finds all instance templates that are associated with the current cluster
|
||||
|
|
|
@ -18,11 +18,13 @@ package gce
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
compute "google.golang.org/api/compute/v0.beta"
|
||||
"google.golang.org/api/storage/v1"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
dnsproviderclouddns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns"
|
||||
|
@ -51,21 +53,21 @@ func buildMockGCECloud(region string, project string) *mockGCECloud {
|
|||
}
|
||||
|
||||
// GetCloudGroups is not implemented yet
|
||||
func (c *mockGCECloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *mockGCECloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
glog.V(8).Infof("mockGCECloud cloud provider GetCloudGroups not implemented yet")
|
||||
return nil, fmt.Errorf("mockGCECloud cloud provider does not support getting cloud groups at this time.")
|
||||
return nil, fmt.Errorf("mockGCECloud cloud provider does not support getting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteGroup is not implemented yet
|
||||
func (c *mockGCECloud) DeleteGroup(name string, template string) error {
|
||||
glog.V(8).Infof("mockGCECloud cloud provider DeleteGroup not implemented yet")
|
||||
return fmt.Errorf("mockGCECloud cloud provider does not support deleting cloud groups at this time.")
|
||||
return fmt.Errorf("mockGCECloud cloud provider does not support deleting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteInstance is not implemented yet
|
||||
func (c *mockGCECloud) DeleteInstance(id *string) error {
|
||||
glog.V(8).Infof("mockGCECloud cloud provider DeleteInstance not implemented yet")
|
||||
return fmt.Errorf("mockGCECloud cloud provider does not support deleting cloud instances at this time.")
|
||||
return fmt.Errorf("mockGCECloud cloud provider does not support deleting cloud instances at this time")
|
||||
}
|
||||
|
||||
// Zones is not implemented yet
|
||||
|
|
|
@ -22,6 +22,10 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vmware/govmomi"
|
||||
|
@ -34,12 +38,10 @@ import (
|
|||
"github.com/vmware/govmomi/vim25/types"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||
k8scoredns "k8s.io/kubernetes/federation/pkg/dnsprovider/providers/coredns"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// VSphereCloud represents a vSphere cloud instance.
|
||||
|
@ -105,9 +107,9 @@ func NewVSphereCloud(spec *kops.ClusterSpec) (*VSphereCloud, error) {
|
|||
}
|
||||
|
||||
// GetCloudGroups is not implemented yet, that needs to return the instances and groups that back a kops cluster.
|
||||
func (c *VSphereCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodeMap map[string]*v1.Node) (map[string]*fi.CloudGroup, error) {
|
||||
func (c *VSphereCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
|
||||
glog.V(8).Infof("vSphere cloud provider GetCloudGroups not implemented yet")
|
||||
return nil, fmt.Errorf("vSphere cloud provider does not support getting cloud groups at this time.")
|
||||
return nil, fmt.Errorf("vSphere cloud provider does not support getting cloud groups at this time")
|
||||
}
|
||||
|
||||
// DeleteGroup is not implemented yet, is a func that needs to delete a vSphere instance group.
|
||||
|
|
Loading…
Reference in New Issue