diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index c03a8bf1d7..54e759e103 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -195,35 +195,6 @@ var ( retriableErrors = []string{accountNotProvisioned, tooManyRequests, shareBeingDeleted, clientThrottled} ) -// DriverOptions defines driver parameters specified in driver deployment -type DriverOptions struct { - NodeID string - DriverName string - CloudConfigSecretName string - CloudConfigSecretNamespace string - CustomUserAgent string - UserAgentSuffix string - AllowEmptyCloudConfig bool - AllowInlineVolumeKeyAccessWithIdentity bool - EnableVHDDiskFeature bool - EnableVolumeMountGroup bool - EnableGetVolumeStats bool - AppendMountErrorHelpLink bool - MountPermissions uint64 - FSGroupChangePolicy string - KubeAPIQPS float64 - KubeAPIBurst int - EnableWindowsHostProcess bool - AppendClosetimeoOption bool - AppendNoShareSockOption bool - AppendNoResvPortOption bool - AppendActimeoOption bool - SkipMatchingTagCacheExpireInMinutes int - VolStatsCacheExpireInMinutes int - PrintVolumeStatsCallLogs bool - SasTokenExpirationMinutes int -} - // Driver implements all interfaces of CSI drivers type Driver struct { csicommon.CSIDriver @@ -280,6 +251,9 @@ type Driver struct { sasTokenExpirationMinutes int // azcopy for provide exec mock for ut azcopy *fileutil.Azcopy + + kubeconfig string + endpoint string } // NewDriver Creates a NewCSIDriver object. Assumes vendor version is equal to driver version & @@ -314,6 +288,8 @@ func NewDriver(options *DriverOptions) *Driver { driver.subnetLockMap = newLockMap() driver.volumeLocks = newVolumeLocks() driver.azcopy = &fileutil.Azcopy{} + driver.kubeconfig = options.KubeConfig + driver.endpoint = options.Endpoint var err error getter := func(key string) (interface{}, error) { return nil, nil } @@ -356,16 +332,21 @@ func NewDriver(options *DriverOptions) *Driver { } // Run driver initialization -func (d *Driver) Run(ctx context.Context, endpoint, kubeconfig string) error { +func (d *Driver) Run(ctx context.Context) error { versionMeta, err := GetVersionYAML(d.Name) if err != nil { klog.Fatalf("%v", err) } klog.Infof("\nDRIVER INFORMATION:\n-------------------\n%s\n\nStreaming logs below:", versionMeta) + if *&d.NodeID == "" { + // nodeid is not needed in controller component + klog.Warning("nodeid is empty") + } + userAgent := GetUserAgent(d.Name, d.customUserAgent, d.userAgentSuffix) klog.V(2).Infof("driver userAgent: %s", userAgent) - d.cloud, err = getCloudProvider(context.Background(), kubeconfig, d.NodeID, d.cloudConfigSecretName, d.cloudConfigSecretNamespace, userAgent, d.allowEmptyCloudConfig, d.enableWindowsHostProcess, d.kubeAPIQPS, d.kubeAPIBurst) + d.cloud, err = getCloudProvider(context.Background(), d.kubeconfig, d.NodeID, d.cloudConfigSecretName, d.cloudConfigSecretNamespace, userAgent, d.allowEmptyCloudConfig, d.enableWindowsHostProcess, d.kubeAPIQPS, d.kubeAPIBurst) if err != nil { klog.Fatalf("failed to get Azure Cloud Provider, error: %v", err) } @@ -420,7 +401,7 @@ func (d *Driver) Run(ctx context.Context, endpoint, kubeconfig string) error { csi.RegisterNodeServer(server, d) d.server = server - listener, err := csicommon.ListenEndpoint(endpoint) + listener, err := csicommon.ListenEndpoint(d.endpoint) if err != nil { klog.Fatalf("failed to listen endpoint: %v", err) } diff --git a/pkg/azurefile/azurefile_options.go b/pkg/azurefile/azurefile_options.go new file mode 100644 index 0000000000..2ab816025d --- /dev/null +++ b/pkg/azurefile/azurefile_options.go @@ -0,0 +1,86 @@ +/* +Copyright 2019 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 azurefile + +import "flag" + +// DriverOptions defines driver parameters specified in driver deployment +type DriverOptions struct { + NodeID string + DriverName string + CloudConfigSecretName string + CloudConfigSecretNamespace string + CustomUserAgent string + UserAgentSuffix string + AllowEmptyCloudConfig bool + AllowInlineVolumeKeyAccessWithIdentity bool + EnableVHDDiskFeature bool + EnableVolumeMountGroup bool + EnableGetVolumeStats bool + AppendMountErrorHelpLink bool + MountPermissions uint64 + FSGroupChangePolicy string + KubeAPIQPS float64 + KubeAPIBurst int + EnableWindowsHostProcess bool + AppendClosetimeoOption bool + AppendNoShareSockOption bool + AppendNoResvPortOption bool + AppendActimeoOption bool + SkipMatchingTagCacheExpireInMinutes int + VolStatsCacheExpireInMinutes int + PrintVolumeStatsCallLogs bool + SasTokenExpirationMinutes int + KubeConfig string + Endpoint string +} + +func (o *DriverOptions) AddFlags() *flag.FlagSet { + if o == nil { + return nil + } + fs := flag.NewFlagSet("", flag.ExitOnError) + fs.StringVar(&o.NodeID, "nodeid", "", "node id") + fs.StringVar(&o.DriverName, "drivername", DefaultDriverName, "name of the driver") + fs.StringVar(&o.CloudConfigSecretName, "cloud-config-secret-name", "azure-cloud-provider", "secret name of cloud config") + fs.StringVar(&o.CloudConfigSecretNamespace, "cloud-config-secret-namespace", "kube-system", "secret namespace of cloud config") + fs.StringVar(&o.CustomUserAgent, "custom-user-agent", "", "custom userAgent") + fs.StringVar(&o.UserAgentSuffix, "user-agent-suffix", "", "userAgent suffix") + fs.BoolVar(&o.AllowEmptyCloudConfig, "allow-empty-cloud-config", true, "allow running driver without cloud config") + fs.BoolVar(&o.AllowInlineVolumeKeyAccessWithIdentity, "allow-inline-volume-key-access-with-identity", false, "allow accessing storage account key using cluster identity for inline volume") + fs.BoolVar(&o.EnableVHDDiskFeature, "enable-vhd", true, "enable VHD disk feature (experimental)") + fs.BoolVar(&o.EnableVolumeMountGroup, "enable-volume-mount-group", true, "indicates whether enabling VOLUME_MOUNT_GROUP") + fs.BoolVar(&o.EnableGetVolumeStats, "enable-get-volume-stats", true, "allow GET_VOLUME_STATS on agent node") + fs.BoolVar(&o.AppendMountErrorHelpLink, "append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") + fs.Uint64Var(&o.MountPermissions, "mount-permissions", 0777, "mounted folder permissions") + fs.StringVar(&o.FSGroupChangePolicy, "fsgroup-change-policy", "", "indicates how the volume's ownership will be changed by the driver, OnRootMismatch is the default value") + fs.Float64Var(&o.KubeAPIQPS, "kube-api-qps", 25.0, "QPS to use while communicating with the kubernetes apiserver.") + fs.IntVar(&o.KubeAPIBurst, "kube-api-burst", 50, "Burst to use while communicating with the kubernetes apiserver.") + fs.BoolVar(&o.EnableWindowsHostProcess, "enable-windows-host-process", false, "enable windows host process") + fs.BoolVar(&o.AppendClosetimeoOption, "append-closetimeo-option", false, "Whether appending closetimeo=0 option to smb mount command") + fs.BoolVar(&o.AppendNoShareSockOption, "append-nosharesock-option", true, "Whether appending nosharesock option to smb mount command") + fs.BoolVar(&o.AppendNoResvPortOption, "append-noresvport-option", true, "Whether appending noresvport option to nfs mount command") + fs.BoolVar(&o.AppendActimeoOption, "append-actimeo-option", true, "Whether appending actimeo=0 option to nfs mount command") + fs.IntVar(&o.SkipMatchingTagCacheExpireInMinutes, "skip-matching-tag-cache-expire-in-minutes", 30, "The cache expire time in minutes for skipMatchingTagCache") + fs.IntVar(&o.VolStatsCacheExpireInMinutes, "vol-stats-cache-expire-in-minutes", 10, "The cache expire time in minutes for volume stats cache") + fs.BoolVar(&o.PrintVolumeStatsCallLogs, "print-volume-stats-call-logs", false, "Whether to print volume statfs call logs with log level 2") + fs.IntVar(&o.SasTokenExpirationMinutes, "sas-token-expiration-minutes", 1440, "sas token expiration minutes during volume cloning") + fs.StringVar(&o.KubeConfig, "kubeconfig", "", "Absolute path to the kubeconfig file. Required only when running out of cluster.") + fs.StringVar(&o.Endpoint, "endpoint", "unix://tmp/csi.sock", "CSI endpoint") + + return fs +} diff --git a/pkg/azurefile/azurefile_options_test.go b/pkg/azurefile/azurefile_options_test.go new file mode 100644 index 0000000000..42425d737d --- /dev/null +++ b/pkg/azurefile/azurefile_options_test.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 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 azurefile + +import ( + "flag" + "reflect" + "testing" +) + +func TestDriverOptions_AddFlags(t *testing.T) { + o := &DriverOptions{} + typeInfo := reflect.TypeOf(*o) + + got := o.AddFlags() + count := 0 + got.VisitAll(func(f *flag.Flag) { + count++ + }) + if count != typeInfo.NumField() { + t.Errorf("DriverOptions.AddFlags() = %v, want %v", count, typeInfo.NumField()) + } +} diff --git a/pkg/azurefile/azurefile_test.go b/pkg/azurefile/azurefile_test.go index 04dff01f65..a0ec4c226e 100644 --- a/pkg/azurefile/azurefile_test.go +++ b/pkg/azurefile/azurefile_test.go @@ -55,6 +55,8 @@ func NewFakeDriver() *Driver { driverOptions := DriverOptions{ NodeID: fakeNodeID, DriverName: DefaultDriverName, + KubeConfig: "", + Endpoint: "tcp://127.0.0.1:0", } driver := NewDriver(&driverOptions) driver.Name = fakeDriverName @@ -97,6 +99,8 @@ func TestNewFakeDriver(t *testing.T) { driverOptions := DriverOptions{ NodeID: fakeNodeID, DriverName: DefaultDriverName, + Endpoint: "tcp://127.0.0.1:0", + KubeConfig: "", } d := NewDriver(&driverOptions) assert.NotNil(t, d) @@ -1058,7 +1062,7 @@ func TestRun(t *testing.T) { time.Sleep(1 * time.Second) cancelFn() }() - if err := d.Run(ctx, "tcp://127.0.0.1:0", ""); err != nil { + if err := d.Run(ctx); err != nil { t.Error(err.Error()) } @@ -1093,7 +1097,7 @@ func TestRun(t *testing.T) { }() d.cloud = &azure.Cloud{} d.NodeID = "" - if err := d.Run(ctx, "tcp://127.0.0.1:0", ""); err != nil { + if err := d.Run(ctx); err != nil { t.Error(err.Error()) } }, diff --git a/pkg/azurefileplugin/main.go b/pkg/azurefileplugin/main.go index 729cfc7234..5f9a0cb3e2 100644 --- a/pkg/azurefileplugin/main.go +++ b/pkg/azurefileplugin/main.go @@ -33,44 +33,21 @@ import ( func init() { klog.InitFlags(nil) + driverOptions.AddFlags().VisitAll(func(f *flag.Flag) { + flag.CommandLine.Var(f.Value, f.Name, f.Usage) + }) } var ( - endpoint = flag.String("endpoint", "unix://tmp/csi.sock", "CSI endpoint") - nodeID = flag.String("nodeid", "", "node id") - version = flag.Bool("version", false, "Print the version and exit.") - metricsAddress = flag.String("metrics-address", "", "export the metrics") - kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file. Required only when running out of cluster.") - driverName = flag.String("drivername", azurefile.DefaultDriverName, "name of the driver") - cloudConfigSecretName = flag.String("cloud-config-secret-name", "azure-cloud-provider", "secret name of cloud config") - cloudConfigSecretNamespace = flag.String("cloud-config-secret-namespace", "kube-system", "secret namespace of cloud config") - customUserAgent = flag.String("custom-user-agent", "", "custom userAgent") - userAgentSuffix = flag.String("user-agent-suffix", "", "userAgent suffix") - allowEmptyCloudConfig = flag.Bool("allow-empty-cloud-config", true, "allow running driver without cloud config") - enableVolumeMountGroup = flag.Bool("enable-volume-mount-group", true, "indicates whether enabling VOLUME_MOUNT_GROUP") - enableGetVolumeStats = flag.Bool("enable-get-volume-stats", true, "allow GET_VOLUME_STATS on agent node") - mountPermissions = flag.Uint64("mount-permissions", 0777, "mounted folder permissions") - allowInlineVolumeKeyAccessWithIdentity = flag.Bool("allow-inline-volume-key-access-with-identity", false, "allow accessing storage account key using cluster identity for inline volume") - fsGroupChangePolicy = flag.String("fsgroup-change-policy", "", "indicates how the volume's ownership will be changed by the driver, OnRootMismatch is the default value") - enableVHDDiskFeature = flag.Bool("enable-vhd", true, "enable VHD disk feature (experimental)") - kubeAPIQPS = flag.Float64("kube-api-qps", 25.0, "QPS to use while communicating with the kubernetes apiserver.") - kubeAPIBurst = flag.Int("kube-api-burst", 50, "Burst to use while communicating with the kubernetes apiserver.") - appendMountErrorHelpLink = flag.Bool("append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") - enableWindowsHostProcess = flag.Bool("enable-windows-host-process", false, "enable windows host process") - appendClosetimeoOption = flag.Bool("append-closetimeo-option", false, "Whether appending closetimeo=0 option to smb mount command") - appendNoShareSockOption = flag.Bool("append-nosharesock-option", true, "Whether appending nosharesock option to smb mount command") - appendNoResvPortOption = flag.Bool("append-noresvport-option", true, "Whether appending noresvport option to nfs mount command") - appendActimeoOption = flag.Bool("append-actimeo-option", true, "Whether appending actimeo=0 option to nfs mount command") - skipMatchingTagCacheExpireInMinutes = flag.Int("skip-matching-tag-cache-expire-in-minutes", 30, "The cache expire time in minutes for skipMatchingTagCache") - volStatsCacheExpireInMinutes = flag.Int("vol-stats-cache-expire-in-minutes", 10, "The cache expire time in minutes for volume stats cache") - printVolumeStatsCallLogs = flag.Bool("print-volume-stats-call-logs", false, "Whether to print volume statfs call logs with log level 2") - sasTokenExpirationMinutes = flag.Int("sas-token-expiration-minutes", 1440, "sas token expiration minutes during volume cloning") + version = flag.Bool("version", false, "Print the version and exit.") + metricsAddress = flag.String("metrics-address", "", "export the metrics") + driverOptions azurefile.DriverOptions ) func main() { flag.Parse() if *version { - info, err := azurefile.GetVersionYAML(*driverName) + info, err := azurefile.GetVersionYAML(driverOptions.DriverName) if err != nil { klog.Fatalln(err) } @@ -78,49 +55,17 @@ func main() { os.Exit(0) } - if *nodeID == "" { - // nodeid is not needed in controller component - klog.Warning("nodeid is empty") - } - exportMetrics() handle() os.Exit(0) } func handle() { - driverOptions := azurefile.DriverOptions{ - NodeID: *nodeID, - DriverName: *driverName, - CloudConfigSecretName: *cloudConfigSecretName, - CloudConfigSecretNamespace: *cloudConfigSecretNamespace, - CustomUserAgent: *customUserAgent, - UserAgentSuffix: *userAgentSuffix, - AllowEmptyCloudConfig: *allowEmptyCloudConfig, - EnableVolumeMountGroup: *enableVolumeMountGroup, - EnableGetVolumeStats: *enableGetVolumeStats, - MountPermissions: *mountPermissions, - AllowInlineVolumeKeyAccessWithIdentity: *allowInlineVolumeKeyAccessWithIdentity, - FSGroupChangePolicy: *fsGroupChangePolicy, - EnableVHDDiskFeature: *enableVHDDiskFeature, - AppendMountErrorHelpLink: *appendMountErrorHelpLink, - KubeAPIQPS: *kubeAPIQPS, - KubeAPIBurst: *kubeAPIBurst, - EnableWindowsHostProcess: *enableWindowsHostProcess, - AppendClosetimeoOption: *appendClosetimeoOption, - AppendNoShareSockOption: *appendNoShareSockOption, - AppendNoResvPortOption: *appendNoResvPortOption, - AppendActimeoOption: *appendActimeoOption, - SkipMatchingTagCacheExpireInMinutes: *skipMatchingTagCacheExpireInMinutes, - VolStatsCacheExpireInMinutes: *volStatsCacheExpireInMinutes, - PrintVolumeStatsCallLogs: *printVolumeStatsCallLogs, - SasTokenExpirationMinutes: *sasTokenExpirationMinutes, - } driver := azurefile.NewDriver(&driverOptions) if driver == nil { klog.Fatalln("Failed to initialize azurefile CSI Driver") } - if err := driver.Run(context.Background(), *endpoint, *kubeconfig); err != nil { + if err := driver.Run(context.Background()); err != nil { klog.Fatalln(err) } } diff --git a/test/e2e/suite_test.go b/test/e2e/suite_test.go index 5eec4d781b..30a808a816 100644 --- a/test/e2e/suite_test.go +++ b/test/e2e/suite_test.go @@ -146,11 +146,13 @@ var _ = ginkgo.BeforeSuite(func(ctx ginkgo.SpecContext) { driverOptions := azurefile.DriverOptions{ NodeID: os.Getenv("nodeid"), DriverName: azurefile.DefaultDriverName, + Endpoint: fmt.Sprintf("unix:///tmp/csi-%s.sock", uuid.NewUUID().String()), + KubeConfig: kubeconfig, } azurefileDriver = azurefile.NewDriver(&driverOptions) go func() { os.Setenv("AZURE_CREDENTIAL_FILE", credentials.TempAzureCredentialFilePath) - err := azurefileDriver.Run(context.Background(), fmt.Sprintf("unix:///tmp/csi-%s.sock", uuid.NewUUID().String()), kubeconfig) + err := azurefileDriver.Run(context.Background()) gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() }