From f3e91eef62299fbe1a806698784c2bfe005527a1 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 20 Dec 2023 14:49:08 +0530 Subject: [PATCH] Enable lll, nakedret, asciicheck, depguard, dogsled, dupl, exportloopref golang linters (#2238) * Enable gocyclo linter * Enable gocritic linter * Fix typo for linters-settings, fix gocyclo lint failures * Add lll linter * Add nakedret linter * Enable dupl linter * Enable exportloopref linter * Update new lint misses, add TODO for lint disables * Apply linter to new changes * Fix merge issues * Add explanation for ignoring dupl linter * Address review comments * Address review comments - move args * Temporarily disable depguard linter, lint fix --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .golangci.yml | 13 +++++ pkg/app/cassandra.go | 13 +++-- pkg/app/cockroachdb.go | 2 +- pkg/app/couchbase.go | 2 +- pkg/app/mariadb.go | 7 ++- pkg/app/mongodb-deploymentconfig.go | 4 +- pkg/app/mongodb.go | 4 +- pkg/app/mysql.go | 6 ++- pkg/aws/rds/rds.go | 30 +++++++++-- pkg/blockstorage/vmware/vmware.go | 8 ++- pkg/chronicle/chronicle_push.go | 16 +++--- pkg/function/export_rds_snapshot_location.go | 30 ++++++++++- pkg/function/restore_rds_snapshot.go | 29 +++++++++- pkg/function/scale_test.go | 13 ++--- pkg/function/scale_workload.go | 53 +++++++++++-------- pkg/kanctl/actionset.go | 3 +- pkg/kopia/command/parse_command_output.go | 3 +- pkg/kube/snapshot/snapshot_beta.go | 13 ++++- pkg/kube/snapshot/snapshot_test.go | 3 +- pkg/kube/volume/volume.go | 22 +++++++- pkg/testutil/testutil.go | 2 +- .../repositoryserver_handler.go | 1 + 22 files changed, 212 insertions(+), 65 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 90bc437aba..571f30eb08 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -14,6 +14,13 @@ linters: - unparam - gocyclo - gocritic + - lll + - nakedret + - asciicheck + # - depguard # Disabling temporarily due to https://github.com/golangci/golangci-lint/issues/3906 + - dogsled + - dupl + - exportloopref run: timeout: 10m # golangci-lint run's timeout. @@ -27,6 +34,8 @@ issues: linters: - errcheck # Errors may be ignored in tests. - unparam # Tests might have unused function parameters. + - lll + - dupl - text: "`ctx` is unused" # Context might not be in use in places, but for consistency, we pass it. linters: @@ -35,3 +44,7 @@ issues: linters-settings: gocyclo: min-complexity: 20 + lll: + line-length: 240 + nakedret: + max-func-lines: 2 diff --git a/pkg/app/cassandra.go b/pkg/app/cassandra.go index d5b9c071e8..46d9c5d24b 100644 --- a/pkg/app/cassandra.go +++ b/pkg/app/cassandra.go @@ -158,7 +158,9 @@ func (cas *CassandraInstance) Ping(ctx context.Context) error { // Insert is used to insert the records into the database func (cas *CassandraInstance) Insert(ctx context.Context) error { log.Print("Inserting records into the database.", field.M{"app": cas.name}) - insertCMD := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"insert into restaurants.guests (id, firstname, lastname, birthday) values (uuid(), 'Tom', 'Singh', '2015-02-18');\" --request-timeout=%s", cqlTimeout)} + insertCMD := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"insert into "+ + "restaurants.guests (id, firstname, lastname, birthday) values (uuid(), 'Tom', 'Singh', "+ + "'2015-02-18');\" --request-timeout=%s", cqlTimeout)} _, stderr, err := cas.execCommand(ctx, insertCMD) if err != nil { return errors.Wrapf(err, "Error %s inserting records into the database.", stderr) @@ -191,7 +193,8 @@ func (cas *CassandraInstance) Count(ctx context.Context) (int, error) { // Reset is used to reset or imitate disaster, in the database func (cas *CassandraInstance) Reset(ctx context.Context) error { // delete keyspace and table if they already exist - delRes := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e 'drop table if exists restaurants.guests; drop keyspace if exists restaurants;' --request-timeout=%s", cqlTimeout)} + delRes := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e "+ + "'drop table if exists restaurants.guests; drop keyspace if exists restaurants;' --request-timeout=%s", cqlTimeout)} _, stderr, err := cas.execCommand(ctx, delRes) if err != nil { return errors.Wrapf(err, "Error %s, deleting resources while reseting application.", stderr) @@ -202,14 +205,16 @@ func (cas *CassandraInstance) Reset(ctx context.Context) error { // Initialize is used to initialize the database or create schema func (cas *CassandraInstance) Initialize(ctx context.Context) error { // create the keyspace - createKS := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"create keyspace restaurants with replication = {'class':'SimpleStrategy', 'replication_factor': 3};\" --request-timeout=%s", cqlTimeout)} + createKS := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"create keyspace "+ + "restaurants with replication = {'class':'SimpleStrategy', 'replication_factor': 3};\" --request-timeout=%s", cqlTimeout)} _, stderr, err := cas.execCommand(ctx, createKS) if err != nil { return errors.Wrapf(err, "Error %s while creating the keyspace for application.", stderr) } // create the table - createTab := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"create table restaurants.guests (id UUID primary key, firstname text, lastname text, birthday timestamp);\" --request-timeout=%s", cqlTimeout)} + createTab := []string{"sh", "-c", fmt.Sprintf("cqlsh -u cassandra -p $CASSANDRA_PASSWORD -e \"create table "+ + "restaurants.guests (id UUID primary key, firstname text, lastname text, birthday timestamp);\" --request-timeout=%s", cqlTimeout)} _, stderr, err = cas.execCommand(ctx, createTab) if err != nil { return errors.Wrapf(err, "Error %s creating table.", stderr) diff --git a/pkg/app/cockroachdb.go b/pkg/app/cockroachdb.go index a07ff5927d..66fdec7496 100644 --- a/pkg/app/cockroachdb.go +++ b/pkg/app/cockroachdb.go @@ -57,7 +57,7 @@ func (c *CockroachDB) Init(context.Context) error { return err } -func (c *CockroachDB) Install(ctx context.Context, namespace string) error { +func (c *CockroachDB) Install(ctx context.Context, namespace string) error { //nolint:dupl // Not a duplicate, common code already extracted log.Info().Print("Installing cockroachdb cluster helm chart.", field.M{"app": c.name}) c.namespace = namespace diff --git a/pkg/app/couchbase.go b/pkg/app/couchbase.go index 7f660fbdaa..0f0ed3d16a 100644 --- a/pkg/app/couchbase.go +++ b/pkg/app/couchbase.go @@ -80,7 +80,7 @@ func (cb *CouchbaseDB) Init(ctx context.Context) error { return err } -func (cb *CouchbaseDB) Install(ctx context.Context, ns string) error { +func (cb *CouchbaseDB) Install(ctx context.Context, ns string) error { //nolint:dupl // Not a duplicate, common code already extracted log.Info().Print("Installing couchbase operator and cluster helm chart.", field.M{"app": cb.name}) cb.namespace = ns diff --git a/pkg/app/mariadb.go b/pkg/app/mariadb.go index 3d4a4c316f..d76a6accbc 100644 --- a/pkg/app/mariadb.go +++ b/pkg/app/mariadb.go @@ -74,7 +74,7 @@ func (m *MariaDB) Init(context.Context) error { return nil } -func (m *MariaDB) Install(ctx context.Context, namespace string) error { +func (m *MariaDB) Install(ctx context.Context, namespace string) error { //nolint:dupl // Not a duplicate, common code already extracted m.namespace = namespace cli, err := helm.NewCliClient() if err != nil { @@ -204,7 +204,10 @@ func (m *MariaDB) Reset(ctx context.Context) error { func (m *MariaDB) Initialize(ctx context.Context) error { // create the database and a pets table - createTableCMD := []string{"sh", "-c", "mysql -u root --password=$MARIADB_ROOT_PASSWORD -e 'create database testdb; use testdb; CREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);'"} + createTableCMD := []string{"sh", "-c", "mysql -u root --password=$MARIADB_ROOT_PASSWORD " + + "-e 'create database testdb; use testdb; " + + "CREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), " + + "birth DATE, death DATE);'"} _, stderr, err := m.execCommand(ctx, createTableCMD) if err != nil { return errors.Wrapf(err, "Error while creating the maria table: %s", stderr) diff --git a/pkg/app/mongodb-deploymentconfig.go b/pkg/app/mongodb-deploymentconfig.go index 84e901636e..043508028d 100644 --- a/pkg/app/mongodb-deploymentconfig.go +++ b/pkg/app/mongodb-deploymentconfig.go @@ -134,7 +134,9 @@ func (mongo *MongoDBDepConfig) Ping(ctx context.Context) error { func (mongo *MongoDBDepConfig) Insert(ctx context.Context) error { log.Print("Inserting documents into collection.", field.M{"app": mongo.name}) - insertCMD := []string{"bash", "-c", fmt.Sprintf("mongo admin --authenticationDatabase admin -u %s -p $MONGODB_ADMIN_PASSWORD --quiet --eval \"db.restaurants.insert({'_id': '%s','name' : 'Tom', 'cuisine' : 'Hawaiian', 'id' : '8675309'})\"", mongo.user, uuid.New())} + insertCMD := []string{"bash", "-c", fmt.Sprintf("mongo admin --authenticationDatabase admin -u %s -p "+ + "$MONGODB_ADMIN_PASSWORD --quiet --eval \"db.restaurants.insert({'_id': '%s','name' : 'Tom', "+ + "'cuisine' : 'Hawaiian', 'id' : '8675309'})\"", mongo.user, uuid.New())} _, stderr, err := mongo.execCommand(ctx, insertCMD) if err != nil { return errors.Wrapf(err, "Error %s while inserting data data into mongodb collection.", stderr) diff --git a/pkg/app/mongodb.go b/pkg/app/mongodb.go index d284896fca..d722f108d5 100644 --- a/pkg/app/mongodb.go +++ b/pkg/app/mongodb.go @@ -180,7 +180,9 @@ func (mongo *MongoDB) Ping(ctx context.Context) error { func (mongo *MongoDB) Insert(ctx context.Context) error { log.Print("Inserting documents into collection.", field.M{"app": mongo.name}) - insertCMD := []string{"sh", "-c", fmt.Sprintf("mongosh admin --authenticationDatabase admin -u %s -p $MONGODB_ROOT_PASSWORD --quiet --eval \"db.restaurants.insertOne({'_id': '%s','name' : 'Tom', 'cuisine' : 'Hawaiian', 'id' : '8675309'})\"", mongo.username, uuid.New())} + insertCMD := []string{"sh", "-c", fmt.Sprintf("mongosh admin --authenticationDatabase admin -u %s -p "+ + "$MONGODB_ROOT_PASSWORD --quiet --eval \"db.restaurants.insertOne({'_id': '%s','name' : 'Tom', "+ + "'cuisine' : 'Hawaiian', 'id' : '8675309'})\"", mongo.username, uuid.New())} _, stderr, err := mongo.execCommand(ctx, insertCMD) if err != nil { return errors.Wrapf(err, "Error %s while inserting data data into mongodb collection.", stderr) diff --git a/pkg/app/mysql.go b/pkg/app/mysql.go index d113cac06b..70dee51694 100644 --- a/pkg/app/mysql.go +++ b/pkg/app/mysql.go @@ -83,7 +83,7 @@ func (mdb *MysqlDB) Init(ctx context.Context) error { return nil } -func (mdb *MysqlDB) Install(ctx context.Context, namespace string) error { +func (mdb *MysqlDB) Install(ctx context.Context, namespace string) error { //nolint:dupl // Not a duplicate, common code already extracted mdb.namespace = namespace cli, err := helm.NewCliClient() if err != nil { @@ -215,7 +215,9 @@ func (mdb *MysqlDB) Reset(ctx context.Context) error { // Initialize is used to initialize the database or create schema func (mdb *MysqlDB) Initialize(ctx context.Context) error { // create the database and a pets table - createTableCMD := []string{"sh", "-c", "mysql -u root --password=$MYSQL_ROOT_PASSWORD -e 'create database testdb; use testdb; CREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);'"} + createTableCMD := []string{"sh", "-c", "mysql -u root --password=$MYSQL_ROOT_PASSWORD -e " + + "'create database testdb; use testdb; CREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), " + + "species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);'"} _, stderr, err := mdb.execCommand(ctx, createTableCMD) if err != nil { return errors.Wrapf(err, "Error while creating the mysql table: %s", stderr) diff --git a/pkg/aws/rds/rds.go b/pkg/aws/rds/rds.go index f98314e5db..dd5249d6e3 100644 --- a/pkg/aws/rds/rds.go +++ b/pkg/aws/rds/rds.go @@ -48,7 +48,19 @@ func NewClient(ctx context.Context, awsConfig *aws.Config, region string) (*RDS, } // CreateDBInstanceWithContext -func (r RDS) CreateDBInstance(ctx context.Context, storage *int64, instanceClass, instanceID, engine, username, password string, sgIDs []string, publicAccess *bool, restoredClusterID *string, dbSubnetGroup string) (*rds.CreateDBInstanceOutput, error) { +func (r RDS) CreateDBInstance( + ctx context.Context, + storage *int64, + instanceClass, + instanceID, + engine, + username, + password string, + sgIDs []string, + publicAccess *bool, + restoredClusterID *string, + dbSubnetGroup string, +) (*rds.CreateDBInstanceOutput, error) { dbi := &rds.CreateDBInstanceInput{ DBInstanceClass: &instanceClass, DBInstanceIdentifier: &instanceID, @@ -74,7 +86,18 @@ func (r RDS) CreateDBInstance(ctx context.Context, storage *int64, instanceClass return r.CreateDBInstanceWithContext(ctx, dbi) } -func (r RDS) CreateDBCluster(ctx context.Context, storage int64, instanceClass, instanceID, dbSubnetGroup, engine, dbName, username, password string, sgIDs []string) (*rds.CreateDBClusterOutput, error) { +func (r RDS) CreateDBCluster( + ctx context.Context, + storage int64, + instanceClass, + instanceID, + dbSubnetGroup, + engine, + dbName, + username, + password string, + sgIDs []string, +) (*rds.CreateDBClusterOutput, error) { dbi := &rds.CreateDBClusterInput{ DBClusterIdentifier: &instanceID, DatabaseName: &dbName, @@ -319,7 +342,8 @@ func (r RDS) RestoreDBClusterFromDBSnapshot(ctx context.Context, instanceID, dbS func convertSGIDs(sgIDs []string) []*string { var refSGIDs []*string for _, ID := range sgIDs { - refSGIDs = append(refSGIDs, &ID) + idPtr := &ID + refSGIDs = append(refSGIDs, idPtr) } return refSGIDs } diff --git a/pkg/blockstorage/vmware/vmware.go b/pkg/blockstorage/vmware/vmware.go index 51013a7d24..8cc2c23954 100644 --- a/pkg/blockstorage/vmware/vmware.go +++ b/pkg/blockstorage/vmware/vmware.go @@ -357,10 +357,14 @@ func (p *FcdProvider) SnapshotDelete(ctx context.Context, snapshot *blockstorage if soap.IsVimFault(lerr) { switch soap.ToVimFault(lerr).(type) { case *types.InvalidArgument: - log.Error().WithError(lerr).Print("Disk doesn't have given snapshot due to the snapshot stamp being removed in the previous DeleteSnapshot operation which failed with an InvalidState fault. It will be resolved by the next snapshot operation on the same VM. Will NOT retry") + log.Error().WithError(lerr).Print("Disk doesn't have given snapshot due to the snapshot stamp being " + + "removed in the previous DeleteSnapshot operation which failed with an InvalidState fault. It " + + "will be resolved by the next snapshot operation on the same VM. Will NOT retry") return true, nil case *types.NotFound: - log.Error().WithError(lerr).Print("There is a temporary catalog mismatch due to a race condition with one another concurrent DeleteSnapshot operation. It will be resolved by the next consolidateDisks operation on the same VM. Will NOT retry") + log.Error().WithError(lerr).Print("There is a temporary catalog mismatch due to a race condition with " + + "one another concurrent DeleteSnapshot operation. It will be resolved by the next " + + "consolidateDisks operation on the same VM. Will NOT retry") return true, nil case *types.InvalidState: log.Error().WithError(lerr).Print("There is some operation, other than this DeleteSnapshot invocation, on the same VM still being protected by its VM state. Will retry") diff --git a/pkg/chronicle/chronicle_push.go b/pkg/chronicle/chronicle_push.go index 3dd8d2de97..be7c4df5fe 100644 --- a/pkg/chronicle/chronicle_push.go +++ b/pkg/chronicle/chronicle_push.go @@ -142,23 +142,21 @@ func readArtifactPathFile(path string) (string, error) { return t, errors.Wrap(err, "Could not read artifact path file") } -func readProfile(path string) (p param.Profile, ok bool, err error) { +func readProfile(path string) (param.Profile, bool, error) { var buf []byte - buf, err = os.ReadFile(path) + buf, err := os.ReadFile(path) + var p param.Profile switch { case os.IsNotExist(err): err = nil - return + return p, false, err case err != nil: - err = errors.Wrap(err, "Failed to read profile") - return + return p, false, errors.Wrap(err, "Failed to read profile") } if err = json.Unmarshal(buf, &p); err != nil { - err = errors.Wrap(err, "Failed to unmarshal profile") - } else { - ok = true + return p, false, errors.Wrap(err, "Failed to unmarshal profile") } - return + return p, true, nil } func writeProfile(path string, p param.Profile) error { diff --git a/pkg/function/export_rds_snapshot_location.go b/pkg/function/export_rds_snapshot_location.go index 38f5a6d9a4..a11603fa38 100644 --- a/pkg/function/export_rds_snapshot_location.go +++ b/pkg/function/export_rds_snapshot_location.go @@ -81,7 +81,20 @@ func (*exportRDSSnapshotToLocationFunc) Name() string { return ExportRDSSnapshotToLocFuncName } -func exportRDSSnapshotToLoc(ctx context.Context, namespace, instanceID, snapshotID, username, password string, databases []string, dbSubnetGroup, backupPrefix string, dbEngine RDSDBEngine, sgIDs []string, profile *param.Profile) (map[string]interface{}, error) { +func exportRDSSnapshotToLoc( + ctx context.Context, + namespace, + instanceID, + snapshotID, + username, + password string, + databases []string, + dbSubnetGroup, + backupPrefix string, + dbEngine RDSDBEngine, + sgIDs []string, + profile *param.Profile, +) (map[string]interface{}, error) { // Validate profilextractDumpFromDBe if err := ValidateProfile(profile); err != nil { return nil, errors.Wrap(err, "Profile Validation failed") @@ -234,7 +247,20 @@ func (d *exportRDSSnapshotToLocationFunc) ExecutionProgress() (crv1alpha1.PhaseP }, nil } -func execDumpCommand(ctx context.Context, dbEngine RDSDBEngine, action RDSAction, namespace, dbEndpoint, username, password string, databases []string, backupPrefix, backupID string, profile *param.Profile, dbEngineVersion string) (map[string]interface{}, error) { +func execDumpCommand( + ctx context.Context, + dbEngine RDSDBEngine, + action RDSAction, + namespace, + dbEndpoint, + username, + password string, + databases []string, + backupPrefix, + backupID string, + profile *param.Profile, + dbEngineVersion string, +) (map[string]interface{}, error) { // Trim "\n" from creds username = strings.TrimSpace(username) password = strings.TrimSpace(password) diff --git a/pkg/function/restore_rds_snapshot.go b/pkg/function/restore_rds_snapshot.go index bec1e357eb..c52099b17b 100644 --- a/pkg/function/restore_rds_snapshot.go +++ b/pkg/function/restore_rds_snapshot.go @@ -164,7 +164,20 @@ func (r *restoreRDSSnapshotFunc) ExecutionProgress() (crv1alpha1.PhaseProgress, }, nil } -func restoreRDSSnapshot(ctx context.Context, namespace, instanceID, subnetGroup, snapshotID, backupArtifactPrefix, backupID, username, password string, dbEngine RDSDBEngine, sgIDs []string, profile *param.Profile) (map[string]interface{}, error) { +func restoreRDSSnapshot( + ctx context.Context, + namespace, + instanceID, + subnetGroup, + snapshotID, + backupArtifactPrefix, + backupID, + username, + password string, + dbEngine RDSDBEngine, + sgIDs []string, + profile *param.Profile, +) (map[string]interface{}, error) { // Validate profile if err := ValidateProfile(profile); err != nil { return nil, errors.Wrap(err, "Error validating profile") @@ -324,7 +337,19 @@ func restoreAuroraFromSnapshot(ctx context.Context, rdsCli *rds.RDS, instanceID, log.WithContext(ctx).Print("Creating DB instance in the cluster") // After Aurora cluster is created, we will have to explictly create the DB instance - dbInsOp, err := rdsCli.CreateDBInstance(ctx, nil, defaultAuroraInstanceClass, fmt.Sprintf("%s-%s", *op.DBCluster.DBClusterIdentifier, restoredAuroraInstanceSuffix), dbEngine, "", "", nil, nil, aws.String(*op.DBCluster.DBClusterIdentifier), subnetGroup) + dbInsOp, err := rdsCli.CreateDBInstance( + ctx, + nil, + defaultAuroraInstanceClass, + fmt.Sprintf("%s-%s", *op.DBCluster.DBClusterIdentifier, restoredAuroraInstanceSuffix), + dbEngine, + "", + "", + nil, + nil, + aws.String(*op.DBCluster.DBClusterIdentifier), + subnetGroup, + ) if err != nil { return errors.Wrap(err, "Error while creating Aurora DB instance in the cluster.") } diff --git a/pkg/function/scale_test.go b/pkg/function/scale_test.go index 50b668480a..aef6f23821 100644 --- a/pkg/function/scale_test.go +++ b/pkg/function/scale_test.go @@ -315,15 +315,16 @@ func (s *ScaleSuite) TestGetArgs(c *C) { check: IsNil, }, } { - namespace, kind, name, replicas, waitForReady, err := getArgs(tc.tp, tc.args) + s := scaleWorkloadFunc{} + err := s.setArgs(tc.tp, tc.args) c.Assert(err, tc.check) if err != nil { continue } - c.Assert(namespace, Equals, tc.wantNamespace) - c.Assert(name, Equals, tc.wantName) - c.Assert(kind, Equals, tc.wantKind) - c.Assert(replicas, Equals, tc.wantReplicas) - c.Assert(waitForReady, Equals, tc.wantWaitForReady) + c.Assert(s.namespace, Equals, tc.wantNamespace) + c.Assert(s.name, Equals, tc.wantName) + c.Assert(s.kind, Equals, tc.wantKind) + c.Assert(s.replicas, Equals, tc.wantReplicas) + c.Assert(s.waitForReady, Equals, tc.wantWaitForReady) } } diff --git a/pkg/function/scale_workload.go b/pkg/function/scale_workload.go index 9d6de8ec0e..819e771759 100644 --- a/pkg/function/scale_workload.go +++ b/pkg/function/scale_workload.go @@ -52,6 +52,11 @@ var ( type scaleWorkloadFunc struct { progressPercent string + namespace string + kind string + name string + replicas int32 + waitForReady bool } func (*scaleWorkloadFunc) Name() string { @@ -63,9 +68,7 @@ func (s *scaleWorkloadFunc) Exec(ctx context.Context, tp param.TemplateParams, a s.progressPercent = progress.StartedPercent defer func() { s.progressPercent = progress.CompletedPercent }() - var namespace, kind, name string - var replicas int32 - namespace, kind, name, replicas, waitForReady, err := getArgs(tp, args) + err := s.setArgs(tp, args) if err != nil { return nil, err } @@ -78,19 +81,19 @@ func (s *scaleWorkloadFunc) Exec(ctx context.Context, tp param.TemplateParams, a if err != nil { return nil, errors.Wrapf(err, "Failed to create Kubernetes client") } - switch strings.ToLower(kind) { + switch strings.ToLower(s.kind) { case param.StatefulSetKind: - return nil, kube.ScaleStatefulSet(ctx, cli, namespace, name, replicas, waitForReady) + return nil, kube.ScaleStatefulSet(ctx, cli, s.namespace, s.name, s.replicas, s.waitForReady) case param.DeploymentKind: - return nil, kube.ScaleDeployment(ctx, cli, namespace, name, replicas, waitForReady) + return nil, kube.ScaleDeployment(ctx, cli, s.namespace, s.name, s.replicas, s.waitForReady) case param.DeploymentConfigKind: osCli, err := osversioned.NewForConfig(cfg) if err != nil { return nil, errors.Wrapf(err, "Failed to create OpenShift client") } - return nil, kube.ScaleDeploymentConfig(ctx, cli, osCli, namespace, name, replicas, waitForReady) + return nil, kube.ScaleDeploymentConfig(ctx, cli, osCli, s.namespace, s.name, s.replicas, s.waitForReady) } - return nil, errors.New("Workload type not supported " + kind) + return nil, errors.New("Workload type not supported " + s.kind) } func (*scaleWorkloadFunc) RequiredArgs() []string { @@ -115,14 +118,17 @@ func (s *scaleWorkloadFunc) ExecutionProgress() (crv1alpha1.PhaseProgress, error }, nil } -func getArgs(tp param.TemplateParams, args map[string]interface{}) (namespace, kind, name string, replicas int32, waitForReady bool, err error) { +func (s *scaleWorkloadFunc) setArgs(tp param.TemplateParams, args map[string]interface{}) error { var rep interface{} - waitForReady = true - err = Arg(args, ScaleWorkloadReplicas, &rep) + waitForReady := true + err := Arg(args, ScaleWorkloadReplicas, &rep) if err != nil { - return + return err } + var namespace, kind, name string + var replicas int32 + switch val := rep.(type) { case int: replicas = int32(val) @@ -133,13 +139,11 @@ func getArgs(tp param.TemplateParams, args map[string]interface{}) (namespace, k case string: var v int if v, err = strconv.Atoi(val); err != nil { - err = errors.Wrapf(err, "Cannot convert %s to int ", val) - return + return errors.Wrapf(err, "Cannot convert %s to int ", val) } replicas = int32(v) default: - err = errors.Errorf("Invalid arg type %T for Arg %s ", rep, ScaleWorkloadReplicas) - return + return errors.Errorf("Invalid arg type %T for Arg %s ", rep, ScaleWorkloadReplicas) } // Populate default values for optional arguments from template parameters switch { @@ -157,25 +161,30 @@ func getArgs(tp param.TemplateParams, args map[string]interface{}) (namespace, k namespace = tp.DeploymentConfig.Namespace default: if !ArgExists(args, ScaleWorkloadNamespaceArg) || !ArgExists(args, ScaleWorkloadNameArg) || !ArgExists(args, ScaleWorkloadKindArg) { - return namespace, kind, name, replicas, waitForReady, errors.New("Workload information not available via defaults or namespace/name/kind parameters") + return errors.New("Workload information not available via defaults or namespace/name/kind parameters") } } err = OptArg(args, ScaleWorkloadNamespaceArg, &namespace, namespace) if err != nil { - return + return err } err = OptArg(args, ScaleWorkloadNameArg, &name, name) if err != nil { - return + return err } err = OptArg(args, ScaleWorkloadKindArg, &kind, kind) if err != nil { - return + return err } err = OptArg(args, ScaleWorkloadWaitArg, &waitForReady, waitForReady) if err != nil { - return + return err } - return + s.kind = kind + s.name = name + s.namespace = namespace + s.replicas = replicas + s.waitForReady = waitForReady + return nil } diff --git a/pkg/kanctl/actionset.go b/pkg/kanctl/actionset.go index 39b8da6f2a..65a4134abb 100644 --- a/pkg/kanctl/actionset.go +++ b/pkg/kanctl/actionset.go @@ -103,7 +103,8 @@ func newActionSetCmd() *cobra.Command { cmd.Flags().StringSliceP(pvcFlagName, "v", []string{}, "pvc for the action set, comma separated namespace/name pairs (eg: --pvc namespace1/name1,namespace2/name2)") cmd.Flags().StringSliceP(secretsFlagName, "s", []string{}, "secrets for the action set, comma separated ref=namespace/name pairs (eg: --secrets ref1=namespace1/name1,ref2=namespace2/name2)") cmd.Flags().StringSliceP(statefulSetFlagName, "t", []string{}, "statefulset for the action set, comma separated namespace/name pairs (eg: --statefulset namespace1/name1,namespace2/name2)") - cmd.Flags().StringSliceP(deploymentConfigFlagName, "D", []string{}, "deploymentconfig for action set, comma separated namespace/name pairs (e.g. --deploymentconfig namespace1/name1,namespace2/name2). Will ideally be used on openshift clusters.") + cmd.Flags().StringSliceP(deploymentConfigFlagName, "D", []string{}, "deploymentconfig for action set, comma separated namespace/name pairs "+ + "(e.g. --deploymentconfig namespace1/name1,namespace2/name2). Will ideally be used on openshift clusters.") cmd.Flags().StringP(selectorFlagName, "l", "", "k8s selector for objects") cmd.Flags().StringP(selectorKindFlag, "k", "all", "resource kind to apply selector on. Used along with the selector specified using --selector/-l") cmd.Flags().String(selectorNamespaceFlag, "", "namespace to apply selector on. Used along with the selector specified using --selector/-l") diff --git a/pkg/kopia/command/parse_command_output.go b/pkg/kopia/command/parse_command_output.go index ae282f0bee..0f510abd0d 100644 --- a/pkg/kopia/command/parse_command_output.go +++ b/pkg/kopia/command/parse_command_output.go @@ -37,6 +37,7 @@ const ( typeKey = "type" snapshotValue = "snapshot" + //nolint:lll snapshotCreateOutputRegEx = `(?P[|/\-\\\*]).+[^\d](?P\d+) hashed \((?P[^\)]+)\), (?P\d+) cached \((?P[^\)]+)\), uploaded (?P[^\)]+), (?:estimating...|estimated (?P[^\)]+) \((?P[^\)]+)\%\).+)` extractSnapshotIDRegEx = `Created snapshot with root ([^\s]+) and ID ([^\s]+).*$` repoTotalSizeFromBlobStatsRegEx = `Total: (\d+)$` @@ -57,7 +58,7 @@ func SnapshotIDsFromSnapshot(output string) (snapID, rootID string, err error) { if len(match) > 0 && len(match[0]) > 2 { snapID = match[0][2] rootID = match[0][1] - return + return snapID, rootID, nil } } return snapID, rootID, errors.New("Failed to find Root ID from output") diff --git a/pkg/kube/snapshot/snapshot_beta.go b/pkg/kube/snapshot/snapshot_beta.go index 2cbd35478d..a4426d4798 100644 --- a/pkg/kube/snapshot/snapshot_beta.go +++ b/pkg/kube/snapshot/snapshot_beta.go @@ -82,7 +82,18 @@ func (sna *SnapshotBeta) Create(ctx context.Context, name, namespace, volumeName return createSnapshot(ctx, sna.dynCli, sna.kubeCli, v1beta1.VolSnapGVR, name, namespace, volumeName, snapshotClass, waitForReady, labels) } -func createSnapshot(ctx context.Context, dynCli dynamic.Interface, kubeCli kubernetes.Interface, snapGVR schema.GroupVersionResource, name, namespace, volumeName string, snapshotClass *string, waitForReady bool, labels map[string]string) error { +func createSnapshot( + ctx context.Context, + dynCli dynamic.Interface, + kubeCli kubernetes.Interface, + snapGVR schema.GroupVersionResource, + name, + namespace, + volumeName string, + snapshotClass *string, + waitForReady bool, + labels map[string]string, +) error { if _, err := kubeCli.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, volumeName, metav1.GetOptions{}); err != nil { if k8errors.IsNotFound(err) { return errors.Errorf("Failed to find PVC %s, Namespace %s", volumeName, namespace) diff --git a/pkg/kube/snapshot/snapshot_test.go b/pkg/kube/snapshot/snapshot_test.go index 72e48fc848..68f369096f 100644 --- a/pkg/kube/snapshot/snapshot_test.go +++ b/pkg/kube/snapshot/snapshot_test.go @@ -790,7 +790,8 @@ func (s *SnapshotTestSuite) TestNewSnapshotter(c *C) { check: IsNil, }, } { - fakeCli.Resources = []*metav1.APIResourceList{&tc.apiResources} + apiRes := tc.apiResources + fakeCli.Resources = []*metav1.APIResourceList{&apiRes} ss, err := snapshot.NewSnapshotter(fakeCli, nil) c.Assert(err, tc.check) c.Assert(reflect.TypeOf(ss).String(), Equals, tc.expected) diff --git a/pkg/kube/volume/volume.go b/pkg/kube/volume/volume.go index 08dc56fdd8..29d07e5b16 100644 --- a/pkg/kube/volume/volume.go +++ b/pkg/kube/volume/volume.go @@ -49,7 +49,17 @@ const ( // An empty 'targetVolID' indicates the caller would like the PV to be dynamically provisioned // An empty 'name' indicates the caller would like the name to be auto-generated // An error indicating that the PVC already exists is ignored (for idempotency) -func CreatePVC(ctx context.Context, kubeCli kubernetes.Interface, ns string, name string, sizeInBytes int64, targetVolID string, annotations map[string]string, accessmodes []v1.PersistentVolumeAccessMode, volumemode *v1.PersistentVolumeMode) (string, error) { +func CreatePVC( + ctx context.Context, + kubeCli kubernetes.Interface, + ns, + name string, + sizeInBytes int64, + targetVolID string, + annotations map[string]string, + accessmodes []v1.PersistentVolumeAccessMode, + volumemode *v1.PersistentVolumeMode, +) (string, error) { sizeFmt := fmt.Sprintf("%d", sizeInBytes) size, err := resource.ParseQuantity(sizeFmt) emptyStorageClass := "" @@ -219,7 +229,15 @@ func getPVCRestoreSize(ctx context.Context, args *CreatePVCFromSnapshotArgs) (*r // CreatePV creates a PersistentVolume and returns its name // For retry idempotency, checks whether PV associated with volume already exists -func CreatePV(ctx context.Context, kubeCli kubernetes.Interface, vol *blockstorage.Volume, volType blockstorage.Type, annotations map[string]string, accessmodes []v1.PersistentVolumeAccessMode, volumemode *v1.PersistentVolumeMode) (string, error) { +func CreatePV( + ctx context.Context, + kubeCli kubernetes.Interface, + vol *blockstorage.Volume, + volType blockstorage.Type, + annotations map[string]string, + accessmodes []v1.PersistentVolumeAccessMode, + volumemode *v1.PersistentVolumeMode, +) (string, error) { sizeFmt := fmt.Sprintf("%d", vol.SizeInBytes) size, err := resource.ParseQuantity(sizeFmt) if err != nil { diff --git a/pkg/testutil/testutil.go b/pkg/testutil/testutil.go index 312fab5d47..353e2e33c8 100644 --- a/pkg/testutil/testutil.go +++ b/pkg/testutil/testutil.go @@ -376,7 +376,7 @@ func CreateSecret(cli kubernetes.Interface, namespace, name string, secrettype v se.APIVersion = "v1" se.Kind = "Secret" } - return + return se, err } func GetRepoPasswordSecretData(password string) map[string][]byte { diff --git a/pkg/validatingwebhook/repositoryserver_handler.go b/pkg/validatingwebhook/repositoryserver_handler.go index 16172c6ba8..9c8a1a6fb3 100644 --- a/pkg/validatingwebhook/repositoryserver_handler.go +++ b/pkg/validatingwebhook/repositoryserver_handler.go @@ -28,6 +28,7 @@ type RepositoryServerValidator struct{} var _ webhook.CustomValidator = &RepositoryServerValidator{} +//nolint:lll //+kubebuilder:webhook:path=/validate/v1alpha1/repositoryserver,mutating=false,failurePolicy=fail,sideEffects=None,groups=cr.kanister.io,resources=repositoryservers,verbs=update,versions=v1alpha1,name=repositoryserver.cr.kanister.io,admissionReviewVersions=v1 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type