Skip to content

Commit

Permalink
Merge pull request #26 from weaveworks/capi
Browse files Browse the repository at this point in the history
Add capi to supported providers
  • Loading branch information
ranatrk authored Dec 19, 2023
2 parents e2687cc + bf04068 commit dfb060a
Show file tree
Hide file tree
Showing 12 changed files with 1,866 additions and 61 deletions.
3 changes: 2 additions & 1 deletion api/v1alpha1/automatedclusterdiscovery_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ type AutomatedClusterDiscoverySpec struct {
Name string `json:"name,omitempty"`

// Type is the provider type.
// +kubebuilder:validation:Enum=aks
// +kubebuilder:validation:Enum=aks;capi
Type string `json:"type"`

// If DisableTags is true, labels will not be applied to the generated
// Clusters from the tags on the upstream Clusters.
// +optional
DisableTags bool `json:"disableTags"`

// AKS configures discovery of AKS clusters from Azure.
AKS *AKS `json:"aks,omitempty"`

// The interval at which to run the discovery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ spec:
description: Type is the provider type.
enum:
- aks
- capi
type: string
required:
- interval
Expand Down
8 changes: 8 additions & 0 deletions config/samples/capi_discovery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: clusters.weave.works/v1alpha1
kind: AutomatedClusterDiscovery
metadata:
name: capi-cluster-discovery
namespace: default
spec:
type: capi
interval: 10m
3 changes: 2 additions & 1 deletion config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Append samples of your project ##
resources:
- aks_discovery.yaml
- aks_discovery.yaml
- capi_discovery.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
k8s.io/apimachinery v0.27.5
k8s.io/client-go v0.27.5
sigs.k8s.io/cli-utils v0.35.0
sigs.k8s.io/cluster-api v1.5.2
sigs.k8s.io/controller-runtime v0.15.2
sigs.k8s.io/yaml v1.3.0
)
Expand All @@ -31,6 +32,8 @@ require (
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.10.0 // indirect
Expand Down Expand Up @@ -66,7 +69,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down Expand Up @@ -98,7 +100,6 @@ require (
k8s.io/component-base v0.27.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
k8s.io/kubectl v0.27.2 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.2 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
Expand Down Expand Up @@ -190,7 +194,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
Expand Down Expand Up @@ -425,11 +428,12 @@ k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
k8s.io/kubectl v0.27.2 h1:sSBM2j94MHBFRWfHIWtEXWCicViQzZsb177rNsKBhZg=
k8s.io/kubectl v0.27.2/go.mod h1:GCOODtxPcrjh+EC611MqREkU8RjYBh10ldQCQ6zpFKw=
k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/cli-utils v0.35.0 h1:dfSJaF1W0frW74PtjwiyoB4cwdRygbHnC7qe7HF0g/Y=
sigs.k8s.io/cli-utils v0.35.0/go.mod h1:ITitykCJxP1vaj1Cew/FZEaVJ2YsTN9Q71m02jebkoE=
sigs.k8s.io/cluster-api v1.5.2 h1:pCsyEHwTBb7n+U5Z2OA5STxdJ1EuSpJv8FLBx4lii3s=
sigs.k8s.io/cluster-api v1.5.2/go.mod h1:EGJUNpFWi7dF426tO8MG/jE+w7T0UO5KyMnOwQ5riUY=
sigs.k8s.io/controller-runtime v0.15.2 h1:9V7b7SDQSJ08IIsJ6CY1CE85Okhp87dyTMNDG0FS7f4=
sigs.k8s.io/controller-runtime v0.15.2/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
Expand Down
141 changes: 91 additions & 50 deletions internal/controller/automatedclusterdiscovery_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ type AutomatedClusterDiscoveryReconciler struct {
Scheme *runtime.Scheme
EventRecorder eventRecorder

AKSProvider func(string) providers.Provider
AKSProvider func(string) providers.Provider
CAPIProvider func(client.Client, string) providers.Provider
}

// event emits a Kubernetes event and forwards the event to the event recorder
Expand Down Expand Up @@ -173,6 +174,19 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileResources(ctx context.Con

return nil, err
}
} else if cd.Spec.Type == "capi" {
logger.Info("reconciling CAPI cluster reflector",
"name", cd.Spec.Name,
)

capiProvider := r.CAPIProvider(r.Client, cd.Namespace)

clusters, err = capiProvider.ListClusters(ctx)
if err != nil {
logger.Error(err, "failed to list CAPI clusters")
return nil, err
}

}

// TODO: Fix this so that we record the inventoryRefs even if we get an
Expand Down Expand Up @@ -230,7 +244,7 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont
}
secretName := fmt.Sprintf("%s-kubeconfig", cluster.Name)

gitopsCluster := newGitopsCluster(secretName, types.NamespacedName{
gitopsCluster := newGitopsCluster(types.NamespacedName{
Name: cluster.Name,
Namespace: acd.Namespace,
})
Expand Down Expand Up @@ -259,12 +273,19 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont
gitopsCluster.SetAnnotations(mergeMaps(acd.Spec.CommonAnnotations, map[string]string{
gitopsv1alpha1.GitOpsClusterNoSecretFinalizerAnnotation: "true",
}))

_, err = controllerutil.CreateOrPatch(ctx, r.Client, gitopsCluster, func() error {
gitopsCluster.Spec = gitopsv1alpha1.GitopsClusterSpec{
SecretRef: &meta.LocalObjectReference{
Name: secretName,
},
if acd.Spec.Type == "aks" {
gitopsCluster.Spec = gitopsv1alpha1.GitopsClusterSpec{
SecretRef: &meta.LocalObjectReference{
Name: secretName,
},
}
} else if acd.Spec.Type == "capi" {
gitopsCluster.Spec = gitopsv1alpha1.GitopsClusterSpec{
CAPIClusterRef: &meta.LocalObjectReference{
Name: cluster.Name,
},
}
}

return nil
Expand All @@ -275,40 +296,18 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont

inventoryResources = append(inventoryResources, clusterRef)

secret := newSecret(types.NamespacedName{
Name: secretName,
Namespace: acd.Namespace,
})

secretRef, err := clustersv1alpha1.ResourceRefFromObject(secret)
if err != nil {
return inventoryResources, err
}
if cluster.KubeConfig != nil {
secretRef, err := r.createSecret(ctx, secretName, acd.Namespace, gitopsCluster, acd, cluster)
if err != nil {
return inventoryResources, err
}

logger.Info("creating secret", "name", secret.GetName())
if err := controllerutil.SetOwnerReference(gitopsCluster, secret, r.Scheme); err != nil {
return inventoryResources, fmt.Errorf("failed to set ownership on created Secret: %w", err)
inventoryResources = append(inventoryResources, *secretRef)
}

// publish event for ClusterCreated
r.event(acd, corev1.EventTypeNormal, "ClusterCreated", fmt.Sprintf("Cluster %s created", cluster.Name))

secret.SetLabels(labelsForResource(*acd))
secret.SetAnnotations(acd.Spec.CommonAnnotations)
_, err = controllerutil.CreateOrPatch(ctx, r.Client, secret, func() error {
value, err := clientcmd.Write(*cluster.KubeConfig)
if err != nil {
return err
}
secret.Data["value"] = value

return nil
})
if err != nil {
return inventoryResources, err
}

inventoryResources = append(inventoryResources, secretRef)
}

if acd.Status.Inventory != nil {
Expand Down Expand Up @@ -349,21 +348,23 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont
return inventoryResources, fmt.Errorf("failed to load GitopsCluster for update: %w", err)
}

secretToUpdate := &corev1.Secret{}
if err := r.Client.Get(ctx, types.NamespacedName{Name: existingCluster.Spec.SecretRef.Name, Namespace: acd.GetNamespace()}, secretToUpdate); err != nil {
// TODO: don't error, create a new secret!
return inventoryResources, fmt.Errorf("failed to get the secret to update: %w", err)
}
if existingCluster.Spec.SecretRef != nil {
secretToUpdate := &corev1.Secret{}
if err := r.Client.Get(ctx, types.NamespacedName{Name: existingCluster.Spec.SecretRef.Name, Namespace: acd.GetNamespace()}, secretToUpdate); err != nil {
// TODO: don't error, create a new secret!
return inventoryResources, fmt.Errorf("failed to get the secret to update: %w", err)
}

cluster := clusterMapping[existingCluster.GetName()]
value, err := clientcmd.Write(*cluster.KubeConfig)
if err != nil {
return inventoryResources, err
}
secretToUpdate.Data["value"] = value
// TODO: Patch!
if err := r.Client.Update(ctx, secretToUpdate); err != nil {
return inventoryResources, err
cluster := clusterMapping[existingCluster.GetName()]
value, err := clientcmd.Write(*cluster.KubeConfig)
if err != nil {
return inventoryResources, err
}
secretToUpdate.Data["value"] = value
// TODO: Patch!
if err := r.Client.Update(ctx, secretToUpdate); err != nil {
return inventoryResources, err
}
}
}

Expand All @@ -382,7 +383,47 @@ func (r *AutomatedClusterDiscoveryReconciler) patchStatus(ctx context.Context, r
return r.Status().Patch(ctx, &set, patch)
}

func newGitopsCluster(secretName string, name types.NamespacedName) *gitopsv1alpha1.GitopsCluster {
func (r *AutomatedClusterDiscoveryReconciler) createSecret(ctx context.Context, secretName, namespace string, gitopsCluster *gitopsv1alpha1.GitopsCluster, acd *clustersv1alpha1.AutomatedClusterDiscovery, cluster *providers.ProviderCluster) (*clustersv1alpha1.ResourceRef, error) {
logger := log.FromContext(ctx)
secret := newSecret(types.NamespacedName{
Name: secretName,
Namespace: namespace,
})

secretRef, err := clustersv1alpha1.ResourceRefFromObject(secret)
if err != nil {
return nil, err
}

logger.Info("creating secret", "name", secret.GetName())
if err := controllerutil.SetOwnerReference(gitopsCluster, secret, r.Scheme); err != nil {
logger.Error(err, "failed to set ownership on created Secret")
return nil, fmt.Errorf("failed to set ownership on created Secret: %w", err)
}

secret.SetLabels(labelsForResource(*acd))
secret.SetAnnotations(acd.Spec.CommonAnnotations)

// publish event for ClusterCreated
r.event(acd, corev1.EventTypeNormal, "ClusterCreated", fmt.Sprintf("Cluster %s created", cluster.Name))
_, err = controllerutil.CreateOrPatch(ctx, r.Client, secret, func() error {
value, err := clientcmd.Write(*cluster.KubeConfig)
if err != nil {
return err
}

secret.Data["value"] = value

return nil
})
if err != nil {
return nil, err
}

return &secretRef, nil
}

func newGitopsCluster(name types.NamespacedName) *gitopsv1alpha1.GitopsCluster {
return &gitopsv1alpha1.GitopsCluster{
TypeMeta: metav1.TypeMeta{
Kind: "GitopsCluster",
Expand Down
Loading

0 comments on commit dfb060a

Please sign in to comment.