Skip to content

Commit 1c322be

Browse files
committed
feat - migrate crd in etcd
Signed-off-by: Hélia Barroso <[email protected]>
1 parent 07e44b9 commit 1c322be

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

cmd/migrate.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2024 The prometheus-operator Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/prometheus-operator/poctl/internal/etcdmigrate"
21+
"github.com/prometheus-operator/poctl/internal/k8sutil"
22+
"github.com/prometheus-operator/poctl/internal/log"
23+
"github.com/spf13/cobra"
24+
)
25+
26+
// migrateCmd represents the etcd store objects migration command.
27+
var migrateCmd = &cobra.Command{
28+
Use: "migrate",
29+
Short: "Automatically update Custom Resources to the latest storage version.",
30+
Long: `The migrate command in poctl automates the process of updating Kubernetes Custom Resources to the latest storage version. This is essential when upgrading a CRD that supports multiple API versions.`,
31+
RunE: runMigration,
32+
}
33+
34+
func init() {
35+
rootCmd.AddCommand(migrateCmd)
36+
}
37+
38+
func runMigration(cmd *cobra.Command, _ []string) error {
39+
logger, err := log.NewLogger()
40+
if err != nil {
41+
return fmt.Errorf("error while creating logger: %v", err)
42+
}
43+
clientSets, err := k8sutil.GetClientSets(kubeconfig)
44+
if err != nil {
45+
logger.Error("error while getting client sets", "err", err)
46+
return err
47+
}
48+
49+
if err := etcdmigrate.MigrateCRDs(cmd.Context(), clientSets); err != nil {
50+
logger.Error("error while updating etcd store", "err", err)
51+
}
52+
53+
logger.Info("Prometheus Operator CRD were update in etcd store ")
54+
return nil
55+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2024 The prometheus-operator Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package etcdmigrate
16+
17+
import (
18+
"context"
19+
"encoding/json"
20+
"fmt"
21+
22+
"github.com/prometheus-operator/poctl/internal/k8sutil"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25+
"k8s.io/apimachinery/pkg/runtime/schema"
26+
)
27+
28+
func MigrateCRDs(ctx context.Context, clientSets *k8sutil.ClientSets) error {
29+
crds, err := clientSets.APIExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{})
30+
if err != nil {
31+
return fmt.Errorf("failed to list CRDs: %w", err)
32+
}
33+
34+
for _, crd := range crds.Items {
35+
if crd.Spec.Group != "monitoring.coreos.com" {
36+
continue
37+
}
38+
39+
var storageVersion string
40+
for _, version := range crd.Spec.Versions {
41+
if version.Storage {
42+
storageVersion = version.Name
43+
break
44+
}
45+
}
46+
if storageVersion == "" {
47+
continue
48+
}
49+
50+
crdResourceVersion := schema.GroupVersionResource{
51+
Group: crd.Spec.Group,
52+
Version: storageVersion,
53+
Resource: crd.Spec.Names.Plural,
54+
}
55+
56+
namespaces, err := clientSets.KClient.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
57+
if err != nil {
58+
return fmt.Errorf("failed to list Namespaces %v", err)
59+
}
60+
for _, namespace := range namespaces.Items {
61+
ns := namespace.Name
62+
63+
customResourcesInstances, err := clientSets.DClient.Resource(crdResourceVersion).Namespace(ns).List(ctx, metav1.ListOptions{})
64+
if err != nil {
65+
continue
66+
}
67+
68+
for _, cri := range customResourcesInstances.Items {
69+
name := cri.GetName()
70+
apiVersion := cri.GetAPIVersion()
71+
72+
expectedAPIVersion := fmt.Sprintf("%s/%s", crd.Spec.Group, storageVersion)
73+
if apiVersion == expectedAPIVersion {
74+
continue
75+
}
76+
77+
crdJSON, err := json.Marshal(cri.Object)
78+
if err != nil {
79+
continue
80+
}
81+
82+
updatedStorageObject := &unstructured.Unstructured{}
83+
if err := json.Unmarshal(crdJSON, &updatedStorageObject.Object); err != nil {
84+
continue
85+
}
86+
87+
_, err = clientSets.DClient.Resource(crdResourceVersion).Namespace(ns).Update(ctx, updatedStorageObject, metav1.UpdateOptions{})
88+
if err != nil {
89+
return fmt.Errorf("failed to update %s %s: %v", ns, name, err)
90+
}
91+
}
92+
}
93+
}
94+
95+
fmt.Println("CRD migration completed.")
96+
return nil
97+
}

0 commit comments

Comments
 (0)