-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Support cluster API objects in multiple namespaces #481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
da0e454
6f3b124
da42f35
31c617e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ import ( | |
"time" | ||
|
||
apiv1 "k8s.io/api/core/v1" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
tcmd "k8s.io/client-go/tools/clientcmd" | ||
clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" | ||
|
@@ -73,6 +74,37 @@ func (c *clusterClient) removeKubeconfigFile() error { | |
return os.Remove(c.kubeconfigFile) | ||
} | ||
|
||
func (c *clusterClient) EnsureNamespace(namespaceName string) error { | ||
clientset, err := clientcmd.NewCoreClientSetForKubeconfig(c.kubeconfigFile) | ||
if err != nil { | ||
return fmt.Errorf("error creating core clientset: %v", err) | ||
} | ||
|
||
namespace := apiv1.Namespace{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: namespaceName, | ||
}, | ||
} | ||
_, err = clientset.CoreV1().Namespaces().Create(&namespace) | ||
if err != nil && !apierrors.IsAlreadyExists(err) { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (c *clusterClient) DeleteNamespace(namespaceName string) error { | ||
clientset, err := clientcmd.NewCoreClientSetForKubeconfig(c.kubeconfigFile) | ||
if err != nil { | ||
return fmt.Errorf("error creating core clientset: %v", err) | ||
} | ||
|
||
err = clientset.CoreV1().Namespaces().Delete(namespaceName, &metav1.DeleteOptions{}) | ||
if err != nil && !apierrors.IsNotFound(err) { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// NewClusterClientFromDefaultSearchPath creates and returns the address of a clusterClient, the kubeconfigFile argument is expected to be the path to a | ||
// valid kubeconfig file. | ||
func NewClusterClientFromDefaultSearchPath(kubeconfigFile string, overrides tcmd.ConfigOverrides) (*clusterClient, error) { | ||
|
@@ -104,12 +136,33 @@ func (c *clusterClient) Apply(manifest string) error { | |
return c.waitForKubectlApply(manifest) | ||
} | ||
|
||
func (c *clusterClient) GetClusterObjects() ([]*clusterv1.Cluster, error) { | ||
func (c *clusterClient) GetContextNamespace() string { | ||
if c.configOverrides.Context.Namespace == "" { | ||
c.configOverrides.Context.Namespace = apiv1.NamespaceDefault | ||
} | ||
return c.configOverrides.Context.Namespace | ||
} | ||
|
||
func (c *clusterClient) GetClusterObject(name, ns string) (*clusterv1.Cluster, error) { | ||
clustersInNamespace, err := c.GetClusterObjectsInNamespace(ns) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var cluster *clusterv1.Cluster | ||
for _, nc := range clustersInNamespace { | ||
if nc.Name == name { | ||
cluster = nc | ||
ashish-amarnath marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
} | ||
} | ||
return cluster, nil | ||
} | ||
|
||
func (c *clusterClient) GetClusterObjectsInNamespace(namespace string) ([]*clusterv1.Cluster, error) { | ||
clusters := []*clusterv1.Cluster{} | ||
// TODO: Iterate over all namespaces where we could have Cluster API Objects https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
clusterlist, err := c.clientSet.ClusterV1alpha1().Clusters(apiv1.NamespaceDefault).List(metav1.ListOptions{}) | ||
clusterlist, err := c.clientSet.ClusterV1alpha1().Clusters(namespace).List(metav1.ListOptions{}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error listing cluster objects: %v", err) | ||
return nil, fmt.Errorf("error listing cluster objects in namespace %q: %v", namespace, err) | ||
} | ||
|
||
for i := 0; i < len(clusterlist.Items); i++ { | ||
|
@@ -118,11 +171,16 @@ func (c *clusterClient) GetClusterObjects() ([]*clusterv1.Cluster, error) { | |
return clusters, nil | ||
} | ||
|
||
func (c *clusterClient) GetMachineDeploymentObjects() ([]*clusterv1.MachineDeployment, error) { | ||
// TODO: Iterate over all namespaces where we could have Cluster API Objects https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
machineDeploymentList, err := c.clientSet.ClusterV1alpha1().MachineDeployments(apiv1.NamespaceDefault).List(metav1.ListOptions{}) | ||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) GetClusterObjects() ([]*clusterv1.Cluster, error) { | ||
davidewatson marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add comments to these preserved methods to indicate that they are deprecated and to be removed in the future? It might be good to also log the deprecation as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestion. Added comments and log messages. |
||
glog.V(2).Info("GetClusterObjects API is deprecated, use GetClusterObjectsInNamespace instead") | ||
return c.GetClusterObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) GetMachineDeploymentObjectsInNamespace(namespace string) ([]*clusterv1.MachineDeployment, error) { | ||
machineDeploymentList, err := c.clientSet.ClusterV1alpha1().MachineDeployments(namespace).List(metav1.ListOptions{}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error listing machine deployment objects: %v", err) | ||
return nil, fmt.Errorf("error listing machine deployment objects in namespace %q: %v", namespace, err) | ||
} | ||
var machineDeployments []*clusterv1.MachineDeployment | ||
for i := 0; i < len(machineDeploymentList.Items); i++ { | ||
|
@@ -131,11 +189,16 @@ func (c *clusterClient) GetMachineDeploymentObjects() ([]*clusterv1.MachineDeplo | |
return machineDeployments, nil | ||
} | ||
|
||
func (c *clusterClient) GetMachineSetObjects() ([]*clusterv1.MachineSet, error) { | ||
// TODO: Iterate over all namespaces where we could have Cluster API Objects https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) GetMachineDeploymentObjects() ([]*clusterv1.MachineDeployment, error) { | ||
glog.V(2).Info("GetMachineDeploymentObjects API is deprecated, use GetMachineDeploymentObjectsInNamespace instead") | ||
return c.GetMachineDeploymentObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) GetMachineSetObjectsInNamespace(namespace string) ([]*clusterv1.MachineSet, error) { | ||
machineSetList, err := c.clientSet.ClusterV1alpha1().MachineSets(apiv1.NamespaceDefault).List(metav1.ListOptions{}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error listing machine set objects: %v", err) | ||
return nil, fmt.Errorf("error listing machine set objects in namespace %q: %v", namespace, err) | ||
} | ||
var machineSets []*clusterv1.MachineSet | ||
for i := 0; i < len(machineSetList.Items); i++ { | ||
|
@@ -144,12 +207,17 @@ func (c *clusterClient) GetMachineSetObjects() ([]*clusterv1.MachineSet, error) | |
return machineSets, nil | ||
} | ||
|
||
func (c *clusterClient) GetMachineObjects() ([]*clusterv1.Machine, error) { | ||
// TODO: Iterate over all namespaces where we could have Cluster API Objects https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) GetMachineSetObjects() ([]*clusterv1.MachineSet, error) { | ||
glog.V(2).Info("GetMachineSetObjects API is deprecated, use GetMachineSetObjectsInNamespace instead") | ||
return c.GetMachineSetObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) GetMachineObjectsInNamespace(namespace string) ([]*clusterv1.Machine, error) { | ||
machines := []*clusterv1.Machine{} | ||
machineslist, err := c.clientSet.ClusterV1alpha1().Machines(apiv1.NamespaceDefault).List(metav1.ListOptions{}) | ||
machineslist, err := c.clientSet.ClusterV1alpha1().Machines(namespace).List(metav1.ListOptions{}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error listing machine objects: %v", err) | ||
return nil, fmt.Errorf("error listing machine objects in namespace %q: %v", namespace, err) | ||
} | ||
|
||
for i := 0; i < len(machineslist.Items); i++ { | ||
|
@@ -158,46 +226,53 @@ func (c *clusterClient) GetMachineObjects() ([]*clusterv1.Machine, error) { | |
return machines, nil | ||
} | ||
|
||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) GetMachineObjects() ([]*clusterv1.Machine, error) { | ||
glog.V(2).Info("GetMachineObjects API is deprecated, use GetMachineObjectsInNamespace instead") | ||
return c.GetMachineObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) CreateClusterObject(cluster *clusterv1.Cluster) error { | ||
// TODO: Support specific namespaces https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
_, err := c.clientSet.ClusterV1alpha1().Clusters(apiv1.NamespaceDefault).Create(cluster) | ||
namespace := c.GetContextNamespace() | ||
if cluster.Namespace != "" { | ||
namespace = cluster.Namespace | ||
} | ||
|
||
_, err := c.clientSet.ClusterV1alpha1().Clusters(namespace).Create(cluster) | ||
if err != nil { | ||
return fmt.Errorf("error creating cluster: %v", err) | ||
return fmt.Errorf("error creating cluster in namespace %v: %v", namespace, err) | ||
} | ||
return err | ||
} | ||
|
||
func (c *clusterClient) CreateMachineDeploymentObjects(deployments []*clusterv1.MachineDeployment) error { | ||
// TODO: Support specific namespaces https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
func (c *clusterClient) CreateMachineDeploymentObjects(deployments []*clusterv1.MachineDeployment, namespace string) error { | ||
for _, deploy := range deployments { | ||
// TODO: Run in parallel https://github.com/kubernetes-sigs/cluster-api/issues/258 | ||
_, err := c.clientSet.ClusterV1alpha1().MachineDeployments(apiv1.NamespaceDefault).Create(deploy) | ||
_, err := c.clientSet.ClusterV1alpha1().MachineDeployments(namespace).Create(deploy) | ||
if err != nil { | ||
return fmt.Errorf("error creating a machine deployment object: %v", err) | ||
return fmt.Errorf("error creating a machine deployment object in namespace %q: %v", namespace, err) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (c *clusterClient) CreateMachineSetObjects(machineSets []*clusterv1.MachineSet) error { | ||
// TODO: Support specific namespaces https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
func (c *clusterClient) CreateMachineSetObjects(machineSets []*clusterv1.MachineSet, namespace string) error { | ||
for _, ms := range machineSets { | ||
// TODO: Run in parallel https://github.com/kubernetes-sigs/cluster-api/issues/258 | ||
_, err := c.clientSet.ClusterV1alpha1().MachineSets(apiv1.NamespaceDefault).Create(ms) | ||
_, err := c.clientSet.ClusterV1alpha1().MachineSets(namespace).Create(ms) | ||
if err != nil { | ||
return fmt.Errorf("error creating a machine set object: %v", err) | ||
return fmt.Errorf("error creating a machine set object in namespace %q: %v", namespace, err) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (c *clusterClient) CreateMachineObjects(machines []*clusterv1.Machine) error { | ||
// TODO: Support specific namespaces https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
func (c *clusterClient) CreateMachineObjects(machines []*clusterv1.Machine, namespace string) error { | ||
for _, machine := range machines { | ||
// TODO: Run in parallel https://github.com/kubernetes-sigs/cluster-api/issues/258 | ||
createdMachine, err := c.clientSet.ClusterV1alpha1().Machines(apiv1.NamespaceDefault).Create(machine) | ||
createdMachine, err := c.clientSet.ClusterV1alpha1().Machines(namespace).Create(machine) | ||
if err != nil { | ||
return fmt.Errorf("error creating a machine object: %v", err) | ||
return fmt.Errorf("error creating a machine object in namespace %v: %v", namespace, err) | ||
} | ||
err = waitForMachineReady(c.clientSet, createdMachine) | ||
if err != nil { | ||
|
@@ -207,71 +282,90 @@ func (c *clusterClient) CreateMachineObjects(machines []*clusterv1.Machine) erro | |
return nil | ||
} | ||
|
||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) DeleteClusterObjects() error { | ||
err := c.clientSet.ClusterV1alpha1().Clusters(apiv1.NamespaceDefault).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
glog.V(2).Info("DeleteClusterObjects API is deprecated, use DeleteClusterObjectsInNamespace instead") | ||
return c.DeleteClusterObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) DeleteClusterObjectsInNamespace(namespace string) error { | ||
err := c.clientSet.ClusterV1alpha1().Clusters(namespace).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("error deleting cluster objects: %v", err) | ||
return fmt.Errorf("error deleting cluster objects in namespace %q: %v", namespace, err) | ||
} | ||
err = c.waitForClusterDelete() | ||
if err != nil { | ||
return fmt.Errorf("error waiting for cluster(s) deletion to complete: %v", err) | ||
return fmt.Errorf("error waiting for cluster(s) deletion to complete in namespace %q: %v", namespace, err) | ||
} | ||
return nil | ||
} | ||
|
||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) DeleteMachineDeploymentObjects() error { | ||
err := c.clientSet.ClusterV1alpha1().MachineDeployments(apiv1.NamespaceDefault).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
glog.V(2).Info("DeleteMachineDeploymentObjects API is deprecated, use DeleteMachineDeploymentObjectsInNamespace instead") | ||
return c.DeleteMachineDeploymentObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) DeleteMachineDeploymentObjectsInNamespace(namespace string) error { | ||
err := c.clientSet.ClusterV1alpha1().MachineDeployments(namespace).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("error deleting machine deployment objects: %v", err) | ||
return fmt.Errorf("error deleting machine deployment objects in namespace %q: %v", namespace, err) | ||
} | ||
err = c.waitForMachineDeploymentsDelete() | ||
if err != nil { | ||
return fmt.Errorf("error waiting for machine deployment(s) deletion to complete: %v", err) | ||
return fmt.Errorf("error waiting for machine deployment(s) deletion to complete in namespace %q: %v", namespace, err) | ||
} | ||
return nil | ||
} | ||
|
||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) DeleteMachineSetObjects() error { | ||
err := c.clientSet.ClusterV1alpha1().MachineSets(apiv1.NamespaceDefault).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
glog.V(2).Info("DeleteMachineSetObjects API is deprecated, use DeleteMachineSetObjectsInNamespace instead") | ||
return c.DeleteMachineSetObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) DeleteMachineSetObjectsInNamespace(namespace string) error { | ||
err := c.clientSet.ClusterV1alpha1().MachineSets(namespace).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("error deleting machine set objects: %v", err) | ||
return fmt.Errorf("error deleting machine set objects in namespace %q: %v", namespace, err) | ||
} | ||
err = c.waitForMachineSetsDelete() | ||
if err != nil { | ||
return fmt.Errorf("error waiting for machine set(s) deletion to complete: %v", err) | ||
return fmt.Errorf("error waiting for machine set(s) deletion to complete in namespace %q: %v", namespace, err) | ||
} | ||
return nil | ||
} | ||
|
||
// Deprecated API. Please do not extend or use. | ||
func (c *clusterClient) DeleteMachineObjects() error { | ||
err := c.clientSet.ClusterV1alpha1().Machines(apiv1.NamespaceDefault).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
glog.V(2).Info("DeleteMachineObjects API is deprecated, use DeleteMachineObjectsInNamespace instead") | ||
return c.DeleteMachineObjectsInNamespace(apiv1.NamespaceDefault) | ||
} | ||
|
||
func (c *clusterClient) DeleteMachineObjectsInNamespace(namespace string) error { | ||
err := c.clientSet.ClusterV1alpha1().Machines(namespace).DeleteCollection(newDeleteOptions(), metav1.ListOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("error deleting machine objects: %v", err) | ||
return fmt.Errorf("error deleting machine objects in namespace %q: %v", namespace, err) | ||
} | ||
err = c.waitForMachinesDelete() | ||
if err != nil { | ||
return fmt.Errorf("error waiting for machine(s) deletion to complete: %v", err) | ||
return fmt.Errorf("error waiting for machine(s) deletion to complete in namespace %q: %v", namespace, err) | ||
} | ||
return nil | ||
} | ||
|
||
func newDeleteOptions() *metav1.DeleteOptions { | ||
propogationPolicy := metav1.DeletePropagationForeground | ||
propagationPolicy := metav1.DeletePropagationForeground | ||
return &metav1.DeleteOptions{ | ||
PropagationPolicy: &propogationPolicy, | ||
PropagationPolicy: &propagationPolicy, | ||
} | ||
} | ||
|
||
func (c *clusterClient) UpdateClusterObjectEndpoint(masterIP string) error { | ||
clusters, err := c.GetClusterObjects() | ||
func (c *clusterClient) UpdateClusterObjectEndpoint(masterIP, clusterName, ns string) error { | ||
cluster, err := c.GetClusterObject(clusterName, ns) | ||
if err != nil { | ||
return err | ||
} | ||
if len(clusters) != 1 { | ||
// TODO: Do not assume default namespace nor single cluster https://github.com/kubernetes-sigs/cluster-api/issues/252 | ||
return fmt.Errorf("More than the one expected cluster found %v", clusters) | ||
} | ||
cluster := clusters[0] | ||
cluster.Status.APIEndpoints = append(cluster.Status.APIEndpoints, | ||
clusterv1.APIEndpoint{ | ||
Host: masterIP, | ||
|
Uh oh!
There was an error while loading. Please reload this page.