Skip to content

Commit ea198dd

Browse files
authored
Convert outstanding commands to cobra (kubernetes#2384)
* magnum-auto-healer: Stop registering klog options Per [1], this is no longer desirable. We are already registering the minimal options that the KEP suggests so we can simply stop registering the others. [1] https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2845-deprecate-klog-specific-flags-in-k8s-components Signed-off-by: Stephen Finucane <[email protected]> * client-keystone-auth: Stop registering klog options As with magnum-auto-healer, we don't need/want to do this anymore. Don't. Signed-off-by: Stephen Finucane <[email protected]> * cinder-csi-plugin: Use binary name in help page Signed-off-by: Stephen Finucane <[email protected]> * client-keystone-auth: Migrate to cobra This one is relatively trivial since the 'Run' function in 'k8s.io/component-base/cli' does most of the heavy lifting for us now, including registering logging arguments. Signed-off-by: Stephen Finucane <[email protected]> * k8s-keystone-auth: Migrate to cobra This one is slightly trickier due to how we're doing configuration but there's still nothing crazy confusing here. Signed-off-by: Stephen Finucane <[email protected]> * occm: Remove unnecessary flag handling code k8s.io/cloud-provider switched to cobra some time back [1] and cobra uses 'pflag' rather than 'flag' under the hood. As such, there's no reason to keep the handling code for 'flag' options around. Remove it. [1] https://github.com/kubernetes/cloud-provider/blob/v0.28.0/app/controllermanager.go#L87-L124 Signed-off-by: Stephen Finucane <[email protected]> * occm: Register additional options correctly The 'NewCloudControllerManagerCommand' function, which generates the cobra Command that forms the basis of a cloud provider binary, accepts an 'additionalFlags' argument that allows us to (surprise) pass in additional provider-specific arguments. We were not making use of this, which means our options were not showing in the usage string shown on e.g. '--help'. Correct this on our end, while we wait for the fix in k8s.io/cloud-provider [1] to close the loop fully. In additional, move our 'InitLogs' call higher up the function to before our first logging call so that everything is initialised correctly. [1] kubernetes/kubernetes#120522 Signed-off-by: Stephen Finucane <[email protected]> * magnum-auto-healer: Remove use of 'init' methods Instead, register the health checks and cloud provider plugins on controller start up. This avoids side-effects from merely importing the modules - which are polluting the output of '--help' - and is generally "less weird". To do this, we must make the registration methods part of the public API and remove the 'pkg/autohealing/cloudprovider/register' package in favour of a public registration method in the 'pkg/autohealing/cloudprovider/openstack' package. Signed-off-by: Stephen Finucane <[email protected]> --------- Signed-off-by: Stephen Finucane <[email protected]>
1 parent d28a24b commit ea198dd

File tree

11 files changed

+138
-196
lines changed

11 files changed

+138
-196
lines changed

cmd/cinder-csi-plugin/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var (
4242

4343
func main() {
4444
cmd := &cobra.Command{
45-
Use: "Cinder",
45+
Use: "cinder-csi-plugin",
4646
Short: "CSI based Cinder driver",
4747
Run: func(cmd *cobra.Command, args []string) {
4848
handle()

cmd/client-keystone-auth/main.go

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,20 @@ limitations under the License.
1717
package main
1818

1919
import (
20-
"flag"
2120
"fmt"
2221
"io"
2322
"os"
2423
"time"
2524

2625
"github.com/gophercloud/gophercloud"
2726
"github.com/gophercloud/utils/openstack/clientconfig"
28-
"github.com/spf13/pflag"
29-
"k8s.io/component-base/logs"
27+
"github.com/spf13/cobra"
28+
"k8s.io/component-base/cli"
3029

3130
"golang.org/x/term"
3231

3332
"k8s.io/cloud-provider-openstack/pkg/identity/keystone"
3433
"k8s.io/cloud-provider-openstack/pkg/version"
35-
kflag "k8s.io/component-base/cli/flag"
36-
"k8s.io/klog/v2"
3734
)
3835

3936
const errRespTemplate string = `{
@@ -137,51 +134,49 @@ func argumentsAreSet(url, user, project, password, domain, applicationCredential
137134
return false
138135
}
139136

137+
var (
138+
url string
139+
domain string
140+
user string
141+
project string
142+
password string
143+
clientCertPath string
144+
clientKeyPath string
145+
clientCAPath string
146+
options keystone.Options
147+
err error
148+
applicationCredentialID string
149+
applicationCredentialName string
150+
applicationCredentialSecret string
151+
)
152+
140153
func main() {
141-
var url string
142-
var domain string
143-
var user string
144-
var project string
145-
var password string
146-
var clientCertPath string
147-
var clientKeyPath string
148-
var clientCAPath string
149-
var options keystone.Options
150-
var err error
151-
var applicationCredentialID string
152-
var applicationCredentialName string
153-
var applicationCredentialSecret string
154-
var showVersion bool
155-
156-
pflag.StringVar(&url, "keystone-url", os.Getenv("OS_AUTH_URL"), "URL for the OpenStack Keystone API")
157-
pflag.StringVar(&domain, "domain-name", os.Getenv("OS_DOMAIN_NAME"), "Keystone domain name")
158-
pflag.StringVar(&user, "user-name", os.Getenv("OS_USERNAME"), "User name")
159-
pflag.StringVar(&project, "project-name", os.Getenv("OS_PROJECT_NAME"), "Keystone project name")
160-
pflag.StringVar(&password, "password", os.Getenv("OS_PASSWORD"), "Password")
161-
pflag.StringVar(&clientCertPath, "cert", os.Getenv("OS_CERT"), "Client certificate bundle file")
162-
pflag.StringVar(&clientKeyPath, "key", os.Getenv("OS_KEY"), "Client certificate key file")
163-
pflag.StringVar(&clientCAPath, "cacert", os.Getenv("OS_CACERT"), "Certificate authority file")
164-
pflag.StringVar(&applicationCredentialID, "application-credential-id", os.Getenv("OS_APPLICATION_CREDENTIAL_ID"), "Application Credential ID")
165-
pflag.StringVar(&applicationCredentialName, "application-credential-name", os.Getenv("OS_APPLICATION_CREDENTIAL_NAME"), "Application Credential Name")
166-
pflag.StringVar(&applicationCredentialSecret, "application-credential-secret", os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET"), "Application Credential Secret")
167-
pflag.BoolVar(&showVersion, "version", false, "Show current version and exit")
168-
169-
logs.AddFlags(pflag.CommandLine)
170-
171-
klogFlags := flag.NewFlagSet("klog", flag.ExitOnError)
172-
klog.InitFlags(klogFlags)
173-
pflag.CommandLine.AddGoFlagSet(klogFlags)
174-
175-
kflag.InitFlags()
176-
177-
if showVersion {
178-
fmt.Println(version.Version)
179-
os.Exit(0)
154+
cmd := &cobra.Command{
155+
Use: "client-keystone-auth",
156+
Short: "Keystone client credential plugin for Kubernetes",
157+
Run: func(cmd *cobra.Command, args []string) {
158+
handle()
159+
},
160+
Version: version.Version,
180161
}
181162

182-
logs.InitLogs()
183-
defer logs.FlushLogs()
163+
cmd.PersistentFlags().StringVar(&url, "keystone-url", os.Getenv("OS_AUTH_URL"), "URL for the OpenStack Keystone API")
164+
cmd.PersistentFlags().StringVar(&domain, "domain-name", os.Getenv("OS_DOMAIN_NAME"), "Keystone domain name")
165+
cmd.PersistentFlags().StringVar(&user, "user-name", os.Getenv("OS_USERNAME"), "User name")
166+
cmd.PersistentFlags().StringVar(&project, "project-name", os.Getenv("OS_PROJECT_NAME"), "Keystone project name")
167+
cmd.PersistentFlags().StringVar(&password, "password", os.Getenv("OS_PASSWORD"), "Password")
168+
cmd.PersistentFlags().StringVar(&clientCertPath, "cert", os.Getenv("OS_CERT"), "Client certificate bundle file")
169+
cmd.PersistentFlags().StringVar(&clientKeyPath, "key", os.Getenv("OS_KEY"), "Client certificate key file")
170+
cmd.PersistentFlags().StringVar(&clientCAPath, "cacert", os.Getenv("OS_CACERT"), "Certificate authority file")
171+
cmd.PersistentFlags().StringVar(&applicationCredentialID, "application-credential-id", os.Getenv("OS_APPLICATION_CREDENTIAL_ID"), "Application Credential ID")
172+
cmd.PersistentFlags().StringVar(&applicationCredentialName, "application-credential-name", os.Getenv("OS_APPLICATION_CREDENTIAL_NAME"), "Application Credential Name")
173+
cmd.PersistentFlags().StringVar(&applicationCredentialSecret, "application-credential-secret", os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET"), "Application Credential Secret")
174+
175+
code := cli.Run(cmd)
176+
os.Exit(code)
177+
}
184178

179+
func handle() {
185180
// Generate Gophercloud Auth Options based on input data from stdin
186181
// if IsTerminal returns "true", or from env variables otherwise.
187182
if !term.IsTerminal(int(os.Stdin.Fd())) {

cmd/k8s-keystone-auth/main.go

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,45 @@ limitations under the License.
1515
package main
1616

1717
import (
18-
"fmt"
1918
"os"
2019

20+
"github.com/spf13/cobra"
2121
"github.com/spf13/pflag"
22+
"k8s.io/component-base/cli"
2223
"k8s.io/klog/v2"
2324

2425
"k8s.io/cloud-provider-openstack/pkg/identity/keystone"
2526
"k8s.io/cloud-provider-openstack/pkg/version"
26-
kflag "k8s.io/component-base/cli/flag"
27-
"k8s.io/component-base/logs"
2827
)
2928

29+
var config = keystone.NewConfig()
30+
3031
func main() {
31-
var showVersion bool
32-
pflag.BoolVar(&showVersion, "version", false, "Show current version and exit")
32+
cmd := &cobra.Command{
33+
Use: "k8s-keystone-auth",
34+
Short: "Keystone authentication webhook plugin for Kubernetes",
35+
Run: func(cmd *cobra.Command, args []string) {
36+
if err := config.ValidateFlags(); err != nil {
37+
klog.Errorf("%v", err)
38+
os.Exit(1)
39+
}
40+
41+
keystoneAuth, err := keystone.NewKeystoneAuth(config)
42+
if err != nil {
43+
klog.Errorf("%v", err)
44+
os.Exit(1)
45+
}
46+
keystoneAuth.Run()
47+
48+
},
49+
Version: version.Version,
50+
}
3351

34-
logs.AddFlags(pflag.CommandLine)
3552
keystone.AddExtraFlags(pflag.CommandLine)
3653

37-
logs.InitLogs()
38-
defer logs.FlushLogs()
39-
40-
config := keystone.NewConfig()
4154
config.AddFlags(pflag.CommandLine)
4255

43-
kflag.InitFlags()
44-
45-
if showVersion {
46-
fmt.Println(version.Version)
47-
os.Exit(0)
48-
}
49-
50-
if err := config.ValidateFlags(); err != nil {
51-
klog.Errorf("%v", err)
52-
os.Exit(1)
53-
}
56+
code := cli.Run(cmd)
57+
os.Exit(code)
5458

55-
keystoneAuth, err := keystone.NewKeystoneAuth(config)
56-
if err != nil {
57-
klog.Errorf("%v", err)
58-
os.Exit(1)
59-
}
60-
keystoneAuth.Run()
6159
}

cmd/openstack-cloud-controller-manager/main.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@ limitations under the License.
2020
package main
2121

2222
import (
23-
goflag "flag"
2423
"fmt"
2524
"os"
2625

27-
"github.com/spf13/pflag"
2826
"k8s.io/apimachinery/pkg/util/wait"
2927
cloudprovider "k8s.io/cloud-provider"
3028
"k8s.io/cloud-provider/app"
@@ -43,26 +41,18 @@ import (
4341
)
4442

4543
func main() {
44+
logs.InitLogs()
45+
defer logs.FlushLogs()
46+
4647
ccmOptions, err := options.NewCloudControllerManagerOptions()
4748
if err != nil {
4849
klog.Fatalf("unable to initialize command options: %v", err)
4950
}
5051

5152
fss := cliflag.NamedFlagSets{}
52-
command := app.NewCloudControllerManagerCommand(ccmOptions, cloudInitializer, app.DefaultInitFuncConstructors, names.CCMControllerAliases(), fss, wait.NeverStop)
53-
54-
openstack.AddExtraFlags(pflag.CommandLine)
53+
openstack.AddExtraFlags(fss.FlagSet("OpenStack Client"))
5554

56-
// TODO: once we switch everything over to Cobra commands, we can go back to calling
57-
// utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
58-
// normalize func and add the go flag set by hand.
59-
// Here is an sample
60-
pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
61-
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
62-
63-
// utilflag.InitFlags()
64-
logs.InitLogs()
65-
defer logs.FlushLogs()
55+
command := app.NewCloudControllerManagerCommand(ccmOptions, cloudInitializer, app.DefaultInitFuncConstructors, names.CCMControllerAliases(), fss, wait.NeverStop)
6656

6757
klog.V(1).Infof("openstack-cloud-controller-manager version: %s", version.Version)
6858

pkg/autohealing/cloudprovider/openstack/provider.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"time"
2626

2727
"github.com/gophercloud/gophercloud"
28+
gopenstack "github.com/gophercloud/gophercloud/openstack"
2829
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
2930
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop"
3031
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
@@ -43,8 +44,10 @@ import (
4344
"k8s.io/client-go/util/retry"
4445
log "k8s.io/klog/v2"
4546

47+
"k8s.io/cloud-provider-openstack/pkg/autohealing/cloudprovider"
4648
"k8s.io/cloud-provider-openstack/pkg/autohealing/config"
4749
"k8s.io/cloud-provider-openstack/pkg/autohealing/healthcheck"
50+
"k8s.io/cloud-provider-openstack/pkg/client"
4851
)
4952

5053
const (
@@ -671,3 +674,55 @@ func CheckNodeCondition(node *apiv1.Node, conditionType apiv1.NodeConditionType,
671674
}
672675
return false
673676
}
677+
678+
func NewOpenStackCloudProvider(cfg config.Config, kubeClient kubernetes.Interface) (cloudprovider.CloudProvider, error) {
679+
client, err := client.NewOpenStackClient(&cfg.OpenStack, "magnum-auto-healer")
680+
if err != nil {
681+
return nil, err
682+
}
683+
684+
eoOpts := gophercloud.EndpointOpts{
685+
Region: cfg.OpenStack.Region,
686+
Availability: cfg.OpenStack.EndpointType,
687+
}
688+
689+
// get nova service client
690+
var novaClient *gophercloud.ServiceClient
691+
novaClient, err = gopenstack.NewComputeV2(client, eoOpts)
692+
if err != nil {
693+
return nil, fmt.Errorf("failed to find Nova service endpoint in the region %s: %v", cfg.OpenStack.Region, err)
694+
}
695+
696+
// get heat service client
697+
var heatClient *gophercloud.ServiceClient
698+
heatClient, err = gopenstack.NewOrchestrationV1(client, eoOpts)
699+
if err != nil {
700+
return nil, fmt.Errorf("failed to find Heat service endpoint in the region %s: %v", cfg.OpenStack.Region, err)
701+
}
702+
703+
// get magnum service client
704+
var magnumClient *gophercloud.ServiceClient
705+
magnumClient, err = gopenstack.NewContainerInfraV1(client, eoOpts)
706+
if err != nil {
707+
return nil, fmt.Errorf("failed to find Magnum service endpoint in the region %s: %v", cfg.OpenStack.Region, err)
708+
}
709+
magnumClient.Microversion = "latest"
710+
711+
// get cinder service client
712+
var cinderClient *gophercloud.ServiceClient
713+
cinderClient, err = gopenstack.NewBlockStorageV3(client, eoOpts)
714+
if err != nil {
715+
return nil, fmt.Errorf("failed to find Cinder service endpoint in the region %s: %v", cfg.OpenStack.Region, err)
716+
}
717+
718+
p := CloudProvider{
719+
KubeClient: kubeClient,
720+
Nova: novaClient,
721+
Heat: heatClient,
722+
Magnum: magnumClient,
723+
Cinder: cinderClient,
724+
Config: cfg,
725+
}
726+
727+
return p, nil
728+
}

0 commit comments

Comments
 (0)