generated from kubernetes/kubernetes-template-project
/
upgrade_plan.go
169 lines (131 loc) · 5.23 KB
/
upgrade_plan.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//nolint
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"context"
"fmt"
"os"
"text/tabwriter"
"github.com/go-errors/errors"
"github.com/spf13/cobra"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
)
type upgradePlanOptions struct {
kubeconfig string
kubeconfigContext string
}
// certManagerUpgradePlan defines the upgrade plan if cert-manager needs to be
// upgraded to a different version.
type certManagerUpgradePlan struct {
ExternallyManaged bool
From, To string
ShouldUpgrade bool
}
// upgradePlan defines a list of possible upgrade targets for a management cluster.
type upgradePlan struct {
Contract string
Providers []upgradeItem
}
// upgradeItem defines a possible upgrade target for a provider in the management cluster.
type upgradeItem struct {
operatorv1.GenericProvider
NextVersion string
}
var upgradePlanOpts = &upgradePlanOptions{}
var upgradePlanCmd = &cobra.Command{
Use: "plan",
Short: "Provide a list of recommended target versions for upgrading Cluster API providers in a management cluster",
Long: LongDesc(`
The upgrade plan command provides a list of recommended target versions for upgrading the
Cluster API providers in a management cluster.
All the providers should be supporting the same API Version of Cluster API (contract) in order
to guarantee the proper functioning of the management cluster.
Then, for each provider, the following upgrade options are provided:
- The latest patch release for the current API Version of Cluster API (contract).
- The latest patch release for the next API Version of Cluster API (contract), if available.`),
Example: Examples(`
# Gets the recommended target versions for upgrading Cluster API providers.
capioperator upgrade plan`),
RunE: func(cmd *cobra.Command, args []string) error {
return runUpgradePlan()
},
}
func init() {
upgradePlanCmd.Flags().StringVar(&upgradePlanOpts.kubeconfig, "kubeconfig", "",
"Path to the kubeconfig file to use for accessing the management cluster. If empty, default discovery rules apply.")
upgradePlanCmd.Flags().StringVar(&upgradePlanOpts.kubeconfigContext, "kubeconfig-context", "",
"Context to be used within the kubeconfig file. If empty, current context will be used.")
}
func runUpgradePlan() error {
ctx := context.Background()
certManUpgradePlan, err := planCertManagerUpgrade(ctx, upgradePlanOpts)
if err != nil {
return err
}
if !certManUpgradePlan.ExternallyManaged {
if certManUpgradePlan.ShouldUpgrade {
fmt.Printf("Cert-Manager will be upgraded from %q to %q\n\n", certManUpgradePlan.From, certManUpgradePlan.To)
} else {
fmt.Printf("Cert-Manager is already up to date\n\n")
}
}
upgradePlans, err := planUpgrade(ctx, upgradePlanOpts)
if err != nil {
return err
}
if len(upgradePlans) == 0 {
fmt.Println("There are no providers in the cluster. Please use capioperator init to initialize a Cluster API management cluster.")
return nil
}
// ensure upgrade plans are sorted consistently (by CoreProvider.Namespace, Contract).
sortUpgradePlans(upgradePlans)
for _, plan := range upgradePlans {
// ensure provider are sorted consistently (by Type, Name, Namespace).
sortUpgradeItems(plan)
upgradeAvailable := false
fmt.Printf("\nLatest release available for the %s API Version of Cluster API (contract):\n\n", plan.Contract)
w := tabwriter.NewWriter(os.Stdout, 10, 4, 3, ' ', 0)
fmt.Fprintln(w, "NAME\tNAMESPACE\tTYPE\tCURRENT VERSION\tNEXT VERSION")
for _, upgradeItem := range plan.Providers {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", upgradeItem.GetName(), upgradeItem.GetNamespace(), upgradeItem.GetType(), upgradeItem.GetSpec().Version, prettifyTargetVersion(upgradeItem.NextVersion))
if upgradeItem.NextVersion != "" {
upgradeAvailable = true
}
}
if err := w.Flush(); err != nil {
return err
}
fmt.Println("")
if upgradeAvailable {
if plan.Contract == clusterv1.GroupVersion.Version {
fmt.Println("You can now apply the upgrade by executing the following command:")
fmt.Println("")
fmt.Printf("capioperator upgrade apply --contract %s\n", plan.Contract)
} else {
fmt.Printf("The current version of capioperator could not upgrade to %s contract (only %s supported).\n", plan.Contract, clusterv1.GroupVersion.Version)
}
} else {
fmt.Println("You are already up to date!")
}
fmt.Println("")
}
return nil
}
func planCertManagerUpgrade(ctx context.Context, opts *upgradePlanOptions) (certManagerUpgradePlan, error) {
return certManagerUpgradePlan{}, errors.New("Not implemented")
}
func planUpgrade(ctx context.Context, opts *upgradePlanOptions) ([]upgradePlan, error) {
return nil, errors.New("Not implemented")
}