diff --git a/api/v1/checks.go b/api/v1/checks.go index 437ba2cbe..f4fbe9a4b 100644 --- a/api/v1/checks.go +++ b/api/v1/checks.go @@ -152,9 +152,9 @@ type Bucket struct { } type S3Check struct { - Description `yaml:",inline" json:",inline"` - connection.AWSConnection `yaml:",inline" json:",inline"` - BucketName string `yaml:"bucketName" json:"bucketName,omitempty"` + Description `yaml:",inline" json:",inline"` + connection.S3Connection `yaml:",inline" json:",inline"` + BucketName string `yaml:"bucketName" json:"bucketName,omitempty"` } func (c S3Check) GetEndpoint() string { @@ -797,11 +797,14 @@ type FolderCheck struct { Description `yaml:",inline" json:",inline"` Templatable `yaml:",inline" json:",inline"` // Path to folder or object storage, e.g. `s3://`, `gcs://`, `/path/tp/folder` - Path string `yaml:"path" json:"path"` + Path string `yaml:"path" json:"path"` + // Recursive when set to true will recursively scan the folder to list the files in it. + // However, symlinks are simply listed but not traversed. + Recursive bool `yaml:"recursive,omitempty" json:"recursive,omitempty"` Filter FolderFilter `yaml:"filter,omitempty" json:"filter,omitempty"` FolderTest `yaml:",inline" json:",inline"` - *connection.AWSConnection `yaml:"awsConnection,omitempty" json:"awsConnection,omitempty"` - *connection.GCPConnection `yaml:"gcpConnection,omitempty" json:"gcpConnection,omitempty"` + *connection.S3Connection `yaml:"awsConnection,omitempty" json:"awsConnection,omitempty"` + *connection.GCSConnection `yaml:"gcpConnection,omitempty" json:"gcpConnection,omitempty"` *connection.SMBConnection `yaml:"smbConnection,omitempty" json:"smbConnection,omitempty"` *connection.SFTPConnection `yaml:"sftpConnection,omitempty" json:"sftpConnection,omitempty"` } diff --git a/api/v1/common.go b/api/v1/common.go index 79fde13cb..abe87ca4a 100644 --- a/api/v1/common.go +++ b/api/v1/common.go @@ -86,6 +86,7 @@ type FolderFilterContext struct { FolderFilter minAge, maxAge *time.Duration minSize, maxSize *int64 + AllowDir bool // Allow directories to support recursive folder checks Since *time.Time // kubebuilder:object:generate=false regex *regexp.Regexp @@ -157,7 +158,7 @@ func tryParse(s string) (time.Time, error) { } func (f *FolderFilterContext) Filter(i fs.FileInfo) bool { - if i.IsDir() { + if i.IsDir() && !f.AllowDir { return false } if f.maxAge != nil && time.Since(i.ModTime()) > *f.maxAge { diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index dd0e6cec3..69009faef 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -1712,14 +1712,14 @@ func (in *FolderCheck) DeepCopyInto(out *FolderCheck) { out.Templatable = in.Templatable out.Filter = in.Filter in.FolderTest.DeepCopyInto(&out.FolderTest) - if in.AWSConnection != nil { - in, out := &in.AWSConnection, &out.AWSConnection - *out = new(connection.AWSConnection) + if in.S3Connection != nil { + in, out := &in.S3Connection, &out.S3Connection + *out = new(connection.S3Connection) (*in).DeepCopyInto(*out) } - if in.GCPConnection != nil { - in, out := &in.GCPConnection, &out.GCPConnection - *out = new(connection.GCPConnection) + if in.GCSConnection != nil { + in, out := &in.GCSConnection, &out.GCSConnection + *out = new(connection.GCSConnection) (*in).DeepCopyInto(*out) } if in.SMBConnection != nil { @@ -2793,7 +2793,7 @@ func (in *S3) DeepCopy() *S3 { func (in *S3Check) DeepCopyInto(out *S3Check) { *out = *in in.Description.DeepCopyInto(&out.Description) - in.AWSConnection.DeepCopyInto(&out.AWSConnection) + in.S3Connection.DeepCopyInto(&out.S3Connection) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Check. diff --git a/checks/folder.go b/checks/folder.go index f8d9fb525..e48bc325e 100644 --- a/checks/folder.go +++ b/checks/folder.go @@ -2,6 +2,7 @@ package checks import ( "fmt" + "io/fs" "os" "strings" @@ -12,6 +13,7 @@ import ( "github.com/flanksource/canary-checker/api/external" v1 "github.com/flanksource/canary-checker/api/v1" "github.com/flanksource/canary-checker/pkg" + "github.com/flanksource/duty/models" ) const SizeNotSupported = -1 @@ -89,7 +91,14 @@ func checkLocalFolder(ctx *context.Context, check v1.FolderCheck) pkg.Results { result := pkg.Success(check, ctx.Canary) var results pkg.Results results = append(results, result) - folders, err := getLocalFolderCheck(check.Path, check.Filter) + + // Form a dummy connection to get a local filesystem + localFS, err := artifacts.GetFSForConnection(ctx.Duty(), models.Connection{Type: models.ConnectionTypeFolder}) + if err != nil { + return results.ErrorMessage(err) + } + + folders, err := genericFolderCheck(localFS, check.Path, check.Recursive, check.Filter) result.AddDetails(folders) if err != nil { @@ -102,80 +111,91 @@ func checkLocalFolder(ctx *context.Context, check v1.FolderCheck) pkg.Results { return results } -func getLocalFolderCheck(path string, filter v1.FolderFilter) (FolderCheck, error) { +func genericFolderCheck(dirFS artifacts.Filesystem, path string, recursive bool, filter v1.FolderFilter) (FolderCheck, error) { + return _genericFolderCheck(true, dirFS, path, recursive, filter) +} + +// genericFolderCheckWithoutPrecheck is used for those filesystems that do not support fetching the stat of a directory. +// Eg: s3, gcs. +// It will not pre check whether the given path is a directory. +func genericFolderCheckWithoutPrecheck(dirFS artifacts.Filesystem, path string, recursive bool, filter v1.FolderFilter) (FolderCheck, error) { + return _genericFolderCheck(false, dirFS, path, recursive, filter) +} + +func _genericFolderCheck(supportsDirStat bool, dirFS artifacts.Filesystem, path string, recursive bool, filter v1.FolderFilter) (FolderCheck, error) { result := FolderCheck{} _filter, err := filter.New() if err != nil { return result, err } - if dir, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - return result, nil + _filter.AllowDir = recursive + + var fileInfo os.FileInfo + if supportsDirStat { + fileInfo, err := dirFS.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return result, nil + } + return result, err + } else if !fileInfo.IsDir() { + return result, fmt.Errorf("%s is not a directory", path) } - return result, err - } else if !dir.IsDir() { - return result, fmt.Errorf("%s is not a directory", path) } - files, err := os.ReadDir(path) + + files, err := getFolderContents(dirFS, path, _filter) if err != nil { return result, err } + if len(files) == 0 { - // directory is empty. returning duration of directory - info, err := os.Stat(path) - if err != nil { - return result, err + if fileInfo == nil { + return FolderCheck{}, nil } + + // directory is empty. returning duration of directory return FolderCheck{ - Oldest: newFile(info), - Newest: newFile(info), + Oldest: newFile(fileInfo), + Newest: newFile(fileInfo), AvailableSize: SizeNotSupported, TotalSize: SizeNotSupported}, nil } for _, file := range files { - info, err := file.Info() - if err != nil { - return result, err - } - if file.IsDir() || !_filter.Filter(info) { - continue - } - - result.Append(info) + result.Append(file) } + return result, err } -func getGenericFolderCheck(fs artifacts.Filesystem, dir string, filter v1.FolderFilter) (*FolderCheck, error) { - result := FolderCheck{} - _filter, err := filter.New() - if err != nil { - return nil, err - } - files, err := fs.ReadDir(dir) +// getFolderContents walks the folder and returns all files. +// Also supports recursively fetching contents +func getFolderContents(dirFs artifacts.Filesystem, path string, filter *v1.FolderFilterContext) ([]fs.FileInfo, error) { + files, err := dirFs.ReadDir(path) if err != nil { return nil, err } + if len(files) == 0 { - // directory is empty. returning duration of directory - info, err := fs.Stat(dir) - if err != nil { - return nil, err - } - return &FolderCheck{ - Oldest: newFile(info), - Newest: newFile(info), - AvailableSize: SizeNotSupported, - TotalSize: SizeNotSupported}, nil + return nil, nil } - for _, file := range files { - if file.IsDir() || !_filter.Filter(file) { + var result []fs.FileInfo + for _, info := range files { + if !filter.Filter(info) { continue } - result.Append(file) + result = append(result, info) + if info.IsDir() { // This excludes even directory symlinks + subFiles, err := getFolderContents(dirFs, path+"/"+info.Name(), filter) + if err != nil { + return nil, err + } + + result = append(result, subFiles...) + } } - return &result, nil + + return result, err } diff --git a/checks/folder_check.go b/checks/folder_check.go index de60bf913..8b31a684d 100644 --- a/checks/folder_check.go +++ b/checks/folder_check.go @@ -35,6 +35,7 @@ func newFile(file os.FileInfo) *File { IsDir: file.IsDir(), } } + func (f *FolderCheck) Append(osFile os.FileInfo) { file := newFile(osFile) if f.Oldest == nil || f.Oldest.Modified.After(osFile.ModTime()) { diff --git a/checks/folder_gcs.go b/checks/folder_gcs.go index d5e972ec4..83c9d9dbb 100644 --- a/checks/folder_gcs.go +++ b/checks/folder_gcs.go @@ -1,13 +1,15 @@ package checks import ( + "errors" "strings" gcs "cloud.google.com/go/storage" - "github.com/flanksource/artifacts/clients/gcp" + "github.com/flanksource/artifacts" "github.com/flanksource/canary-checker/api/context" v1 "github.com/flanksource/canary-checker/api/v1" "github.com/flanksource/canary-checker/pkg" + "github.com/flanksource/duty/models" ) type GCS struct { @@ -20,62 +22,54 @@ func CheckGCSBucket(ctx *context.Context, check v1.FolderCheck) pkg.Results { var results pkg.Results results = append(results, result) - if err := check.GCPConnection.HydrateConnection(ctx); err != nil { - return results.Failf("failed to populate GCP connection: %v", err) + if check.GCSConnection == nil { + return results.ErrorMessage(errors.New("missing GCS connection")) } - cfg, err := gcp.NewSession(ctx.Duty(), check.GCPConnection) + var bucket string + bucket, check.Path = parseGCSPath(check.Path) + + connection, err := ctx.HydrateConnectionByURL(check.GCPConnection.ConnectionName) if err != nil { - return results.ErrorMessage(err) + return results.Failf("failed to populate GCS connection: %v", err) + } else if connection == nil { + connection = &models.Connection{Type: models.ConnectionTypeGCS} + if check.GCSConnection.Bucket == "" { + check.GCSConnection.Bucket = bucket + } + + connection, err = connection.Merge(ctx, check.GCSConnection) + if err != nil { + return results.Failf("failed to populate GCS connection: %v", err) + } } - client := GCS{ - BucketName: getGCSBucketName(check.Path), - Client: cfg, + + fs, err := artifacts.GetFSForConnection(ctx.Duty(), *connection) + if err != nil { + return results.ErrorMessage(err) } - folders, err := client.CheckFolder(ctx, check.Filter) + + folders, err := genericFolderCheckWithoutPrecheck(fs, check.Path, check.Recursive, check.Filter) if err != nil { return results.ErrorMessage(err) } result.AddDetails(folders) + if test := folders.Test(check.FolderTest); test != "" { - results.Failf(test) + return results.Failf(test) } + return results } -func (conn *GCS) CheckFolder(ctx *context.Context, filter v1.FolderFilter) (*FolderCheck, error) { - result := FolderCheck{} - bucket := conn.Bucket(conn.BucketName) - objs := bucket.Objects(ctx, nil) - _filter, err := filter.New() - if err != nil { - return nil, err - } - obj, err := objs.Next() - // empty bucket - if obj == nil { - return &result, nil - } - if err != nil { - return nil, nil +// parseGCSPath returns the bucket name and the actual path stripping of the gcs:// prefix and the bucket name. +// The path is expected to be in the format "gcs://bucket_name/" +func parseGCSPath(fullpath string) (bucket, path string) { + trimmed := strings.TrimPrefix(fullpath, "gcs://") + splits := strings.SplitN(trimmed, "/", 2) + if len(splits) != 2 { + return splits[0], "" } - for { - file := gcp.GCSFileInfo{Object: obj} - if file.IsDir() || !_filter.Filter(file) { - continue - } - - result.Append(file) - obj, err = objs.Next() - if obj == nil { - return &result, nil - } - if err != nil { - return nil, err - } - } -} -func getGCSBucketName(bucket string) string { - return strings.TrimPrefix(bucket, "gcs://") + return splits[0], splits[1] } diff --git a/checks/folder_s3.go b/checks/folder_s3.go index 98d660e0f..4542c0b99 100644 --- a/checks/folder_s3.go +++ b/checks/folder_s3.go @@ -3,18 +3,15 @@ package checks import ( - "fmt" + "errors" "strings" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" - awsUtil "github.com/flanksource/artifacts/clients/aws" + "github.com/flanksource/artifacts" "github.com/flanksource/canary-checker/api/context" v1 "github.com/flanksource/canary-checker/api/v1" "github.com/flanksource/canary-checker/pkg" - "github.com/flanksource/canary-checker/pkg/utils" - "github.com/flanksource/commons/logger" - "github.com/flanksource/duty/connection" + "github.com/flanksource/duty/models" ) type S3 struct { @@ -27,26 +24,36 @@ func CheckS3Bucket(ctx *context.Context, check v1.FolderCheck) pkg.Results { var results pkg.Results results = append(results, result) - if check.AWSConnection == nil { - check.AWSConnection = &connection.AWSConnection{} - } else if err := check.AWSConnection.Populate(ctx); err != nil { - return results.Failf("failed to populate aws connection: %v", err) + if check.S3Connection == nil { + return results.ErrorMessage(errors.New("missing AWS connection")) } - cfg, err := awsUtil.NewSession(ctx.Duty(), *check.AWSConnection) + var bucket string + bucket, check.Path = parseS3Path(check.Path) + + connection, err := ctx.HydrateConnectionByURL(check.AWSConnection.ConnectionName) if err != nil { - return results.ErrorMessage(err) + return results.Failf("failed to populate AWS connection: %v", err) + } else if connection == nil { + connection = &models.Connection{Type: models.ConnectionTypeS3} + if check.S3Connection.Bucket == "" { + check.S3Connection.Bucket = bucket + } + + connection, err = connection.Merge(ctx, check.S3Connection) + if err != nil { + return results.Failf("failed to populate AWS connection: %v", err) + } } - client := &S3{ - Client: s3.NewFromConfig(*cfg, func(o *s3.Options) { - o.UsePathStyle = check.AWSConnection.UsePathStyle - }), - Bucket: getS3BucketName(check.Path), + fs, err := artifacts.GetFSForConnection(ctx.Duty(), *connection) + if err != nil { + return results.ErrorMessage(err) } - folders, err := client.CheckFolder(ctx, check.Filter) + + folders, err := genericFolderCheckWithoutPrecheck(fs, check.Path, check.Recursive, check.Filter) if err != nil { - return results.ErrorMessage(fmt.Errorf("failed to retrieve s3://%s: %v", getS3BucketName(check.Path), err)) + return results.ErrorMessage(err) } result.AddDetails(folders) @@ -57,51 +64,14 @@ func CheckS3Bucket(ctx *context.Context, check v1.FolderCheck) pkg.Results { return results } -func (conn *S3) CheckFolder(ctx *context.Context, filter v1.FolderFilter) (*FolderCheck, error) { - result := FolderCheck{} - - var marker *string = nil - parts := strings.Split(conn.Bucket, "/") - bucket := parts[0] - prefix := "" - if len(parts) > 0 { - prefix = strings.Join(parts[1:], "/") +// parseS3Path returns the bucket name and the actual path stripping of the s3:// prefix and the bucket name. +// The path is expected to be in the format "s3://bucket_name/" +func parseS3Path(fullpath string) (bucket, path string) { + trimmed := strings.TrimPrefix(fullpath, "s3://") + splits := strings.SplitN(trimmed, "/", 2) + if len(splits) != 2 { + return splits[0], "" } - maxKeys := 500 - for { - logger.Debugf("%s fetching %d, prefix%s, marker=%s", bucket, maxKeys, prefix, marker) - req := &s3.ListObjectsInput{ - Bucket: aws.String(conn.Bucket), - Marker: marker, - MaxKeys: utils.Ptr(int32(maxKeys)), - Prefix: &prefix, - } - resp, err := conn.ListObjects(ctx, req) - if err != nil { - return nil, err - } - - _filter, err := filter.New() - if err != nil { - return nil, err - } - for _, obj := range resp.Contents { - file := awsUtil.S3FileInfo{Object: obj} - if !_filter.Filter(file) { - continue - } - result.Append(file) - } - if resp.IsTruncated != nil && *resp.IsTruncated && len(resp.Contents) > 0 { - marker = resp.Contents[len(resp.Contents)-1].Key - } else { - break - } - } - // bucketScanTotalSize.WithLabelValues(bucket.Endpoint, bucket.Bucket).Add(float64(aws.Int64Value(obj.Size))) - return &result, nil -} -func getS3BucketName(bucket string) string { - return strings.TrimPrefix(bucket, "s3://") + return splits[0], splits[1] } diff --git a/checks/folder_s3_test.go b/checks/folder_s3_test.go new file mode 100644 index 000000000..2df2aa427 --- /dev/null +++ b/checks/folder_s3_test.go @@ -0,0 +1,30 @@ +//go:build !fast + +package checks + +import "testing" + +func Test_parseS3Path(t *testing.T) { + tests := []struct { + name string + fullpath string + wantBucket string + wantPath string + }{ + {name: "basic", fullpath: "s3://mybucket/developers", wantBucket: "mybucket", wantPath: "developers"}, + {name: "basic", fullpath: "s3://mybucket", wantBucket: "mybucket", wantPath: ""}, + {name: "basic", fullpath: "mybucket", wantBucket: "mybucket", wantPath: ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotBucket, gotPath := parseS3Path(tt.fullpath) + if gotBucket != tt.wantBucket { + t.Errorf("parseS3Path() gotBucket = %v, want %v", gotBucket, tt.wantBucket) + } + if gotPath != tt.wantPath { + t.Errorf("parseS3Path() gotPath = %v, want %v", gotPath, tt.wantPath) + } + }) + } +} diff --git a/checks/folder_sftp.go b/checks/folder_sftp.go index 6e2aba8d9..eb315baf0 100644 --- a/checks/folder_sftp.go +++ b/checks/folder_sftp.go @@ -36,7 +36,7 @@ func CheckSFTP(ctx *context.Context, check v1.FolderCheck) pkg.Results { defer client.Close() session := artifacts.Filesystem(client) - folders, err := getGenericFolderCheck(session, check.Path, check.Filter) + folders, err := genericFolderCheck(session, check.Path, check.Recursive, check.Filter) if err != nil { return results.ErrorMessage(err) } diff --git a/checks/folder_smb.go b/checks/folder_smb.go index 7e0197f83..ded278ec3 100644 --- a/checks/folder_smb.go +++ b/checks/folder_smb.go @@ -42,7 +42,7 @@ func CheckSmb(ctx *context.Context, check v1.FolderCheck) pkg.Results { defer session.Close() } - folders, err := getGenericFolderCheck(session, path, check.Filter) + folders, err := genericFolderCheck(session, path, check.Recursive, check.Filter) if err != nil { return results.ErrorMessage(err) } diff --git a/checks/s3.go b/checks/s3.go index 488732d95..c95a4567a 100644 --- a/checks/s3.go +++ b/checks/s3.go @@ -81,7 +81,7 @@ func (c *S3Checker) Check(ctx *context.Context, extConfig external.Check) pkg.Re } client := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = check.AWSConnection.UsePathStyle + o.UsePathStyle = check.S3Connection.UsePathStyle }) listTimer := NewTimer() diff --git a/config/deploy/crd.yaml b/config/deploy/crd.yaml index fabd98b62..747a44316 100644 --- a/config/deploy/crd.yaml +++ b/config/deploy/crd.yaml @@ -449,9 +449,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string query: type: string region: @@ -566,9 +563,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name - query @@ -686,9 +680,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string rules: @@ -806,9 +797,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name type: object @@ -1075,9 +1063,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -1192,9 +1177,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name type: object @@ -2229,9 +2211,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -2326,9 +2305,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean userData: type: string waitTime: @@ -2767,9 +2743,6 @@ spec: type: string endpoint: type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -2857,9 +2830,6 @@ spec: skipTLSVerify: description: Skip TLS verify when connecting to aws type: boolean - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean type: object azure: properties: @@ -3138,142 +3108,11 @@ spec: type: string awsConnection: properties: - accessKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - connection: - description: ConnectionName of the connection. It'll be used to populate the endpoint, accessKey and secretKey. - type: string - endpoint: + bucket: type: string objectPath: description: glob path to restrict matches to a subset type: string - region: - type: string - secretKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - sessionToken: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - skipTLSVerify: - description: Skip TLS verify when connecting to aws - type: boolean usePathStyle: description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' type: boolean @@ -3309,6 +3148,8 @@ spec: type: object gcpConnection: properties: + bucket: + type: string connection: description: ConnectionName of the connection. It'll be used to populate the endpoint and credentials. type: string @@ -3416,6 +3257,9 @@ spec: path: description: Path to folder or object storage, e.g. `s3://`, `gcs://`, `/path/tp/folder` type: string + recursive: + description: Recursive when set to true will recursively scan the folder to list the files in it. However, symlinks are simply listed but not traversed. + type: boolean sftpConnection: properties: connection: @@ -6368,57 +6212,13 @@ spec: s3: items: properties: - accessKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - bucketName: + bucket: type: string - connection: - description: ConnectionName of the connection. It'll be used to populate the endpoint, accessKey and secretKey. + bucketName: type: string description: description: Description for the check type: string - endpoint: - type: string icon: description: Icon for overwriting default icon on the dashboard type: string @@ -6461,93 +6261,6 @@ spec: objectPath: description: glob path to restrict matches to a subset type: string - region: - type: string - secretKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - sessionToken: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - skipTLSVerify: - description: Skip TLS verify when connecting to aws - type: boolean transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string diff --git a/config/deploy/manifests.yaml b/config/deploy/manifests.yaml index 79b7a61e8..64c2c754a 100644 --- a/config/deploy/manifests.yaml +++ b/config/deploy/manifests.yaml @@ -448,9 +448,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string query: type: string region: @@ -565,9 +562,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name - query @@ -685,9 +679,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string rules: @@ -805,9 +796,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name type: object @@ -1074,9 +1062,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -1191,9 +1176,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean required: - name type: object @@ -2228,9 +2210,6 @@ spec: namespace: description: Namespace of the check type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -2325,9 +2304,6 @@ spec: transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean userData: type: string waitTime: @@ -2766,9 +2742,6 @@ spec: type: string endpoint: type: string - objectPath: - description: glob path to restrict matches to a subset - type: string region: type: string secretKey: @@ -2856,9 +2829,6 @@ spec: skipTLSVerify: description: Skip TLS verify when connecting to aws type: boolean - usePathStyle: - description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' - type: boolean type: object azure: properties: @@ -3137,142 +3107,11 @@ spec: type: string awsConnection: properties: - accessKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - connection: - description: ConnectionName of the connection. It'll be used to populate the endpoint, accessKey and secretKey. - type: string - endpoint: + bucket: type: string objectPath: description: glob path to restrict matches to a subset type: string - region: - type: string - secretKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - sessionToken: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - skipTLSVerify: - description: Skip TLS verify when connecting to aws - type: boolean usePathStyle: description: 'Use path style path: http://s3.amazonaws.com/BUCKET/KEY instead of http://BUCKET.s3.amazonaws.com/KEY' type: boolean @@ -3308,6 +3147,8 @@ spec: type: object gcpConnection: properties: + bucket: + type: string connection: description: ConnectionName of the connection. It'll be used to populate the endpoint and credentials. type: string @@ -3415,6 +3256,9 @@ spec: path: description: Path to folder or object storage, e.g. `s3://`, `gcs://`, `/path/tp/folder` type: string + recursive: + description: Recursive when set to true will recursively scan the folder to list the files in it. However, symlinks are simply listed but not traversed. + type: boolean sftpConnection: properties: connection: @@ -6367,57 +6211,13 @@ spec: s3: items: properties: - accessKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - bucketName: + bucket: type: string - connection: - description: ConnectionName of the connection. It'll be used to populate the endpoint, accessKey and secretKey. + bucketName: type: string description: description: Description for the check type: string - endpoint: - type: string icon: description: Icon for overwriting default icon on the dashboard type: string @@ -6460,93 +6260,6 @@ spec: objectPath: description: glob path to restrict matches to a subset type: string - region: - type: string - secretKey: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - sessionToken: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - helmRef: - properties: - key: - description: Key is a JSONPath expression used to fetch the key from the merged JSON. - type: string - name: - type: string - required: - - key - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - required: - - key - type: object - serviceAccount: - description: ServiceAccount specifies the service account whose token should be fetched - type: string - type: object - type: object - skipTLSVerify: - description: Skip TLS verify when connecting to aws - type: boolean transformDeleteStrategy: description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is type: string diff --git a/config/schemas/canary.schema.json b/config/schemas/canary.schema.json index 547bdce3d..a731d4c5f 100644 --- a/config/schemas/canary.schema.json +++ b/config/schemas/canary.schema.json @@ -25,12 +25,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -204,12 +198,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "aggregatorName": { "type": "string" } @@ -294,12 +282,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -829,12 +811,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "test": { "$ref": "#/$defs/Template" }, @@ -1314,12 +1290,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "ami": { "type": "string" }, @@ -1569,6 +1539,9 @@ "path": { "type": "string" }, + "recursive": { + "type": "boolean" + }, "filter": { "$ref": "#/$defs/FolderFilter" }, @@ -1597,10 +1570,10 @@ "type": "string" }, "awsConnection": { - "$ref": "#/$defs/AWSConnection" + "$ref": "#/$defs/S3Connection" }, "gcpConnection": { - "$ref": "#/$defs/GCPConnection" + "$ref": "#/$defs/GCSConnection" }, "smbConnection": { "$ref": "#/$defs/SMBConnection" @@ -1674,6 +1647,24 @@ "instance" ] }, + "GCSConnection": { + "properties": { + "connection": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "credentials": { + "$ref": "#/$defs/EnvVar" + }, + "bucket": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, "GitCheckout": { "properties": { "url": { @@ -3173,6 +3164,9 @@ "skipTLSVerify": { "type": "boolean" }, + "bucket": { + "type": "string" + }, "objectPath": { "type": "string" }, @@ -3189,6 +3183,42 @@ "name" ] }, + "S3Connection": { + "properties": { + "connection": { + "type": "string" + }, + "accessKey": { + "$ref": "#/$defs/EnvVar" + }, + "secretKey": { + "$ref": "#/$defs/EnvVar" + }, + "sessionToken": { + "$ref": "#/$defs/EnvVar" + }, + "region": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "skipTLSVerify": { + "type": "boolean" + }, + "bucket": { + "type": "string" + }, + "objectPath": { + "type": "string" + }, + "usePathStyle": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, "SFTPConnection": { "properties": { "connection": { diff --git a/config/schemas/component.schema.json b/config/schemas/component.schema.json index 9bd36a40c..ad79499e4 100644 --- a/config/schemas/component.schema.json +++ b/config/schemas/component.schema.json @@ -25,12 +25,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -204,12 +198,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "aggregatorName": { "type": "string" } @@ -294,12 +282,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -732,12 +714,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "test": { "$ref": "#/$defs/Template" }, @@ -1490,12 +1466,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "ami": { "type": "string" }, @@ -1745,6 +1715,9 @@ "path": { "type": "string" }, + "recursive": { + "type": "boolean" + }, "filter": { "$ref": "#/$defs/FolderFilter" }, @@ -1773,10 +1746,10 @@ "type": "string" }, "awsConnection": { - "$ref": "#/$defs/AWSConnection" + "$ref": "#/$defs/S3Connection" }, "gcpConnection": { - "$ref": "#/$defs/GCPConnection" + "$ref": "#/$defs/GCSConnection" }, "smbConnection": { "$ref": "#/$defs/SMBConnection" @@ -1883,6 +1856,24 @@ "instance" ] }, + "GCSConnection": { + "properties": { + "connection": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "credentials": { + "$ref": "#/$defs/EnvVar" + }, + "bucket": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, "GitCheckout": { "properties": { "url": { @@ -3522,6 +3513,9 @@ "skipTLSVerify": { "type": "boolean" }, + "bucket": { + "type": "string" + }, "objectPath": { "type": "string" }, @@ -3538,6 +3532,42 @@ "name" ] }, + "S3Connection": { + "properties": { + "connection": { + "type": "string" + }, + "accessKey": { + "$ref": "#/$defs/EnvVar" + }, + "secretKey": { + "$ref": "#/$defs/EnvVar" + }, + "sessionToken": { + "$ref": "#/$defs/EnvVar" + }, + "region": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "skipTLSVerify": { + "type": "boolean" + }, + "bucket": { + "type": "string" + }, + "objectPath": { + "type": "string" + }, + "usePathStyle": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, "SFTPConnection": { "properties": { "connection": { diff --git a/config/schemas/health_awsconfig.schema.json b/config/schemas/health_awsconfig.schema.json index 0c4343991..e276042cf 100644 --- a/config/schemas/health_awsconfig.schema.json +++ b/config/schemas/health_awsconfig.schema.json @@ -62,12 +62,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "aggregatorName": { "type": "string" } diff --git a/config/schemas/health_awsconfigrule.schema.json b/config/schemas/health_awsconfigrule.schema.json index f4d9eda4a..7dd816df6 100644 --- a/config/schemas/health_awsconfigrule.schema.json +++ b/config/schemas/health_awsconfigrule.schema.json @@ -76,12 +76,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, diff --git a/config/schemas/health_cloudwatch.schema.json b/config/schemas/health_cloudwatch.schema.json index 23dfdd017..b18b98f2f 100644 --- a/config/schemas/health_cloudwatch.schema.json +++ b/config/schemas/health_cloudwatch.schema.json @@ -50,12 +50,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "test": { "$ref": "#/$defs/Template" }, diff --git a/config/schemas/health_ec2.schema.json b/config/schemas/health_ec2.schema.json index dc53528a4..bd9eedeb9 100644 --- a/config/schemas/health_ec2.schema.json +++ b/config/schemas/health_ec2.schema.json @@ -65,12 +65,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "ami": { "type": "string" }, diff --git a/config/schemas/health_exec.schema.json b/config/schemas/health_exec.schema.json index c795af4dd..7ac9c9405 100644 --- a/config/schemas/health_exec.schema.json +++ b/config/schemas/health_exec.schema.json @@ -25,12 +25,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, diff --git a/config/schemas/health_folder.schema.json b/config/schemas/health_folder.schema.json index 5919622da..ff9f02bdf 100644 --- a/config/schemas/health_folder.schema.json +++ b/config/schemas/health_folder.schema.json @@ -3,39 +3,6 @@ "$id": "https://github.com/flanksource/canary-checker/api/v1/folder-check", "$ref": "#/$defs/FolderCheck", "$defs": { - "AWSConnection": { - "properties": { - "connection": { - "type": "string" - }, - "accessKey": { - "$ref": "#/$defs/EnvVar" - }, - "secretKey": { - "$ref": "#/$defs/EnvVar" - }, - "sessionToken": { - "$ref": "#/$defs/EnvVar" - }, - "region": { - "type": "string" - }, - "endpoint": { - "type": "string" - }, - "skipTLSVerify": { - "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - } - }, - "additionalProperties": false, - "type": "object" - }, "ConfigMapKeySelector": { "properties": { "name": { @@ -122,6 +89,9 @@ "path": { "type": "string" }, + "recursive": { + "type": "boolean" + }, "filter": { "$ref": "#/$defs/FolderFilter" }, @@ -150,10 +120,10 @@ "type": "string" }, "awsConnection": { - "$ref": "#/$defs/AWSConnection" + "$ref": "#/$defs/S3Connection" }, "gcpConnection": { - "$ref": "#/$defs/GCPConnection" + "$ref": "#/$defs/GCSConnection" }, "smbConnection": { "$ref": "#/$defs/SMBConnection" @@ -193,7 +163,7 @@ "additionalProperties": false, "type": "object" }, - "GCPConnection": { + "GCSConnection": { "properties": { "connection": { "type": "string" @@ -203,6 +173,9 @@ }, "credentials": { "$ref": "#/$defs/EnvVar" + }, + "bucket": { + "type": "string" } }, "additionalProperties": false, @@ -273,6 +246,42 @@ "additionalProperties": false, "type": "object" }, + "S3Connection": { + "properties": { + "connection": { + "type": "string" + }, + "accessKey": { + "$ref": "#/$defs/EnvVar" + }, + "secretKey": { + "$ref": "#/$defs/EnvVar" + }, + "sessionToken": { + "$ref": "#/$defs/EnvVar" + }, + "region": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "skipTLSVerify": { + "type": "boolean" + }, + "bucket": { + "type": "string" + }, + "objectPath": { + "type": "string" + }, + "usePathStyle": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, "SFTPConnection": { "properties": { "connection": { diff --git a/config/schemas/health_s3.schema.json b/config/schemas/health_s3.schema.json index 96232322c..565143b5e 100644 --- a/config/schemas/health_s3.schema.json +++ b/config/schemas/health_s3.schema.json @@ -163,6 +163,9 @@ "skipTLSVerify": { "type": "boolean" }, + "bucket": { + "type": "string" + }, "objectPath": { "type": "string" }, diff --git a/config/schemas/topology.schema.json b/config/schemas/topology.schema.json index 255ab572c..e32b0bb41 100644 --- a/config/schemas/topology.schema.json +++ b/config/schemas/topology.schema.json @@ -25,12 +25,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -204,12 +198,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "aggregatorName": { "type": "string" } @@ -294,12 +282,6 @@ }, "skipTLSVerify": { "type": "boolean" - }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" } }, "additionalProperties": false, @@ -732,12 +714,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "test": { "$ref": "#/$defs/Template" }, @@ -1460,12 +1436,6 @@ "skipTLSVerify": { "type": "boolean" }, - "objectPath": { - "type": "string" - }, - "usePathStyle": { - "type": "boolean" - }, "ami": { "type": "string" }, @@ -1715,6 +1685,9 @@ "path": { "type": "string" }, + "recursive": { + "type": "boolean" + }, "filter": { "$ref": "#/$defs/FolderFilter" }, @@ -1743,10 +1716,10 @@ "type": "string" }, "awsConnection": { - "$ref": "#/$defs/AWSConnection" + "$ref": "#/$defs/S3Connection" }, "gcpConnection": { - "$ref": "#/$defs/GCPConnection" + "$ref": "#/$defs/GCSConnection" }, "smbConnection": { "$ref": "#/$defs/SMBConnection" @@ -1853,6 +1826,24 @@ "instance" ] }, + "GCSConnection": { + "properties": { + "connection": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "credentials": { + "$ref": "#/$defs/EnvVar" + }, + "bucket": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, "GitCheckout": { "properties": { "url": { @@ -3492,6 +3483,9 @@ "skipTLSVerify": { "type": "boolean" }, + "bucket": { + "type": "string" + }, "objectPath": { "type": "string" }, @@ -3508,6 +3502,42 @@ "name" ] }, + "S3Connection": { + "properties": { + "connection": { + "type": "string" + }, + "accessKey": { + "$ref": "#/$defs/EnvVar" + }, + "secretKey": { + "$ref": "#/$defs/EnvVar" + }, + "sessionToken": { + "$ref": "#/$defs/EnvVar" + }, + "region": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "skipTLSVerify": { + "type": "boolean" + }, + "bucket": { + "type": "string" + }, + "objectPath": { + "type": "string" + }, + "usePathStyle": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, "SFTPConnection": { "properties": { "connection": { diff --git a/fixtures/datasources/GCP/database_backup.yaml b/fixtures/datasources/GCP/database_backup.yaml index 9e31b15c1..bf761b39a 100644 --- a/fixtures/datasources/GCP/database_backup.yaml +++ b/fixtures/datasources/GCP/database_backup.yaml @@ -5,7 +5,8 @@ metadata: spec: interval: 60 databaseBackup: - - maxAge: 6h + - name: backup + maxAge: 6h GCP: project: google-project-name - instance: cloudsql-instance-name \ No newline at end of file + instance: cloudsql-instance-name diff --git a/fixtures/datasources/GCP/folder_pass.yaml b/fixtures/datasources/GCP/folder_pass.yaml new file mode 100644 index 000000000..452ed6f72 --- /dev/null +++ b/fixtures/datasources/GCP/folder_pass.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: recursive-folder-check +spec: + interval: 30 + folder: + - path: gcs://folder-check-test/recursive-test + name: recursive folders + namespace: default + minCount: 3 + recursive: true + display: + expr: results.?files.orValue([]).map(i, i.name).join(", ") + gcpConnection: + connection: connection://gcs/flanksource-prod diff --git a/fixtures/datasources/main.go b/fixtures/datasources/main.go index 7bbc8b532..5da4ed1ec 100644 --- a/fixtures/datasources/main.go +++ b/fixtures/datasources/main.go @@ -155,6 +155,7 @@ var ( CreateBuckets: []string{ "tests-e2e-1", "tests-e2e-2", + "recursive-test", }, Files: []S3FixtureFile{ { @@ -178,6 +179,34 @@ var ( Age: 7*24*time.Hour - 10*time.Minute, // 30 days ContentType: "application/zip", }, + { + Bucket: "recursive-test", + Filename: "developers/john.txt", + Size: 30, + Age: 7*24*time.Hour - 10*time.Minute, // 30 days + ContentType: "text/plain", + }, + { + Bucket: "recursive-test", + Filename: "developers/backend/james.txt", + Size: 40, + Age: 7*24*time.Hour - 10*time.Minute, // 30 days + ContentType: "text/plain", + }, + { + Bucket: "recursive-test", + Filename: "developers/backend/go/aditya.txt", + Size: 50, + Age: 7*24*time.Hour - 10*time.Minute, // 30 days + ContentType: "text/plain", + }, + { + Bucket: "recursive-test", + Filename: "developers/backend/node/taylor.txt", + Size: 60, + Age: 7*24*time.Hour - 10*time.Minute, // 30 days + ContentType: "text/plain", + }, }, } ) diff --git a/fixtures/datasources/s3_bucket_pass.yaml b/fixtures/datasources/s3_bucket_pass.yaml index 78e21e5a5..ae9f8fd46 100644 --- a/fixtures/datasources/s3_bucket_pass.yaml +++ b/fixtures/datasources/s3_bucket_pass.yaml @@ -8,7 +8,7 @@ spec: folder: # Check for any backup not older than 7 days and min size 25 bytes - path: s3://tests-e2e-1 - name: mysql backup check + name: mysql backup check awsConnection: accessKey: valueFrom: @@ -72,3 +72,25 @@ spec: regex: "pg\\/backups\\/(.*)\\/backup.zip$" maxAge: 7d minSize: 25b + - name: recursive folders + namespace: default + path: s3://recursive-test/developers + minCount: 3 + recursive: true + display: + expr: results.?files.orValue([]).map(i, i.name).join(", ") + awsConnection: + region: "minio" + endpoint: "http://minio.minio:9000" + usePathStyle: true + skipTLSVerify: true + accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY diff --git a/go.mod b/go.mod index e2ca1e240..709860d4a 100644 --- a/go.mod +++ b/go.mod @@ -19,10 +19,10 @@ require ( github.com/eko/gocache/lib/v4 v4.1.5 github.com/eko/gocache/store/bigcache/v4 v4.2.1 github.com/elastic/go-elasticsearch/v8 v8.10.1 - github.com/fergusstrange/embedded-postgres v1.24.0 - github.com/flanksource/artifacts v1.0.0 + github.com/fergusstrange/embedded-postgres v1.25.0 + github.com/flanksource/artifacts v1.0.3 github.com/flanksource/commons v1.19.2 - github.com/flanksource/duty v1.0.245 + github.com/flanksource/duty v1.0.247 github.com/flanksource/gomplate/v3 v3.20.26 github.com/flanksource/is-healthy v0.0.0-20231003215854-76c51e3a3ff7 github.com/flanksource/kommons v0.31.4 @@ -58,6 +58,7 @@ require ( github.com/prometheus/common v0.45.0 github.com/robertkrimen/otto v0.2.1 github.com/robfig/cron/v3 v3.0.1 + github.com/samber/lo v1.39.0 github.com/sevennt/echo-pprof v0.1.1-0.20220616082843-66a461746b5f github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 @@ -215,7 +216,6 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/samber/lo v1.39.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/sirupsen/logrus v1.9.3 // indirect diff --git a/go.sum b/go.sum index a9bb5a09a..7351a6b24 100644 --- a/go.sum +++ b/go.sum @@ -614,7 +614,6 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybI github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= @@ -627,7 +626,6 @@ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86 github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= @@ -665,8 +663,6 @@ github.com/antonmedv/expr v1.15.5/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4J github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -743,7 +739,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -824,14 +819,14 @@ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fergusstrange/embedded-postgres v1.24.0 h1:WqXbmYrBeT5JfNWQ8Qa+yHa5YJO/0sBIgL9k5rn3dFk= -github.com/fergusstrange/embedded-postgres v1.24.0/go.mod h1:wL562t1V+iuFwq0UcgMi2e9rp8CROY9wxWZEfP8Y874= -github.com/flanksource/artifacts v1.0.0 h1:Fer3firlsI1L0YoOoUOw77w7j4PgtMkNTsQDYz7ViE8= -github.com/flanksource/artifacts v1.0.0/go.mod h1:KWGcGNGTJe+wb/Pv31thiWsNSdhu7iWqRO/hApLflyA= +github.com/fergusstrange/embedded-postgres v1.25.0 h1:sa+k2Ycrtz40eCRPOzI7Ry7TtkWXXJ+YRsxpKMDhxK0= +github.com/fergusstrange/embedded-postgres v1.25.0/go.mod h1:t/MLs0h9ukYM6FSt99R7InCHs1nW0ordoVCcnzmpTYw= +github.com/flanksource/artifacts v1.0.3 h1:Ci26mDhVFyxPefX96tgPGTe5fR0wfntXotSxaPyrAzk= +github.com/flanksource/artifacts v1.0.3/go.mod h1:KfDDG7B4wsiGqJYOamcRU19u5hBvpYjlru3GfcORvko= github.com/flanksource/commons v1.19.2 h1:6JAnKzBBk5iUROrR79dm7Bzbg9beAiFTehkTeZyI2/g= github.com/flanksource/commons v1.19.2/go.mod h1:k+3B7McXUOS+TirYFR9h0pPk6mHNG3dqVUEY9gKI3/U= -github.com/flanksource/duty v1.0.245 h1:tfyrbQ//WFxni6lFQKuYNbPgoPvzKOU/0fBh0pXCp2g= -github.com/flanksource/duty v1.0.245/go.mod h1:nhvoArC48DByxrRvvcCKwRfbAfn9wUbo4YWietT9t7I= +github.com/flanksource/duty v1.0.247 h1:ohgKvccKlfHMC2lLvvH2DBTI3FHAUt3vZvrf9hoeDu4= +github.com/flanksource/duty v1.0.247/go.mod h1:nhvoArC48DByxrRvvcCKwRfbAfn9wUbo4YWietT9t7I= github.com/flanksource/gomplate/v3 v3.20.4/go.mod h1:27BNWhzzSjDed1z8YShO6W+z6G9oZXuxfNFGd/iGSdc= github.com/flanksource/gomplate/v3 v3.20.26 h1:85lUzlKgZjb1uIkzoa4zN03OcdOnFPG+oWxshZTYqz4= github.com/flanksource/gomplate/v3 v3.20.26/go.mod h1:GKmptFMdr2LbOuqwQZrmo9a/UygyZ0pbXffks8MuYhE= @@ -947,7 +942,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -1127,8 +1121,6 @@ github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6 github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= @@ -1138,12 +1130,10 @@ github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf h1:I1sbT4ZbI github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf/go.mod h1:jDHmWDKZY6MIIYltYYfW4Rs7hQ50oS4qf/6spSiZAxY= github.com/hairyhenderson/yaml v0.0.0-20220618171115-2d35fca545ce h1:cVkYhlWAxwuS2/Yp6qPtcl0fGpcWxuZNonywHZ6/I+s= github.com/hairyhenderson/yaml v0.0.0-20220618171115-2d35fca545ce/go.mod h1:7TyiGlHI+IO+iJbqRZ82QbFtvgj/AIcFm5qc9DLn7Kc= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= @@ -1193,7 +1183,6 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= @@ -1447,7 +1436,6 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= @@ -1461,7 +1449,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= @@ -1541,7 +1528,6 @@ github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1 github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ= @@ -1561,7 +1547,6 @@ github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= diff --git a/hack/generate-schemas/go.mod b/hack/generate-schemas/go.mod index 34381f066..41da6d0af 100644 --- a/hack/generate-schemas/go.mod +++ b/hack/generate-schemas/go.mod @@ -43,7 +43,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/flanksource/duty v1.0.245 // indirect + github.com/flanksource/duty v1.0.247 // indirect github.com/flanksource/is-healthy v0.0.0-20231003215854-76c51e3a3ff7 // indirect github.com/flanksource/kommons v0.31.4 // indirect github.com/ghodss/yaml v1.0.0 // indirect diff --git a/hack/generate-schemas/go.sum b/hack/generate-schemas/go.sum index 01af2f12d..42149ccbc 100644 --- a/hack/generate-schemas/go.sum +++ b/hack/generate-schemas/go.sum @@ -715,8 +715,8 @@ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flanksource/commons v1.19.2 h1:6JAnKzBBk5iUROrR79dm7Bzbg9beAiFTehkTeZyI2/g= github.com/flanksource/commons v1.19.2/go.mod h1:k+3B7McXUOS+TirYFR9h0pPk6mHNG3dqVUEY9gKI3/U= -github.com/flanksource/duty v1.0.245 h1:tfyrbQ//WFxni6lFQKuYNbPgoPvzKOU/0fBh0pXCp2g= -github.com/flanksource/duty v1.0.245/go.mod h1:nhvoArC48DByxrRvvcCKwRfbAfn9wUbo4YWietT9t7I= +github.com/flanksource/duty v1.0.247 h1:ohgKvccKlfHMC2lLvvH2DBTI3FHAUt3vZvrf9hoeDu4= +github.com/flanksource/duty v1.0.247/go.mod h1:nhvoArC48DByxrRvvcCKwRfbAfn9wUbo4YWietT9t7I= github.com/flanksource/gomplate/v3 v3.20.4/go.mod h1:27BNWhzzSjDed1z8YShO6W+z6G9oZXuxfNFGd/iGSdc= github.com/flanksource/gomplate/v3 v3.20.26 h1:85lUzlKgZjb1uIkzoa4zN03OcdOnFPG+oWxshZTYqz4= github.com/flanksource/gomplate/v3 v3.20.26/go.mod h1:GKmptFMdr2LbOuqwQZrmo9a/UygyZ0pbXffks8MuYhE=