11package kubernetes
22
33import (
4- "context"
54 "fmt"
6- "strings"
75
86 "github.com/MakeNowJust/heredoc/v2"
97 "github.com/charmbracelet/log"
108 "github.com/ctrlplanedev/cli/internal/api"
119 ctrlp "github.com/ctrlplanedev/cli/internal/common"
1210 "github.com/spf13/cobra"
1311 "github.com/spf13/viper"
14- appsv1 "k8s.io/api/apps/v1"
15- corev1 "k8s.io/api/core/v1"
16- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17- "k8s.io/client-go/kubernetes"
1812)
1913
20- func processNamespace (_ context.Context , clusterName string , namespace corev1.Namespace ) api.ResourceProviderResource {
21- metadata := map [string ]string {}
22- for key , value := range namespace .Labels {
23- metadata [fmt .Sprintf ("tags/%s" , key )] = value
24- }
25-
26- metadata ["kubernetes/namespace" ] = namespace .Name
27- metadata ["namespace/id" ] = string (namespace .UID )
28- metadata ["namespace/api-version" ] = namespace .APIVersion
29- metadata ["namespace/status" ] = string (namespace .Status .Phase )
30-
31- return api.ResourceProviderResource {
32- Version : "ctrlplane.dev/kubernetes/namespace/v1" ,
33- Kind : "KubernetesNamespace" ,
34- Name : fmt .Sprintf ("%s/%s" , clusterName , namespace .Name ),
35- Identifier : string (namespace .UID ),
36- Config : map [string ]any {
37- "id" : string (namespace .UID ),
38- "name" : namespace .Name ,
39- "status" : namespace .Status .Phase ,
40- },
41- Metadata : metadata ,
42- }
43- }
44-
45- func processDeployment (_ context.Context , clusterName string , deployment appsv1.Deployment ) api.ResourceProviderResource {
46- metadata := map [string ]string {}
47- for key , value := range deployment .Labels {
48- metadata [fmt .Sprintf ("tags/%s" , key )] = value
49- }
50- metadata ["deployment/name" ] = deployment .Name
51- metadata ["deployment/id" ] = string (deployment .UID )
52- metadata ["deployment/api-version" ] = deployment .APIVersion
53- metadata ["deployment/namespace" ] = deployment .Namespace
54-
55- return api.ResourceProviderResource {
56- Version : "ctrlplane.dev/kubernetes/deployment/v1" ,
57- Kind : "KubernetesDeployment" ,
58- Name : fmt .Sprintf ("%s/%s/%s" , clusterName , deployment .Namespace , deployment .Name ),
59- Identifier : string (deployment .UID ),
60- Config : map [string ]any {
61- "id" : string (deployment .UID ),
62- "name" : deployment .Name ,
63- "namespace" : deployment .Namespace ,
64- },
65- Metadata : metadata ,
66- }
67- }
68-
6914func NewSyncKubernetesCmd () * cobra.Command {
7015 var clusterIdentifier string
7116 var providerName string
7217 var clusterName string
18+ var selectors ResourceTypes
7319
7420 cmd := & cobra.Command {
7521 Use : "kubernetes" ,
@@ -78,7 +24,7 @@ func NewSyncKubernetesCmd() *cobra.Command {
7824 $ ctrlc sync kubernetes --cluster-identifier 1234567890 --cluster-name my-cluster
7925 ` ),
8026 RunE : func (cmd * cobra.Command , args []string ) error {
81- ctx := context . Background ()
27+ ctx := cmd . Context ()
8228 log .Info ("Syncing Kubernetes resources on a cluster" )
8329 if clusterIdentifier == "" {
8430 clusterIdentifier = viper .GetString ("cluster-identifier" )
@@ -89,6 +35,10 @@ func NewSyncKubernetesCmd() *cobra.Command {
8935 return err
9036 }
9137
38+ if clusterName == "" {
39+ clusterName = configClusterName
40+ }
41+
9242 log .Info ("Connected to cluster" , "name" , clusterName )
9343
9444 apiURL := viper .GetString ("url" )
@@ -99,70 +49,19 @@ func NewSyncKubernetesCmd() *cobra.Command {
9949 if err != nil {
10050 return fmt .Errorf ("failed to create API client: %w" , err )
10151 }
102-
103- clusterResource , err := ctrlplaneClient .GetResourceByIdentifierWithResponse (ctx , workspaceId , clusterIdentifier )
104- if err != nil {
105- log .Warn ("Failed to get cluster resource" )
106- }
107- if clusterResource .StatusCode () > 499 {
108- log .Warn ("Failed to get cluster resource" , "status" , clusterResource .StatusCode (), "identifier" , clusterIdentifier , "error" , err )
109- return fmt .Errorf ("error access ctrlplane api: %s" , clusterResource .Status ())
110- }
111- if clusterResource != nil && clusterResource .JSON200 != nil {
112- log .Info ("Found cluster resource" , "name" , clusterResource .JSON200 .Name )
113- clusterName = clusterResource .JSON200 .Name
114- }
115-
116- if clusterName == "" {
117- clusterName = configClusterName
118- }
119-
120- clientset , err := kubernetes .NewForConfig (config )
121- if err != nil {
122- return err
123- }
124-
125- namespaces , err := clientset .CoreV1 ().Namespaces ().List (ctx , metav1.ListOptions {})
52+ sync := newSync (clusterIdentifier , workspaceId , ctrlplaneClient , config , clusterName )
53+ resources , err := sync .process (ctx , selectors )
12654 if err != nil {
12755 return err
12856 }
12957
130- resources := []api.ResourceProviderResource {}
131- for _ , namespace := range namespaces .Items {
132- resource := processNamespace (context .Background (), clusterName , namespace )
133- resources = append (resources , resource )
134- }
135-
136- deployments , err := clientset .AppsV1 ().Deployments (metav1 .NamespaceAll ).List (ctx , metav1.ListOptions {})
137- if err != nil {
138- return err
139- }
140-
141- for _ , deployment := range deployments .Items {
142- resource := processDeployment (context .Background (), clusterName , deployment )
143- resources = append (resources , resource )
144- }
145-
146- if clusterResource != nil && clusterResource .JSON200 != nil {
147- for _ , resource := range resources {
148- for key , value := range clusterResource .JSON200 .Metadata {
149- if strings .HasPrefix (key , "tags/" ) {
150- continue
151- }
152- if _ , exists := resource .Metadata [key ]; ! exists {
153- resource .Metadata [key ] = value
154- }
155- }
156- resource .Metadata ["kubernetes/name" ] = clusterResource .JSON200 .Name
157- }
158- }
159-
16058 return ctrlp .UpsertResources (ctx , resources , & providerName )
16159 },
16260 }
16361 cmd .Flags ().StringVarP (& providerName , "provider" , "p" , "" , "Name of the resource provider" )
16462 cmd .Flags ().StringVarP (& clusterIdentifier , "cluster-identifier" , "c" , "" , "The identifier of the parent cluster in ctrlplane (if not provided, will use the CLUSTER_IDENTIFIER environment variable)" )
16563 cmd .Flags ().StringVarP (& clusterName , "cluster-name" , "n" , "" , "The name of the cluster" )
64+ cmd .Flags ().VarP (& selectors , "selector" , "s" , "Select resources to sync [nodes|deployments|namespaces]. Repeat the flag to select multiple resources; omit it to sync all resources." )
16665
16766 return cmd
16867}
0 commit comments