diff --git a/.bingo/bingo.mod b/.bingo/bingo.mod index 2b2b5467e8..271199eabe 100644 --- a/.bingo/bingo.mod +++ b/.bingo/bingo.mod @@ -1,5 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 require github.com/bwplotka/bingo v0.10.0 diff --git a/.bingo/gci.mod b/.bingo/gci.mod index c1a38bbaea..8057ec6aa3 100644 --- a/.bingo/gci.mod +++ b/.bingo/gci.mod @@ -1,5 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 require github.com/daixiang0/gci v0.14.0 diff --git a/.bingo/go-bindata.mod b/.bingo/go-bindata.mod index 6ec3c50faf..e911d0144f 100644 --- a/.bingo/go-bindata.mod +++ b/.bingo/go-bindata.mod @@ -1,5 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 require github.com/go-bindata/go-bindata v3.1.2+incompatible // go-bindata diff --git a/.bingo/golangci-lint.mod b/.bingo/golangci-lint.mod index 52b5c8bb78..033d71f80b 100644 --- a/.bingo/golangci-lint.mod +++ b/.bingo/golangci-lint.mod @@ -1,5 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 require github.com/golangci/golangci-lint/v2 v2.12.2 // cmd/golangci-lint diff --git a/.bingo/goreleaser.mod b/.bingo/goreleaser.mod index 06401f9044..94a0e6be87 100644 --- a/.bingo/goreleaser.mod +++ b/.bingo/goreleaser.mod @@ -1,6 +1,6 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 require ( al.essio.dev/pkg/shellescape v1.6.0 // indirect diff --git a/.bingo/mockgen.mod b/.bingo/mockgen.mod index 177c08515b..5a47ec5cf8 100644 --- a/.bingo/mockgen.mod +++ b/.bingo/mockgen.mod @@ -1,3 +1,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT -go 1.25.8 +go 1.26.3 + +require go.uber.org/mock v0.4.0 // mockgen diff --git a/Dockerfile b/Dockerfile index 03cbc28671..6d2d02a73e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/go-toolset:1.25.8 AS builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.26.3 AS builder COPY --chown=1001:0 . . ENV GOFLAGS=-buildvcs=false diff --git a/cmd/create/iamserviceaccount/cmd.go b/cmd/create/iamserviceaccount/cmd.go index 365c043cef..14f5800584 100644 --- a/cmd/create/iamserviceaccount/cmd.go +++ b/cmd/create/iamserviceaccount/cmd.go @@ -37,7 +37,9 @@ func NewCreateIamServiceAccountCommand() *cobra.Command { var Cmd = NewCreateIamServiceAccountCommand() -func CreateIamServiceAccountRunner(userOptions *iamServiceAccountOpts.CreateIamServiceAccountUserOptions) rosa.CommandRunner { +func CreateIamServiceAccountRunner( + userOptions *iamServiceAccountOpts.CreateIamServiceAccountUserOptions, +) rosa.CommandRunner { return func(ctx context.Context, r *rosa.Runtime, cmd *cobra.Command, argv []string) error { cluster := r.FetchCluster() @@ -75,7 +77,11 @@ func CreateIamServiceAccountRunner(userOptions *iamServiceAccountOpts.CreateIamS if len(userOptions.ServiceAccountNames) > 1 { return fmt.Errorf("role name is required when specifying multiple service accounts") } - roleName = iamserviceaccount.GenerateRoleName(cluster.Name(), userOptions.Namespace, userOptions.ServiceAccountNames[0]) + roleName = iamserviceaccount.GenerateRoleName( + cluster.Name(), + userOptions.Namespace, + userOptions.ServiceAccountNames[0], + ) } serviceAccounts := make([]iamserviceaccount.ServiceAccountIdentifier, len(userOptions.ServiceAccountNames)) @@ -92,10 +98,23 @@ func CreateIamServiceAccountRunner(userOptions *iamServiceAccountOpts.CreateIamS } trustPolicy := iamserviceaccount.GenerateTrustPolicyMultiple(oidcProviderARN, serviceAccounts) - tags := iamserviceaccount.GenerateDefaultTags(cluster.Name(), userOptions.Namespace, userOptions.ServiceAccountNames[0]) + tags := iamserviceaccount.GenerateDefaultTags( + cluster.Name(), + userOptions.Namespace, + userOptions.ServiceAccountNames[0], + ) managedPolicies := false - roleARN, err := r.AWSClient.EnsureRole(r.Reporter, roleName, trustPolicy, userOptions.PermissionsBoundary, "", tags, userOptions.Path, managedPolicies) + roleARN, err := r.AWSClient.EnsureRole( + r.Reporter, + roleName, + trustPolicy, + userOptions.PermissionsBoundary, + "", + tags, + userOptions.Path, + managedPolicies, + ) if err != nil { return fmt.Errorf("failed to create role: %s", err) } @@ -120,8 +139,8 @@ func CreateIamServiceAccountRunner(userOptions *iamServiceAccountOpts.CreateIamS inlinePolicy := userOptions.InlinePolicy // Process inline policy if it's a file reference - if strings.HasPrefix(inlinePolicy, "file://") { - policyPath := strings.TrimPrefix(inlinePolicy, "file://") + if after, ok := strings.CutPrefix(inlinePolicy, "file://"); ok { + policyPath := after policyBytes, err := os.ReadFile(policyPath) if err != nil { return fmt.Errorf("failed to read policy file '%s': %s", policyPath, err) diff --git a/cmd/create/idp/cmd.go b/cmd/create/idp/cmd.go index 33241b183e..cc5aa84ac6 100644 --- a/cmd/create/idp/cmd.go +++ b/cmd/create/idp/cmd.go @@ -444,20 +444,20 @@ func getIDPName(cmd *cobra.Command, idpName string, r *rosa.Runtime) string { return strings.Trim(idpName, " \t") } -func ValidateIdpName(idpName interface{}) error { +func ValidateIdpName(idpName any) error { name, ok := idpName.(string) if !ok { - return fmt.Errorf("Invalid type for identity provider name. Expected a string, got %T", idpName) + return fmt.Errorf("invalid type for identity provider name: expected a string, got %T", idpName) } if !idRE.MatchString(name) { - return fmt.Errorf("Invalid identifier '%s' for 'name'", idpName) + return fmt.Errorf("invalid identifier '%s' for 'name'", idpName) } if strings.EqualFold(name, "cluster-admin") { - return fmt.Errorf("The name \"cluster-admin\" is reserved for admin user IDP") + return fmt.Errorf("the name \"cluster-admin\" is reserved for admin user IDP") } return nil } @@ -550,7 +550,7 @@ func getMappingMethod(cmd *cobra.Command, mappingMethod string) (string, error) } } if !isValidMappingMethod { - err = fmt.Errorf("Expected a valid mapping method. Options are %s", validMappingMethods) + err = fmt.Errorf("expected a valid mapping method; options are %s", validMappingMethods) } return mappingMethod, err } diff --git a/cmd/create/idp/htpasswd.go b/cmd/create/idp/htpasswd.go index a5f660320d..c6fa007e1c 100644 --- a/cmd/create/idp/htpasswd.go +++ b/cmd/create/idp/htpasswd.go @@ -256,7 +256,7 @@ func exitHTPasswdCreate(format, clusterKey string, err error, r *rosa.Runtime) { os.Exit(1) } -func UsernameValidator(val interface{}) error { +func UsernameValidator(val any) error { if username, ok := val.(string); ok { if strings.ContainsAny(username, "/:%") { return fmt.Errorf("invalid username '%s': "+ @@ -267,7 +267,7 @@ func UsernameValidator(val interface{}) error { return fmt.Errorf("can only validate strings, got '%v'", val) } -func clusterAdminValidator(val interface{}) error { +func clusterAdminValidator(val any) error { if username, ok := val.(string); ok { if username == ClusterAdminUsername { return fmt.Errorf("username '%s' is not allowed. It is preserved for cluster admin creation. "+ @@ -302,7 +302,7 @@ func parseHtpasswordFile(usersList *map[string]string, filePath string) error { // split "user:password" at colon username, password, found := strings.Cut(line, ":") if !found || username == "" || password == "" { - return fmt.Errorf("Malformed line, Expected: validUsername:validPassword, Got: %s", line) + return fmt.Errorf("malformed line, expected validUsername:validPassword, got: %s", line) } (*usersList)[username] = password diff --git a/cmd/edit/ingress/flags.go b/cmd/edit/ingress/flags.go index 6a819bc9c2..436162346c 100644 --- a/cmd/edit/ingress/flags.go +++ b/cmd/edit/ingress/flags.go @@ -2,13 +2,14 @@ package ingress import ( "fmt" + "slices" "strings" cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" "github.com/spf13/pflag" "github.com/openshift/rosa/pkg/helper" - . "github.com/openshift/rosa/pkg/ingress" + pkgingress "github.com/openshift/rosa/pkg/ingress" ) type stringTransformation func(source string) string @@ -47,13 +48,7 @@ var expectedParameters = []string{ } func IsIngressV2SetViaCLI(flags *pflag.FlagSet) bool { - for _, parameter := range exclusivelyIngressV2Flags { - if flags.Changed(parameter) { - return true - } - } - - return false + return slices.ContainsFunc(exclusivelyIngressV2Flags, flags.Changed) } func addIngressV2Flags(flags *pflag.FlagSet) { @@ -70,7 +65,7 @@ func addIngressV2Flags(flags *pflag.FlagSet) { wildcardPolicyFlag, "", fmt.Sprintf("Wildcard Policy for ingress. Options are %s. Default is '%s'.", - strings.Join(ValidWildcardPolicies, ","), DefaultWildcardPolicy), + strings.Join(pkgingress.ValidWildcardPolicies, ","), pkgingress.DefaultWildcardPolicy), ) flags.StringVar( @@ -78,7 +73,7 @@ func addIngressV2Flags(flags *pflag.FlagSet) { namespaceOwnershipPolicyFlag, "", fmt.Sprintf("Namespace Ownership Policy for ingress. Options are %s. Default is '%s'.", - strings.Join(ValidNamespaceOwnershipPolicies, ","), DefaultNamespaceOwnershipPolicy), + strings.Join(pkgingress.ValidNamespaceOwnershipPolicies, ","), pkgingress.DefaultNamespaceOwnershipPolicy), ) flags.StringVar( @@ -158,9 +153,10 @@ func parseComponentRoutes(input string) (map[string]*cmv1.ComponentRouteBuilder, parameterValue = t(parameterValue) } // TODO: use reflection, couldn't get it to work - if parameterName == hostnameParameter { + switch parameterName { + case hostnameParameter: componentRouteBuilder.Hostname(parameterValue) - } else if parameterName == tlsSecretRefParameter { + case tlsSecretRefParameter: componentRouteBuilder.TlsSecretRef(parameterValue) } } diff --git a/cmd/list/accessrequests/cmd.go b/cmd/list/accessrequests/cmd.go index 7d40f027ff..e24c7814a4 100644 --- a/cmd/list/accessrequests/cmd.go +++ b/cmd/list/accessrequests/cmd.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strings" "text/tabwriter" "time" @@ -85,7 +86,8 @@ func ListAccessRequestsRunner() rosa.CommandRunner { } func getAccessRequestsOutput(clusterId string, accessRequests []*v1.AccessRequest) (string, bool, string) { - output := "STATE\tID\tCLUSTER ID\tUPDATED AT\n" + var output strings.Builder + output.WriteString("STATE\tID\tCLUSTER ID\tUPDATED AT\n") hasPending := false id := "" for _, accessRequest := range accessRequests { @@ -95,12 +97,12 @@ func getAccessRequestsOutput(clusterId string, accessRequests []*v1.AccessReques id = accessRequest.ID() } } - output += fmt.Sprintf("%s\t%s\t%s\t%s\n", + fmt.Fprintf(&output, "%s\t%s\t%s\t%s\n", accessRequest.Status().State(), accessRequest.ID(), accessRequest.ClusterId(), accessRequest.UpdatedAt().Format(time.UnixDate)) } - return output, hasPending, id + return output.String(), hasPending, id } diff --git a/cmd/list/imagemirrors/cmd.go b/cmd/list/imagemirrors/cmd.go index d0f29220cb..17c4c12267 100644 --- a/cmd/list/imagemirrors/cmd.go +++ b/cmd/list/imagemirrors/cmd.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "os" + "strings" "text/tabwriter" "github.com/spf13/cobra" @@ -71,7 +72,7 @@ func ListImageMirrorsRunner(options *ListImageMirrorsOptions) rosa.CommandRunner } imageMirrors, err := runtime.OCMClient.ListImageMirrors(cluster.ID()) if err != nil { - return fmt.Errorf("Failed to list image mirrors: %v", err) + return fmt.Errorf("failed to list image mirrors: %v", err) } if output.HasFlag() { @@ -88,13 +89,13 @@ func ListImageMirrorsRunner(options *ListImageMirrorsOptions) rosa.CommandRunner fmt.Fprintf(writer, "ID\tTYPE\tSOURCE\tMIRRORS\n") for _, mirror := range imageMirrors { - mirrors := "" + var mirrors strings.Builder if len(mirror.Mirrors()) > 0 { for i, m := range mirror.Mirrors() { if i > 0 { - mirrors += ", " + mirrors.WriteString(", ") } - mirrors += m + mirrors.WriteString(m) } } @@ -102,7 +103,7 @@ func ListImageMirrorsRunner(options *ListImageMirrorsOptions) rosa.CommandRunner mirror.ID(), mirror.Type(), mirror.Source(), - mirrors, + mirrors.String(), ) } diff --git a/cmd/list/imagemirrors/cmd_test.go b/cmd/list/imagemirrors/cmd_test.go index 71fed7b22c..ab014a3be0 100644 --- a/cmd/list/imagemirrors/cmd_test.go +++ b/cmd/list/imagemirrors/cmd_test.go @@ -147,7 +147,7 @@ var _ = Describe("List image mirrors", func() { Expect(err).ToNot(HaveOccurred()) err = runner(context.Background(), t.RosaRuntime, cmd, []string{}) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Failed to list image mirrors")) + Expect(err.Error()).To(ContainSubstring("failed to list image mirrors")) }) }) diff --git a/go.mod b/go.mod index 388e567219..392576826a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openshift/rosa -go 1.25.8 +go 1.26.3 require ( github.com/AlecAivazis/survey/v2 v2.3.7 diff --git a/images/Dockerfile.e2e b/images/Dockerfile.e2e index a57bdbfffc..6add3c8dc8 100644 --- a/images/Dockerfile.e2e +++ b/images/Dockerfile.e2e @@ -1,5 +1,5 @@ # The image is for Prow CI steps to manage the ROSA cluster lifecycle and testing -FROM registry.access.redhat.com/ubi9/go-toolset:1.25.8 as builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.26.3 as builder WORKDIR /rosa USER root ENV GOBIN=/go/bin @@ -13,13 +13,13 @@ RUN go test -c -o /go/bin/rosatest ./tests/e2e RUN rosa verify openshift-client RUN rosatest --ginkgo.no-color --ginkgo.label-filter "e2e-commit" -FROM registry.access.redhat.com/ubi9/go-toolset:1.25.8 AS rosa-support +FROM registry.access.redhat.com/ubi9/go-toolset:1.26.3 AS rosa-support WORKDIR /opt/app-root/src/rosa-support RUN go install github.com/openshift-online/rosa-support@latest FROM registry.ci.openshift.org/ci/cli-ocm:latest as ocmcli -FROM registry.access.redhat.com/ubi9/go-toolset:1.25.8 +FROM registry.access.redhat.com/ubi9/go-toolset:1.26.3 USER root COPY --from=builder /go/bin/rosa* /usr/bin COPY --from=builder /rosa/tests/ci/data /rosa/tests/ci/data diff --git a/images/Dockerfile.konflux b/images/Dockerfile.konflux index 3a31fee397..604b55a530 100644 --- a/images/Dockerfile.konflux +++ b/images/Dockerfile.konflux @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/go-toolset:1.25.8 AS builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.26.3 AS builder WORKDIR /rosa USER root COPY . . diff --git a/pkg/fedramp/config.go b/pkg/fedramp/config.go index dc4fdaec12..ce6405105d 100644 --- a/pkg/fedramp/config.go +++ b/pkg/fedramp/config.go @@ -19,17 +19,15 @@ limitations under the License. package fedramp -import "fmt" +import ( + "fmt" + "slices" +) var regions = []string{"us-gov-west-1", "us-gov-east-1"} func IsGovRegion(region string) bool { - for _, r := range regions { - if r == region { - return true - } - } - return false + return slices.Contains(regions, region) } func IsValidEnv(env string) bool { @@ -43,61 +41,68 @@ func IsValidEnv(env string) bool { // JumpAccounts are the various of AWS accounts used for the installer jump role in the various OCM environments var JumpAccounts = map[string]string{ - "production": "448648337690", - "staging": "448870092490", - "staging01": "448870092490", - "integration": "449053620653", + envProduction: "448648337690", + envStaging: "448870092490", + envStaging01: "448870092490", + envIntegration: "449053620653", } // LoginURLs allows the value of the `--env` option to map to the various login URLs. var LoginURLs = map[string]string{ - "production": "https://api.openshiftusgov.com/auth", - "staging": "https://api.stage.openshiftusgov.com/auth", - "staging01": "https://api01.stage.openshiftusgov.com/auth", - "integration": "https://api.int.openshiftusgov.com/auth", + envProduction: "https://api.openshiftusgov.com/auth", + envStaging: "https://api.stage.openshiftusgov.com/auth", + envStaging01: "https://api01.stage.openshiftusgov.com/auth", + envIntegration: "https://api.int.openshiftusgov.com/auth", } // AdminLoginURLs allows the value of the `--env` option to map to the various Admin login URLs. var AdminLoginURLs = map[string]string{ - "production": "https://api-admin.openshiftusgov.com/auth", - "staging": "https://api-admin.stage.openshiftusgov.com/auth", - "staging01": "https://api.stage.openshiftusgov.com/auth", - "integration": "https://api-admin.int.openshiftusgov.com/auth", + envProduction: "https://api-admin.openshiftusgov.com/auth", + envStaging: "https://api-admin.stage.openshiftusgov.com/auth", + envStaging01: "https://api.stage.openshiftusgov.com/auth", + envIntegration: "https://api-admin.int.openshiftusgov.com/auth", } // URLAliases allows the value of the `--env` option to map to the various API URLs. var URLAliases = map[string]string{ - "production": "https://api.openshiftusgov.com", - "staging": "https://api.stage.openshiftusgov.com", - "staging01": "https://api01.stage.openshiftusgov.com", - "integration": "https://api.int.openshiftusgov.com", + envProduction: "https://api.openshiftusgov.com", + envStaging: "https://api.stage.openshiftusgov.com", + envStaging01: "https://api01.stage.openshiftusgov.com", + envIntegration: "https://api.int.openshiftusgov.com", } // AdminURLAliases allows the value of the `--env` option to map to the various Admin API URLs. var AdminURLAliases = map[string]string{ - "production": "https://api-admin.openshiftusgov.com", - "staging": "https://api-admin.stage.openshiftusgov.com", - "staging01": "https://api01.stage.openshiftusgov.com", - "integration": "https://api-admin.int.openshiftusgov.com", + envProduction: "https://api-admin.openshiftusgov.com", + envStaging: "https://api-admin.stage.openshiftusgov.com", + envStaging01: "https://api01.stage.openshiftusgov.com", + envIntegration: "https://api-admin.int.openshiftusgov.com", } const cognitoURL = "auth-fips.us-gov-west-1.amazoncognito.com/oauth2/token" const keycloakURL = "realms/redhat-external/protocol/openid-connect/token" +const ( + envProduction = "production" + envStaging = "staging" + envStaging01 = "staging01" + envIntegration = "integration" +) + // TokenURLs allows the value of the `--env` option to map to the various AWS Cognito token URLs. var TokenURLs = map[string]string{ - "production": fmt.Sprintf("https://sso.openshiftusgov.com/%s", keycloakURL), - "staging": fmt.Sprintf("https://sso.stage.openshiftusgov.com/%s", keycloakURL), - "staging01": fmt.Sprintf("https://sso01.stage.openshiftusgov.com/%s", keycloakURL), - "integration": fmt.Sprintf("https://sso.int.openshiftusgov.com/%s", keycloakURL), + envProduction: fmt.Sprintf("https://sso.openshiftusgov.com/%s", keycloakURL), + envStaging: fmt.Sprintf("https://sso.stage.openshiftusgov.com/%s", keycloakURL), + envStaging01: fmt.Sprintf("https://sso01.stage.openshiftusgov.com/%s", keycloakURL), + envIntegration: fmt.Sprintf("https://sso.int.openshiftusgov.com/%s", keycloakURL), } // AdminTokenURLs allows the value of the `--env` option to map to the various Admin AWS Cognito token URLs. var AdminTokenURLs = map[string]string{ - "production": fmt.Sprintf("https://ocm-ra-production-domain.%s", cognitoURL), - "staging": fmt.Sprintf("https://ocm-ra-stage-domain.%s", cognitoURL), - "staging01": fmt.Sprintf("https://ocm-ra-stage-domain.%s", cognitoURL), - "integration": fmt.Sprintf("https://rh-ocm-appsre-integration.%s", cognitoURL), + envProduction: fmt.Sprintf("https://ocm-ra-production-domain.%s", cognitoURL), + envStaging: fmt.Sprintf("https://ocm-ra-stage-domain.%s", cognitoURL), + envStaging01: fmt.Sprintf("https://ocm-ra-stage-domain.%s", cognitoURL), + envIntegration: fmt.Sprintf("https://rh-ocm-appsre-integration.%s", cognitoURL), } // ClientID stores the client id for use with all `--env` options for Keycloak authentication flow. @@ -106,8 +111,8 @@ var ClientID = "console-dot" // AdminClientIDs allows the value of the `--env` option to map to the various Admin AWS Cognito user pool clients. var AdminClientIDs = map[string]string{ - "production": "72ekjh5laouap6qcfis521jlgi", - "staging": "1lb687dlpsmsfuj53r3je06vpp", - "staging01": "1lb687dlpsmsfuj53r3je06vpp", - "integration": "20fbrpgl28f8oehp6709mk3nnr", + envProduction: "72ekjh5laouap6qcfis521jlgi", + envStaging: "1lb687dlpsmsfuj53r3je06vpp", + envStaging01: "1lb687dlpsmsfuj53r3je06vpp", + envIntegration: "20fbrpgl28f8oehp6709mk3nnr", } diff --git a/pkg/helper/url/helpers.go b/pkg/helper/url/helpers.go index 0794f3ec05..e277114a4f 100644 --- a/pkg/helper/url/helpers.go +++ b/pkg/helper/url/helpers.go @@ -99,12 +99,12 @@ func validateIPv6LiteralHost(rawURL string) error { } func getAuthority(rawURL string) (string, bool) { - schemeIdx := strings.Index(rawURL, "://") - if schemeIdx == -1 { + _, after, ok := strings.Cut(rawURL, "://") + if !ok { return "", false } - authority := rawURL[schemeIdx+len("://"):] + authority := after if endIdx := strings.IndexAny(authority, "/?#"); endIdx != -1 { authority = authority[:endIdx] } diff --git a/pkg/iamserviceaccount/helpers.go b/pkg/iamserviceaccount/helpers.go index f165eab5a2..370b26290f 100644 --- a/pkg/iamserviceaccount/helpers.go +++ b/pkg/iamserviceaccount/helpers.go @@ -17,6 +17,7 @@ package iamserviceaccount import ( "fmt" "regexp" + "slices" "strings" ) @@ -140,14 +141,15 @@ func GenerateTrustPolicyMultiple(oidcProviderARN string, serviceAccounts []Servi }`, oidcProviderARN, oidcProviderURL, subjects[0]) } else { // Multiple subjects - use array format - subjectsJSON := `[` + var subjectsJSON strings.Builder + subjectsJSON.WriteString(`[`) for i, subject := range subjects { if i > 0 { - subjectsJSON += ", " + subjectsJSON.WriteString(", ") } - subjectsJSON += fmt.Sprintf(`"%s"`, subject) + fmt.Fprintf(&subjectsJSON, `"%s"`, subject) } - subjectsJSON += `]` + subjectsJSON.WriteString(`]`) trustPolicy = fmt.Sprintf(`{ "Version": "2012-10-17", @@ -165,7 +167,7 @@ func GenerateTrustPolicyMultiple(oidcProviderARN string, serviceAccounts []Servi } } ] -}`, oidcProviderARN, oidcProviderURL, subjectsJSON) +}`, oidcProviderARN, oidcProviderURL, subjectsJSON.String()) } return trustPolicy @@ -182,7 +184,10 @@ func ValidateServiceAccountName(name string) error { } if !ServiceAccountNameRE.MatchString(name) { - return fmt.Errorf("service account name must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character") + return fmt.Errorf( + "service account name must consist of lower case alphanumeric characters, '-' or '.', " + + "and must start and end with an alphanumeric character", + ) } return nil @@ -199,15 +204,16 @@ func ValidateNamespaceName(name string) error { } if !NamespaceNameRE.MatchString(name) { - return fmt.Errorf("namespace name must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character") + return fmt.Errorf( + "namespace name must consist of lower case alphanumeric characters or '-', " + + "and must start and end with an alphanumeric character", + ) } // Reserved namespaces (only system namespaces) reserved := []string{"kube-system", "kube-public", "kube-node-lease"} - for _, r := range reserved { - if name == r { - return fmt.Errorf("namespace '%s' is reserved and cannot be used", name) - } + if slices.Contains(reserved, name) { + return fmt.Errorf("namespace '%s' is reserved and cannot be used", name) } return nil @@ -233,11 +239,11 @@ func GetRoleARN(accountID, roleName, path, partition string) string { } // ServiceAccountNameValidator is an interactive validator for service account names -func ServiceAccountNameValidator(val interface{}) error { +func ServiceAccountNameValidator(val any) error { return ValidateServiceAccountName(val.(string)) } // NamespaceNameValidator is an interactive validator for namespace names -func NamespaceNameValidator(val interface{}) error { +func NamespaceNameValidator(val any) error { return ValidateNamespaceName(val.(string)) } diff --git a/pkg/input/helper.go b/pkg/input/helper.go index 93add86996..516f6f3d0a 100644 --- a/pkg/input/helper.go +++ b/pkg/input/helper.go @@ -8,8 +8,8 @@ import ( ) // UnmarshalInputFile is a generic unmarshaller from an input path -func UnmarshalInputFile(specPath string) (map[string]interface{}, error) { - var result map[string]interface{} +func UnmarshalInputFile(specPath string) (map[string]any, error) { + var result map[string]any specFile, err := os.Open(specPath) if err != nil { return result, err diff --git a/pkg/kubeletconfig/output.go b/pkg/kubeletconfig/output.go index e9a5d30dc5..6d5d745369 100644 --- a/pkg/kubeletconfig/output.go +++ b/pkg/kubeletconfig/output.go @@ -2,6 +2,7 @@ package kubeletconfig import ( "fmt" + "strings" cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" ) @@ -9,12 +10,13 @@ import ( const emptyName = "-" func PrintKubeletConfigsForTabularOutput(configs []*cmv1.KubeletConfig) string { - output := "ID\tNAME\tPOD PIDS LIMIT\n" + var output strings.Builder + output.WriteString("ID\tNAME\tPOD PIDS LIMIT\n") for _, config := range configs { - output += fmt.Sprintf("%s\t%s\t%d\n", config.ID(), getName(config), config.PodPidsLimit()) + fmt.Fprintf(&output, "%s\t%s\t%d\n", config.ID(), getName(config), config.PodPidsLimit()) } - return output + return output.String() } func getName(config *cmv1.KubeletConfig) string { @@ -25,15 +27,16 @@ func getName(config *cmv1.KubeletConfig) string { } func PrintKubeletConfigForHcp(config *cmv1.KubeletConfig, nodePools []*cmv1.NodePool) string { - output := PrintKubeletConfigForClassic(config) + var output strings.Builder + output.WriteString(PrintKubeletConfigForClassic(config)) if len(nodePools) != 0 { - output += "MachinePools Using This KubeletConfig:\n" + output.WriteString("MachinePools Using This KubeletConfig:\n") for _, n := range nodePools { - output += fmt.Sprintf(" - %s\n", n.ID()) + fmt.Fprintf(&output, " - %s\n", n.ID()) } } - return output + return output.String() } func PrintKubeletConfigForClassic(config *cmv1.KubeletConfig) string { diff --git a/pkg/logforwarding/helpers.go b/pkg/logforwarding/helpers.go index 8452809683..013fa8cccb 100644 --- a/pkg/logforwarding/helpers.go +++ b/pkg/logforwarding/helpers.go @@ -2,6 +2,7 @@ package logforwarding import ( "os" + "strings" "gopkg.in/yaml.v3" @@ -48,14 +49,14 @@ type LogForwarderYaml struct { func ConstructPodGroupsHelpMessage(options []*cmv1.LogForwarderGroupVersions) (s string) { s = "" for _, option := range options { - apps := "" + var apps strings.Builder for i, application := range option.Versions()[len(option.Versions())-1].Applications() { if i != 0 { - apps += "," + apps.WriteString(",") } - apps += application + apps.WriteString(application) } - s = s + option.Name() + ": " + apps + "\n" + s = s + option.Name() + ": " + apps.String() + "\n" } return } diff --git a/pkg/logforwarding/output.go b/pkg/logforwarding/output.go index 0aca9341a4..34a5b5c7e7 100644 --- a/pkg/logforwarding/output.go +++ b/pkg/logforwarding/output.go @@ -2,6 +2,7 @@ package logforwarding import ( "fmt" + "strings" cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1" ) @@ -20,25 +21,25 @@ func LogForwarderObjectAsString(logForwarder *cmv1.LogForwarder) string { } if logForwarder.Applications() != nil && len(logForwarder.Applications()) > 0 { - applicationsStr := "" + var applicationsStr strings.Builder for i, app := range logForwarder.Applications() { if i > 0 { - applicationsStr += " " + applicationsStr.WriteString(" ") } - applicationsStr += app + applicationsStr.WriteString(app) } - out += fmt.Sprintf("Applications: %s\n", applicationsStr) + out += fmt.Sprintf("Applications: %s\n", applicationsStr.String()) } if logForwarder.Groups() != nil && len(logForwarder.Groups()) > 0 { - groupsStr := "" + var groupsStr strings.Builder for i, group := range logForwarder.Groups() { if i > 0 { - groupsStr += " " + groupsStr.WriteString(" ") } - groupsStr += fmt.Sprintf("(%s,v%s)", group.ID(), group.Version()) + fmt.Fprintf(&groupsStr, "(%s,v%s)", group.ID(), group.Version()) } - out += fmt.Sprintf("Groups: %s\n", groupsStr) + out += fmt.Sprintf("Groups: %s\n", groupsStr.String()) } if logForwarder.Status() != nil { @@ -47,14 +48,14 @@ func LogForwarderObjectAsString(logForwarder *cmv1.LogForwarder) string { } if logForwarder.Status().ResolvedApplications() != nil && len(logForwarder.Status().ResolvedApplications()) > 0 { - resolvedAppsStr := "" + var resolvedAppsStr strings.Builder for i, app := range logForwarder.Status().ResolvedApplications() { if i > 0 { - resolvedAppsStr += " " + resolvedAppsStr.WriteString(" ") } - resolvedAppsStr += app + resolvedAppsStr.WriteString(app) } - out += fmt.Sprintf("Resolved Applications: %s\n", resolvedAppsStr) + out += fmt.Sprintf("Resolved Applications: %s\n", resolvedAppsStr.String()) } } diff --git a/pkg/logging/aws_logger.go b/pkg/logging/aws_logger.go index b28a59cd9b..78eca06089 100644 --- a/pkg/logging/aws_logger.go +++ b/pkg/logging/aws_logger.go @@ -61,6 +61,6 @@ func (b *AWSLoggerBuilder) Build() (result *AWSLogger, err error) { return } -func (l *AWSLogger) Log(args ...interface{}) { +func (l *AWSLogger) Log(args ...any) { l.logger.Info(args...) } diff --git a/pkg/logging/round_tripper.go b/pkg/logging/round_tripper.go index 382d21047e..ee93c22e22 100644 --- a/pkg/logging/round_tripper.go +++ b/pkg/logging/round_tripper.go @@ -24,6 +24,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "mime" "net/http" "net/url" @@ -99,9 +100,7 @@ func (b *RoundTripperBuilder) Build() (result *RoundTripper, err error) { // Copy the set of redactedReplacement fields: redact := make(map[string]bool) - for key, value := range b.redact { - redact[key] = value - } + maps.Copy(redact, b.redact) // Create and populate the object: result = &RoundTripper{ diff --git a/pkg/network/helper.go b/pkg/network/helper.go index 54c94bd305..f85a02f16c 100644 --- a/pkg/network/helper.go +++ b/pkg/network/helper.go @@ -82,8 +82,8 @@ func ParseParams(params []string) (map[string]string, map[string]string, error) return nil, nil, errors.New("invalid parameter format") } if parts[0] == "Tags" { - tagEntries := strings.Split(parts[1], ",") - for _, entry := range tagEntries { + tagEntries := strings.SplitSeq(parts[1], ",") + for entry := range tagEntries { tagParts := strings.SplitN(strings.TrimSpace(entry), "=", 2) if len(tagParts) != 2 { return nil, nil, errors.New("invalid tag format") @@ -110,29 +110,29 @@ func SelectTemplate(templateDir, command string) string { } func formatParams(params map[string]string) string { - var paramStr string + var paramStr strings.Builder keys := make([]string, 0, len(params)) for k := range params { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { - paramStr += fmt.Sprintf("ParameterKey=%s,ParameterValue=%s ", k, params[k]) + fmt.Fprintf(¶mStr, "ParameterKey=%s,ParameterValue=%s ", k, params[k]) } - return paramStr + return paramStr.String() } func formatTags(tags map[string]string) string { - var tagStr string + var tagStr strings.Builder keys := make([]string, 0, len(tags)) for k := range tags { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { - tagStr += fmt.Sprintf("Key=%s,Value=%s ", k, tags[k]) + fmt.Fprintf(&tagStr, "Key=%s,Value=%s ", k, tags[k]) } - return tagStr + return tagStr.String() } func deleteHelperMessage(logger *logrus.Logger, params map[string]string, err error) { diff --git a/pkg/output/reporter.go b/pkg/output/reporter.go index 50fa564cf6..70be75ff0c 100644 --- a/pkg/output/reporter.go +++ b/pkg/output/reporter.go @@ -36,7 +36,7 @@ func NewStructuredReporter(r reporter.Logger) reporter.Logger { return &StructuredReporter{inner: r} } -func (r *StructuredReporter) Errorf(format string, args ...interface{}) error { +func (r *StructuredReporter) Errorf(format string, args ...any) error { err := fmt.Errorf(format, args...) if !PrintError(err) { return r.inner.Errorf(format, args...) @@ -44,17 +44,17 @@ func (r *StructuredReporter) Errorf(format string, args ...interface{}) error { return err } -func (r *StructuredReporter) Warnf(format string, args ...interface{}) { +func (r *StructuredReporter) Warnf(format string, args ...any) { if !PrintWarn(fmt.Errorf(format, args...)) { r.inner.Warnf(format, args...) } } -func (r *StructuredReporter) Debugf(format string, args ...interface{}) { +func (r *StructuredReporter) Debugf(format string, args ...any) { r.inner.Debugf(format, args...) } -func (r *StructuredReporter) Infof(format string, args ...interface{}) { +func (r *StructuredReporter) Infof(format string, args ...any) { r.inner.Infof(format, args...) } diff --git a/pkg/reporter/reporter.go b/pkg/reporter/reporter.go index f8af5e763f..94f46d30f0 100644 --- a/pkg/reporter/reporter.go +++ b/pkg/reporter/reporter.go @@ -27,19 +27,19 @@ import ( type Logger interface { // Debugf logs a debug message with formatted arguments. - Debugf(format string, args ...interface{}) + Debugf(format string, args ...any) // Errorf logs an error message with formatted arguments and returns an error. - Errorf(format string, args ...interface{}) error + Errorf(format string, args ...any) error // Infof logs an info message with formatted arguments. - Infof(format string, args ...interface{}) + Infof(format string, args ...any) // IsTerminal checks if the output is a terminal. IsTerminal() bool // Warnf logs a warning message with formatted arguments. - Warnf(format string, args ...interface{}) + Warnf(format string, args ...any) } // Object is the reported object used by the tool. It prints the messages to the standard output or @@ -48,7 +48,7 @@ type Object struct { } // Debugf prints a debug message with the given format and arguments. -func (r *Object) Debugf(format string, args ...interface{}) { +func (r *Object) Debugf(format string, args ...any) { if !debug.Enabled() { return } @@ -56,7 +56,7 @@ func (r *Object) Debugf(format string, args ...interface{}) { } // Infof prints an informative message with the given format and arguments. -func (r *Object) Infof(format string, args ...interface{}) { +func (r *Object) Infof(format string, args ...any) { message := fmt.Sprintf(format, args...) if color.UseColor() { _, _ = fmt.Fprintf(os.Stdout, "%s%s\n", infoColorPrefix, message) @@ -66,7 +66,7 @@ func (r *Object) Infof(format string, args ...interface{}) { } // Warnf prints an warning message with the given format and arguments. -func (r *Object) Warnf(format string, args ...interface{}) { +func (r *Object) Warnf(format string, args ...any) { message := fmt.Sprintf(format, args...) if color.UseColor() { _, _ = fmt.Fprintf(os.Stderr, "%s%s\n", warnColorPrefix, message) @@ -80,7 +80,7 @@ func (r *Object) Warnf(format string, args ...interface{}) { // report the error and also return it. // //nolint:errcheck -func (r *Object) Errorf(format string, args ...interface{}) error { +func (r *Object) Errorf(format string, args ...any) error { message := fmt.Sprintf(format, args...) if color.UseColor() { _, _ = fmt.Fprintf(os.Stderr, "%s%s\n", errorColorPrefix, message) diff --git a/renovate.json b/renovate.json index 4e179e63d0..00c898d787 100644 --- a/renovate.json +++ b/renovate.json @@ -27,7 +27,7 @@ }, "gomod": { "constraints": { - "go": "1.25.8" + "go": "1.26.3" }, "managerFilePatterns": [ "/(^|/)\\.bingo/[^/]+\\.mod$/" @@ -128,16 +128,6 @@ "sigs.k8s.io/{/,}**" ] }, - { - "description": "Pin k8s.io/apimachinery below the Go 1.26-only line", - "matchManagers": [ - "gomod" - ], - "matchPackageNames": [ - "k8s.io/apimachinery" - ], - "allowedVersions": "< 0.36.0" - }, { "description": "Test and generator stack", "groupName": "testing",