@@ -17,17 +17,32 @@ limitations under the License.
17
17
package cmd
18
18
19
19
import (
20
+ "context"
21
+ "errors"
20
22
"fmt"
23
+ "os"
21
24
25
+ appsv1 "k8s.io/api/apps/v1"
26
+ corev1 "k8s.io/api/core/v1"
27
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
28
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22
29
"k8s.io/apimachinery/pkg/runtime"
23
30
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
24
31
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
25
32
"k8s.io/client-go/tools/clientcmd"
33
+ clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
26
34
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
27
35
28
36
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
29
37
)
30
38
39
+ var capiOperatorLabels = map [string ]string {
40
+ "clusterctl.cluster.x-k8s.io/core" : "capi-operator" ,
41
+ "control-plane" : "controller-manager" ,
42
+ }
43
+
44
+ var ErrNotFound = fmt .Errorf ("resource was not found" )
45
+
31
46
// CreateKubeClient creates a kubernetes client from provided kubeconfig and kubecontext.
32
47
func CreateKubeClient (kubeconfigPath , kubeconfigContext string ) (ctrlclient.Client , error ) {
33
48
// Use specified kubeconfig path and context
@@ -51,3 +66,98 @@ func CreateKubeClient(kubeconfigPath, kubeconfigContext string) (ctrlclient.Clie
51
66
52
67
return client , nil
53
68
}
69
+
70
+ func EnsureNamespaceExists (ctx context.Context , client ctrlclient.Client , namespace string ) error {
71
+ // Check if the namespace exists
72
+ ns := & corev1.Namespace {}
73
+
74
+ err := client .Get (ctx , ctrlclient.ObjectKey {Name : namespace }, ns )
75
+ if err == nil {
76
+ return nil
77
+ }
78
+
79
+ if ! apierrors .IsNotFound (err ) {
80
+ return fmt .Errorf ("unexpected error during namespace checking: %w" , err )
81
+ }
82
+
83
+ // Create the namespace if it doesn't exist
84
+ newNamespace := & corev1.Namespace {
85
+ ObjectMeta : metav1.ObjectMeta {
86
+ Name : namespace ,
87
+ },
88
+ }
89
+
90
+ if err := client .Create (ctx , newNamespace ); err != nil {
91
+ return fmt .Errorf ("unable to create namespace %s: %w" , namespace , err )
92
+ }
93
+
94
+ return nil
95
+ }
96
+
97
+ // GetDeploymentByLabels fetches deployment based on the provided labels.
98
+ func GetDeploymentByLabels (ctx context.Context , client ctrlclient.Client , labels map [string ]string ) (* appsv1.Deployment , error ) {
99
+ var deploymentList appsv1.DeploymentList
100
+
101
+ // Search deployments with desired labels in all namespaces.
102
+ if err := client .List (ctx , & deploymentList , ctrlclient .MatchingLabels (labels )); err != nil {
103
+ return nil , fmt .Errorf ("cannot get a list of deployments from the server: %w" , err )
104
+ }
105
+
106
+ if len (deploymentList .Items ) > 1 {
107
+ return nil , fmt .Errorf ("more than one deployment found for given labels %v" , labels )
108
+ }
109
+
110
+ if len (deploymentList .Items ) == 0 {
111
+ return nil , ErrNotFound
112
+ }
113
+
114
+ return & deploymentList .Items [0 ], nil
115
+ }
116
+
117
+ // CheckDeploymentAvailability checks if the deployment with given labels is available.
118
+ func CheckDeploymentAvailability (ctx context.Context , client ctrlclient.Client , labels map [string ]string ) (bool , error ) {
119
+ deployment , err := GetDeploymentByLabels (ctx , client , labels )
120
+ if err != nil {
121
+ if errors .Is (err , ErrNotFound ) {
122
+ return false , nil
123
+ }
124
+
125
+ return false , err
126
+ }
127
+
128
+ for _ , cond := range deployment .Status .Conditions {
129
+ if cond .Type == appsv1 .DeploymentAvailable && cond .Status == corev1 .ConditionTrue {
130
+ return true , nil
131
+ }
132
+ }
133
+
134
+ return false , nil
135
+ }
136
+
137
+ // GetKubeconfigLocation will read the environment variable $KUBECONFIG otherwise set it to ~/.kube/config.
138
+ func GetKubeconfigLocation () string {
139
+ if kubeconfig := os .Getenv ("KUBECONFIG" ); kubeconfig != "" {
140
+ return kubeconfig
141
+ }
142
+
143
+ return clientcmd .RecommendedHomeFile
144
+ }
145
+
146
+ func NewGenericProvider (providerType clusterctlv1.ProviderType ) operatorv1.GenericProvider {
147
+ switch providerType {
148
+ case clusterctlv1 .CoreProviderType :
149
+ return & operatorv1.CoreProvider {}
150
+ case clusterctlv1 .BootstrapProviderType :
151
+ return & operatorv1.BootstrapProvider {}
152
+ case clusterctlv1 .ControlPlaneProviderType :
153
+ return & operatorv1.ControlPlaneProvider {}
154
+ case clusterctlv1 .InfrastructureProviderType :
155
+ return & operatorv1.InfrastructureProvider {}
156
+ case clusterctlv1 .AddonProviderType :
157
+ return & operatorv1.AddonProvider {}
158
+ case clusterctlv1 .IPAMProviderType , clusterctlv1 .RuntimeExtensionProviderType , clusterctlv1 .ProviderTypeUnknown :
159
+ panic (fmt .Sprintf ("unsupported provider type %s" , providerType ))
160
+ default :
161
+ panic (fmt .Sprintf ("unknown provider type %s" , providerType ))
162
+ }
163
+ }
0 commit comments