From 71474cb650e4d21e4f34e3edd1285ffbcc7f5896 Mon Sep 17 00:00:00 2001 From: Anton Korotkov <106995168+korotkov-aerospike@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:40:07 +0200 Subject: [PATCH] Add more linters and address identified issues (#314) * add godot linter * add errorlint linter * capital letters * add nlreturn linter * set limit 15 * set limit 12 * set limit 10 * delete @Description from models * delete @Description from models * sort linters --- .golangci.yml | 14 ++++++++++--- build/readme/readme_example_generator.go | 1 + cmd/backup/main.go | 1 + .../server/configuration/storage_manager.go | 2 +- internal/server/handlers/backup.go | 1 + internal/util/util.go | 2 ++ internal/util/white_list.go | 1 + pkg/dto/aerospike_cluster.go | 4 ++-- pkg/dto/backup_details.go | 2 +- pkg/dto/backup_policy.go | 3 ++- pkg/dto/backup_routine.go | 3 ++- pkg/dto/base_dto.go | 12 +++++------ pkg/dto/compression_policy.go | 3 ++- pkg/dto/config.go | 2 +- pkg/dto/encryption_policy.go | 2 +- pkg/dto/http_server_config.go | 1 + pkg/dto/logger_config.go | 2 ++ pkg/dto/restore_namespace.go | 3 +-- pkg/dto/restore_policy.go | 1 + pkg/dto/restore_request.go | 2 ++ pkg/dto/routine_state.go | 2 +- pkg/dto/storage_s3.go | 2 ++ pkg/dto/time_bounds.go | 4 ++-- pkg/model/aerospike_cluster.go | 12 +++++------ pkg/model/backup_details.go | 3 +-- pkg/model/backup_routine.go | 1 - pkg/model/backup_service_config.go | 1 - pkg/model/compression_policy.go | 1 - pkg/model/config.go | 4 ++++ pkg/model/encryption_policy.go | 8 -------- pkg/model/http_server_config.go | 2 -- pkg/model/logger_config.go | 4 ---- pkg/model/restore_namespace.go | 3 --- pkg/model/restore_policy.go | 1 - pkg/model/restore_request.go | 2 -- pkg/model/restore_result.go | 1 - pkg/model/routine_state.go | 2 +- pkg/model/secret_agent.go | 3 --- pkg/service/aerospike/client_manager.go | 2 ++ pkg/service/aerospike/client_manager_test.go | 1 + pkg/service/aerospike/namespace_empty.go | 2 +- pkg/service/backup_backend.go | 1 + pkg/service/backup_routine_orchestrator.go | 3 ++- .../backup_routine_orchestrator_test.go | 2 +- pkg/service/backup_scheduler.go | 3 ++- pkg/service/backup_scheduler_test.go | 2 +- pkg/service/config_applier.go | 3 ++- pkg/service/metrics.go | 20 ++++++++++--------- pkg/service/restore_data_test.go | 2 +- pkg/service/retryable_backup_handler.go | 2 +- pkg/service/storage/azure.go | 2 ++ pkg/service/storage/gcp.go | 2 ++ pkg/service/storage/local.go | 2 ++ pkg/service/storage/operations.go | 4 +++- pkg/service/storage/s3.go | 3 +++ pkg/util/loading_cache.go | 2 ++ pkg/validation/config_validation.go | 2 ++ 57 files changed, 100 insertions(+), 78 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 9edb8157..95557767 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,15 +5,16 @@ linters: enable: - gci - bodyclose - - unused - dogsled - dupl - errcheck + - errorlint - funlen - gci - goconst - gocritic - gocyclo + - godot - gofmt - goimports - gocyclo @@ -22,12 +23,14 @@ linters: - govet - ineffassign - misspell - - prealloc - - promlinter - nolintlint - nakedret + - nestif + - nlreturn - prealloc # pre-allocate slices with define size if the slice size is known in advance - predeclared + - promlinter + - reassign - revive - sloglint - staticcheck @@ -46,6 +49,10 @@ linters-settings: gosec: excludes: - G115 + nlreturn: + block-size: 10 + godot: + exclude: [ "@(Success|Failure|Router).*" ] tagliatelle: case: rules: @@ -61,6 +68,7 @@ issues: - prealloc - funlen - goconst + - nlreturn exclude-dirs: - examples diff --git a/build/readme/readme_example_generator.go b/build/readme/readme_example_generator.go index 3eb9b6f7..9fd50ebf 100644 --- a/build/readme/readme_example_generator.go +++ b/build/readme/readme_example_generator.go @@ -187,6 +187,7 @@ func main() { buffer.WriteString(fmt.Sprintf("<!-- %s -->\n\n```%s\n", name, format)) buffer.Write(formattedExample) buffer.WriteString("\n```") + return buffer.Bytes() }) err = os.WriteFile("README.md", updatedReadme, 0600) diff --git a/cmd/backup/main.go b/cmd/backup/main.go index 2ac4f856..acd08aa4 100644 --- a/cmd/backup/main.go +++ b/cmd/backup/main.go @@ -177,6 +177,7 @@ func runHTTPServer(ctx context.Context, serverConfig *model.HTTPServerConfig, h } slog.Info("HTTP server shutdown gracefully") + return nil } diff --git a/internal/server/configuration/storage_manager.go b/internal/server/configuration/storage_manager.go index 5276332e..d52ebbe8 100644 --- a/internal/server/configuration/storage_manager.go +++ b/internal/server/configuration/storage_manager.go @@ -17,7 +17,7 @@ type storageManager struct { nsValidator aerospike.NamespaceValidator } -// newStorageManager returns new instance of storageManager +// newStorageManager returns new instance of storageManager. func newStorageManager(configStorage model.Storage, nsValidator aerospike.NamespaceValidator) Manager { return &storageManager{ storage: configStorage, diff --git a/internal/server/handlers/backup.go b/internal/server/handlers/backup.go index 47dae470..6fc84108 100644 --- a/internal/server/handlers/backup.go +++ b/internal/server/handlers/backup.go @@ -206,6 +206,7 @@ func readBackupsLogic(ctx context.Context, } result[routine] = list } + return result, nil } diff --git a/internal/util/util.go b/internal/util/util.go index e5b9d376..96714e81 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -44,10 +44,12 @@ func logWriter(config *model.LoggerConfig) io.Writer { if config.GetStdoutWriterOrDefault() { return io.MultiWriter(fileWriter, os.Stdout) } + return fileWriter } else if config.GetStdoutWriterOrDefault() { return os.Stdout } + return &ignoreWriter{} } diff --git a/internal/util/white_list.go b/internal/util/white_list.go index 6e4acf86..0506ff3b 100644 --- a/internal/util/white_list.go +++ b/internal/util/white_list.go @@ -32,6 +32,7 @@ func NewIPWhiteList(ipList []string) *IPWhiteList { networks = append(networks, &network) } } + return &IPWhiteList{ addresses: addresses, networks: networks, diff --git a/pkg/dto/aerospike_cluster.go b/pkg/dto/aerospike_cluster.go index 14203ec0..4d08a20a 100644 --- a/pkg/dto/aerospike_cluster.go +++ b/pkg/dto/aerospike_cluster.go @@ -49,7 +49,7 @@ func (a *AerospikeCluster) Validate() error { return nil } -// NewClusterFromReader creates a new Storage object from a given reader +// NewClusterFromReader creates a new Storage object from a given reader. func NewClusterFromReader(r io.Reader, format SerializationFormat) (*AerospikeCluster, error) { a := &AerospikeCluster{} if err := Deserialize(a, r, format); err != nil { @@ -190,7 +190,7 @@ func (c *Credentials) fromModel(m *model.Credentials, config *model.BackupConfig c.SecretAgentConfig = ResolveSecretAgentFromModel(m.SecretAgent, config) } -// Validate validates the credentials configuration +// Validate validates the credentials configuration. func (c *Credentials) Validate() error { if c == nil { return nil diff --git a/pkg/dto/backup_details.go b/pkg/dto/backup_details.go index c2019d99..0768cf5a 100644 --- a/pkg/dto/backup_details.go +++ b/pkg/dto/backup_details.go @@ -35,7 +35,7 @@ type BackupMetadata struct { UDFCount uint64 `yaml:"udf-count" json:"udf-count" format:"int64" example:"2"` } -// NewBackupDetailsFromModel creates a new BackupDetails from a model.BackupDetails +// NewBackupDetailsFromModel creates a new BackupDetails from a model.BackupDetails. func NewBackupDetailsFromModel(m *model.BackupDetails, config *model.BackupConfig) *BackupDetails { if m == nil { return nil diff --git a/pkg/dto/backup_policy.go b/pkg/dto/backup_policy.go index 53cac609..0b087a8f 100644 --- a/pkg/dto/backup_policy.go +++ b/pkg/dto/backup_policy.go @@ -49,7 +49,7 @@ type BackupPolicy struct { Sealed *bool `yaml:"sealed,omitempty" json:"sealed,omitempty"` } -// NewBackupPolicyFromReader creates a new BackupPolicy object from a given reader +// NewBackupPolicyFromReader creates a new BackupPolicy object from a given reader. func NewBackupPolicyFromReader(r io.Reader, format SerializationFormat) (*BackupPolicy, error) { b := &BackupPolicy{} if err := Deserialize(b, r, format); err != nil { @@ -98,6 +98,7 @@ func (p *BackupPolicy) Validate() error { if err := p.CompressionPolicy.Validate(); err != nil { return err } + return nil } diff --git a/pkg/dto/backup_routine.go b/pkg/dto/backup_routine.go index 80e9099c..9db8fd98 100644 --- a/pkg/dto/backup_routine.go +++ b/pkg/dto/backup_routine.go @@ -80,6 +80,7 @@ func (r *BackupRoutine) Validate() error { return emptyFieldValidationError("secret-agent") } } + return nil } @@ -138,7 +139,7 @@ func (r *BackupRoutine) ToModel( }, nil } -// NewRoutineFromReader creates a new BackupRoutine object from a given reader +// NewRoutineFromReader creates a new BackupRoutine object from a given reader. func NewRoutineFromReader(r io.Reader, format SerializationFormat) (*BackupRoutine, error) { b := &BackupRoutine{} if err := Deserialize(b, r, format); err != nil { diff --git a/pkg/dto/base_dto.go b/pkg/dto/base_dto.go index b92697d2..681b3456 100644 --- a/pkg/dto/base_dto.go +++ b/pkg/dto/base_dto.go @@ -9,7 +9,7 @@ import ( "gopkg.in/yaml.v3" ) -// SerializationFormat represents the format for serialization/deserialization +// SerializationFormat represents the format for serialization/deserialization. type SerializationFormat int const ( @@ -22,7 +22,7 @@ type Validator interface { Validate() error } -// Serialize handles serialization +// Serialize handles serialization. func Serialize(v any, format SerializationFormat) ([]byte, error) { var ( data []byte @@ -45,7 +45,7 @@ func Serialize(v any, format SerializationFormat) ([]byte, error) { return data, nil } -// Deserialize handles deserialization +// Deserialize handles deserialization. func Deserialize(v any, r io.Reader, format SerializationFormat) error { var err error @@ -65,7 +65,7 @@ func Deserialize(v any, r io.Reader, format SerializationFormat) error { return nil } -// ConvertModelsToDTO converts an array of models to an array of DTOs +// ConvertModelsToDTO converts an array of models to an array of DTOs. func ConvertModelsToDTO[M any, D any](models []M, dtoConstructor func(*M) D) []D { result := make([]D, len(models)) for i := range models { @@ -74,7 +74,7 @@ func ConvertModelsToDTO[M any, D any](models []M, dtoConstructor func(*M) D) []D return result } -// ConvertModelMapToDTO converts a map of models to a map of DTOs +// ConvertModelMapToDTO converts a map of models to a map of DTOs. func ConvertModelMapToDTO[M any, D any](modelMap map[string]*M, dtoConstructor func(*M) *D) map[string]*D { result := make(map[string]*D, len(modelMap)) for key, m := range modelMap { @@ -83,7 +83,7 @@ func ConvertModelMapToDTO[M any, D any](modelMap map[string]*M, dtoConstructor f return result } -// ConvertStorageMapToDTO converts a map of models to a map of DTOs +// ConvertStorageMapToDTO converts a map of models to a map of DTOs. func ConvertStorageMapToDTO(modelMap map[string]model.Storage, config *model.BackupConfig) map[string]*Storage { result := make(map[string]*Storage, len(modelMap)) for key, s := range modelMap { diff --git a/pkg/dto/compression_policy.go b/pkg/dto/compression_policy.go index adbf3ee8..ddd0dd53 100644 --- a/pkg/dto/compression_policy.go +++ b/pkg/dto/compression_policy.go @@ -6,7 +6,7 @@ import ( "github.com/aerospike/aerospike-backup-service/v3/pkg/model" ) -// Compression modes +// Compression modes. const ( CompressNone = "NONE" CompressZSTD = "ZSTD" @@ -35,6 +35,7 @@ func (p *CompressionPolicy) Validate() error { if p.Level < -1 { return fmt.Errorf("invalid compression level: %d", p.Level) } + return nil } diff --git a/pkg/dto/config.go b/pkg/dto/config.go index 570aaa85..b17cf55d 100644 --- a/pkg/dto/config.go +++ b/pkg/dto/config.go @@ -61,7 +61,7 @@ func (c *Config) fromModel(m *model.Config) { } } -// NewConfigFromReader creates a new Config object from a given reader +// NewConfigFromReader creates a new Config object from a given reader. func NewConfigFromReader(r io.Reader, format SerializationFormat) (*Config, error) { c := &Config{} if err := Deserialize(c, r, format); err != nil { diff --git a/pkg/dto/encryption_policy.go b/pkg/dto/encryption_policy.go index babc772d..3882cdde 100644 --- a/pkg/dto/encryption_policy.go +++ b/pkg/dto/encryption_policy.go @@ -7,7 +7,7 @@ import ( "github.com/aerospike/aerospike-backup-service/v3/pkg/model" ) -// Encryption modes +// Encryption modes. const ( EncryptNone = "NONE" EncryptAES128 = "AES128" diff --git a/pkg/dto/http_server_config.go b/pkg/dto/http_server_config.go index 28e09fd9..cae4426f 100644 --- a/pkg/dto/http_server_config.go +++ b/pkg/dto/http_server_config.go @@ -35,6 +35,7 @@ func (s *HTTPServerConfig) Validate() error { if s.Timeout != nil && *s.Timeout < 0 { return fmt.Errorf("timeout cannot be negative: %d", *s.Timeout) } + return nil } diff --git a/pkg/dto/logger_config.go b/pkg/dto/logger_config.go index 10e2f2c0..fde1ecb0 100644 --- a/pkg/dto/logger_config.go +++ b/pkg/dto/logger_config.go @@ -42,6 +42,7 @@ func (l *LoggerConfig) Validate() error { if err := l.FileWriter.Validate(); err != nil { return err } + return nil } @@ -129,6 +130,7 @@ func (f *FileLoggerConfig) Validate() error { if f.MaxBackups < 0 { return fmt.Errorf("negative logger MaxBackups: %d", f.MaxBackups) } + return nil } diff --git a/pkg/dto/restore_namespace.go b/pkg/dto/restore_namespace.go index e04af241..d8ed1ee6 100644 --- a/pkg/dto/restore_namespace.go +++ b/pkg/dto/restore_namespace.go @@ -10,8 +10,7 @@ import ( // operation, where Source is the original namespace name and Destination is // the namespace name to which the backup data is to be restored. // -// @Description RestoreNamespace specifies an alternative namespace name for the restore -// @Description operation. +// @Description RestoreNamespace specifies an alternative namespace name for the restore operation. type RestoreNamespace struct { // Original namespace name. Source *string `json:"source,omitempty" example:"source-ns" validate:"required"` diff --git a/pkg/dto/restore_policy.go b/pkg/dto/restore_policy.go index 5d7271d4..cb77fccd 100644 --- a/pkg/dto/restore_policy.go +++ b/pkg/dto/restore_policy.go @@ -117,6 +117,7 @@ func (p *RestorePolicy) Validate() error { if p.ExtraTTL != nil && *p.ExtraTTL <= 0 { return fmt.Errorf("extraTTL %d invalid, should be positive number", *p.ExtraTTL) } + return nil } diff --git a/pkg/dto/restore_request.go b/pkg/dto/restore_request.go index b4ae6194..9c10d6bf 100644 --- a/pkg/dto/restore_request.go +++ b/pkg/dto/restore_request.go @@ -51,6 +51,7 @@ func (r *RestoreRequest) Validate() error { if err := r.Policy.Validate(); err != nil { return err } + return nil } @@ -68,6 +69,7 @@ func (r *RestoreTimestampRequest) Validate() error { if r.Routine == "" { return emptyFieldValidationError(r.Routine) } + return nil } diff --git a/pkg/dto/routine_state.go b/pkg/dto/routine_state.go index 36ea517e..bb81188d 100644 --- a/pkg/dto/routine_state.go +++ b/pkg/dto/routine_state.go @@ -7,7 +7,7 @@ import ( ) // RoutineState represent the current state of backups (full and incremental) -// @Description RoutineState represent the current state of backups (full and incremental) +// @Description RoutineState represent the current state of backups (full and incremental). type RoutineState struct { // Full represents the state of a full backup. Nil if no full backup is running. Full *RunningJob `json:"full,omitempty"` diff --git a/pkg/dto/storage_s3.go b/pkg/dto/storage_s3.go index 449d76c1..187f2d94 100644 --- a/pkg/dto/storage_s3.go +++ b/pkg/dto/storage_s3.go @@ -70,6 +70,7 @@ func (s *S3Storage) toModel(config *model.Config) (*model.S3Storage, error) { SecretAgent: agent, } } + return &model.S3Storage{ Path: s.Path, Bucket: s.Bucket, @@ -99,5 +100,6 @@ func newS3StorageFromModel(s *model.S3Storage, config *model.BackupConfig) *S3St result.AccessKeyID = &s.Auth.KeyIDSecret result.SecretAccessKey = &s.Auth.AccessKeySecret } + return result } diff --git a/pkg/dto/time_bounds.go b/pkg/dto/time_bounds.go index 2125ee41..4263d0be 100644 --- a/pkg/dto/time_bounds.go +++ b/pkg/dto/time_bounds.go @@ -7,6 +7,7 @@ import ( "time" "github.com/aerospike/aerospike-backup-service/v3/pkg/model" + "github.com/aerospike/aerospike-backup-service/v3/pkg/util" ) // TimeBounds represents a period of time between two timestamps. @@ -60,6 +61,5 @@ func parseTimestamp(value string) (*time.Time, error) { return nil, fmt.Errorf("timestamp should be positive or zero, got %d", intValue) } - result := time.UnixMilli(intValue) - return &result, nil + return util.Ptr(time.UnixMilli(intValue)), nil } diff --git a/pkg/model/aerospike_cluster.go b/pkg/model/aerospike_cluster.go index b5319ecc..0828ea4c 100644 --- a/pkg/model/aerospike_cluster.go +++ b/pkg/model/aerospike_cluster.go @@ -23,7 +23,6 @@ import ( const nilString = "<nil>" // AerospikeCluster represents the configuration for an Aerospike cluster for backup. -// @Description AerospikeCluster represents the configuration for an Aerospike cluster for backup. type AerospikeCluster struct { pwd atomic.Pointer[string] // The cluster name. @@ -139,6 +138,7 @@ func (c *Credentials) loadPassword() *string { } slog.Warn("No valid authentication method configured") + return nil } @@ -157,6 +157,7 @@ func (c *Credentials) loadPasswordFromFile() *string { slog.Debug("Successfully read password", "path", *c.PasswordPath) password := string(data) + return &password } @@ -201,7 +202,7 @@ func (c *AerospikeCluster) ASClientPolicy() *as.ClientPolicy { return policy } -//nolint:funlen,staticcheck +//nolint:funlen,staticcheck,nestif func initTLS(t *TLS, clusterLabel *string) *tls.Config { clusterName := "NA" if clusterLabel != nil { @@ -277,7 +278,7 @@ func initTLS(t *TLS, clusterLabel *string) *tls.Config { cert, err := tls.X509KeyPair(certPEM, keyPEM) if err != nil { - errorLog(fmt.Errorf("failed to add client certificate and key to the pool: %s", err)) + errorLog(fmt.Errorf("failed to add client certificate and key to the pool: %w", err)) } clientPool = append(clientPool, cert) @@ -298,7 +299,7 @@ func initTLS(t *TLS, clusterLabel *string) *tls.Config { func readFromFile(filePath string) ([]byte, error) { dataBytes, err := os.ReadFile(filePath) if err != nil { - return nil, fmt.Errorf("failed to read from file %s: %v", filePath, err) + return nil, fmt.Errorf("failed to read from file %s: %w", filePath, err) } data := bytes.TrimSuffix(dataBytes, []byte("\n")) @@ -319,7 +320,6 @@ func (c *AerospikeCluster) ASClientHosts() []*as.Host { } // TLS represents the Aerospike cluster TLS configuration options. -// @Description TLS represents the Aerospike cluster TLS configuration options. type TLS struct { // Path to a trusted CA certificate file. CAFile *string @@ -358,7 +358,6 @@ func (tls *TLS) String() string { } // Credentials represents authentication details to the Aerospike cluster. -// @Description Credentials represents authentication details to the Aerospike cluster. type Credentials struct { // The username for the cluster authentication. User *string @@ -387,7 +386,6 @@ func (c *Credentials) String() string { } // SeedNode represents details of a node in the Aerospike cluster. -// @Description SeedNode represents details of a node in the Aerospike cluster. type SeedNode struct { // The host name of the node. HostName string diff --git a/pkg/model/backup_details.go b/pkg/model/backup_details.go index 2c27c000..5ba12ce3 100644 --- a/pkg/model/backup_details.go +++ b/pkg/model/backup_details.go @@ -9,7 +9,6 @@ import ( ) // BackupDetails contains information about a backup. -// @Description BackupDetails contains information about a backup. type BackupDetails struct { BackupMetadata // The path to the backup files. @@ -38,7 +37,7 @@ type BackupMetadata struct { UDFCount uint64 `yaml:"udf-count" json:"udf-count"` } -// NewMetadataFromBytes creates a new Metadata object from a byte slice +// NewMetadataFromBytes creates a new Metadata object from a byte slice. func NewMetadataFromBytes(data []byte) (*BackupMetadata, error) { if len(data) == 0 { return nil, fmt.Errorf("empty metadata file") diff --git a/pkg/model/backup_routine.go b/pkg/model/backup_routine.go index a1ada0b2..3a083012 100644 --- a/pkg/model/backup_routine.go +++ b/pkg/model/backup_routine.go @@ -1,7 +1,6 @@ package model // BackupRoutine represents a scheduled backup operation routine. -// @Description BackupRoutine represents a scheduled backup operation routine. type BackupRoutine struct { // The name of the corresponding backup policy. BackupPolicy *BackupPolicy diff --git a/pkg/model/backup_service_config.go b/pkg/model/backup_service_config.go index 9ec7504d..1734e17f 100644 --- a/pkg/model/backup_service_config.go +++ b/pkg/model/backup_service_config.go @@ -1,7 +1,6 @@ package model // BackupServiceConfig represents the backup service configuration properties. -// @Description BackupServiceConfig represents the backup service configuration properties. type BackupServiceConfig struct { // HTTPServer is the backup service HTTP server configuration. HTTPServer *HTTPServerConfig diff --git a/pkg/model/compression_policy.go b/pkg/model/compression_policy.go index 4562fb3b..951854f8 100644 --- a/pkg/model/compression_policy.go +++ b/pkg/model/compression_policy.go @@ -1,7 +1,6 @@ package model // CompressionPolicy contains backup compression information. -// @Description CompressionPolicy contains backup compression information. type CompressionPolicy struct { // The compression mode to be used (default is NONE). Mode string diff --git a/pkg/model/config.go b/pkg/model/config.go index 33c9ec12..7f379cd3 100644 --- a/pkg/model/config.go +++ b/pkg/model/config.go @@ -79,6 +79,7 @@ func (c *Config) AddStorage(name string, s Storage) error { return fmt.Errorf("add storage %q: %w", name, ErrAlreadyExists) } c.backupConfig.Storage[name] = s + return nil } @@ -94,6 +95,7 @@ func (c *Config) DeleteStorage(name string) error { return fmt.Errorf("delete storage %q: %w: it is used in routine %q", name, ErrInUse, routine) } delete(c.backupConfig.Storage, name) + return nil } @@ -149,6 +151,7 @@ func (c *Config) DeletePolicy(name string) error { return fmt.Errorf("delete backup policy %q: %w: it is used in routine %q", name, ErrInUse, routine) } delete(c.backupConfig.BackupPolicies, name) + return nil } @@ -246,6 +249,7 @@ func (c *Config) DeleteCluster(name string) error { return fmt.Errorf("delete Aerospike cluster %q: %w: it is used in routine %q", name, ErrInUse, routine) } delete(c.backupConfig.AerospikeClusters, name) + return nil } diff --git a/pkg/model/encryption_policy.go b/pkg/model/encryption_policy.go index 12bc3dd3..dba14d46 100644 --- a/pkg/model/encryption_policy.go +++ b/pkg/model/encryption_policy.go @@ -1,14 +1,6 @@ package model -// Encryption modes -const ( - EncryptNone = "NONE" - EncryptAES128 = "AES128" - EncryptAES256 = "AES256" -) - // EncryptionPolicy contains backup encryption information. -// @Description EncryptionPolicy contains backup encryption information. type EncryptionPolicy struct { // The encryption mode to be used (NONE, AES128, AES256) Mode string diff --git a/pkg/model/http_server_config.go b/pkg/model/http_server_config.go index 9b8d3f40..a1238c75 100644 --- a/pkg/model/http_server_config.go +++ b/pkg/model/http_server_config.go @@ -3,7 +3,6 @@ package model import "time" // HTTPServerConfig represents the service's HTTP server configuration. -// @Description HTTPServerConfig represents the service's HTTP server configuration. type HTTPServerConfig struct { // The address to listen on. Address *string @@ -63,7 +62,6 @@ func (s *HTTPServerConfig) GetContextPathOrDefault() string { } // RateLimiterConfig represents the service's HTTP server rate limiter configuration. -// @Description RateLimiterConfig is the HTTP server rate limiter configuration. type RateLimiterConfig struct { // Rate limiter tokens per second threshold. Tps *int diff --git a/pkg/model/logger_config.go b/pkg/model/logger_config.go index ae9d894e..be70db53 100644 --- a/pkg/model/logger_config.go +++ b/pkg/model/logger_config.go @@ -1,9 +1,6 @@ package model // LoggerConfig represents the backup service logger configuration. -// @Description LoggerConfig represents the backup service logger configuration. -// - type LoggerConfig struct { // Level is the logger level. Level *string @@ -43,7 +40,6 @@ func (l *LoggerConfig) GetStdoutWriterOrDefault() bool { } // FileLoggerConfig represents the configuration for the file logger writer. -// @Description FileLoggerConfig represents the configuration for the file logger writer. type FileLoggerConfig struct { // Filename is the file to write logs to. Filename string diff --git a/pkg/model/restore_namespace.go b/pkg/model/restore_namespace.go index e3ecbfe7..d882c3aa 100644 --- a/pkg/model/restore_namespace.go +++ b/pkg/model/restore_namespace.go @@ -3,9 +3,6 @@ package model // RestoreNamespace specifies an alternative namespace name for the restore // operation, where Source is the original namespace name and Destination is // the namespace name to which the backup data is to be restored. -// -// @Description RestoreNamespace specifies an alternative namespace name for the restore -// @Description operation. type RestoreNamespace struct { // Original namespace name. Source *string diff --git a/pkg/model/restore_policy.go b/pkg/model/restore_policy.go index c9f17f74..1334dab0 100644 --- a/pkg/model/restore_policy.go +++ b/pkg/model/restore_policy.go @@ -7,7 +7,6 @@ import ( ) // RestorePolicy represents a policy for the restore operation. -// @Description RestorePolicy represents a policy for the restore operation. type RestorePolicy struct { // The number of concurrent record readers from backup files. Default: 20 Parallel *int diff --git a/pkg/model/restore_request.go b/pkg/model/restore_request.go index e29c4aef..1e773d9c 100644 --- a/pkg/model/restore_request.go +++ b/pkg/model/restore_request.go @@ -9,7 +9,6 @@ import ( type RestoreJobID int64 // RestoreRequest represents a restore operation request. -// @Description RestoreRequest represents a restore operation request. type RestoreRequest struct { DestinationCluster *AerospikeCluster Policy *RestorePolicy @@ -19,7 +18,6 @@ type RestoreRequest struct { } // RestoreTimestampRequest represents a restore by timestamp operation request. -// @Description RestoreTimestampRequest represents a restore by timestamp operation request. type RestoreTimestampRequest struct { // The details of the Aerospike destination cluster. DestinationCluster *AerospikeCluster diff --git a/pkg/model/restore_result.go b/pkg/model/restore_result.go index c4542ba6..46fefb77 100644 --- a/pkg/model/restore_result.go +++ b/pkg/model/restore_result.go @@ -10,7 +10,6 @@ const ( ) // RestoreJobStatus represents a restore job status. -// @Description RestoreJobStatus represents a restore job status. type RestoreJobStatus struct { ReadRecords uint64 TotalBytes uint64 diff --git a/pkg/model/routine_state.go b/pkg/model/routine_state.go index ba8c70d1..f07ba1aa 100644 --- a/pkg/model/routine_state.go +++ b/pkg/model/routine_state.go @@ -4,7 +4,7 @@ import ( "time" ) -// RoutineState represent the current state of backups (full and incremental) +// RoutineState represent the current state of backups (full and incremental). type RoutineState struct { // Full represents the state of a full backup. Nil if no full backup is running. Full *RunningJob diff --git a/pkg/model/secret_agent.go b/pkg/model/secret_agent.go index 1bc6cae4..4d58e568 100644 --- a/pkg/model/secret_agent.go +++ b/pkg/model/secret_agent.go @@ -13,9 +13,6 @@ import ( // for a backup/restore operation. // Aerospike Secret Agent acts as a proxy layer between Aerospike server and one or more // external secrets management services, fetching secrets on behalf of the server. -// -// @Description SecretAgent represents the configuration of an Aerospike Secret Agent -// @Description for a backup/restore operation. type SecretAgent struct { once sync.Once // Connection type: tcp, unix. diff --git a/pkg/service/aerospike/client_manager.go b/pkg/service/aerospike/client_manager.go index 091b8552..1c0d7cd7 100644 --- a/pkg/service/aerospike/client_manager.go +++ b/pkg/service/aerospike/client_manager.go @@ -54,6 +54,7 @@ func (f *DefaultClientFactory) IsClusterHealthy(client backup.AerospikeClient) b } info, err := node.RequestInfo(client.GetDefaultInfoPolicy(), "status") + return err == nil && info["status"] == "ok" } @@ -179,6 +180,7 @@ func (cm *ClientManagerImpl) createClient(cluster *model.AerospikeCluster) (*bac if cluster.ClusterLabel != nil { options = append(options, backup.WithID(*cluster.ClusterLabel)) } + return backup.NewClient(aeroClient, options...) } diff --git a/pkg/service/aerospike/client_manager_test.go b/pkg/service/aerospike/client_manager_test.go index 685f01bd..8a7610a9 100644 --- a/pkg/service/aerospike/client_manager_test.go +++ b/pkg/service/aerospike/client_manager_test.go @@ -47,6 +47,7 @@ func (f *MockClientFactory) NewClientWithPolicyAndHost(_ *as.ClientPolicy, _ ... m := &mocks.MockAerospikeClient{} m.On("Close").Return() m.On("Cluster").Return(&as.Cluster{}) + return m, nil } diff --git a/pkg/service/aerospike/namespace_empty.go b/pkg/service/aerospike/namespace_empty.go index 954ed595..48cf5e44 100644 --- a/pkg/service/aerospike/namespace_empty.go +++ b/pkg/service/aerospike/namespace_empty.go @@ -92,7 +92,7 @@ func getNodeStats(policy *as.InfoPolicy, node *as.Node, statsKey string) (string // parseObjectCount parses the object count from stats string. // when fetch namespaces, aerospike return a string separated by `;` -// for list of sets, delimiter is `:` +// for list of sets, delimiter is `:`. func parseObjectCount(stats, delimiter, key string) (int64, error) { statsPairs := strings.Split(stats, delimiter) for _, pair := range statsPairs { diff --git a/pkg/service/backup_backend.go b/pkg/service/backup_backend.go index c8b9db35..5e3c27f3 100644 --- a/pkg/service/backup_backend.go +++ b/pkg/service/backup_backend.go @@ -148,6 +148,7 @@ func latestBackupBeforeTime(allBackups []model.BackupDetails, upperBound *time.T result = append(result, *current) } } + return result } diff --git a/pkg/service/backup_routine_orchestrator.go b/pkg/service/backup_routine_orchestrator.go index 752d3f5e..938e6c9f 100644 --- a/pkg/service/backup_routine_orchestrator.go +++ b/pkg/service/backup_routine_orchestrator.go @@ -66,7 +66,7 @@ type ClusterConfigWriter interface { Write(ctx context.Context, client backup.AerospikeClient, timestamp time.Time) } -// BackupHandlerHolder stores backupRunners by routine name +// BackupHandlerHolder stores backupRunners by routine name. type BackupHandlerHolder = *util.SafeMap[string, backupRunner] func NewBackupHandlerHolder() BackupHandlerHolder { @@ -278,5 +278,6 @@ func (h *BackupRoutineOrchestrator) runIncrementalBackupInternal(ctx context.Con } h.registry.unregister(h.routineName, jobTypeIncremental, now) + return nil } diff --git a/pkg/service/backup_routine_orchestrator_test.go b/pkg/service/backup_routine_orchestrator_test.go index 688538f8..b15fe957 100644 --- a/pkg/service/backup_routine_orchestrator_test.go +++ b/pkg/service/backup_routine_orchestrator_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/mock" ) -// Mock implementations +// Mock implementations. type mockBackupService struct { mock.Mock } diff --git a/pkg/service/backup_scheduler.go b/pkg/service/backup_scheduler.go index a69b0a97..ac44a8fe 100644 --- a/pkg/service/backup_scheduler.go +++ b/pkg/service/backup_scheduler.go @@ -42,7 +42,7 @@ func NewAdHocFullBackupJobForRoutine(routineName string) *quartz.JobDetail { return quartz.NewJobDetail(job.Job(), jobKey) } -// NewScheduler creates a new quartz.Scheduler +// NewScheduler creates a new quartz.Scheduler. func NewScheduler() quartz.Scheduler { return quartz.NewStdSchedulerWithOptions(quartz.StdSchedulerOptions{ OutdatedThreshold: 1 * time.Second, @@ -81,6 +81,7 @@ func scheduleRoutines( } jobStore.ReplaceContent(newJobs) + return errs } diff --git a/pkg/service/backup_scheduler_test.go b/pkg/service/backup_scheduler_test.go index 0d6374d2..23eceb10 100644 --- a/pkg/service/backup_scheduler_test.go +++ b/pkg/service/backup_scheduler_test.go @@ -42,7 +42,7 @@ func TestDisabledRoutine(t *testing.T) { mockScheduler.AssertNumberOfCalls(t, "ScheduleJob", 1) } -// MockBackupRunner is a mock implementation of backupRunner interface +// MockBackupRunner is a mock implementation of backupRunner interface. type MockBackupRunner struct { mock.Mock } diff --git a/pkg/service/config_applier.go b/pkg/service/config_applier.go index 60314542..ee870e0d 100644 --- a/pkg/service/config_applier.go +++ b/pkg/service/config_applier.go @@ -63,7 +63,7 @@ func (a *DefaultConfigApplier) ApplyNewRoutines(routines map[string]*model.Backu return nil } -// we don't want to delete ad-hoc jobs +// we don't want to delete ad-hoc jobs. func (a *DefaultConfigApplier) clearPeriodicSchedulerJobs() error { keys, err := a.scheduler.GetJobKeys(matcher.JobGroupEquals(string(quartzGroupScheduled))) if err != nil { @@ -77,6 +77,7 @@ func (a *DefaultConfigApplier) clearPeriodicSchedulerJobs() error { return fmt.Errorf("cannot delete job %q: %w", key, err) } } + return nil } diff --git a/pkg/service/metrics.go b/pkg/service/metrics.go index 3455ef57..e8bdec2e 100644 --- a/pkg/service/metrics.go +++ b/pkg/service/metrics.go @@ -10,54 +10,55 @@ import ( ) var ( - // a counter metric for backup run number + // A counter metric for backup run number. backupCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_runs_total", Help: "Successful backup runs counter", }) - // a counter metric for incremental backup run number + // A counter metric for incremental backup run number. incrBackupCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_incremental_runs_total", Help: "Successful incremental backup runs counter.", }) - // a counter metric for backup skip number + // A counter metric for backup skip number. backupSkippedCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_skip_total", Help: "Backup skip counter.", }) - // a counter metric for incremental backup skip number + // A counter metric for incremental backup skip number. incrBackupSkippedCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_incremental_skip_total", Help: "Incremental backup skip counter.", }) - // a counter metric for backup failure number + // A counter metric for backup failure number. backupFailureCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_failure_total", Help: "Backup failure counter.", }) - // a counter metric for incremental backup failure number + // A counter metric for incremental backup failure number. incrBackupFailureCounter = prometheus.NewCounter( prometheus.CounterOpts{ Name: "aerospike_backup_service_incremental_failure_total", Help: "Incremental backup failure counter.", }) - // a gauge metric for full backup duration + // A gauge metric for full backup duration. backupDurationGauge = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "aerospike_backup_service_duration_millis", Help: "Full backup duration in milliseconds.", }) - // a gauge metric for incremental backup duration + // A gauge metric for incremental backup duration. incrBackupDurationGauge = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "aerospike_backup_service_incremental_duration_millis", Help: "Incremental backup duration in milliseconds.", }) + // A gauge metrics for backup process, filter by name and type. backupProgress = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "aerospike_backup_service_backup_progress_pct", @@ -65,6 +66,7 @@ var ( }, []string{"routine", "type"}, ) + // A gauge metrics for restore processes. restoreProgress = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "aerospike_backup_service_restore_progress_pct", @@ -92,7 +94,7 @@ type MetricsCollector struct { restores *RestoreJobsHolder } -// NewMetricsCollector creates a new MetricsCollector +// NewMetricsCollector creates a new MetricsCollector. func NewMetricsCollector(bh RunningBackupsRegistry, jh *RestoreJobsHolder) *MetricsCollector { return &MetricsCollector{ backups: bh, diff --git a/pkg/service/restore_data_test.go b/pkg/service/restore_data_test.go index 4402d3af..18ca2bcd 100644 --- a/pkg/service/restore_data_test.go +++ b/pkg/service/restore_data_test.go @@ -296,7 +296,7 @@ func Test_restoreTimestampFail(t *testing.T) { require.Error(t, err) } -// MockClientManager is a mock implementation of ClientManager for testing +// MockClientManager is a mock implementation of ClientManager for testing. type MockClientManager struct { } diff --git a/pkg/service/retryable_backup_handler.go b/pkg/service/retryable_backup_handler.go index 8d9703d5..14b183f5 100644 --- a/pkg/service/retryable_backup_handler.go +++ b/pkg/service/retryable_backup_handler.go @@ -9,7 +9,7 @@ import ( ) // retryableBackupHandler is a wrapper around BackupHandler that adds -// retry logic and cancellation support +// retry logic and cancellation support. type retryableBackupHandler struct { sync.RWMutex handler BackupHandler diff --git a/pkg/service/storage/azure.go b/pkg/service/storage/azure.go index a5523a00..7f36f8f1 100644 --- a/pkg/service/storage/azure.go +++ b/pkg/service/storage/azure.go @@ -38,6 +38,7 @@ func (a *AzureStorageAccessor) createReader( } else { opts = append(opts, azure.WithDir(fullPath)) } + return azure.NewReader(ctx, client, azures.ContainerName, opts...) } @@ -62,6 +63,7 @@ func (a *AzureStorageAccessor) createWriter( if withNested { opts = append(opts, azure.WithNestedDir()) } + return azure.NewWriter(ctx, client, azures.ContainerName, opts...) } diff --git a/pkg/service/storage/gcp.go b/pkg/service/storage/gcp.go index 50813aab..4cc5ec70 100644 --- a/pkg/service/storage/gcp.go +++ b/pkg/service/storage/gcp.go @@ -38,6 +38,7 @@ func (a *GcpStorageAccessor) createReader( } else { opts = append(opts, gcp.WithDir(fullPath)) } + return gcp.NewReader(ctx, client, gcps.BucketName, opts...) } @@ -62,6 +63,7 @@ func (a *GcpStorageAccessor) createWriter( if withNested { opts = append(opts, gcp.WithNestedDir()) } + return gcp.NewWriter(ctx, client, gcps.BucketName, opts...) } diff --git a/pkg/service/storage/local.go b/pkg/service/storage/local.go index 48dbe619..413e4fb5 100644 --- a/pkg/service/storage/local.go +++ b/pkg/service/storage/local.go @@ -30,6 +30,7 @@ func (a *LocalStorageAccessor) createReader( } else { opts = append(opts, local.WithDir(fullPath)) } + return local.NewReader(opts...) } @@ -50,6 +51,7 @@ func (a *LocalStorageAccessor) createWriter( if withNested { opts = append(opts, local.WithNestedDir()) } + return local.NewWriter(ctx, opts...) } diff --git a/pkg/service/storage/operations.go b/pkg/service/storage/operations.go index d8cfb979..fb51a155 100644 --- a/pkg/service/storage/operations.go +++ b/pkg/service/storage/operations.go @@ -3,6 +3,7 @@ package storage import ( "bytes" "context" + "errors" "fmt" "io" "path/filepath" @@ -69,7 +70,7 @@ func ReadFiles(ctx context.Context, storage model.Storage, path string, filterSt for { select { case err := <-errorsCh: - if err == io.EOF { + if errors.Is(err, io.EOF) { return files, nil } return nil, err @@ -105,6 +106,7 @@ func WriteFile(ctx context.Context, storage model.Storage, fileName string, cont defer w.Close() _, err = w.Write(content) + return err } diff --git a/pkg/service/storage/s3.go b/pkg/service/storage/s3.go index f25daed5..b3621641 100644 --- a/pkg/service/storage/s3.go +++ b/pkg/service/storage/s3.go @@ -49,6 +49,7 @@ func (a *S3StorageAccessor) createReader( } else { opts = append(opts, s3.WithDir(fullPath)) } + return s3.NewReader(ctx, client, s3s.Bucket, opts...) } @@ -73,6 +74,7 @@ func (a *S3StorageAccessor) createWriter( if withNested { opts = append(opts, s3.WithNestedDir()) } + return s3.NewWriter(ctx, client, s3s.Bucket, opts...) } @@ -124,6 +126,7 @@ func withCredentialsProvider(a *model.S3Authentication) (config.LoadOptionsFunc, if err != nil { return nil, err } + return config.WithCredentialsProvider(credentials.StaticCredentialsProvider{ Value: aws.Credentials{ AccessKeyID: keyID, SecretAccessKey: accessKey, diff --git a/pkg/util/loading_cache.go b/pkg/util/loading_cache.go index 9bb5a8fc..1537e4b0 100644 --- a/pkg/util/loading_cache.go +++ b/pkg/util/loading_cache.go @@ -28,6 +28,7 @@ func NewLoadingCache[K comparable, T any](ctx context.Context, } go cache.startCleanup() + return cache } @@ -54,6 +55,7 @@ func (c *LoadingCache[K, T]) GetWithContext(ctx context.Context, key K) (T, erro } c.data[key] = loadedValue + return loadedValue, nil } diff --git a/pkg/validation/config_validation.go b/pkg/validation/config_validation.go index ef28061f..dbc2a1a2 100644 --- a/pkg/validation/config_validation.go +++ b/pkg/validation/config_validation.go @@ -43,6 +43,7 @@ func ValidateRestoreRequest(request *dto.RestoreRequest, conf *dto.Config) error } _, err = request.ToModel(model) + return err } @@ -65,5 +66,6 @@ func ValidateRestoreTimestampRequest(request *dto.RestoreTimestampRequest, conf } _, err = request.ToModel(model) + return err }