Skip to content
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

feat: fix the matchselector issue and some little typos #9

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ kubernetes-labels-migrator \

![Screenshot of a terminal with all the execution](.github/docs/demo.png "CLI demo")

## Tutorial

Let's say you are managing your application with the gitops's philosohpy ([ArgoCD](https://argo-cd.readthedocs.io/en/stable/) is really great to do the job). You want to add or edit a label. This difference has already been done by your code but ArgoCD refused to sync because of the "immutable field" error. Then following this:
- ⚠️ First of all, nothing intervene during the operation! `kubernetes-labels-migrator` should be free until the end. If you have tools like ArgoCD that synchronize your resources, **please** ensure this feature is **disabled**.
- You can commit the changes on the resource and observe the difference
- Launch the script and watch the magic happens
- According your changes, the difference should have been resolved
Tchoupinax marked this conversation as resolved.
Show resolved Hide resolved

## Motivation

Deployment's labels are immutable. That means, if you have to edit, rename or add labels to a deployed application, you have to delete the deployment. On a production application, it is very annoying.
Expand Down
1 change: 1 addition & 0 deletions logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func logBlocking(msg string) {
magenta := color.New(color.Bold, color.FgHiMagenta).SprintFunc()
fmt.Println(magenta(fmt.Sprintf("⌛️ %s", msg)))
}

func logBlockingDot() {
magenta := color.New(color.Bold, color.FgHiMagenta).SprintFunc()
fmt.Print(magenta("."))
Expand Down
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ func main() {
var labelToChangeValue = ""
var goalOfOperationIsToRemoveLabel = false

flag.StringVar(&deploymentName, "deployment", "" , "Name of the deployment to edit label")
flag.StringVar(&namespace, "namespace", "" , "Namespace of the deployment to edit label")
flag.StringVar(&deploymentName, "deployment", "", "Name of the deployment to edit label")
flag.StringVar(&namespace, "namespace", "", "Namespace of the deployment to edit label")
flag.BoolVar(&goalOfOperationIsToRemoveLabel, "remove-label", false, "If true, the label will be removed instead of be added/edited")
flag.StringVar(&labelToChangeKey, "label", "app.kubernetes.io/name", "Name of the label")
flag.StringVar(&labelToChangeValue, "value", "", "Value of the label")
Expand Down Expand Up @@ -62,7 +62,7 @@ func main() {
os.Exit(0)
}

Step1(
MigrationWorkflow(
namespace,
clientset,
deploymentName,
Expand Down
26 changes: 15 additions & 11 deletions steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Step1(
func MigrationWorkflow(
namespace string,
clientset *kubernetes.Clientset,
deploymentName string,
Expand All @@ -33,7 +33,7 @@ func Step1(
// It's required because an error is thrown, we can not create a deployment with this property provided
temporalDeployment.ResourceVersion = ""

_, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), &temporalDeployment, metav1.CreateOptions{});
_, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), &temporalDeployment, metav1.CreateOptions{})
if err != nil {
if strings.Contains(err.Error(), "already exists, the server was not able to generate a unique name for the object") {
logWarning("1. Temporary deployment already created. Continue...")
Expand All @@ -45,7 +45,7 @@ func Step1(
logInfo("2. Updating the service...")
var temporalService = *currentService
delete(temporalService.Spec.Selector, changingLabelKey)
_, err = clientset.CoreV1().Services(namespace).Update(context.TODO(), &temporalService, metav1.UpdateOptions{});
_, err = clientset.CoreV1().Services(namespace).Update(context.TODO(), &temporalService, metav1.UpdateOptions{})
check(err)
logSuccess("2. Service updated")

Expand All @@ -54,9 +54,9 @@ func Step1(
for !areAllPodReady {
logBlockingDot()
time.Sleep(1 * time.Second)
areAllPodReady =
waitUntilAllPodAreReady(clientset, namespace, "api") &&
waitUntilAllPodAreReady(clientset, namespace, fmt.Sprintf("%s-%s", currentDeployment.Name, "changing-label-tmp"))
areAllPodReady =
waitUntilAllPodAreReady(clientset, namespace, currentDeployment.Name) &&
waitUntilAllPodAreReady(clientset, namespace, fmt.Sprintf("%s-%s", currentDeployment.Name, "changing-label-tmp"))
}
fmt.Println("")

Expand All @@ -78,12 +78,17 @@ func Step1(
if removeLabel {
delete(futureOfficialDeployment.ObjectMeta.Labels, changingLabelKey)
delete(futureOfficialDeployment.Spec.Template.ObjectMeta.Labels, changingLabelKey)
} else {
delete(futureOfficialDeployment.Spec.Selector.MatchLabels, changingLabelKey)
} else {
// Label of the deployment
futureOfficialDeployment.ObjectMeta.Labels[changingLabelKey] = changingLabelValue
// Label of the pod created by the deployment
futureOfficialDeployment.Spec.Template.ObjectMeta.Labels[changingLabelKey] = changingLabelValue
// Then we must include the label in the matchSelector for the deployment to find pods
futureOfficialDeployment.Spec.Selector.MatchLabels[changingLabelKey] = changingLabelValue
}

_, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), &futureOfficialDeployment, metav1.CreateOptions{});
_, err = clientset.AppsV1().Deployments(namespace).Create(context.TODO(), &futureOfficialDeployment, metav1.CreateOptions{})
if err != nil {
if strings.Contains(err.Error(), "already exists, the server was not able to generate a unique name for the object") {
fmt.Println("⚠️ Temporary deployment already created. Continue...")
Expand All @@ -97,7 +102,7 @@ func Step1(
for !areAllPodReady {
logBlockingDot()
time.Sleep(1 * time.Second)
areAllPodReady = waitUntilAllPodAreReady(clientset, namespace, "api")
areAllPodReady = waitUntilAllPodAreReady(clientset, namespace, currentDeployment.Name)
}
fmt.Println("")

Expand All @@ -109,7 +114,7 @@ func Step1(
logSuccess("7. Temporary deployment deleted")
}

func AddLabelToServiceSelector (
func AddLabelToServiceSelector(
namespace string,
clientset *kubernetes.Clientset,
applicationName string,
Expand All @@ -123,7 +128,6 @@ func AddLabelToServiceSelector (
currentService, err := clientset.CoreV1().Services(namespace).Get(context.TODO(), applicationName, metav1.GetOptions{})
check(err)


var futureService = *currentService
if removeLabel {
// Update the value of the label
Expand Down
4 changes: 2 additions & 2 deletions summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func displaySummary(
t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"Parameter", "Value"})
t.AppendRows([]table.Row{{"Deployement name", namespace}})
t.AppendRows([]table.Row{{"Namespace", deploymentName}})
t.AppendRows([]table.Row{{"Deployment name", deploymentName}})
t.AppendRows([]table.Row{{"Namespace", namespace}})
if goalOfOperationIsToRemoveLabel {
t.AppendRows([]table.Row{{"Label", labelToChangeKey}})
} else {
Expand Down
4 changes: 2 additions & 2 deletions version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/fatih/color"
)

const Version string = "0.1.1"
const BuildDate string = "2024-03-24"
const Version string = "0.1.2"
const BuildDate string = "2024-04-11"

func cliCommandDisplayHelp(args []string) {
displayVersion := stringInSlice("-v", args[1:]) || stringInSlice("--version", args[1:])
Expand Down
Loading