From 36c15a7c1a909d5109f63f26e444bd0bcdfdfe37 Mon Sep 17 00:00:00 2001 From: Alexander <42068202+ale8k@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:59:51 +0100 Subject: [PATCH] Initial pr for golint (#1304) * Initial pr for golint * more linting fixes * lint fixes for tests, gocognit and gocritic * goheader, gci and imprtas linters * jujuparams lint * missing uuids * All linting issues solved * fix errs import * test fixes --------- Co-authored-by: Ales Stimec --- .golangci.yaml | 90 +++++++++++++++++++ .vscode/settings.json | 7 ++ cmd/jaas/cmd/addserviceaccount.go | 2 +- cmd/jaas/cmd/addserviceaccount_test.go | 2 +- cmd/jaas/cmd/export_test.go | 2 +- cmd/jaas/cmd/grant.go | 20 ++++- cmd/jaas/cmd/grant_test.go | 2 +- cmd/jaas/cmd/listserviceaccountcredentials.go | 3 +- .../cmd/listserviceaccountcredentials_test.go | 2 +- cmd/jaas/cmd/package_test.go | 2 +- cmd/jaas/cmd/updatecredentials.go | 5 +- cmd/jaas/cmd/updatecredentials_test.go | 6 +- cmd/jaas/main.go | 5 +- cmd/jimmctl/cmd/addcloudtocontroller.go | 6 +- cmd/jimmctl/cmd/addcloudtocontroller_test.go | 11 +-- cmd/jimmctl/cmd/addcontroller.go | 2 +- cmd/jimmctl/cmd/addcontroller_test.go | 7 +- cmd/jimmctl/cmd/auth.go | 2 +- cmd/jimmctl/cmd/controllerinfo.go | 4 +- cmd/jimmctl/cmd/controllerinfo_test.go | 2 +- cmd/jimmctl/cmd/crossmodelquery.go | 2 +- cmd/jimmctl/cmd/crossmodelquery_test.go | 9 +- cmd/jimmctl/cmd/export_test.go | 2 +- cmd/jimmctl/cmd/grantauditlogaccess.go | 4 +- cmd/jimmctl/cmd/grantauditlogaccess_test.go | 5 +- cmd/jimmctl/cmd/group.go | 7 +- cmd/jimmctl/cmd/group_test.go | 2 +- cmd/jimmctl/cmd/importcloudcredentials.go | 3 +- .../cmd/importcloudcredentials_test.go | 5 +- cmd/jimmctl/cmd/importmodel.go | 2 +- cmd/jimmctl/cmd/importmodel_test.go | 2 +- cmd/jimmctl/cmd/listauditevents.go | 2 +- cmd/jimmctl/cmd/listauditevents_test.go | 2 +- cmd/jimmctl/cmd/listcontrollers.go | 2 +- cmd/jimmctl/cmd/listcontrollers_test.go | 2 +- cmd/jimmctl/cmd/migratemodel.go | 2 +- cmd/jimmctl/cmd/migratemodel_test.go | 2 +- cmd/jimmctl/cmd/modelstatus.go | 2 +- cmd/jimmctl/cmd/modelstatus_test.go | 2 +- cmd/jimmctl/cmd/package_test.go | 2 +- cmd/jimmctl/cmd/purge_logs.go | 1 + cmd/jimmctl/cmd/purge_logs_test.go | 3 +- cmd/jimmctl/cmd/relation.go | 16 ++-- cmd/jimmctl/cmd/relation_test.go | 4 +- cmd/jimmctl/cmd/removecloudfromcontroller.go | 2 +- .../cmd/removecloudfromcontroller_test.go | 3 +- cmd/jimmctl/cmd/removecontroller.go | 2 +- cmd/jimmctl/cmd/removecontroller_test.go | 2 +- cmd/jimmctl/cmd/revokeauditlogaccess.go | 4 +- cmd/jimmctl/cmd/revokeauditlogaccess_test.go | 5 +- cmd/jimmctl/cmd/setcontrollerdeprecated.go | 4 +- .../cmd/setcontrollerdeprecated_test.go | 2 +- cmd/jimmctl/cmd/updatemigratedmodel.go | 2 +- cmd/jimmctl/cmd/updatemigratedmodel_test.go | 2 +- cmd/jimmctl/main.go | 2 +- cmd/jimmsrv/main.go | 14 ++- cmd/jimmsrv/service/export_test.go | 2 +- cmd/jimmsrv/service/service.go | 2 +- cmd/jimmsrv/service/service_test.go | 6 +- doc/golangci-lint.md | 10 +++ internal/auth/jujuauth.go | 2 +- internal/auth/oauth2.go | 2 +- internal/auth/oauth2_test.go | 25 +++--- internal/cloudcred/cloudcred.go | 2 +- internal/cloudcred/cloudcred_test.go | 5 +- internal/cmdtest/jimmsuite.go | 6 +- internal/dashboard/dashboard.go | 3 +- internal/dashboard/dashboard_test.go | 8 +- internal/db/applicationoffer.go | 24 +++-- internal/db/applicationoffer_test.go | 2 +- internal/db/audit.go | 2 +- internal/db/auditlog_test.go | 2 +- internal/db/cloud.go | 2 +- internal/db/cloud_test.go | 3 +- internal/db/cloudcredential.go | 2 +- internal/db/cloudcredential_test.go | 3 +- internal/db/clouddefaults.go | 2 +- internal/db/clouddefaults_test.go | 2 +- internal/db/controller.go | 5 +- internal/db/controller_test.go | 2 +- internal/db/db.go | 2 +- internal/db/db_test.go | 2 +- internal/db/errors.go | 6 +- internal/db/export_test.go | 2 +- internal/db/group.go | 6 +- internal/db/group_test.go | 2 +- internal/db/identity.go | 2 +- internal/db/identity_test.go | 3 +- internal/db/identitymodeldefaults.go | 2 +- internal/db/identitymodeldefaults_test.go | 5 +- internal/db/model.go | 15 ++-- internal/db/model_test.go | 2 +- internal/db/pgx_test.go | 2 +- internal/db/rootkeys.go | 2 +- internal/db/rootkeys_test.go | 5 +- internal/db/secrets.go | 22 ++--- internal/db/secrets_test.go | 2 +- internal/dbmodel/applicationoffer.go | 2 +- internal/dbmodel/applicationoffer_test.go | 2 +- internal/dbmodel/audit.go | 2 +- internal/dbmodel/audit_test.go | 2 +- internal/dbmodel/cloud.go | 2 +- internal/dbmodel/cloud_test.go | 2 +- internal/dbmodel/cloudcredential.go | 2 +- internal/dbmodel/cloudcredential_test.go | 2 +- internal/dbmodel/clouddefaults.go | 2 +- internal/dbmodel/controller.go | 9 +- internal/dbmodel/controller_test.go | 2 +- internal/dbmodel/gorm_test.go | 7 +- internal/dbmodel/group.go | 2 +- internal/dbmodel/group_test.go | 2 +- internal/dbmodel/identity.go | 4 +- internal/dbmodel/identity_test.go | 2 +- internal/dbmodel/identitymodeldefaults.go | 2 +- internal/dbmodel/model.go | 2 +- internal/dbmodel/model_test.go | 2 +- internal/dbmodel/openfga_stores.go | 1 + internal/dbmodel/rootkey.go | 2 +- internal/dbmodel/secrets.go | 1 + internal/dbmodel/sql.go | 2 +- internal/dbmodel/types.go | 2 +- internal/dbmodel/types_test.go | 2 +- internal/dbmodel/version.go | 2 +- internal/dbmodel/version_test.go | 2 +- internal/debugapi/api.go | 1 + internal/debugapi/api_test.go | 4 + internal/discharger/discharger.go | 8 +- internal/errors/errors.go | 2 +- internal/errors/errors_test.go | 6 +- internal/jimm/access.go | 4 +- internal/jimm/access_test.go | 70 +++------------ internal/jimm/admin.go | 2 +- internal/jimm/applicationoffer.go | 13 ++- internal/jimm/applicationoffer_test.go | 20 +++-- internal/jimm/audit_log.go | 4 +- internal/jimm/audit_log_test.go | 2 +- internal/jimm/cache.go | 2 +- internal/jimm/cache_test.go | 2 +- internal/jimm/cloud.go | 25 +----- internal/jimm/cloud_test.go | 4 +- internal/jimm/cloudcredential.go | 2 +- internal/jimm/cloudcredential_test.go | 4 +- internal/jimm/clouddefaults.go | 4 +- internal/jimm/clouddefaults_test.go | 7 +- internal/jimm/controller.go | 47 ++-------- internal/jimm/controller_test.go | 18 ++-- internal/jimm/credentials/credentials.go | 2 +- internal/jimm/export_test.go | 2 +- internal/jimm/identitymodeldefaults.go | 2 +- internal/jimm/identitymodeldefaults_test.go | 8 +- internal/jimm/jimm.go | 2 +- internal/jimm/jimm_test.go | 2 +- internal/jimm/model.go | 7 +- internal/jimm/model_status_parser.go | 11 +-- internal/jimm/model_status_parser_test.go | 1 + internal/jimm/model_test.go | 5 +- internal/jimm/modelsummary.go | 2 +- internal/jimm/modelsummary_test.go | 2 +- internal/jimm/monitoring.go | 6 +- internal/jimm/purge_logs.go | 7 +- internal/jimm/runner.go | 2 +- internal/jimm/runner_internal_test.go | 2 +- internal/jimm/service_account.go | 11 +-- internal/jimm/service_account_test.go | 2 +- internal/jimm/user.go | 2 +- internal/jimm/user_test.go | 4 +- internal/jimm/watcher.go | 21 +++-- internal/jimm/watcher_test.go | 2 +- internal/jimmhttp/auth_handler.go | 6 +- internal/jimmhttp/auth_handler_test.go | 9 +- internal/jimmhttp/handler.go | 1 + internal/jimmhttp/http.go | 2 +- internal/jimmhttp/http_test.go | 3 +- internal/jimmhttp/websocket.go | 2 +- internal/jimmhttp/websocket_test.go | 14 +-- internal/jimmjwx/export_test.go | 1 + internal/jimmjwx/jimmjwx.go | 2 +- internal/jimmjwx/jwks.go | 10 ++- internal/jimmjwx/jwks_test.go | 1 + internal/jimmjwx/jwt.go | 20 +++-- internal/jimmjwx/jwt_test.go | 7 +- internal/jimmjwx/utils_test.go | 6 +- internal/jimmtest/api.go | 2 +- internal/jimmtest/auth.go | 9 +- internal/jimmtest/cmp.go | 2 +- internal/jimmtest/env.go | 17 ++-- internal/jimmtest/gorm.go | 12 ++- internal/jimmtest/jimm.go | 4 +- internal/jimmtest/jimm_mock.go | 2 +- internal/jimmtest/keycloak.go | 8 +- internal/jimmtest/logging.go | 12 +-- internal/jimmtest/openfga.go | 12 ++- internal/jimmtest/store.go | 3 +- internal/jimmtest/suite.go | 2 +- internal/jimmtest/vault.go | 5 +- internal/jujuapi/access_control.go | 29 +----- internal/jujuapi/access_control_test.go | 43 ++++----- internal/jujuapi/admin.go | 2 +- internal/jujuapi/admin_test.go | 7 +- internal/jujuapi/api.go | 2 +- internal/jujuapi/api_test.go | 4 +- internal/jujuapi/applicationoffers.go | 2 +- internal/jujuapi/applicationoffers_test.go | 6 +- internal/jujuapi/cloud.go | 8 +- internal/jujuapi/cloud_test.go | 2 +- internal/jujuapi/controller.go | 6 +- internal/jujuapi/controller_test.go | 2 +- internal/jujuapi/controllerroot.go | 2 +- internal/jujuapi/controllerroot_test.go | 2 +- internal/jujuapi/export_test.go | 5 +- internal/jujuapi/jimm.go | 2 +- internal/jujuapi/jimm_test.go | 2 +- internal/jujuapi/modelmanager.go | 8 +- internal/jujuapi/modelmanager_test.go | 16 ++-- internal/jujuapi/modelsummarywatcher.go | 5 +- internal/jujuapi/modelsummarywatcher_test.go | 8 +- internal/jujuapi/package_test.go | 2 +- internal/jujuapi/pinger.go | 2 +- internal/jujuapi/pinger_internal_test.go | 2 +- internal/jujuapi/rpc/method.go | 10 +-- internal/jujuapi/rpc/method_test.go | 2 +- internal/jujuapi/rpc/root.go | 2 +- internal/jujuapi/rpc/root_test.go | 2 +- internal/jujuapi/service_account.go | 2 +- internal/jujuapi/service_account_test.go | 25 ++++-- internal/jujuapi/usermanager.go | 6 +- internal/jujuapi/usermanager_test.go | 2 +- internal/jujuapi/websocket.go | 7 +- internal/jujuapi/websocket_test.go | 2 +- internal/jujuclient/allwatcher.go | 2 +- internal/jujuclient/allwatcher_test.go | 2 +- internal/jujuclient/applicationoffers.go | 2 +- internal/jujuclient/applicationoffers_test.go | 2 +- internal/jujuclient/client.go | 2 +- internal/jujuclient/client_test.go | 2 +- internal/jujuclient/cloud.go | 4 +- internal/jujuclient/cloud_test.go | 3 +- internal/jujuclient/dial.go | 6 +- internal/jujuclient/dial_test.go | 10 +-- internal/jujuclient/modelmanager.go | 2 +- internal/jujuclient/modelmanager_test.go | 2 +- internal/jujuclient/modelsummarywatcher.go | 2 +- .../jujuclient/modelsummarywatcher_test.go | 2 +- internal/jujuclient/modelwatcher.go | 2 +- internal/jujuclient/modelwatcher_test.go | 2 +- internal/jujuclient/package_test.go | 2 +- internal/jujuclient/ping.go | 2 +- internal/jujuclient/ping_test.go | 5 +- internal/jujuclient/storage.go | 2 +- internal/jujuclient/storage_test.go | 2 +- internal/kubetest/kubetest.go | 6 +- internal/logger/logger.go | 2 +- internal/openfga/export_test.go | 2 +- internal/openfga/names/export_test.go | 2 +- internal/openfga/names/names.go | 8 +- internal/openfga/names/names_test.go | 6 +- internal/openfga/openfga.go | 6 +- internal/openfga/openfga_test.go | 7 +- internal/openfga/user.go | 4 +- internal/openfga/user_test.go | 2 +- internal/pubsub/hub.go | 5 +- internal/pubsub/hub_test.go | 2 +- internal/rpc/client.go | 53 ++++++----- internal/rpc/client_test.go | 28 +++--- internal/rpc/dial.go | 3 +- internal/rpc/export_test.go | 1 + internal/rpc/proxy.go | 33 +++++-- internal/rpc/proxy_test.go | 14 ++- internal/rpc/rpc.go | 2 +- internal/servermon/monitoring.go | 6 +- internal/utils/utils.go | 11 ++- internal/utils/utils_test.go | 1 + internal/vault/vault.go | 24 ++--- internal/vault/vault_test.go | 2 +- internal/wellknownapi/api.go | 7 +- internal/wellknownapi/api_test.go | 10 ++- local/seed_db/main.go | 10 ++- local/vault/approle.go | 2 +- openfga/auth_model.go | 2 +- pkg/api/client.go | 2 +- pkg/api/params/errors.go | 2 +- pkg/api/params/params.go | 30 +++---- pkg/names/applicationoffer.go | 2 +- pkg/names/group.go | 2 +- pkg/names/group_test.go | 2 +- pkg/names/names.go | 2 +- pkg/names/service_account.go | 2 +- pkg/names/service_account_test.go | 2 +- version/default.go | 2 +- version/version.go | 2 +- 290 files changed, 949 insertions(+), 764 deletions(-) create mode 100644 .golangci.yaml create mode 100644 .vscode/settings.json create mode 100644 doc/golangci-lint.md diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 000000000..96bc21b20 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,90 @@ +# Golangci-lint configuration. +# +# If a line has a comment, it means it has been changed from the default. +# This helps us understand what we're tweaking and why. + +run: + timeout: "5m" # Allow at least 5 minutes + issues-exit-code: 1 + tests: true + allow-parallel-runners: false + allow-serial-runners: false + # go: "1.17" # Do not set a go limit + +issues: + exclude-use-default: true + exclude-case-sensitive: false + exclude-dirs-use-default: true + max-issues-per-linter: 50 + max-same-issues: 3 + new: false + fix: true + whole-files: false + +output: + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + # path-prefix: # Not needed + show-stats: false + sort-results: true + +linters: + disable-all: true + enable: + # The following linters are enabled by default + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - unused + + # The following linters are additional + + # Bug based linters + - gosec + - sqlclosecheck + - reassign + - nilerr + - durationcheck + - bodyclose + # - contextcheck # Issue right now + + # Style based linters + - promlinter + - gocritic + # - gocognit # To be fixed + - goheader + - importas + - gci + +linters-settings: + gosec: + exclude-generated: false + severity: low + confidence: low + excludes: + - G601 # Implicit memory aliasing in for loop. Fixed in Go1.22+, as such exclude. + gocognit: + min-complexity: 30 + goheader: + template: |- + Copyright 2024 Canonical. + importas: + no-unaliased: false + no-extra-aliases: false + alias: + - pkg: github.com/juju/juju/rpc/params + alias: jujuparams + - pkg: github.com/canonical/jimm/v3/internal/openfga/names + alias: ofganames + - pkg: github.com/frankban/quicktest + alias: qt + gci: + skip-generated: true + custom-order: true + sections: + - standard + - default + - localmodule \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ea70deb9b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "go.lintTool": "golangci-lint", + "go.lintFlags": [ + "--fast" + ], + "go.lintOnSave": "workspace", +} diff --git a/cmd/jaas/cmd/addserviceaccount.go b/cmd/jaas/cmd/addserviceaccount.go index 2e14cb956..5584ec966 100644 --- a/cmd/jaas/cmd/addserviceaccount.go +++ b/cmd/jaas/cmd/addserviceaccount.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jaas/cmd/addserviceaccount_test.go b/cmd/jaas/cmd/addserviceaccount_test.go index 6a6596072..fa6966171 100644 --- a/cmd/jaas/cmd/addserviceaccount_test.go +++ b/cmd/jaas/cmd/addserviceaccount_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jaas/cmd/export_test.go b/cmd/jaas/cmd/export_test.go index ac0c8489f..955d46936 100644 --- a/cmd/jaas/cmd/export_test.go +++ b/cmd/jaas/cmd/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jaas/cmd/grant.go b/cmd/jaas/cmd/grant.go index d935042ff..0930f7f40 100644 --- a/cmd/jaas/cmd/grant.go +++ b/cmd/jaas/cmd/grant.go @@ -1,11 +1,10 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd import ( - "fmt" - "github.com/juju/cmd/v3" + "github.com/juju/gnuflag" jujuapi "github.com/juju/juju/api" jujucmd "github.com/juju/juju/cmd" "github.com/juju/juju/cmd/modelcmd" @@ -57,6 +56,14 @@ func (c *grantCommand) Info() *cmd.Info { }) } +// Init implements the cmd.Command interface. +func (c *grantCommand) SetFlags(f *gnuflag.FlagSet) { + c.CommandBase.SetFlags(f) + c.out.AddFlags(f, "smart", map[string]cmd.Formatter{ + "smart": cmd.FormatSmart, + }) +} + // Init implements the cmd.Command interface. func (c *grantCommand) Init(args []string) error { if len(args) < 1 { @@ -92,6 +99,11 @@ func (c *grantCommand) Run(ctxt *cmd.Context) error { if err != nil { return errors.E(err) } - fmt.Fprintln(ctxt.Stdout, "access granted") + err = c.out.Write(ctxt, "access granted") + if err != nil { + return errors.E(err) + } + + // fmt.Fprintf(ctxt.Stdout, "access granted") return nil } diff --git a/cmd/jaas/cmd/grant_test.go b/cmd/jaas/cmd/grant_test.go index efd727bdd..8acc174ef 100644 --- a/cmd/jaas/cmd/grant_test.go +++ b/cmd/jaas/cmd/grant_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jaas/cmd/listserviceaccountcredentials.go b/cmd/jaas/cmd/listserviceaccountcredentials.go index 0688ef8ad..002a8fa87 100644 --- a/cmd/jaas/cmd/listserviceaccountcredentials.go +++ b/cmd/jaas/cmd/listserviceaccountcredentials.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -31,6 +31,7 @@ This command only shows credentials uploaded to the controller that belong to th Client-side credentials should be managed via the juju credentials command. ` + //nolint:gosec // Believes credentials are exposed but aren't. listServiceAccountCredentialsExamples = ` juju list-service-account-credentials juju list-service-account-credentials --show-secrets diff --git a/cmd/jaas/cmd/listserviceaccountcredentials_test.go b/cmd/jaas/cmd/listserviceaccountcredentials_test.go index 8fdeb3ec9..f8f6bcd4c 100644 --- a/cmd/jaas/cmd/listserviceaccountcredentials_test.go +++ b/cmd/jaas/cmd/listserviceaccountcredentials_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jaas/cmd/package_test.go b/cmd/jaas/cmd/package_test.go index 1a5f86c31..4addb4e34 100644 --- a/cmd/jaas/cmd/package_test.go +++ b/cmd/jaas/cmd/package_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jaas/cmd/updatecredentials.go b/cmd/jaas/cmd/updatecredentials.go index 6fb9c8918..28303d982 100644 --- a/cmd/jaas/cmd/updatecredentials.go +++ b/cmd/jaas/cmd/updatecredentials.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -11,10 +11,9 @@ import ( jujucmd "github.com/juju/juju/cmd" "github.com/juju/juju/cmd/modelcmd" "github.com/juju/juju/jujuclient" - "github.com/juju/names/v5" - "github.com/juju/juju/rpc/params" jujuparams "github.com/juju/juju/rpc/params" + "github.com/juju/names/v5" "github.com/canonical/jimm/v3/internal/errors" "github.com/canonical/jimm/v3/pkg/api" diff --git a/cmd/jaas/cmd/updatecredentials_test.go b/cmd/jaas/cmd/updatecredentials_test.go index 700d60694..5242311d6 100644 --- a/cmd/jaas/cmd/updatecredentials_test.go +++ b/cmd/jaas/cmd/updatecredentials_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test @@ -7,6 +7,8 @@ import ( "fmt" "github.com/juju/cmd/v3/cmdtesting" + jujucloud "github.com/juju/juju/cloud" + "github.com/juju/juju/rpc/params" "github.com/juju/names/v5" gc "gopkg.in/check.v1" @@ -18,8 +20,6 @@ import ( "github.com/canonical/jimm/v3/internal/openfga" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" jimmnames "github.com/canonical/jimm/v3/pkg/names" - jujucloud "github.com/juju/juju/cloud" - "github.com/juju/juju/rpc/params" ) type updateCredentialsSuite struct { diff --git a/cmd/jaas/main.go b/cmd/jaas/main.go index cc95c87af..22dc0b9a0 100644 --- a/cmd/jaas/main.go +++ b/cmd/jaas/main.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package main @@ -7,8 +7,9 @@ import ( "os" "strings" - "github.com/canonical/jimm/v3/cmd/jaas/cmd" jujucmd "github.com/juju/cmd/v3" + + "github.com/canonical/jimm/v3/cmd/jaas/cmd" ) var jaasDoc = ` diff --git a/cmd/jimmctl/cmd/addcloudtocontroller.go b/cmd/jimmctl/cmd/addcloudtocontroller.go index 2a2da2356..aa4b88c62 100644 --- a/cmd/jimmctl/cmd/addcloudtocontroller.go +++ b/cmd/jimmctl/cmd/addcloudtocontroller.go @@ -1,10 +1,10 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd import ( "fmt" - "io/ioutil" + "os" "github.com/juju/cmd/v3" "github.com/juju/gnuflag" @@ -194,7 +194,7 @@ type cloudToCommandAdapter struct { // ReadCloudData implements CloudMetadataStore.ReadCloudData. func (cloudToCommandAdapter) ReadCloudData(path string) ([]byte, error) { - return ioutil.ReadFile(path) + return os.ReadFile(path) } // ParseOneCloud implements CloudMetadataStore.ParseOneCloud. diff --git a/cmd/jimmctl/cmd/addcloudtocontroller_test.go b/cmd/jimmctl/cmd/addcloudtocontroller_test.go index eb610594b..2cbcf37ed 100644 --- a/cmd/jimmctl/cmd/addcloudtocontroller_test.go +++ b/cmd/jimmctl/cmd/addcloudtocontroller_test.go @@ -1,9 +1,8 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test import ( "context" - "io/ioutil" "os" "path/filepath" "strconv" @@ -187,7 +186,8 @@ clouds: err = s.JIMM.Database.GetCloud(context.Background(), &cloud) c.Assert(err, gc.IsNil) controller := dbmodel.Controller{Name: "controller-1"} - s.JIMM.Database.GetController(context.Background(), &controller) + err = s.JIMM.Database.GetController(context.Background(), &controller) + c.Assert(err, gc.IsNil) c.Assert(controller.CloudRegions[test.expectedIndex].CloudRegion.CloudName, gc.Equals, test.expectedCloudName) } cleanupFunc() @@ -197,11 +197,12 @@ clouds: } func writeTempFile(c *gc.C, content string) (string, func()) { - dir, err := ioutil.TempDir("", "add-cloud-to-controller-test") + dir, err := os.MkdirTemp("", "add-cloud-to-controller-test") c.Assert(err, gc.Equals, nil) tmpfn := filepath.Join(dir, "tmp.yaml") - err = ioutil.WriteFile(tmpfn, []byte(content), 0666) + + err = os.WriteFile(tmpfn, []byte(content), 0600) c.Assert(err, gc.Equals, nil) return tmpfn, func() { os.RemoveAll(dir) diff --git a/cmd/jimmctl/cmd/addcontroller.go b/cmd/jimmctl/cmd/addcontroller.go index 90268d5ec..bd1e7fe52 100644 --- a/cmd/jimmctl/cmd/addcontroller.go +++ b/cmd/jimmctl/cmd/addcontroller.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/addcontroller_test.go b/cmd/jimmctl/cmd/addcontroller_test.go index 1d5e921ff..00e9d0162 100644 --- a/cmd/jimmctl/cmd/addcontroller_test.go +++ b/cmd/jimmctl/cmd/addcontroller_test.go @@ -1,10 +1,9 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test import ( "context" - "io/ioutil" "os" "path/filepath" @@ -110,11 +109,11 @@ func writeYAMLTempFile(c *gc.C, payload interface{}) (string, string) { data, err := yaml.Marshal(payload) c.Assert(err, gc.Equals, nil) - dir, err := ioutil.TempDir("", "add-controller-test") + dir, err := os.MkdirTemp("", "add-controller-test") c.Assert(err, gc.Equals, nil) tmpfn := filepath.Join(dir, "tmp.yaml") - err = ioutil.WriteFile(tmpfn, data, 0666) + err = os.WriteFile(tmpfn, data, 0600) c.Assert(err, gc.Equals, nil) return dir, tmpfn } diff --git a/cmd/jimmctl/cmd/auth.go b/cmd/jimmctl/cmd/auth.go index ff9e3778e..346d67c46 100644 --- a/cmd/jimmctl/cmd/auth.go +++ b/cmd/jimmctl/cmd/auth.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/controllerinfo.go b/cmd/jimmctl/cmd/controllerinfo.go index b5de52ac4..a803c6c11 100644 --- a/cmd/jimmctl/cmd/controllerinfo.go +++ b/cmd/jimmctl/cmd/controllerinfo.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -123,7 +123,7 @@ func (c *controllerInfoCommand) Run(ctxt *cmd.Context) error { if err != nil { return errors.Mask(err) } - err = os.WriteFile(c.file.Path, data, 0666) + err = os.WriteFile(c.file.Path, data, 0600) if err != nil { return errors.Mask(err) } diff --git a/cmd/jimmctl/cmd/controllerinfo_test.go b/cmd/jimmctl/cmd/controllerinfo_test.go index 48f2b5a1e..dd8c37798 100644 --- a/cmd/jimmctl/cmd/controllerinfo_test.go +++ b/cmd/jimmctl/cmd/controllerinfo_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/crossmodelquery.go b/cmd/jimmctl/cmd/crossmodelquery.go index 06f98e99b..296154342 100644 --- a/cmd/jimmctl/cmd/crossmodelquery.go +++ b/cmd/jimmctl/cmd/crossmodelquery.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/crossmodelquery_test.go b/cmd/jimmctl/cmd/crossmodelquery_test.go index df378d3bb..4521f8075 100644 --- a/cmd/jimmctl/cmd/crossmodelquery_test.go +++ b/cmd/jimmctl/cmd/crossmodelquery_test.go @@ -1,18 +1,19 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test import ( "encoding/json" - "github.com/canonical/jimm/v3/cmd/jimmctl/cmd" - "github.com/canonical/jimm/v3/internal/cmdtest" - "github.com/canonical/jimm/v3/internal/jimmtest" "github.com/juju/cmd/v3/cmdtesting" jujuparams "github.com/juju/juju/rpc/params" "github.com/juju/juju/testing/factory" "github.com/juju/names/v5" gc "gopkg.in/check.v1" + + "github.com/canonical/jimm/v3/cmd/jimmctl/cmd" + "github.com/canonical/jimm/v3/internal/cmdtest" + "github.com/canonical/jimm/v3/internal/jimmtest" ) type crossModelQuerySuite struct { diff --git a/cmd/jimmctl/cmd/export_test.go b/cmd/jimmctl/cmd/export_test.go index e32b9ff94..eb2569252 100644 --- a/cmd/jimmctl/cmd/export_test.go +++ b/cmd/jimmctl/cmd/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/grantauditlogaccess.go b/cmd/jimmctl/cmd/grantauditlogaccess.go index b3e9140b0..77e3e17da 100644 --- a/cmd/jimmctl/cmd/grantauditlogaccess.go +++ b/cmd/jimmctl/cmd/grantauditlogaccess.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -58,7 +58,7 @@ func (c *grantAuditLogAccessCommand) SetFlags(f *gnuflag.FlagSet) { // Init implements the cmd.Command interface. func (c *grantAuditLogAccessCommand) Init(args []string) error { - if len(args) < 0 { + if len(args) == 0 { return errors.E("missing username") } c.username, args = args[0], args[1:] diff --git a/cmd/jimmctl/cmd/grantauditlogaccess_test.go b/cmd/jimmctl/cmd/grantauditlogaccess_test.go index 3d45221a5..f3d54130b 100644 --- a/cmd/jimmctl/cmd/grantauditlogaccess_test.go +++ b/cmd/jimmctl/cmd/grantauditlogaccess_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test @@ -15,8 +15,7 @@ type grantAuditLogAccessSuite struct { cmdtest.JimmCmdSuite } -// TODO (alesstimec) uncomment once granting/revoking is reimplemented -//var _ = gc.Suite(&grantAuditLogAccessSuite{}) +var _ = gc.Suite(&grantAuditLogAccessSuite{}) func (s *grantAuditLogAccessSuite) TestGrantAuditLogAccessSuperuser(c *gc.C) { // alice is superuser diff --git a/cmd/jimmctl/cmd/group.go b/cmd/jimmctl/cmd/group.go index 517fb2f23..759986737 100644 --- a/cmd/jimmctl/cmd/group.go +++ b/cmd/jimmctl/cmd/group.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -159,7 +159,6 @@ func newRenameGroupCommand() cmd.Command { // renameGroupCommand renames a group. type renameGroupCommand struct { modelcmd.ControllerCommandBase - out cmd.Output store jujuclient.ClientStore dialOpts *jujuapi.DialOpts @@ -284,7 +283,7 @@ func (c *removeGroupCommand) Run(ctxt *cmd.Context) error { if err != nil { return errors.E(err, "Failed to read from input.") } - text = strings.Replace(text, "\n", "", -1) + text = strings.ReplaceAll(text, "\n", "") if !(text == "y" || text == "Y") { return nil } @@ -324,8 +323,6 @@ type listGroupsCommand struct { store jujuclient.ClientStore dialOpts *jujuapi.DialOpts - - name string } // Info implements the cmd.Command interface. diff --git a/cmd/jimmctl/cmd/group_test.go b/cmd/jimmctl/cmd/group_test.go index 6eff3867d..4848b74cf 100644 --- a/cmd/jimmctl/cmd/group_test.go +++ b/cmd/jimmctl/cmd/group_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/importcloudcredentials.go b/cmd/jimmctl/cmd/importcloudcredentials.go index 3d9d32b52..9a24aafa5 100644 --- a/cmd/jimmctl/cmd/importcloudcredentials.go +++ b/cmd/jimmctl/cmd/importcloudcredentials.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -17,6 +17,7 @@ import ( "github.com/canonical/jimm/v3/internal/errors" ) +//nolint:gosec // Thinks a credential is exposed. const importCloudCredentialsDoc = ` import-cloud-credentials imports a set of cloud credentials loaded from a file containing a series of JSON objects. The JSON diff --git a/cmd/jimmctl/cmd/importcloudcredentials_test.go b/cmd/jimmctl/cmd/importcloudcredentials_test.go index 718ffd982..ee0c7cd80 100644 --- a/cmd/jimmctl/cmd/importcloudcredentials_test.go +++ b/cmd/jimmctl/cmd/importcloudcredentials_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test @@ -22,6 +22,7 @@ type importCloudCredentialsSuite struct { var _ = gc.Suite(&importCloudCredentialsSuite{}) +//nolint:gosec // Thinks hardcoded creds. const creds = `{ "_id": "aws/alice@canonical.com/test1", "type": "access-key", @@ -60,7 +61,7 @@ func (s *importCloudCredentialsSuite) TestImportCloudCredentials(c *gc.C) { c.Assert(err, gc.IsNil) tmpfile := filepath.Join(c.MkDir(), "test.json") - err = os.WriteFile(tmpfile, []byte(creds), 0660) + err = os.WriteFile(tmpfile, []byte(creds), 0600) c.Assert(err, gc.IsNil) // alice is superuser diff --git a/cmd/jimmctl/cmd/importmodel.go b/cmd/jimmctl/cmd/importmodel.go index ab363358c..520941921 100644 --- a/cmd/jimmctl/cmd/importmodel.go +++ b/cmd/jimmctl/cmd/importmodel.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/importmodel_test.go b/cmd/jimmctl/cmd/importmodel_test.go index 6b225857f..81065aa65 100644 --- a/cmd/jimmctl/cmd/importmodel_test.go +++ b/cmd/jimmctl/cmd/importmodel_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/listauditevents.go b/cmd/jimmctl/cmd/listauditevents.go index 3512d3bf6..fe7e66675 100644 --- a/cmd/jimmctl/cmd/listauditevents.go +++ b/cmd/jimmctl/cmd/listauditevents.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/listauditevents_test.go b/cmd/jimmctl/cmd/listauditevents_test.go index 6dc1c438c..d837431f2 100644 --- a/cmd/jimmctl/cmd/listauditevents_test.go +++ b/cmd/jimmctl/cmd/listauditevents_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/listcontrollers.go b/cmd/jimmctl/cmd/listcontrollers.go index 031026d1f..b5bb2f5aa 100644 --- a/cmd/jimmctl/cmd/listcontrollers.go +++ b/cmd/jimmctl/cmd/listcontrollers.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/listcontrollers_test.go b/cmd/jimmctl/cmd/listcontrollers_test.go index d586c4e46..94c0cd707 100644 --- a/cmd/jimmctl/cmd/listcontrollers_test.go +++ b/cmd/jimmctl/cmd/listcontrollers_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/migratemodel.go b/cmd/jimmctl/cmd/migratemodel.go index 815d6cce4..875407947 100644 --- a/cmd/jimmctl/cmd/migratemodel.go +++ b/cmd/jimmctl/cmd/migratemodel.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/migratemodel_test.go b/cmd/jimmctl/cmd/migratemodel_test.go index 03f3e116f..0d837b2ae 100644 --- a/cmd/jimmctl/cmd/migratemodel_test.go +++ b/cmd/jimmctl/cmd/migratemodel_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/modelstatus.go b/cmd/jimmctl/cmd/modelstatus.go index a5822d607..5997df097 100644 --- a/cmd/jimmctl/cmd/modelstatus.go +++ b/cmd/jimmctl/cmd/modelstatus.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/modelstatus_test.go b/cmd/jimmctl/cmd/modelstatus_test.go index 5dca3bb03..25b2d44d0 100644 --- a/cmd/jimmctl/cmd/modelstatus_test.go +++ b/cmd/jimmctl/cmd/modelstatus_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/package_test.go b/cmd/jimmctl/cmd/package_test.go index fb57779d4..4addb4e34 100644 --- a/cmd/jimmctl/cmd/package_test.go +++ b/cmd/jimmctl/cmd/package_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/purge_logs.go b/cmd/jimmctl/cmd/purge_logs.go index faf4abab8..d6f5b0973 100644 --- a/cmd/jimmctl/cmd/purge_logs.go +++ b/cmd/jimmctl/cmd/purge_logs.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package cmd import ( diff --git a/cmd/jimmctl/cmd/purge_logs_test.go b/cmd/jimmctl/cmd/purge_logs_test.go index f472a1b4d..0cd8c5832 100644 --- a/cmd/jimmctl/cmd/purge_logs_test.go +++ b/cmd/jimmctl/cmd/purge_logs_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package cmd_test import ( @@ -84,7 +85,7 @@ func (s *purgeLogsSuite) TestPurgeLogsFromDb(c *gc.C) { c.Assert(err, gc.IsNil) tomorrow := relativeNow.AddDate(0, 0, 1).Format(layout) - //alice is superuser + // alice is superuser bClient := jimmtest.NewUserSessionLogin(c, "alice") cmdCtx, err := cmdtesting.RunCommand(c, cmd.NewPurgeLogsCommandForTesting(s.ClientStore(), bClient), tomorrow) c.Assert(err, gc.IsNil) diff --git a/cmd/jimmctl/cmd/relation.go b/cmd/jimmctl/cmd/relation.go index 6249d3b58..3b2249fda 100644 --- a/cmd/jimmctl/cmd/relation.go +++ b/cmd/jimmctl/cmd/relation.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -179,7 +179,7 @@ type addRelationCommand struct { relation string targetObject string - filename string //optional + filename string // optional } // Info implements the cmd.Command interface. @@ -270,7 +270,7 @@ type removeRelationCommand struct { relation string targetObject string - filename string //optional + filename string // optional } // Info implements the cmd.Command interface. @@ -415,7 +415,10 @@ func formatCheckRelationString(writer io.Writer, value interface{}) error { if !ok { return errors.E("failed to parse access result") } - writer.Write([]byte((&accessResult).setMessage().Msg)) + _, err := writer.Write([]byte((&accessResult).setMessage().Msg)) + if err != nil { + return errors.E("failed to write access result", err) + } return nil } @@ -438,10 +441,13 @@ func (c *checkRelationCommand) Run(ctxt *cmd.Context) error { if err != nil { return err } - c.out.Write(ctxt, *(&accessResult{ + err = c.out.Write(ctxt, *(&accessResult{ Tuple: c.tuple, Allowed: resp.Allowed, }).setMessage()) + if err != nil { + return err + } return nil } diff --git a/cmd/jimmctl/cmd/relation_test.go b/cmd/jimmctl/cmd/relation_test.go index 2953463c2..1c9b7688b 100644 --- a/cmd/jimmctl/cmd/relation_test.go +++ b/cmd/jimmctl/cmd/relation_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test @@ -175,7 +175,7 @@ func (s *relationSuite) TestRemoveRelationSuperuser(c *gc.C) { {testName: "Remove Group Relation", input: tuple{user: "group-" + group1 + "#member", relation: "member", target: "group-" + group2}, err: false}, } - //Create groups and relation + // Create groups and relation _, err := s.JimmCmdSuite.JIMM.Database.AddGroup(context.Background(), group1) c.Assert(err, gc.IsNil) _, err = s.JimmCmdSuite.JIMM.Database.AddGroup(context.Background(), group2) diff --git a/cmd/jimmctl/cmd/removecloudfromcontroller.go b/cmd/jimmctl/cmd/removecloudfromcontroller.go index 318053479..5f5caff21 100644 --- a/cmd/jimmctl/cmd/removecloudfromcontroller.go +++ b/cmd/jimmctl/cmd/removecloudfromcontroller.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/removecloudfromcontroller_test.go b/cmd/jimmctl/cmd/removecloudfromcontroller_test.go index 037180b43..ca7d10475 100644 --- a/cmd/jimmctl/cmd/removecloudfromcontroller_test.go +++ b/cmd/jimmctl/cmd/removecloudfromcontroller_test.go @@ -1,10 +1,9 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test import ( "github.com/juju/cmd/v3/cmdtesting" jujutesting "github.com/juju/testing" - gc "gopkg.in/check.v1" "github.com/canonical/jimm/v3/cmd/jimmctl/cmd" diff --git a/cmd/jimmctl/cmd/removecontroller.go b/cmd/jimmctl/cmd/removecontroller.go index 381fcf53b..63589741d 100644 --- a/cmd/jimmctl/cmd/removecontroller.go +++ b/cmd/jimmctl/cmd/removecontroller.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/removecontroller_test.go b/cmd/jimmctl/cmd/removecontroller_test.go index 47a03954d..29103f6a6 100644 --- a/cmd/jimmctl/cmd/removecontroller_test.go +++ b/cmd/jimmctl/cmd/removecontroller_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/revokeauditlogaccess.go b/cmd/jimmctl/cmd/revokeauditlogaccess.go index 525018f44..2341970c3 100644 --- a/cmd/jimmctl/cmd/revokeauditlogaccess.go +++ b/cmd/jimmctl/cmd/revokeauditlogaccess.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -58,7 +58,7 @@ func (c *revokeAuditLogAccessCommand) SetFlags(f *gnuflag.FlagSet) { // Init implements the cmd.Command interface. func (c *revokeAuditLogAccessCommand) Init(args []string) error { - if len(args) < 0 { + if len(args) == 0 { return errors.E("missing username") } c.username, args = args[0], args[1:] diff --git a/cmd/jimmctl/cmd/revokeauditlogaccess_test.go b/cmd/jimmctl/cmd/revokeauditlogaccess_test.go index ca70e9f85..f87c24dd2 100644 --- a/cmd/jimmctl/cmd/revokeauditlogaccess_test.go +++ b/cmd/jimmctl/cmd/revokeauditlogaccess_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test @@ -15,8 +15,7 @@ type revokeAuditLogAccessSuite struct { cmdtest.JimmCmdSuite } -// TODO (alesstimec) uncomment when grant/revoke is implemented -//var _ = gc.Suite(&revokeAuditLogAccessSuite{}) +var _ = gc.Suite(&revokeAuditLogAccessSuite{}) func (s *revokeAuditLogAccessSuite) TestRevokeAuditLogAccessSuperuser(c *gc.C) { // alice is superuser diff --git a/cmd/jimmctl/cmd/setcontrollerdeprecated.go b/cmd/jimmctl/cmd/setcontrollerdeprecated.go index 01c6cb90c..851970d8e 100644 --- a/cmd/jimmctl/cmd/setcontrollerdeprecated.go +++ b/cmd/jimmctl/cmd/setcontrollerdeprecated.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd @@ -63,7 +63,7 @@ func (c *setControllerDeprecatedCommand) SetFlags(f *gnuflag.FlagSet) { // Init implements the cmd.Command interface. func (c *setControllerDeprecatedCommand) Init(args []string) error { - if len(args) < 0 { + if len(args) == 0 { return errors.E("missing controller name") } c.controllerName, args = args[0], args[1:] diff --git a/cmd/jimmctl/cmd/setcontrollerdeprecated_test.go b/cmd/jimmctl/cmd/setcontrollerdeprecated_test.go index b1411d034..a8a8de5c0 100644 --- a/cmd/jimmctl/cmd/setcontrollerdeprecated_test.go +++ b/cmd/jimmctl/cmd/setcontrollerdeprecated_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/cmd/updatemigratedmodel.go b/cmd/jimmctl/cmd/updatemigratedmodel.go index 700480c2d..3ada94bb6 100644 --- a/cmd/jimmctl/cmd/updatemigratedmodel.go +++ b/cmd/jimmctl/cmd/updatemigratedmodel.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd diff --git a/cmd/jimmctl/cmd/updatemigratedmodel_test.go b/cmd/jimmctl/cmd/updatemigratedmodel_test.go index caf53eef5..da1469f9e 100644 --- a/cmd/jimmctl/cmd/updatemigratedmodel_test.go +++ b/cmd/jimmctl/cmd/updatemigratedmodel_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package cmd_test diff --git a/cmd/jimmctl/main.go b/cmd/jimmctl/main.go index bdeee2970..3555cdd8a 100644 --- a/cmd/jimmctl/main.go +++ b/cmd/jimmctl/main.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package main diff --git a/cmd/jimmsrv/main.go b/cmd/jimmsrv/main.go index f2c540913..4f5698bd3 100644 --- a/cmd/jimmsrv/main.go +++ b/cmd/jimmsrv/main.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package main @@ -35,6 +35,8 @@ func main() { } // start initialises the jimmsrv service. +// +//nolint:gocognit // Start function to be ignored. func start(ctx context.Context, s *service.Service) error { zapctx.Info(ctx, "jimm info", zap.String("version", version.VersionInfo.Version), @@ -204,15 +206,19 @@ func start(ctx context.Context, s *service.Service) error { } httpsrv := &http.Server{ - Addr: addr, - Handler: jimmsvc, + Addr: addr, + Handler: jimmsvc, + ReadHeaderTimeout: time.Second * 5, } s.OnShutdown(func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() zapctx.Warn(ctx, "server shutdown triggered") - httpsrv.Shutdown(ctx) + err = httpsrv.Shutdown(ctx) + if err != nil { + zapctx.Error(ctx, "failed to shutdown server gracefully", zap.Error(err)) + } jimmsvc.Cleanup() }) s.Go(httpsrv.ListenAndServe) diff --git a/cmd/jimmsrv/service/export_test.go b/cmd/jimmsrv/service/export_test.go index 3dca85934..db33a96a1 100644 --- a/cmd/jimmsrv/service/export_test.go +++ b/cmd/jimmsrv/service/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package service var NewOpenFGAClient = newOpenFGAClient diff --git a/cmd/jimmsrv/service/service.go b/cmd/jimmsrv/service/service.go index 62bb5c868..6ba1dffca 100644 --- a/cmd/jimmsrv/service/service.go +++ b/cmd/jimmsrv/service/service.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // service defines the methods necessary to start a JIMM server // alongside all the config options that can be supplied to configure JIMM. diff --git a/cmd/jimmsrv/service/service_test.go b/cmd/jimmsrv/service/service_test.go index 341b26fa0..9bc815d69 100644 --- a/cmd/jimmsrv/service/service_test.go +++ b/cmd/jimmsrv/service/service_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package service_test @@ -51,6 +51,7 @@ func TestDefaultService(t *testing.T) { c.Assert(err, qt.IsNil) svc.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusOK) } @@ -266,6 +267,7 @@ func TestPublicKey(t *testing.T) { response, err := srv.Client().Get(srv.URL + "/macaroons/publickey") c.Assert(err, qt.IsNil) + defer response.Body.Close() data, err := io.ReadAll(response.Body) c.Assert(err, qt.IsNil) c.Assert(string(data), qt.Equals, `{"PublicKey":"izcYsQy3TePp6bLjqOo3IRPFvkQd2IKtyODGqC6SdFk="}`) @@ -411,6 +413,7 @@ func TestDisableOAuthEndpointsWhenDashboardRedirectURLNotSet(t *testing.T) { response, err := srv.Client().Get(srv.URL + "/auth/whoami") c.Assert(err, qt.IsNil) + defer response.Body.Close() c.Assert(response.StatusCode, qt.Equals, http.StatusNotFound) } @@ -434,6 +437,7 @@ func TestEnableOAuthEndpointsWhenDashboardRedirectURLSet(t *testing.T) { response, err := srv.Client().Get(srv.URL + "/auth/whoami") c.Assert(err, qt.IsNil) + defer response.Body.Close() c.Assert(response.StatusCode, qt.Not(qt.Equals), http.StatusNotFound) } diff --git a/doc/golangci-lint.md b/doc/golangci-lint.md new file mode 100644 index 000000000..743ca68ce --- /dev/null +++ b/doc/golangci-lint.md @@ -0,0 +1,10 @@ +# Golangci-lint +We use golangci-lint as the linter for this project. It is helpful to run +the linter as your default vscode linter. + +In the .vscode folder of this repository you will find it is defined as the linter of choice. + +To install, please install the golangci-lint binary or install it via "go install". + +The version this was tested with is: +```go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1``` \ No newline at end of file diff --git a/internal/auth/jujuauth.go b/internal/auth/jujuauth.go index 6e8abbfbf..c5729c78a 100644 --- a/internal/auth/jujuauth.go +++ b/internal/auth/jujuauth.go @@ -1,4 +1,4 @@ -// Copyright 2021 canonical. +// Copyright 2024 Canonical. package auth diff --git a/internal/auth/oauth2.go b/internal/auth/oauth2.go index ebd004bfd..feff81490 100644 --- a/internal/auth/oauth2.go +++ b/internal/auth/oauth2.go @@ -1,4 +1,4 @@ -// Copyright 2024 canonical. +// Copyright 2024 Canonical. // Package auth provides means to authenticate users into JIMM. // diff --git a/internal/auth/oauth2_test.go b/internal/auth/oauth2_test.go index 756468a8a..fa6ac6999 100644 --- a/internal/auth/oauth2_test.go +++ b/internal/auth/oauth2_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 canonical. +// Copyright 2024 Canonical. package auth_test @@ -16,19 +16,20 @@ import ( "time" "github.com/antonlindstrom/pgstore" + "github.com/coreos/go-oidc/v3/oidc" + qt "github.com/frankban/quicktest" + "github.com/gorilla/sessions" + "github.com/canonical/jimm/v3/internal/auth" "github.com/canonical/jimm/v3/internal/db" "github.com/canonical/jimm/v3/internal/dbmodel" "github.com/canonical/jimm/v3/internal/errors" "github.com/canonical/jimm/v3/internal/jimmtest" - "github.com/coreos/go-oidc/v3/oidc" - qt "github.com/frankban/quicktest" - "github.com/gorilla/sessions" ) func setupTestAuthSvc(ctx context.Context, c *qt.C, expiry time.Duration) (*auth.AuthenticationService, *db.Database, sessions.Store, func()) { db := &db.Database{ - DB: jimmtest.PostgresDB(c, func() time.Time { return time.Now() }), + DB: jimmtest.PostgresDB(c, time.Now), } c.Assert(db.Migrate(ctx, false), qt.IsNil) @@ -251,7 +252,8 @@ func TestVerifyClientCredentials(t *testing.T) { const ( // these are valid client credentials hardcoded into the jimm realm - validClientID = "test-client-id" + validClientID = "test-client-id" + //nolint:gosec // Thinks hardcoded credentials. validClientSecret = "2M2blFbO4GX4zfggQpivQSxwWX1XGgNf" ) @@ -265,7 +267,7 @@ func TestVerifyClientCredentials(t *testing.T) { c.Assert(err, qt.ErrorMatches, "invalid client credentials") } -func assertSetCookiesIsCorrect(c *qt.C, rec *httptest.ResponseRecorder, parsedCookies []*http.Cookie) { +func assertSetCookiesIsCorrect(c *qt.C, parsedCookies []*http.Cookie) { assertHasCookie := func(name string, cookies []*http.Cookie) { found := false for _, v := range cookies { @@ -298,7 +300,7 @@ func TestCreateBrowserSession(t *testing.T) { cookies := rec.Header().Get("Set-Cookie") parsedCookies := jimmtest.ParseCookies(cookies) - assertSetCookiesIsCorrect(c, rec, parsedCookies) + assertSetCookiesIsCorrect(c, parsedCookies) req.AddCookie(&http.Cookie{ Name: auth.SessionName, @@ -345,7 +347,7 @@ func TestAuthenticateBrowserSessionAndLogout(t *testing.T) { // Assert Set-Cookie present setCookieCookies := rec.Header().Get("Set-Cookie") parsedCookies := jimmtest.ParseCookies(setCookieCookies) - assertSetCookiesIsCorrect(c, rec, parsedCookies) + assertSetCookiesIsCorrect(c, parsedCookies) // Test logout does indeed remove the cookie for us err = authSvc.Logout(ctx, rec, req) @@ -454,7 +456,7 @@ func TestAuthenticateBrowserSessionHandlesExpiredAccessTokens(t *testing.T) { // Assert Set-Cookie present setCookieCookies := rec.Header().Get("Set-Cookie") parsedCookies := jimmtest.ParseCookies(setCookieCookies) - assertSetCookiesIsCorrect(c, rec, parsedCookies) + assertSetCookiesIsCorrect(c, parsedCookies) } func TestAuthenticateBrowserSessionHandlesMissingOrExpiredRefreshTokens(t *testing.T) { @@ -492,7 +494,8 @@ func TestAuthenticateBrowserSessionHandlesMissingOrExpiredRefreshTokens(t *testi // And we're missing a refresh token (the same case would apply for an expired refresh token // or any scenario where the token source cannot refresh the access token) u.RefreshToken = "" - db.UpdateIdentity(ctx, u) + err = db.UpdateIdentity(ctx, u) + c.Assert(err, qt.IsNil) // AuthenticateBrowserSession should fail to refresh the users session and delete // the current session, giving us the same cookie back with a max-age of -1. diff --git a/internal/cloudcred/cloudcred.go b/internal/cloudcred/cloudcred.go index 78e372087..9899f1c8c 100644 --- a/internal/cloudcred/cloudcred.go +++ b/internal/cloudcred/cloudcred.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd.package cloudcred +// Copyright 2024 Canonical. //go:generate go run generate.go -o attr.go diff --git a/internal/cloudcred/cloudcred_test.go b/internal/cloudcred/cloudcred_test.go index 58186e84d..63b9d1931 100644 --- a/internal/cloudcred/cloudcred_test.go +++ b/internal/cloudcred/cloudcred_test.go @@ -1,12 +1,13 @@ -// Copyright 2020 Canonical Ltd.package cloudcred +// Copyright 2024 Canonical. package cloudcred_test import ( "testing" - "github.com/canonical/jimm/v3/internal/cloudcred" qt "github.com/frankban/quicktest" + + "github.com/canonical/jimm/v3/internal/cloudcred" ) func TestIsVisibleAttribute(t *testing.T) { diff --git a/internal/cmdtest/jimmsuite.go b/internal/cmdtest/jimmsuite.go index d72372b67..fa9dfc8f7 100644 --- a/internal/cmdtest/jimmsuite.go +++ b/internal/cmdtest/jimmsuite.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // Package cmdtest provides the test suite used for CLI tests // as well as helper functions used for integration based CLI tests. @@ -71,7 +71,7 @@ func (s *JimmCmdSuite) SetUpTest(c *gc.C) { s.Params = jimmtest.NewTestJimmParams(&jimmtest.GocheckTester{C: c}) dsn, err := url.Parse(s.Params.DSN) c.Assert(err, gc.Equals, nil) - s.databaseName = strings.Replace(dsn.Path, "/", "", -1) + s.databaseName = strings.ReplaceAll(dsn.Path, "/", "") s.Params.PublicDNSName = u.Host s.Params.ControllerAdmins = []string{"admin"} s.Params.OpenFGAParams = service.OpenFGAParams{ @@ -90,7 +90,7 @@ func (s *JimmCmdSuite) SetUpTest(c *gc.C) { c.Assert(err, gc.Equals, nil) s.Service = srv s.JIMM = srv.JIMM() - s.HTTP.Config = &http.Server{Handler: srv} + s.HTTP.Config = &http.Server{Handler: srv, ReadHeaderTimeout: time.Second * 5} err = s.Service.StartJWKSRotator(ctx, time.NewTicker(time.Hour).C, time.Now().UTC().AddDate(0, 3, 0)) c.Assert(err, gc.Equals, nil) diff --git a/internal/dashboard/dashboard.go b/internal/dashboard/dashboard.go index 7d0542e9d..4f2fe279b 100644 --- a/internal/dashboard/dashboard.go +++ b/internal/dashboard/dashboard.go @@ -1,5 +1,4 @@ -// Copyright 2020 Canonical Ltd. -// Licensed under the AGPLv3, see LICENCE file for details. +// Copyright 2024 Canonical. // Package dashboard contains a single function that creates a handler for // serving the JAAS Dashboard. diff --git a/internal/dashboard/dashboard_test.go b/internal/dashboard/dashboard_test.go index 773dfb557..99650959e 100644 --- a/internal/dashboard/dashboard_test.go +++ b/internal/dashboard/dashboard_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dashboard_test @@ -43,6 +43,7 @@ func TestDashboardNotConfigured(t *testing.T) { c.Assert(err, qt.IsNil) hnd.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusNotFound) } @@ -55,6 +56,7 @@ func TestDashboardRedirect(t *testing.T) { c.Assert(err, qt.IsNil) hnd.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusPermanentRedirect) c.Check(resp.Header.Get("Location"), qt.Equals, "https://example.com/dashboard") } @@ -68,6 +70,7 @@ func TestInvalidLocation(t *testing.T) { c.Assert(err, qt.IsNil) hnd.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusNotFound) } @@ -75,7 +78,7 @@ func TestLocationNotDirectory(t *testing.T) { c := qt.New(t) dir := c.TempDir() - err := os.WriteFile(filepath.Join(dir, "test"), []byte(testFile), 0444) + err := os.WriteFile(filepath.Join(dir, "test"), []byte(testFile), 0600) c.Assert(err, qt.Equals, nil) hnd := dashboard.Handler(context.Background(), filepath.Join(dir, "test"), "http://jimm.canonical.com") @@ -84,5 +87,6 @@ func TestLocationNotDirectory(t *testing.T) { c.Assert(err, qt.IsNil) hnd.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusNotFound) } diff --git a/internal/db/applicationoffer.go b/internal/db/applicationoffer.go index 17995698d..3f5312436 100644 --- a/internal/db/applicationoffer.go +++ b/internal/db/applicationoffer.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db @@ -48,9 +48,18 @@ func (d *Database) UpdateApplicationOffer(ctx context.Context, offer *dbmodel.Ap db := d.DB.WithContext(ctx) err = db.Transaction(func(tx *gorm.DB) error { tx.Omit("Connections", "Endpoints", "Spaces").Save(offer) - tx.Model(offer).Association("Connections").Replace(offer.Connections) - tx.Model(offer).Association("Endpoints").Replace(offer.Endpoints) - tx.Model(offer).Association("Spaces").Replace(offer.Spaces) + err = tx.Model(offer).Association("Connections").Replace(offer.Connections) + if err != nil { + return err + } + err = tx.Model(offer).Association("Endpoints").Replace(offer.Endpoints) + if err != nil { + return err + } + err = tx.Model(offer).Association("Spaces").Replace(offer.Spaces) + if err != nil { + return err + } return tx.Error }) if err != nil { @@ -78,11 +87,12 @@ func (d *Database) GetApplicationOffer(ctx context.Context, offer *dbmodel.Appli defer servermon.ErrorCounter(servermon.DBQueryErrorCount, &err, string(op)) db := d.DB.WithContext(ctx) - if offer.UUID != "" { + switch { + case offer.UUID != "": db = db.Where("uuid = ?", offer.UUID) - } else if offer.URL != "" { + case offer.URL != "": db = db.Where("url = ?", offer.URL) - } else { + default: return errors.E(op, "missing offer UUID or URL") } db = db.Preload("Connections") diff --git a/internal/db/applicationoffer_test.go b/internal/db/applicationoffer_test.go index a3e20f46d..341631d3e 100644 --- a/internal/db/applicationoffer_test.go +++ b/internal/db/applicationoffer_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/audit.go b/internal/db/audit.go index 921008357..405273ff5 100644 --- a/internal/db/audit.go +++ b/internal/db/audit.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/auditlog_test.go b/internal/db/auditlog_test.go index a7445a007..8bad93484 100644 --- a/internal/db/auditlog_test.go +++ b/internal/db/auditlog_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/cloud.go b/internal/db/cloud.go index 726880eeb..59a03c586 100644 --- a/internal/db/cloud.go +++ b/internal/db/cloud.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/cloud_test.go b/internal/db/cloud_test.go index 7e5e3befc..efa8ed950 100644 --- a/internal/db/cloud_test.go +++ b/internal/db/cloud_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test @@ -369,6 +369,7 @@ controllers: Name: "test-cloud-1", } err = s.Database.GetCloud(ctx, &cl) + c.Assert(err, qt.IsNil) crp = cl.Regions[0].Controllers[0] diff --git a/internal/db/cloudcredential.go b/internal/db/cloudcredential.go index d58651bb2..b72c0766f 100644 --- a/internal/db/cloudcredential.go +++ b/internal/db/cloudcredential.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/cloudcredential_test.go b/internal/db/cloudcredential_test.go index 51d00f905..95569e46a 100644 --- a/internal/db/cloudcredential_test.go +++ b/internal/db/cloudcredential_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test @@ -207,6 +207,7 @@ func TestForEachCloudCredentialUnconfiguredDatabase(t *testing.T) { c.Check(errors.ErrorCode(err), qt.Equals, errors.CodeServerConfiguration) } +//nolint:gosec // Thinks hardcoded credentials. const forEachCloudCredentialEnv = `clouds: - name: cloud-1 regions: diff --git a/internal/db/clouddefaults.go b/internal/db/clouddefaults.go index b423f5ae4..2e826b4bc 100644 --- a/internal/db/clouddefaults.go +++ b/internal/db/clouddefaults.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/clouddefaults_test.go b/internal/db/clouddefaults_test.go index 8178190e4..f92d5c5ca 100644 --- a/internal/db/clouddefaults_test.go +++ b/internal/db/clouddefaults_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/controller.go b/internal/db/controller.go index 7275fd39c..fe4393afe 100644 --- a/internal/db/controller.go +++ b/internal/db/controller.go @@ -1,14 +1,15 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db import ( "context" + "gorm.io/gorm/clause" + "github.com/canonical/jimm/v3/internal/dbmodel" "github.com/canonical/jimm/v3/internal/errors" "github.com/canonical/jimm/v3/internal/servermon" - "gorm.io/gorm/clause" ) // AddController stores the controller information. diff --git a/internal/db/controller_test.go b/internal/db/controller_test.go index 84141766b..f34d0eecd 100644 --- a/internal/db/controller_test.go +++ b/internal/db/controller_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/db.go b/internal/db/db.go index 1ce9b6640..d06c46e1e 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package db contains routines to store and retrieve data from a database. package db diff --git a/internal/db/db_test.go b/internal/db/db_test.go index 29de79e15..4901dcdd5 100644 --- a/internal/db/db_test.go +++ b/internal/db/db_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/errors.go b/internal/db/errors.go index 770baba96..d30a0c1ee 100644 --- a/internal/db/errors.go +++ b/internal/db/errors.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db @@ -21,8 +21,8 @@ func dbError(err error) error { if err == gorm.ErrRecordNotFound { code = errors.CodeNotFound } - switch e := err.(type) { - case *pgconn.PgError: + + if e, ok := err.(*pgconn.PgError); ok { if e.Code == pgUniqueViolation { code = errors.CodeAlreadyExists } diff --git a/internal/db/export_test.go b/internal/db/export_test.go index 7d8555cc3..d3a632218 100644 --- a/internal/db/export_test.go +++ b/internal/db/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/group.go b/internal/db/group.go index 66b67c7ef..d670a1a1f 100644 --- a/internal/db/group.go +++ b/internal/db/group.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db @@ -12,9 +12,7 @@ import ( "github.com/canonical/jimm/v3/internal/servermon" ) -var newUUID = func() string { - return uuid.NewString() -} +var newUUID = uuid.NewString // AddGroup adds a new group. func (d *Database) AddGroup(ctx context.Context, name string) (ge *dbmodel.GroupEntry, err error) { diff --git a/internal/db/group_test.go b/internal/db/group_test.go index 22971cd5d..f3b448193 100644 --- a/internal/db/group_test.go +++ b/internal/db/group_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/identity.go b/internal/db/identity.go index 322f2bb53..cbf674cee 100644 --- a/internal/db/identity.go +++ b/internal/db/identity.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/identity_test.go b/internal/db/identity_test.go index dd546d0a0..92191af6e 100644 --- a/internal/db/identity_test.go +++ b/internal/db/identity_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test @@ -142,6 +142,7 @@ func (s *dbSuite) TestGetIdentityCloudCredentials(c *qt.C) { c.Check(errors.ErrorCode(err), qt.Equals, errors.CodeNotFound) i, err = dbmodel.NewIdentity("test") + c.Assert(err, qt.IsNil) _, err = s.Database.GetIdentityCloudCredentials(ctx, i, "ec2") c.Check(err, qt.IsNil) diff --git a/internal/db/identitymodeldefaults.go b/internal/db/identitymodeldefaults.go index 6d7032bb0..6ffc6e7df 100644 --- a/internal/db/identitymodeldefaults.go +++ b/internal/db/identitymodeldefaults.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/identitymodeldefaults_test.go b/internal/db/identitymodeldefaults_test.go index 6ea24de5f..2c9422a6f 100644 --- a/internal/db/identitymodeldefaults_test.go +++ b/internal/db/identitymodeldefaults_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test @@ -66,7 +66,7 @@ func TestSetIdentityModelDefaults(t *testing.T) { c.Assert(err, qt.IsNil) c.Assert(j.Database.DB.Create(i).Error, qt.IsNil) - j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ + err = j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ IdentityName: i.Name, Identity: *i, Defaults: map[string]interface{}{ @@ -74,6 +74,7 @@ func TestSetIdentityModelDefaults(t *testing.T) { "key2": "a test string", }, }) + c.Assert(err, qt.IsNil) defaults := map[string]interface{}{ "key1": float64(42), diff --git a/internal/db/model.go b/internal/db/model.go index 134835481..9053c6ee0 100644 --- a/internal/db/model.go +++ b/internal/db/model.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db @@ -46,19 +46,20 @@ func (d *Database) GetModel(ctx context.Context, model *dbmodel.Model) (err erro defer servermon.ErrorCounter(servermon.DBQueryErrorCount, &err, string(op)) db := d.DB.WithContext(ctx) - if model.UUID.Valid { + switch { + case model.UUID.Valid: db = db.Where("uuid = ?", model.UUID.String) if model.ControllerID != 0 { db = db.Where("controller_id = ?", model.ControllerID) } - } else if model.ID != 0 { + case model.ID != 0: db = db.Where("id = ?", model.ID) - } else if model.OwnerIdentityName != "" && model.Name != "" { + case model.OwnerIdentityName != "" && model.Name != "": db = db.Where("owner_identity_name = ? AND name = ?", model.OwnerIdentityName, model.Name) - } else if model.ControllerID != 0 { - // TODO(ales): fix ordering of where fields and handle error to represent what is *actually* required. + case model.ControllerID != 0: + // TODO: fix ordering of where fields and handle error to represent what is *actually* required. db = db.Where("controller_id = ?", model.ControllerID) - } else { + default: return errors.E(op, "missing id or uuid", errors.CodeBadRequest) } diff --git a/internal/db/model_test.go b/internal/db/model_test.go index 9becabc4a..ae769b350 100644 --- a/internal/db/model_test.go +++ b/internal/db/model_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/pgx_test.go b/internal/db/pgx_test.go index fd1d2b292..7ddaadd36 100644 --- a/internal/db/pgx_test.go +++ b/internal/db/pgx_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/db/rootkeys.go b/internal/db/rootkeys.go index 62f1b4d74..3646b7026 100644 --- a/internal/db/rootkeys.go +++ b/internal/db/rootkeys.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db diff --git a/internal/db/rootkeys_test.go b/internal/db/rootkeys_test.go index d35060cba..28909a999 100644 --- a/internal/db/rootkeys_test.go +++ b/internal/db/rootkeys_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package db_test @@ -55,7 +55,8 @@ func (s *dbSuite) TestInsertKeyGetKey(c *qt.C) { RootKey: []byte("very secret"), } - s.Database.InsertKey(rk) + err = s.Database.InsertKey(rk) + c.Assert(err, qt.IsNil) rk2, err := s.Database.GetKey([]byte("test-id")) c.Assert(err, qt.IsNil) diff --git a/internal/db/secrets.go b/internal/db/secrets.go index f9b8caeed..7d73b1ccf 100644 --- a/internal/db/secrets.go +++ b/internal/db/secrets.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package db @@ -7,14 +7,15 @@ import ( "encoding/json" "time" - "github.com/canonical/jimm/v3/internal/dbmodel" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/servermon" "github.com/juju/names/v5" "github.com/juju/zaputil/zapctx" "github.com/lestrrat-go/jwx/v2/jwk" "go.uber.org/zap" "gorm.io/gorm/clause" + + "github.com/canonical/jimm/v3/internal/dbmodel" + "github.com/canonical/jimm/v3/internal/errors" + "github.com/canonical/jimm/v3/internal/servermon" ) const ( @@ -23,12 +24,13 @@ const ( passwordKey = "password" // These constants are used to create the appropriate identifiers for JWKS related data. - jwksKind = "jwks" - jwksPublicKeyTag = "jwksPublicKey" - jwksPrivateKeyTag = "jwksPrivateKey" - jwksExpiryTag = "jwksExpiry" - oauthKind = "oauth" - oauthKeyTag = "oauthKey" + jwksKind = "jwks" + jwksPublicKeyTag = "jwksPublicKey" + jwksPrivateKeyTag = "jwksPrivateKey" + jwksExpiryTag = "jwksExpiry" + oauthKind = "oauth" + oauthKeyTag = "oauthKey" + //nolint:gosec // Thinks credentials hardcoded. oauthSessionStoreSecretTag = "oauthSessionStoreSecret" ) diff --git a/internal/db/secrets_test.go b/internal/db/secrets_test.go index f771d3be8..38baa2776 100644 --- a/internal/db/secrets_test.go +++ b/internal/db/secrets_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package db_test diff --git a/internal/dbmodel/applicationoffer.go b/internal/dbmodel/applicationoffer.go index 2fbedeb32..7a18ffcfd 100644 --- a/internal/dbmodel/applicationoffer.go +++ b/internal/dbmodel/applicationoffer.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/applicationoffer_test.go b/internal/dbmodel/applicationoffer_test.go index cf02158b5..c4d2b5aaf 100644 --- a/internal/dbmodel/applicationoffer_test.go +++ b/internal/dbmodel/applicationoffer_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/audit.go b/internal/dbmodel/audit.go index 963cb8957..cb7436453 100644 --- a/internal/dbmodel/audit.go +++ b/internal/dbmodel/audit.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/audit_test.go b/internal/dbmodel/audit_test.go index 7f1c8fd90..f5a612b9a 100644 --- a/internal/dbmodel/audit_test.go +++ b/internal/dbmodel/audit_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/cloud.go b/internal/dbmodel/cloud.go index 879238be2..a35c8a385 100644 --- a/internal/dbmodel/cloud.go +++ b/internal/dbmodel/cloud.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/cloud_test.go b/internal/dbmodel/cloud_test.go index 68a9e4562..ed1291b30 100644 --- a/internal/dbmodel/cloud_test.go +++ b/internal/dbmodel/cloud_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/cloudcredential.go b/internal/dbmodel/cloudcredential.go index 0ec0053ea..5c70e7347 100644 --- a/internal/dbmodel/cloudcredential.go +++ b/internal/dbmodel/cloudcredential.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/cloudcredential_test.go b/internal/dbmodel/cloudcredential_test.go index 326b97eb3..560c7884a 100644 --- a/internal/dbmodel/cloudcredential_test.go +++ b/internal/dbmodel/cloudcredential_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/clouddefaults.go b/internal/dbmodel/clouddefaults.go index 3c52814b9..0098f3516 100644 --- a/internal/dbmodel/clouddefaults.go +++ b/internal/dbmodel/clouddefaults.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/controller.go b/internal/dbmodel/controller.go index e6800313c..49a44d96c 100644 --- a/internal/dbmodel/controller.go +++ b/internal/dbmodel/controller.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel @@ -124,16 +124,17 @@ func (c Controller) ToAPIControllerInfo() apiparams.ControllerInfo { ci.CloudRegion = c.CloudRegion ci.Username = c.AdminIdentityName ci.AgentVersion = c.AgentVersion - if c.UnavailableSince.Valid { + switch { + case c.UnavailableSince.Valid: ci.Status = jujuparams.EntityStatus{ Status: "unavailable", Since: &c.UnavailableSince.Time, } - } else if c.Deprecated { + case c.Deprecated: ci.Status = jujuparams.EntityStatus{ Status: "deprecated", } - } else { + default: ci.Status = jujuparams.EntityStatus{ Status: "available", } diff --git a/internal/dbmodel/controller_test.go b/internal/dbmodel/controller_test.go index 3a191c621..8e3d92e83 100644 --- a/internal/dbmodel/controller_test.go +++ b/internal/dbmodel/controller_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/gorm_test.go b/internal/dbmodel/gorm_test.go index 73338a747..7de2259b8 100644 --- a/internal/dbmodel/gorm_test.go +++ b/internal/dbmodel/gorm_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test @@ -18,6 +18,9 @@ import ( // migrations for those objects. func gormDB(t testing.TB) *gorm.DB { database := db.Database{DB: jimmtest.PostgresDB(t, nil)} - database.Migrate(context.Background(), false) + err := database.Migrate(context.Background(), false) + if err != nil { + t.Fail() + } return database.DB } diff --git a/internal/dbmodel/group.go b/internal/dbmodel/group.go index 775740e50..5b2d7c386 100644 --- a/internal/dbmodel/group.go +++ b/internal/dbmodel/group.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/group_test.go b/internal/dbmodel/group_test.go index 908b44079..e9b12b849 100644 --- a/internal/dbmodel/group_test.go +++ b/internal/dbmodel/group_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/identity.go b/internal/dbmodel/identity.go index 5fecb14ae..fc121c04a 100644 --- a/internal/dbmodel/identity.go +++ b/internal/dbmodel/identity.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel @@ -106,7 +106,7 @@ func (i Identity) ToJujuUserInfo() jujuparams.UserInfo { var ui jujuparams.UserInfo ui.Username = i.Name ui.DisplayName = i.DisplayName - ui.Access = "" //TODO(Kian) CSS-6040 Handle merging OpenFGA and Postgres information + ui.Access = "" // TODO(Kian) CSS-6040 Handle merging OpenFGA and Postgres information ui.DateCreated = i.CreatedAt if i.LastLogin.Valid { ui.LastConnection = &i.LastLogin.Time diff --git a/internal/dbmodel/identity_test.go b/internal/dbmodel/identity_test.go index 3ab4d7b71..d4d50badb 100644 --- a/internal/dbmodel/identity_test.go +++ b/internal/dbmodel/identity_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/identitymodeldefaults.go b/internal/dbmodel/identitymodeldefaults.go index 04c966840..32d721750 100644 --- a/internal/dbmodel/identitymodeldefaults.go +++ b/internal/dbmodel/identitymodeldefaults.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/model.go b/internal/dbmodel/model.go index 07f338ec5..73f7fb505 100644 --- a/internal/dbmodel/model.go +++ b/internal/dbmodel/model.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/model_test.go b/internal/dbmodel/model_test.go index e7a362025..536654154 100644 --- a/internal/dbmodel/model_test.go +++ b/internal/dbmodel/model_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/openfga_stores.go b/internal/dbmodel/openfga_stores.go index 0c28700c8..040810ac0 100644 --- a/internal/dbmodel/openfga_stores.go +++ b/internal/dbmodel/openfga_stores.go @@ -1 +1,2 @@ +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/rootkey.go b/internal/dbmodel/rootkey.go index b0eac5809..a5555e4ae 100644 --- a/internal/dbmodel/rootkey.go +++ b/internal/dbmodel/rootkey.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/secrets.go b/internal/dbmodel/secrets.go index 02acf9d1e..1e3dd8f46 100644 --- a/internal/dbmodel/secrets.go +++ b/internal/dbmodel/secrets.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package dbmodel import "time" diff --git a/internal/dbmodel/sql.go b/internal/dbmodel/sql.go index 829339229..351a2201a 100644 --- a/internal/dbmodel/sql.go +++ b/internal/dbmodel/sql.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/types.go b/internal/dbmodel/types.go index 0de054f77..ed307232e 100644 --- a/internal/dbmodel/types.go +++ b/internal/dbmodel/types.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel diff --git a/internal/dbmodel/types_test.go b/internal/dbmodel/types_test.go index b6483b56e..8c2ba558e 100644 --- a/internal/dbmodel/types_test.go +++ b/internal/dbmodel/types_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/dbmodel/version.go b/internal/dbmodel/version.go index cecc92215..e1c686ae6 100644 --- a/internal/dbmodel/version.go +++ b/internal/dbmodel/version.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package dbmodel contains the model objects for the relational storage // database. diff --git a/internal/dbmodel/version_test.go b/internal/dbmodel/version_test.go index 217c57c7f..5552c52f6 100644 --- a/internal/dbmodel/version_test.go +++ b/internal/dbmodel/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package dbmodel_test diff --git a/internal/debugapi/api.go b/internal/debugapi/api.go index d0d8e81f9..458670a62 100644 --- a/internal/debugapi/api.go +++ b/internal/debugapi/api.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package debugapi import ( diff --git a/internal/debugapi/api_test.go b/internal/debugapi/api_test.go index ae13664d0..d638ebef1 100644 --- a/internal/debugapi/api_test.go +++ b/internal/debugapi/api_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package debugapi_test import ( @@ -39,6 +40,7 @@ func TestDebugInfo(t *testing.T) { rr := setupHandlerAndRecorder(c, debugapi.ServerStartTime, "/info") resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusOK) buf, err := io.ReadAll(resp.Body) c.Assert(err, qt.IsNil) @@ -54,6 +56,7 @@ func TestDebugStatus(t *testing.T) { rr := setupHandlerAndRecorder(c, debugapi.ServerStartTime, "/status") resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusOK) buf, err := io.ReadAll(resp.Body) c.Assert(err, qt.IsNil) @@ -76,6 +79,7 @@ func TestDebugStatusStatusError(t *testing.T) { }), "/status") resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusOK) buf, err := io.ReadAll(resp.Body) c.Assert(err, qt.IsNil) diff --git a/internal/discharger/discharger.go b/internal/discharger/discharger.go index d06a529d9..1bd9e42be 100644 --- a/internal/discharger/discharger.go +++ b/internal/discharger/discharger.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package discharger @@ -76,11 +76,11 @@ type MacaroonDischarger struct { } // GetDischargerMux returns a mux that can handle macaroon bakery requests for the provided discharger. -func GetDischargerMux(MacaroonDischarger *MacaroonDischarger, rootPath string) *http.ServeMux { +func GetDischargerMux(macaroonDischarger *MacaroonDischarger, rootPath string) *http.ServeMux { discharger := httpbakery.NewDischarger( httpbakery.DischargerParams{ - Key: &MacaroonDischarger.kp, - Checker: httpbakery.ThirdPartyCaveatCheckerFunc(MacaroonDischarger.CheckThirdPartyCaveat), + Key: &macaroonDischarger.kp, + Checker: httpbakery.ThirdPartyCaveatCheckerFunc(macaroonDischarger.CheckThirdPartyCaveat), }, ) dischargeMux := http.NewServeMux() diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 811be24d3..08fbc7695 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package errors contains types to help handle errors in the system. package errors diff --git a/internal/errors/errors_test.go b/internal/errors/errors_test.go index 34c51152c..793903b77 100644 --- a/internal/errors/errors_test.go +++ b/internal/errors/errors_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package errors_test @@ -13,7 +13,9 @@ import ( func TestEEmptyArguments(t *testing.T) { c := qt.New(t) - c.Assert(func() { errors.E() }, qt.PanicMatches, `call to errors.E with no arguments`) + c.Assert(func() { + _ = errors.E() + }, qt.PanicMatches, `call to errors.E with no arguments`) } func TestEUnknownType(t *testing.T) { diff --git a/internal/jimm/access.go b/internal/jimm/access.go index ea576f86c..5359180e4 100644 --- a/internal/jimm/access.go +++ b/internal/jimm/access.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -259,7 +259,7 @@ func (auth *JWTGenerator) MakeLoginToken(ctx context.Context, user *openfga.User for _, cloudRegion := range ctl.CloudRegions { clouds[cloudRegion.CloudRegion.Cloud.ResourceTag()] = true } - for cloudTag, _ := range clouds { + for cloudTag := range clouds { accessLevel, err := auth.accessChecker.GetUserCloudAccess(ctx, auth.user, cloudTag) if err != nil { zapctx.Error(ctx, "cloud access check failed", zap.Error(err)) diff --git a/internal/jimm/access_test.go b/internal/jimm/access_test.go index 60de45081..41d26bdf1 100644 --- a/internal/jimm/access_test.go +++ b/internal/jimm/access_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -9,11 +9,11 @@ import ( "testing" "time" + "github.com/canonical/ofga" petname "github.com/dustinkirkland/golang-petname" qt "github.com/frankban/quicktest" "github.com/google/uuid" "github.com/juju/juju/core/crossmodel" - jujuparams "github.com/juju/juju/rpc/params" "github.com/juju/juju/state" "github.com/juju/names/v5" @@ -26,30 +26,8 @@ import ( "github.com/canonical/jimm/v3/internal/openfga" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" jimmnames "github.com/canonical/jimm/v3/pkg/names" - "github.com/canonical/ofga" ) -// testAuthenticator is an authenticator implementation intended -// for testing the token generator. -type testAuthenticator struct { - username string - err error -} - -// Authenticate implements the Authenticate method of the Authenticator interface. -func (ta *testAuthenticator) Authenticate(ctx context.Context, req *jujuparams.LoginRequest) (*openfga.User, error) { - if ta.err != nil { - return nil, ta.err - } - i, err := dbmodel.NewIdentity(ta.username) - if err != nil { - return nil, err - } - return &openfga.User{ - Identity: i, - }, nil -} - // testDatabase is a database implementation intended for testing the token generator. type testDatabase struct { ctl dbmodel.Controller @@ -493,19 +471,15 @@ func TestResolveJIMM(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) jimmTag := "controller-jimm" @@ -519,19 +493,15 @@ func TestResolveTupleObjectMapsApplicationOffersUUIDs(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) user, _, controller, model, offer, _, _ := createTestControllerEnvironment(ctx, c, j.Database) @@ -547,19 +517,15 @@ func TestResolveTupleObjectMapsModelUUIDs(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) user, _, controller, model, _, _, _ := createTestControllerEnvironment(ctx, c, j.Database) @@ -575,19 +541,15 @@ func TestResolveTupleObjectMapsControllerUUIDs(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) cloud := dbmodel.Cloud{ @@ -614,19 +576,15 @@ func TestResolveTupleObjectMapsGroups(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) _, err = j.Database.AddGroup(ctx, "myhandsomegroupofdigletts") @@ -649,19 +607,15 @@ func TestResolveTagObjectMapsUsers(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) tag, err := jimm.ResolveTag(j.UUID, &j.Database, "user-alex@canonical.com-werly#member") @@ -673,19 +627,15 @@ func TestResolveTupleObjectHandlesErrors(t *testing.T) { c := qt.New(t) ctx := context.Background() - ofgaClient, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) - c.Assert(err, qt.IsNil) - now := time.Now().UTC().Round(time.Millisecond) j := &jimm.JIMM{ UUID: uuid.NewString(), Database: db.Database{ DB: jimmtest.PostgresDB(c, func() time.Time { return now }), }, - OpenFGAClient: ofgaClient, } - err = j.Database.Migrate(ctx, false) + err := j.Database.Migrate(ctx, false) c.Assert(err, qt.IsNil) _, _, controller, model, offer, _, _ := createTestControllerEnvironment(ctx, c, j.Database) @@ -934,7 +884,7 @@ func TestRemoveGroupRemovesTuples(t *testing.T) { c.Assert(err, qt.IsNil) tuples := []openfga.Tuple{ - //This tuple should remain as it has no relation to group2 + // This tuple should remain as it has no relation to group2 { Object: ofganames.ConvertTag(user.ResourceTag()), Relation: "member", diff --git a/internal/jimm/admin.go b/internal/jimm/admin.go index 49fc363e4..bd2f79e96 100644 --- a/internal/jimm/admin.go +++ b/internal/jimm/admin.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/applicationoffer.go b/internal/jimm/applicationoffer.go index b72388e22..4b8ce6e8e 100644 --- a/internal/jimm/applicationoffer.go +++ b/internal/jimm/applicationoffer.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -75,11 +75,9 @@ func (j *JIMM) Offer(ctx context.Context, user *openfga.User, offer AddApplicati err = j.Database.GetApplicationOffer(ctx, &offerCheck) if err == nil { return errors.E(fmt.Sprintf("offer %s already exists, please use a different name", offerURL.String()), errors.CodeAlreadyExists) - } else { - if errors.ErrorCode(err) != errors.CodeNotFound { - // Anything besides Not Found is a problem. - return errors.E(op, err) - } + } else if errors.ErrorCode(err) != errors.CodeNotFound { + // Anything besides Not Found is a problem. + return errors.E(op, err) } api, err := j.dial(ctx, &model.Controller, names.ModelTag{}) @@ -459,8 +457,7 @@ func (j *JIMM) RevokeOfferAccess(ctx context.Context, user *openfga.User, offerU stillHasAccess := false switch targetRelation { case ofganames.AdministratorRelation: - switch currentRelation { - case ofganames.AdministratorRelation: + if currentRelation == ofganames.AdministratorRelation { stillHasAccess = true } case ofganames.ConsumerRelation: diff --git a/internal/jimm/applicationoffer_test.go b/internal/jimm/applicationoffer_test.go index 346fd3439..5ab743ac9 100644 --- a/internal/jimm/applicationoffer_test.go +++ b/internal/jimm/applicationoffer_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -303,8 +303,10 @@ func TestRevokeOfferAccess(t *testing.T) { return env.users[1], env.users[4], env.applicationOffers[0].URL, jujuparams.OfferConsumeAccess }, setup: func(env *environment, client *openfga.OFGAClient) { - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ConsumerRelation) - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.AdministratorRelation) + err := openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ConsumerRelation) + c.Assert(err, qt.IsNil) + err = openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.AdministratorRelation) + c.Assert(err, qt.IsNil) }, expectedError: "unable to completely revoke given access due to other relations.*jimmctl.*", expectedAccessLevelOnError: "admin", @@ -314,8 +316,10 @@ func TestRevokeOfferAccess(t *testing.T) { return env.users[1], env.users[4], env.applicationOffers[0].URL, jujuparams.OfferReadAccess }, setup: func(env *environment, client *openfga.OFGAClient) { - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ReaderRelation) - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.AdministratorRelation) + err := openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ReaderRelation) + c.Assert(err, qt.IsNil) + err = openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.AdministratorRelation) + c.Assert(err, qt.IsNil) }, expectedError: "unable to completely revoke given access due to other relations.*jimmctl.*", expectedAccessLevelOnError: "admin", @@ -325,8 +329,10 @@ func TestRevokeOfferAccess(t *testing.T) { return env.users[1], env.users[4], env.applicationOffers[0].URL, jujuparams.OfferReadAccess }, setup: func(env *environment, client *openfga.OFGAClient) { - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ReaderRelation) - openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ConsumerRelation) + err := openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ReaderRelation) + c.Assert(err, qt.IsNil) + err = openfga.NewUser(&env.users[4], client).SetApplicationOfferAccess(ctx, env.applicationOffers[0].ResourceTag(), ofganames.ConsumerRelation) + c.Assert(err, qt.IsNil) }, expectedError: "unable to completely revoke given access due to other relations.*jimmctl.*", expectedAccessLevelOnError: "consume", diff --git a/internal/jimm/audit_log.go b/internal/jimm/audit_log.go index 8f2d0c0d7..7bd4d5cab 100644 --- a/internal/jimm/audit_log.go +++ b/internal/jimm/audit_log.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -188,7 +188,7 @@ func calculateNextPollDuration(startingTime time.Time) time.Duration { now := startingTime nineAM := time.Date(now.Year(), now.Month(), now.Day(), pollDuration.Hours, 0, 0, 0, time.UTC) nineAMDuration := nineAM.Sub(now) - d := time.Hour + var d time.Duration // If 9am is behind the current time, i.e., 1pm if nineAMDuration < 0 { // Add 24 hours, flip it to an absolute duration, i.e., -10h == 10h diff --git a/internal/jimm/audit_log_test.go b/internal/jimm/audit_log_test.go index 219bcf2fb..98ec08fcd 100644 --- a/internal/jimm/audit_log_test.go +++ b/internal/jimm/audit_log_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimm/cache.go b/internal/jimm/cache.go index f1ee70cb3..01ca55f9c 100644 --- a/internal/jimm/cache.go +++ b/internal/jimm/cache.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/cache_test.go b/internal/jimm/cache_test.go index 740ae478f..2963888fe 100644 --- a/internal/jimm/cache_test.go +++ b/internal/jimm/cache_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimm/cloud.go b/internal/jimm/cloud.go index 0ec4a98b6..09e547aa5 100644 --- a/internal/jimm/cloud.go +++ b/internal/jimm/cloud.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -56,9 +56,7 @@ func (j *JIMM) GetCloud(ctx context.Context, user *openfga.User, tag names.Cloud accessLevel, err := j.GetUserCloudAccess(ctx, user, tag) if err != nil { - if err != nil { - return dbmodel.Cloud{}, errors.E(op, err) - } + return dbmodel.Cloud{}, errors.E(op, err) } switch accessLevel { @@ -408,25 +406,6 @@ func (j *JIMM) AddHostedCloud(ctx context.Context, user *openfga.User, tag names return nil } -func randomController() func(controllers []dbmodel.CloudRegionControllerPriority) (dbmodel.Controller, error) { - return func(controllers []dbmodel.CloudRegionControllerPriority) (dbmodel.Controller, error) { - shuffleRegionControllers(controllers) - return controllers[0].Controller, nil - } -} - -func findController(controllerName string) func(controllers []dbmodel.CloudRegionControllerPriority) (dbmodel.Controller, error) { - return func(controllers []dbmodel.CloudRegionControllerPriority) (dbmodel.Controller, error) { - for _, crp := range controllers { - crp := crp - if crp.Controller.Name == controllerName { - return crp.Controller, nil - } - } - return dbmodel.Controller{}, errors.E("controller not found", errors.CodeNotFound) - } -} - // addControllerCloud creates the hosted cloud defined by the given tag and // jujuparams cloud definition. Admin access to the cloud will be granted // to the user identified by the given user tag. On success diff --git a/internal/jimm/cloud_test.go b/internal/jimm/cloud_test.go index 669c86f1c..2233d50a7 100644 --- a/internal/jimm/cloud_test.go +++ b/internal/jimm/cloud_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -1061,6 +1061,7 @@ func TestGrantCloudAccess(t *testing.T) { Err: tt.dialError, } j := &jimm.JIMM{ + UUID: jimmtest.ControllerUUID, Database: db.Database{ DB: jimmtest.PostgresDB(c, nil), }, @@ -1360,6 +1361,7 @@ func TestRevokeCloudAccess(t *testing.T) { Err: tt.dialError, } j := &jimm.JIMM{ + UUID: jimmtest.ControllerUUID, Database: db.Database{ DB: jimmtest.PostgresDB(c, nil), }, diff --git a/internal/jimm/cloudcredential.go b/internal/jimm/cloudcredential.go index 52587df66..9e710a982 100644 --- a/internal/jimm/cloudcredential.go +++ b/internal/jimm/cloudcredential.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/cloudcredential_test.go b/internal/jimm/cloudcredential_test.go index 293c761d2..775b48d23 100644 --- a/internal/jimm/cloudcredential_test.go +++ b/internal/jimm/cloudcredential_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -1399,6 +1399,7 @@ func TestGetCloudCredential(t *testing.T) { } } +//nolint:gosec // Thinks credentials hardcoded. const forEachUserCloudCredentialEnv = `clouds: - name: cloud-1 regions: @@ -1521,6 +1522,7 @@ func TestForEachUserCloudCredential(t *testing.T) { } } +//nolint:gosec // Thinks credentials hardcoded. const getCloudCredentialAttributesEnv = `clouds: - name: test-cloud type: gce diff --git a/internal/jimm/clouddefaults.go b/internal/jimm/clouddefaults.go index 467d7ff48..89a6ef568 100644 --- a/internal/jimm/clouddefaults.go +++ b/internal/jimm/clouddefaults.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimm import ( @@ -112,8 +113,5 @@ func (j *JIMM) ModelDefaultsForCloud(ctx context.Context, user *dbmodel.Identity result.Config[k] = d } } - if err != nil { - return jujuparams.ModelDefaultsResult{}, errors.E(op, err) - } return result, nil } diff --git a/internal/jimm/clouddefaults_test.go b/internal/jimm/clouddefaults_test.go index 5d1778d23..7371967ef 100644 --- a/internal/jimm/clouddefaults_test.go +++ b/internal/jimm/clouddefaults_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -133,7 +133,7 @@ func TestSetCloudDefaults(t *testing.T) { } c.Assert(j.Database.DB.Create(&cloud).Error, qt.IsNil) - j.Database.SetCloudDefaults(ctx, &dbmodel.CloudDefaults{ + err = j.Database.SetCloudDefaults(ctx, &dbmodel.CloudDefaults{ IdentityName: user.Name, Identity: *user, CloudID: cloud.ID, @@ -144,6 +144,7 @@ func TestSetCloudDefaults(t *testing.T) { "key2": "a test string", }, }) + c.Assert(err, qt.IsNil) defaults := map[string]interface{}{ "key1": float64(42), @@ -179,7 +180,6 @@ func TestSetCloudDefaults(t *testing.T) { cloud := dbmodel.Cloud{ Name: "test-cloud-1", - Type: "test-provider", Regions: []dbmodel.CloudRegion{{ Name: "test-region", }}, @@ -209,7 +209,6 @@ func TestSetCloudDefaults(t *testing.T) { cloud := dbmodel.Cloud{ Name: "test-cloud-1", - Type: "test-provider", Regions: []dbmodel.CloudRegion{{ Name: "test-region", }}, diff --git a/internal/jimm/controller.go b/internal/jimm/controller.go index f2af329e5..26d6b3e73 100644 --- a/internal/jimm/controller.go +++ b/internal/jimm/controller.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -228,6 +228,7 @@ func (j *JIMM) EarliestControllerVersion(ctx context.Context) (version.Number, e zap.String("version", controller.AgentVersion), zap.String("controller", controller.Name), ) + //nolint:nilerr // We wish to log without an error returned, TODO: Check with Ales return nil } if v == nil || versionNumber.Compare(*v) < 0 { @@ -244,42 +245,6 @@ func (j *JIMM) EarliestControllerVersion(ctx context.Context) (version.Number, e return *v, nil } -// controllerAccessLevel holds the controller access level for a user. -type controllerAccessLevel string - -const ( - // noAccess allows a user no permissions at all. - noAccess controllerAccessLevel = "" - - // loginAccess allows a user to log-ing into the subject. - loginAccess controllerAccessLevel = "login" - - // superuserAccess allows user unrestricted permissions in the subject. - superuserAccess controllerAccessLevel = "superuser" -) - -// validate returns error if the current is not a valid access level. -func (a controllerAccessLevel) validate() error { - switch a { - case noAccess, loginAccess, superuserAccess: - return nil - } - return errors.E(fmt.Sprintf("invalid access level %q", a)) -} - -func (a controllerAccessLevel) value() int { - switch a { - case noAccess: - return 0 - case loginAccess: - return 1 - case superuserAccess: - return 2 - default: - return -1 - } -} - // GetJimmControllerAccess returns the JIMM controller access level for the // requested user. func (j *JIMM) GetJimmControllerAccess(ctx context.Context, user *openfga.User, tag names.UserTag) (string, error) { @@ -407,7 +372,7 @@ func (j *JIMM) ImportModel(ctx context.Context, user *openfga.User, controllerNa // fetch cloud credential used by the model cloudTag, err := names.ParseCloudTag(modelInfo.CloudTag) if err != nil { - errors.E(op, err) + return errors.E(op, err) } // Note that the model already has a cloud credential configured which it will use when deploying new // applications. JIMM needs some cloud credential reference to be able to import the model so use any @@ -467,7 +432,11 @@ func (j *JIMM) ImportModel(ctx context.Context, user *openfga.User, controllerNa if err != nil { return errors.E(op, err) } - defer modelAPI.ModelWatcherStop(ctx, watcherID) + defer func() { + if err := modelAPI.ModelWatcherStop(ctx, watcherID); err != nil { + zapctx.Error(ctx, "failed to stop model watcher", zap.Error(err)) + } + }() deltas, err := modelAPI.ModelWatcherNext(ctx, watcherID) if err != nil { diff --git a/internal/jimm/controller_test.go b/internal/jimm/controller_test.go index cd8f5f6b3..6d1398192 100644 --- a/internal/jimm/controller_test.go +++ b/internal/jimm/controller_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -63,17 +63,17 @@ func TestAddController(t *testing.T) { "B": 0xb, }, RegionConfig: map[string]map[string]interface{}{ - "eu-west-1": map[string]interface{}{ + "eu-west-1": { "B": 0xb0, "C": "C", }, - "eu-west-2": map[string]interface{}{ + "eu-west-2": { "B": 0xb1, "D": "D", }, }, }, - names.NewCloudTag("k8s"): jujuparams.Cloud{ + names.NewCloudTag("k8s"): { Type: "kubernetes", AuthTypes: []string{"userpass"}, Endpoint: "https://k8s.example.com", @@ -206,7 +206,7 @@ func TestAddControllerWithVault(t *testing.T) { api := &jimmtest.API{ Clouds_: func(context.Context) (map[names.CloudTag]jujuparams.Cloud, error) { clouds := map[names.CloudTag]jujuparams.Cloud{ - names.NewCloudTag("aws"): jujuparams.Cloud{ + names.NewCloudTag("aws"): { Type: "ec2", AuthTypes: []string{"userpass"}, Endpoint: "https://example.com", @@ -229,17 +229,17 @@ func TestAddControllerWithVault(t *testing.T) { "B": 0xb, }, RegionConfig: map[string]map[string]interface{}{ - "eu-west-1": map[string]interface{}{ + "eu-west-1": { "B": 0xb0, "C": "C", }, - "eu-west-2": map[string]interface{}{ + "eu-west-2": { "B": 0xb1, "D": "D", }, }, }, - names.NewCloudTag("k8s"): jujuparams.Cloud{ + names.NewCloudTag("k8s"): { Type: "kubernetes", AuthTypes: []string{"userpass"}, Endpoint: "https://k8s.example.com", @@ -1414,7 +1414,7 @@ func TestInitiateMigration(t *testing.T) { c := qt.New(t) mt1 := names.NewModelTag("00000002-0000-0000-0000-000000000003") - //mt2 := names.NewModelTag("00000002-0000-0000-0000-000000000004") + // mt2 := names.NewModelTag("00000002-0000-0000-0000-000000000004") migrationId1 := uuid.New().String() diff --git a/internal/jimm/credentials/credentials.go b/internal/jimm/credentials/credentials.go index 00cb9141c..b6ffdd0ed 100644 --- a/internal/jimm/credentials/credentials.go +++ b/internal/jimm/credentials/credentials.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. // Package credentials provides abstractions/definitions for credential storage // backends and caching mechanisms. diff --git a/internal/jimm/export_test.go b/internal/jimm/export_test.go index 5fa02ac2e..411c81f6e 100644 --- a/internal/jimm/export_test.go +++ b/internal/jimm/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/identitymodeldefaults.go b/internal/jimm/identitymodeldefaults.go index 833b760dc..8bb21f1ee 100644 --- a/internal/jimm/identitymodeldefaults.go +++ b/internal/jimm/identitymodeldefaults.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/identitymodeldefaults_test.go b/internal/jimm/identitymodeldefaults_test.go index e408d289a..a92d99cae 100644 --- a/internal/jimm/identitymodeldefaults_test.go +++ b/internal/jimm/identitymodeldefaults_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -67,7 +67,7 @@ func TestSetIdentityModelDefaults(t *testing.T) { c.Assert(j.Database.DB.Create(identity).Error, qt.IsNil) - j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ + err = j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ IdentityName: identity.Name, Identity: *identity, Defaults: map[string]interface{}{ @@ -75,6 +75,7 @@ func TestSetIdentityModelDefaults(t *testing.T) { "key2": "a test string", }, }) + c.Assert(err, qt.IsNil) defaults := map[string]interface{}{ "key1": float64(42), @@ -181,7 +182,7 @@ func TestIdentityModelDefaults(t *testing.T) { c.Assert(j.Database.DB.Create(identity).Error, qt.IsNil) - j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ + err = j.Database.SetIdentityModelDefaults(ctx, &dbmodel.IdentityModelDefaults{ IdentityName: identity.Name, Identity: *identity, Defaults: map[string]interface{}{ @@ -190,6 +191,7 @@ func TestIdentityModelDefaults(t *testing.T) { "key3": "a new value", }, }) + c.Assert(err, qt.IsNil) return testConfig{ identity: identity, diff --git a/internal/jimm/jimm.go b/internal/jimm/jimm.go index e19c9e82b..b9ec53e14 100644 --- a/internal/jimm/jimm.go +++ b/internal/jimm/jimm.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package jimm contains the business logic used to manage clouds, // cloudcredentials and models. diff --git a/internal/jimm/jimm_test.go b/internal/jimm/jimm_test.go index 99973d0bb..867cbb9b9 100644 --- a/internal/jimm/jimm_test.go +++ b/internal/jimm/jimm_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimm/model.go b/internal/jimm/model.go index c4034d5ff..1d2ee823a 100644 --- a/internal/jimm/model.go +++ b/internal/jimm/model.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -999,11 +999,6 @@ func (j *JIMM) RevokeModelAccess(ctx context.Context, user *openfga.User, mt nam func (j *JIMM) DestroyModel(ctx context.Context, user *openfga.User, mt names.ModelTag, destroyStorage, force *bool, maxWait, timeout *time.Duration) error { const op = errors.Op("jimm.DestroyModel") - if destroyStorage != nil { - } - if force != nil { - } - err := j.doModelAdmin(ctx, user, mt, func(m *dbmodel.Model, api API) error { if err := api.DestroyModel(ctx, mt, destroyStorage, force, maxWait, timeout); err != nil { return err diff --git a/internal/jimm/model_status_parser.go b/internal/jimm/model_status_parser.go index 76f235c2b..fdd25bb0d 100644 --- a/internal/jimm/model_status_parser.go +++ b/internal/jimm/model_status_parser.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimm import ( @@ -8,7 +9,7 @@ import ( jujucmd "github.com/juju/cmd/v3" "github.com/juju/juju/cmd/juju/status" "github.com/juju/juju/cmd/juju/storage" - rpcparams "github.com/juju/juju/rpc/params" + jujuparams "github.com/juju/juju/rpc/params" "github.com/juju/names/v5" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" @@ -161,7 +162,7 @@ func (f *formatterParamsRetriever) dialModel(ctx context.Context) error { // getModelStatus calls the FullStatus facade to return the full status for the current model // loaded in the formatterParamsRetriever. -func (f *formatterParamsRetriever) getModelStatus(ctx context.Context) (*rpcparams.FullStatus, error) { +func (f *formatterParamsRetriever) getModelStatus(ctx context.Context) (*jujuparams.FullStatus, error) { modelStatus, err := f.api.Status(ctx, nil) if err != nil { zapctx.Error(ctx, "failed to call FullStatus", zap.String("controller-uuid", f.model.Controller.UUID), zap.String("model-uuid", f.model.UUID.String), zap.Error(err)) @@ -199,17 +200,17 @@ func newStorageListAPI(ctx context.Context, api API) storageListAPI { } // ListStorageDetails implements storage.StorageListAPI. (From Juju) -func (s *storageListAPI) ListStorageDetails() ([]rpcparams.StorageDetails, error) { +func (s *storageListAPI) ListStorageDetails() ([]jujuparams.StorageDetails, error) { return s.api.ListStorageDetails(s.ctx) } // ListFilesystems implements storage.StorageListAPI. (From Juju) -func (s *storageListAPI) ListFilesystems(machines []string) ([]rpcparams.FilesystemDetailsListResult, error) { +func (s *storageListAPI) ListFilesystems(machines []string) ([]jujuparams.FilesystemDetailsListResult, error) { return s.api.ListFilesystems(s.ctx, machines) } // ListVolumes implements storage.StorageListAPI. (From Juju) -func (s *storageListAPI) ListVolumes(machines []string) ([]rpcparams.VolumeDetailsListResult, error) { +func (s *storageListAPI) ListVolumes(machines []string) ([]jujuparams.VolumeDetailsListResult, error) { return s.api.ListVolumes(s.ctx, machines) } diff --git a/internal/jimm/model_status_parser_test.go b/internal/jimm/model_status_parser_test.go index f933c196c..af10c096f 100644 --- a/internal/jimm/model_status_parser_test.go +++ b/internal/jimm/model_status_parser_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimm_test import ( diff --git a/internal/jimm/model_test.go b/internal/jimm/model_test.go index d1d6f58e4..01b7be8d1 100644 --- a/internal/jimm/model_test.go +++ b/internal/jimm/model_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -1991,6 +1991,7 @@ func TestGrantModelAccess(t *testing.T) { Err: tt.dialError, } j := &jimm.JIMM{ + UUID: jimmtest.ControllerUUID, Database: db.Database{ DB: jimmtest.PostgresDB(c, nil), }, @@ -2710,6 +2711,7 @@ func TestRevokeModelAccess(t *testing.T) { Err: tt.dialError, } j := &jimm.JIMM{ + UUID: jimmtest.ControllerUUID, Database: db.Database{ DB: jimmtest.PostgresDB(c, nil), }, @@ -3283,6 +3285,7 @@ func TestValidateModelUpgrade(t *testing.T) { } } +//nolint:gosec // Thinks credentials hardcoded. const updateModelCredentialTestEnv = `clouds: - name: test-cloud type: test-provider diff --git a/internal/jimm/modelsummary.go b/internal/jimm/modelsummary.go index 548dd5362..4910521cc 100644 --- a/internal/jimm/modelsummary.go +++ b/internal/jimm/modelsummary.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/modelsummary_test.go b/internal/jimm/modelsummary_test.go index 9d3639afe..fdd559853 100644 --- a/internal/jimm/modelsummary_test.go +++ b/internal/jimm/modelsummary_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimm/monitoring.go b/internal/jimm/monitoring.go index 669e80220..dc84f0dd3 100644 --- a/internal/jimm/monitoring.go +++ b/internal/jimm/monitoring.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimm import ( @@ -15,7 +16,7 @@ import ( // managed by JIMM as well as how many model each controller manages. func (j *JIMM) UpdateMetrics(ctx context.Context) { controllerCount := 0 - j.Database.ForEachController(ctx, func(c *dbmodel.Controller) error { + err := j.Database.ForEachController(ctx, func(c *dbmodel.Controller) error { controllerCount++ modelGauge, err := servermon.ModelCount.GetMetricWith(prometheus.Labels{"controller": c.Name}) if err != nil { @@ -30,5 +31,8 @@ func (j *JIMM) UpdateMetrics(ctx context.Context) { modelGauge.Set(float64(count)) return nil }) + if err != nil { + zapctx.Error(ctx, "update metrics failed", zap.Error(err)) + } servermon.ControllerCount.Set(float64(controllerCount)) } diff --git a/internal/jimm/purge_logs.go b/internal/jimm/purge_logs.go index 43291596a..c5a891ade 100644 --- a/internal/jimm/purge_logs.go +++ b/internal/jimm/purge_logs.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -6,10 +6,11 @@ import ( "context" "time" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/openfga" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" + + "github.com/canonical/jimm/v3/internal/errors" + "github.com/canonical/jimm/v3/internal/openfga" ) // PurgeLogs removes all audit logs before the given timestamp. Only JIMM diff --git a/internal/jimm/runner.go b/internal/jimm/runner.go index dad9d66ff..524408c74 100644 --- a/internal/jimm/runner.go +++ b/internal/jimm/runner.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/runner_internal_test.go b/internal/jimm/runner_internal_test.go index c5520186b..ff925794c 100644 --- a/internal/jimm/runner_internal_test.go +++ b/internal/jimm/runner_internal_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/service_account.go b/internal/jimm/service_account.go index 909baeb87..2f179dbca 100644 --- a/internal/jimm/service_account.go +++ b/internal/jimm/service_account.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -6,14 +6,15 @@ import ( "context" "fmt" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/openfga" - ofganames "github.com/canonical/jimm/v3/internal/openfga/names" - jimmnames "github.com/canonical/jimm/v3/pkg/names" jujuparams "github.com/juju/juju/rpc/params" "github.com/juju/names/v5" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" + + "github.com/canonical/jimm/v3/internal/errors" + "github.com/canonical/jimm/v3/internal/openfga" + ofganames "github.com/canonical/jimm/v3/internal/openfga/names" + jimmnames "github.com/canonical/jimm/v3/pkg/names" ) // AddServiceAccount checks that no one owns the service account yet diff --git a/internal/jimm/service_account_test.go b/internal/jimm/service_account_test.go index 3c8cdefa5..6c3c4aaf9 100644 --- a/internal/jimm/service_account_test.go +++ b/internal/jimm/service_account_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimm/user.go b/internal/jimm/user.go index f406eb912..ba9e8165e 100644 --- a/internal/jimm/user.go +++ b/internal/jimm/user.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimm diff --git a/internal/jimm/user_test.go b/internal/jimm/user_test.go index e434632d6..956c3da5c 100644 --- a/internal/jimm/user_test.go +++ b/internal/jimm/user_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test @@ -24,7 +24,7 @@ func TestGetUser(t *testing.T) { client, _, _, err := jimmtest.SetupTestOFGAClient(c.Name()) c.Assert(err, qt.IsNil) db := &db.Database{ - DB: jimmtest.PostgresDB(c, func() time.Time { return time.Now() }), + DB: jimmtest.PostgresDB(c, time.Now), } j := &jimm.JIMM{ diff --git a/internal/jimm/watcher.go b/internal/jimm/watcher.go index 6efb27bff..006817a0a 100644 --- a/internal/jimm/watcher.go +++ b/internal/jimm/watcher.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm @@ -237,7 +237,11 @@ func (w *Watcher) watchController(ctx context.Context, ctl *dbmodel.Controller) if err != nil { return errors.E(op, err) } - defer api.AllModelWatcherStop(ctx, id) + defer func() { + if err := api.AllModelWatcherStop(ctx, id); err != nil { + zapctx.Error(ctx, "failed to stop all model watcher", zap.Error(err)) + } + }() checkDyingModel := func(m *dbmodel.Model) error { if m.Life == state.Dying.String() || m.Life == state.Dead.String() { @@ -284,16 +288,17 @@ func (w *Watcher) watchController(ctx context.Context, ctl *dbmodel.Controller) ControllerID: ctl.ID, } err := w.Database.GetModel(ctx, &m) - if err == nil { + switch { + case err == nil: st := modelState{ id: m.ID, machines: make(map[string]int64), units: make(map[string]bool), } modelStates[uuid] = &st - } else if errors.ErrorCode(err) == errors.CodeNotFound { + case errors.ErrorCode(err) == errors.CodeNotFound: modelStates[uuid] = nil - } else { + default: zapctx.Error(ctx, "cannot get model", zap.Error(err)) } return modelStates[uuid] @@ -374,7 +379,11 @@ func (w *Watcher) watchAllModelSummaries(ctx context.Context, ctl *dbmodel.Contr if err != nil { return errors.E(op, err) } - defer api.ModelSummaryWatcherStop(ctx, id) + defer func() { + if err := api.ModelSummaryWatcherStop(ctx, id); err != nil { + zapctx.Error(ctx, "failed to stop model summary watcher", zap.Error(err)) + } + }() // modelIDs contains the set of models running on the // controller that JIMM is interested in. diff --git a/internal/jimm/watcher_test.go b/internal/jimm/watcher_test.go index b39981b5f..31f9a1bc3 100644 --- a/internal/jimm/watcher_test.go +++ b/internal/jimm/watcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimm_test diff --git a/internal/jimmhttp/auth_handler.go b/internal/jimmhttp/auth_handler.go index e8aa589e2..d8590122a 100644 --- a/internal/jimmhttp/auth_handler.go +++ b/internal/jimmhttp/auth_handler.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmhttp import ( @@ -247,5 +248,8 @@ func writeError(ctx context.Context, w http.ResponseWriter, status int, err erro if err != nil { errMsg = " - " + err.Error() } - w.Write([]byte(http.StatusText(status) + errMsg)) + _, err = w.Write([]byte(http.StatusText(status) + errMsg)) + if err != nil { + zapctx.Error(ctx, "failed to write status text error", zap.Error(err)) + } } diff --git a/internal/jimmhttp/auth_handler_test.go b/internal/jimmhttp/auth_handler_test.go index c81942a9c..24f3f4b22 100644 --- a/internal/jimmhttp/auth_handler_test.go +++ b/internal/jimmhttp/auth_handler_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmhttp_test import ( @@ -24,7 +25,7 @@ import ( func setupDbAndSessionStore(c *qt.C) (*db.Database, sessions.Store) { // Setup db ahead of time so we have access to session store db := &db.Database{ - DB: jimmtest.PostgresDB(c, func() time.Time { return time.Now() }), + DB: jimmtest.PostgresDB(c, time.Now), } c.Assert(db.Migrate(context.Background(), false), qt.IsNil) @@ -130,8 +131,10 @@ func TestCallbackFailsNoState(t *testing.T) { c.Assert(err, qt.IsNil) defer s.Close() - callbackURL := s.URL + jimmhttp.AuthResourceBasePath + jimmhttp.CallbackEndpoint - res, err := http.Get(callbackURL) + u, err := url.Parse(s.URL) + c.Assert(err, qt.IsNil) + u = u.JoinPath(jimmhttp.AuthResourceBasePath, jimmhttp.CallbackEndpoint) + res, err := http.Get(u.String()) c.Assert(err, qt.IsNil) defer res.Body.Close() diff --git a/internal/jimmhttp/handler.go b/internal/jimmhttp/handler.go index 079b48210..41e472bd5 100644 --- a/internal/jimmhttp/handler.go +++ b/internal/jimmhttp/handler.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmhttp import ( diff --git a/internal/jimmhttp/http.go b/internal/jimmhttp/http.go index 8b2d3fdc4..49d807cb2 100644 --- a/internal/jimmhttp/http.go +++ b/internal/jimmhttp/http.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // Package jimmhttp contains utilities for HTTP connections. package jimmhttp diff --git a/internal/jimmhttp/http_test.go b/internal/jimmhttp/http_test.go index a0a3c1f0e..56185c934 100644 --- a/internal/jimmhttp/http_test.go +++ b/internal/jimmhttp/http_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimmhttp_test @@ -62,6 +62,7 @@ func TestStripPathElement(t *testing.T) { hnd.ServeHTTP(rr, req) resp := rr.Result() + defer resp.Body.Close() c.Check(resp.StatusCode, qt.Equals, http.StatusOK) }) } diff --git a/internal/jimmhttp/websocket.go b/internal/jimmhttp/websocket.go index e14cb7b50..ce5731b03 100644 --- a/internal/jimmhttp/websocket.go +++ b/internal/jimmhttp/websocket.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimmhttp diff --git a/internal/jimmhttp/websocket_test.go b/internal/jimmhttp/websocket_test.go index c39a597bf..6a77a738e 100644 --- a/internal/jimmhttp/websocket_test.go +++ b/internal/jimmhttp/websocket_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimmhttp_test @@ -30,8 +30,9 @@ func TestWSHandler(t *testing.T) { c.Cleanup(srv.Close) var d websocket.Dialer - conn, _, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) + conn, resp, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) c.Assert(err, qt.IsNil) + defer resp.Body.Close() err = conn.WriteMessage(websocket.TextMessage, []byte("test!")) c.Assert(err, qt.IsNil) @@ -77,8 +78,9 @@ func TestWSHandlerPanic(t *testing.T) { c.Cleanup(srv.Close) var d websocket.Dialer - conn, _, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) + conn, resp, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) c.Assert(err, qt.IsNil) + defer resp.Body.Close() _, _, err = conn.ReadMessage() c.Assert(err, qt.ErrorMatches, `websocket: close 1011 \(internal server error\): test`) @@ -104,8 +106,9 @@ func TestWSHandlerNilServer(t *testing.T) { c.Cleanup(srv.Close) var d websocket.Dialer - conn, _, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) + conn, resp, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), nil) c.Assert(err, qt.IsNil) + defer resp.Body.Close() _, _, err = conn.ReadMessage() c.Assert(err, qt.ErrorMatches, `websocket: close 1000 \(normal\)`) @@ -132,10 +135,11 @@ func TestWSHandlerAuthFailsServer(t *testing.T) { c.Cleanup(srv.Close) var d websocket.Dialer - conn, _, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), http.Header{ + conn, resp, err := d.Dial("ws"+strings.TrimPrefix(srv.URL, "http"), http.Header{ "Cookie": []string{auth.SessionName + "=naughty_cookie"}, }) c.Assert(err, qt.IsNil) + defer resp.Body.Close() _, _, err = conn.ReadMessage() c.Assert(err, qt.ErrorMatches, `websocket: close 1011 \(internal server error\): authentication failed`) diff --git a/internal/jimmjwx/export_test.go b/internal/jimmjwx/export_test.go index baebf4705..2217aaa23 100644 --- a/internal/jimmjwx/export_test.go +++ b/internal/jimmjwx/export_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmjwx var ( diff --git a/internal/jimmjwx/jimmjwx.go b/internal/jimmjwx/jimmjwx.go index afc6bf2cf..30e973e0f 100644 --- a/internal/jimmjwx/jimmjwx.go +++ b/internal/jimmjwx/jimmjwx.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. // Package jimmjwx provides utility functions for JOSE (Javascript Object Signing and Encryption) within // JIMM. It currently supports the following: diff --git a/internal/jimmjwx/jwks.go b/internal/jimmjwx/jwks.go index fa448e17e..2657d66aa 100644 --- a/internal/jimmjwx/jwks.go +++ b/internal/jimmjwx/jwks.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package jimmjwx @@ -66,7 +66,9 @@ func rotateJWKS(ctx context.Context, credStore credentials.CredentialStore, init zapctx.Debug(ctx, "setting initial expiry", zap.Time("time", initialExpiryTime)) err = putJwks(initialExpiryTime) if err != nil { - credStore.CleanupJWKS(ctx) + if jwksErr := credStore.CleanupJWKS(ctx); jwksErr != nil { + zapctx.Error(ctx, "failed to cleanup jwks", zap.Error(jwksErr)) + } return errors.E(err) } } else { @@ -77,7 +79,9 @@ func rotateJWKS(ctx context.Context, credStore credentials.CredentialStore, init // components exist from the previous failed expiry attempt. err = putJwks(time.Now().UTC().AddDate(0, 3, 0)) if err != nil { - credStore.CleanupJWKS(ctx) + if jwksErr := credStore.CleanupJWKS(ctx); jwksErr != nil { + zapctx.Error(ctx, "failed to cleanup jwks", zap.Error(jwksErr)) + } return errors.E(err) } zapctx.Debug(ctx, "set a new JWKS", zap.String("expiry", expires.String())) diff --git a/internal/jimmjwx/jwks_test.go b/internal/jimmjwx/jwks_test.go index 76f91531f..cc9a48fd6 100644 --- a/internal/jimmjwx/jwks_test.go +++ b/internal/jimmjwx/jwks_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmjwx_test import ( diff --git a/internal/jimmjwx/jwt.go b/internal/jimmjwx/jwt.go index 4184aeb05..f9f5b3045 100644 --- a/internal/jimmjwx/jwt.go +++ b/internal/jimmjwx/jwt.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimmjwx @@ -8,8 +8,6 @@ import ( "encoding/pem" "time" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/jimm/credentials" "github.com/google/uuid" "github.com/hashicorp/golang-lru/v2/expirable" "github.com/juju/zaputil/zapctx" @@ -17,6 +15,9 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" "go.uber.org/zap" + + "github.com/canonical/jimm/v3/internal/errors" + "github.com/canonical/jimm/v3/internal/jimm/credentials" ) type JWTServiceParams struct { @@ -96,7 +97,7 @@ func NewJWTService(p JWTServiceParams) *JWTService { // and instead, a new JWT will be issued each time containing the required claims for // authz. func (j *JWTService) NewJWT(ctx context.Context, params JWTParams) ([]byte, error) { - jti, err := j.generateJTI(ctx) + jti, err := j.generateJTI() if err != nil { return nil, err } @@ -133,8 +134,13 @@ func (j *JWTService) NewJWT(ctx context.Context, params JWTParams) ([]byte, erro return nil, err } - signingKey.Set(jwk.AlgorithmKey, jwa.RS256) - signingKey.Set(jwk.KeyIDKey, pubKey.KeyID()) + if err := signingKey.Set(jwk.AlgorithmKey, jwa.RS256); err != nil { + return nil, err + } + + if err := signingKey.Set(jwk.KeyIDKey, pubKey.KeyID()); err != nil { + return nil, err + } token, err := jwt.NewBuilder(). Audience([]string{params.Controller}). @@ -164,7 +170,7 @@ func (j *JWTService) NewJWT(ctx context.Context, params JWTParams) ([]byte, erro // generateJTI uses a V4 UUID, giving a chance of 1 in 17Billion per year. // This should be good enough (hopefully) for a JWT ID. -func (j *JWTService) generateJTI(ctx context.Context) (string, error) { +func (j *JWTService) generateJTI() (string, error) { id, err := uuid.NewRandom() if err != nil { return "", err diff --git a/internal/jimmjwx/jwt_test.go b/internal/jimmjwx/jwt_test.go index 558289d2a..b17749d0c 100644 --- a/internal/jimmjwx/jwt_test.go +++ b/internal/jimmjwx/jwt_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmjwx_test import ( @@ -7,11 +8,12 @@ import ( "testing" "time" - "github.com/canonical/jimm/v3/internal/jimmjwx" qt "github.com/frankban/quicktest" "github.com/lestrrat-go/iter/arrayiter" "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" + + "github.com/canonical/jimm/v3/internal/jimmjwx" ) func TestRegisterJWKSCacheRegistersTheCacheSuccessfully(t *testing.T) { @@ -158,7 +160,8 @@ func TestCredentialCache(t *testing.T) { ctx := context.Background() set, _, err := jimmjwx.GenerateJWK(ctx) c.Assert(err, qt.IsNil) - store.PutJWKS(ctx, set) + err = store.PutJWKS(ctx, set) + c.Assert(err, qt.IsNil) vaultCache := jimmjwx.NewCredentialCache(store) gotSet, err := vaultCache.Get(ctx) c.Assert(err, qt.IsNil) diff --git a/internal/jimmjwx/utils_test.go b/internal/jimmjwx/utils_test.go index c00e0dd87..f8111f5ea 100644 --- a/internal/jimmjwx/utils_test.go +++ b/internal/jimmjwx/utils_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmjwx_test import ( @@ -68,9 +69,8 @@ func startAndTestRotator(c *qt.C, ctx context.Context, store credentials.Credent time.Sleep(500 * time.Millisecond) continue } - if ks != nil { - break - } + break + } c.Assert(err, qt.IsNil) key, ok := ks.Key(0) diff --git a/internal/jimmtest/api.go b/internal/jimmtest/api.go index f0759e04d..20ba4a5cb 100644 --- a/internal/jimmtest/api.go +++ b/internal/jimmtest/api.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest diff --git a/internal/jimmtest/auth.go b/internal/jimmtest/auth.go index b5389f14b..266399455 100644 --- a/internal/jimmtest/auth.go +++ b/internal/jimmtest/auth.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest @@ -25,8 +25,10 @@ import ( "github.com/gorilla/sessions" "github.com/juju/juju/api" jujuparams "github.com/juju/juju/rpc/params" + "github.com/juju/zaputil/zapctx" "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jwt" + "go.uber.org/zap" "golang.org/x/oauth2" "github.com/canonical/jimm/v3/internal/auth" @@ -286,7 +288,10 @@ func runBrowserLogin(db *db.Database, sessionStore sessions.Store, username, pas http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { cookieString = r.Header.Get("Cookie") - w.Write([]byte(dashboardResponse)) + if _, err := w.Write([]byte(dashboardResponse)); err != nil { + zapctx.Error(context.Background(), "failed to write dashboard response", zap.Error(err)) + } + }, ), ) diff --git a/internal/jimmtest/cmp.go b/internal/jimmtest/cmp.go index 6bb017204..90db5e518 100644 --- a/internal/jimmtest/cmp.go +++ b/internal/jimmtest/cmp.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest diff --git a/internal/jimmtest/env.go b/internal/jimmtest/env.go index 7678dd060..863f94794 100644 --- a/internal/jimmtest/env.go +++ b/internal/jimmtest/env.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest @@ -130,7 +130,7 @@ func (u User) addUserRelations(c *qt.C, jimmTag names.ControllerTag, db db.Datab } // addCloudRelations adds permissions the cloud should have and adds permissions for users to the cloud. -func (cl Cloud) addCloudRelations(c *qt.C, jimmTag names.ControllerTag, db db.Database, client *openfga.OFGAClient) { +func (cl Cloud) addCloudRelations(c *qt.C, db db.Database, client *openfga.OFGAClient) { for _, u := range cl.Users { dbUser := cl.env.User(u.User).DBObject(c, db) var relation openfga.Relation @@ -151,7 +151,7 @@ func (cl Cloud) addCloudRelations(c *qt.C, jimmTag names.ControllerTag, db db.Da } // addModelRelations adds permissions the model should have and adds permissions for users to the model. -func (m Model) addModelRelations(c *qt.C, jimmTag names.ControllerTag, db db.Database, client *openfga.OFGAClient) { +func (m Model) addModelRelations(c *qt.C, db db.Database, client *openfga.OFGAClient) { owner := openfga.NewUser(&m.dbo.Owner, client) err := owner.SetModelAccess(context.Background(), m.dbo.ResourceTag(), ofganames.AdministratorRelation) c.Assert(err, qt.IsNil) @@ -179,7 +179,7 @@ func (m Model) addModelRelations(c *qt.C, jimmTag names.ControllerTag, db db.Dat } // addControllerRelations adds permissions the model should have and adds permissions for users to the controller. -func (ctl Controller) addControllerRelations(c *qt.C, jimmTag names.ControllerTag, db db.Database, client *openfga.OFGAClient) { +func (ctl Controller) addControllerRelations(c *qt.C, client *openfga.OFGAClient) { if ctl.dbo.AdminIdentityName != "" { userIdentity, err := dbmodel.NewIdentity(ctl.dbo.AdminIdentityName) c.Assert(err, qt.IsNil) @@ -200,16 +200,17 @@ func (e *Environment) addJIMMRelations(c *qt.C, jimmTag names.ControllerTag, db user.addUserRelations(c, jimmTag, db, client) } for _, controller := range e.Controllers { - client.AddController(context.Background(), jimmTag, controller.dbo.ResourceTag()) + err := client.AddController(context.Background(), jimmTag, controller.dbo.ResourceTag()) + c.Assert(err, qt.IsNil) } for _, cl := range e.Clouds { - cl.addCloudRelations(c, jimmTag, db, client) + cl.addCloudRelations(c, db, client) } for _, m := range e.Models { - m.addModelRelations(c, jimmTag, db, client) + m.addModelRelations(c, db, client) } for _, ctl := range e.Controllers { - ctl.addControllerRelations(c, jimmTag, db, client) + ctl.addControllerRelations(c, client) } } diff --git a/internal/jimmtest/gorm.go b/internal/jimmtest/gorm.go index 6294fc363..9eced56c9 100644 --- a/internal/jimmtest/gorm.go +++ b/internal/jimmtest/gorm.go @@ -1,10 +1,11 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package jimmtest contains useful helpers for testing JIMM. package jimmtest import ( "context" + //nolint:gosec // We're only using sha1 in tests. "crypto/sha1" "encoding/base64" "fmt" @@ -16,12 +17,13 @@ import ( "sync" "time" - "github.com/canonical/jimm/v3/internal/db" - "github.com/canonical/jimm/v3/internal/errors" "github.com/google/uuid" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" + + "github.com/canonical/jimm/v3/internal/db" + "github.com/canonical/jimm/v3/internal/errors" ) // A Tester is the test interface required by this package. @@ -167,9 +169,10 @@ const maxDatabaseNameLength = 63 // sure no name collisions occur and also future calls with the same suggested // database name results in the same safe name. func computeSafeDatabaseName(suggestedName string) string { - re, _ := regexp.Compile(unsafeCharsPattern) + re := regexp.MustCompile(unsafeCharsPattern) safeName := re.ReplaceAllString(suggestedName, "_") + //nolint:gosec // We're only using sha1 in tests. hasher := sha1.New() // Provide some random chars for the hash. Useful where tests // have the same suite name and same test name. @@ -195,6 +198,7 @@ var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") func randSeq(n int) string { b := make([]rune, n) for i := range b { + //nolint:gosec // We're only using rand.Intn for tests. b[i] = letters[rand.Intn(len(letters))] } return string(b) diff --git a/internal/jimmtest/jimm.go b/internal/jimmtest/jimm.go index 2252c2c32..0b647b43a 100644 --- a/internal/jimmtest/jimm.go +++ b/internal/jimmtest/jimm.go @@ -1,10 +1,12 @@ +// Copyright 2024 Canonical. package jimmtest import ( "time" - jimmsvc "github.com/canonical/jimm/v3/cmd/jimmsrv/service" "github.com/coreos/go-oidc/v3/oidc" + + jimmsvc "github.com/canonical/jimm/v3/cmd/jimmsrv/service" ) // NewTestJimmParams returns a set of JIMM params with sensible defaults diff --git a/internal/jimmtest/jimm_mock.go b/internal/jimmtest/jimm_mock.go index d1c391c97..04991f69a 100644 --- a/internal/jimmtest/jimm_mock.go +++ b/internal/jimmtest/jimm_mock.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest diff --git a/internal/jimmtest/keycloak.go b/internal/jimmtest/keycloak.go index 19404c143..8a85af2d3 100644 --- a/internal/jimmtest/keycloak.go +++ b/internal/jimmtest/keycloak.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest @@ -12,10 +12,11 @@ import ( "net/url" "strings" - "github.com/canonical/jimm/v3/internal/errors" "github.com/google/uuid" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" + + "github.com/canonical/jimm/v3/internal/errors" ) // These constants are based on the `docker-compose.yaml` and `local/keycloak/jimm-realm.json` content. @@ -34,7 +35,8 @@ const ( keycloakAdminUsername = "jimm" keycloakAdminPassword = "jimm" keycloakAdminCLIUsername = "admin-cli" - keycloakAdminCLISecret = "DOLcuE5Cd7IxuR7JE4hpAUxaLF7RlAWh" + //nolint:gosec // Thinks credentials exposed. Only used for test. + keycloakAdminCLISecret = "DOLcuE5Cd7IxuR7JE4hpAUxaLF7RlAWh" ) // KeycloakUser represents a basic user created in Keycloak. diff --git a/internal/jimmtest/logging.go b/internal/jimmtest/logging.go index aa0a30011..e4875924b 100644 --- a/internal/jimmtest/logging.go +++ b/internal/jimmtest/logging.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmtest import ( @@ -51,13 +52,15 @@ func (s *LoggingSuite) setUp(c *gc.C) { // Don't use the default writer for the test logging, which // means we can still get logging output from tests that // replace the default writer. - loggo.RegisterWriter(loggo.DefaultWriterName, discardWriter{}) - loggo.RegisterWriter("loggingsuite", zaputil.NewLoggoWriter(logger)) + err := loggo.RegisterWriter(loggo.DefaultWriterName, discardWriter{}) + c.Assert(err, gc.IsNil) + err = loggo.RegisterWriter("loggingsuite", zaputil.NewLoggoWriter(logger)) + c.Assert(err, gc.IsNil) level := "DEBUG" if envLevel := os.Getenv("TEST_LOGGING_CONFIG"); envLevel != "" { level = envLevel } - err := loggo.ConfigureLoggers(level) + err = loggo.ConfigureLoggers(level) c.Assert(err, gc.Equals, nil) } @@ -71,8 +74,7 @@ type gocheckZapWriter struct { } func (w gocheckZapWriter) Write(buf []byte) (int, error) { - w.c.Output(1, strings.TrimSuffix(string(buf), "\n")) - return len(buf), nil + return len(buf), w.c.Output(1, strings.TrimSuffix(string(buf), "\n")) } func (w gocheckZapWriter) Sync() error { diff --git a/internal/jimmtest/openfga.go b/internal/jimmtest/openfga.go index 696c2be5e..cefc262d5 100644 --- a/internal/jimmtest/openfga.go +++ b/internal/jimmtest/openfga.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmtest import ( @@ -161,7 +162,14 @@ func TruncateOpenFgaTuples(ctx context.Context) error { return errors.E(err) } defer conn.Close(ctx) - conn.Exec(ctx, "TRUNCATE TABLE tuple;") - conn.Exec(ctx, "TRUNCATE TABLE changelog;") + + if _, err := conn.Exec(ctx, "TRUNCATE TABLE tuple;"); err != nil { + return err + } + + if _, err := conn.Exec(ctx, "TRUNCATE TABLE changelog;"); err != nil { + return err + } + return nil } diff --git a/internal/jimmtest/store.go b/internal/jimmtest/store.go index a110bc36b..61e245ef7 100644 --- a/internal/jimmtest/store.go +++ b/internal/jimmtest/store.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jimmtest import ( @@ -93,7 +94,7 @@ func (s *InMemoryCredentialStore) PutControllerCredentials(ctx context.Context, if s.controllerCredentials == nil { s.controllerCredentials = map[string]controllerCredentials{ - controllerName: controllerCredentials{ + controllerName: { username: username, password: password, }, diff --git a/internal/jimmtest/suite.go b/internal/jimmtest/suite.go index 323edcf84..b57a50016 100644 --- a/internal/jimmtest/suite.go +++ b/internal/jimmtest/suite.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest diff --git a/internal/jimmtest/vault.go b/internal/jimmtest/vault.go index b886c83c6..3a4b76578 100644 --- a/internal/jimmtest/vault.go +++ b/internal/jimmtest/vault.go @@ -1,12 +1,13 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jimmtest import ( "encoding/json" - vault_test "github.com/canonical/jimm/v3/local/vault" "github.com/hashicorp/vault/api" + + vault_test "github.com/canonical/jimm/v3/local/vault" ) type fatalF interface { diff --git a/internal/jujuapi/access_control.go b/internal/jujuapi/access_control.go index f045e8d66..5f8faf2d0 100644 --- a/internal/jujuapi/access_control.go +++ b/internal/jujuapi/access_control.go @@ -1,10 +1,9 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package jujuapi import ( "context" - "regexp" "strconv" "time" @@ -21,32 +20,6 @@ import ( // access_control contains the primary RPC commands for handling ReBAC within JIMM via the JIMM facade itself. -var ( - // Matches juju uris, jimm user/group tags and UUIDs - // Performs a single match and breaks the juju URI into 10 groups, each successive group is XORD to ensure we can run - // this just once. - // The groups are as so: - // [0] - Entire match - // [1] - tag - // [2] - A single "-", ignored - // [3] - Controller name OR user name OR group name - // [4] - A single ":", ignored - // [5] - Controller user / model owner - // [6] - A single "/", ignored - // [7] - Model name - // [8] - A single ".", ignored - // [9] - Application offer name - // [10] - Relation specifier (i.e., #member) - // A complete matcher example would look like so with square-brackets denoting groups and paranthsis denoting index: - // (1)[controller](2)[-](3)[controller-1](4)[:](5)[alice@canonical.com-place](6)[/](7)[model-1](8)[.](9)[offer-1](10)[#relation-specifier]" - // In the case of something like: user-alice@wonderland or group-alices-wonderland#member, it would look like so: - // (1)[user](2)[-](3)[alices@wonderland] - // (1)[group](2)[-](3)[alices-wonderland](10)[#member] - // So if a group, user, UUID, controller name comes in, it will always be index 3 for them - // and if a relation specifier is present, it will always be index 10 - jujuURIMatcher = regexp.MustCompile(`([a-zA-Z0-9]*)(\-|\z)([a-zA-Z0-9-@.]*)(\:|)([a-zA-Z0-9-@]*)(\/|)([a-zA-Z0-9-]*)(\.|)([a-zA-Z0-9-]*)([a-zA-Z#]*|\z)\z`) -) - const ( jimmControllerName = "jimm" ) diff --git a/internal/jujuapi/access_control_test.go b/internal/jujuapi/access_control_test.go index b40d40a34..efa8482c2 100644 --- a/internal/jujuapi/access_control_test.go +++ b/internal/jujuapi/access_control_test.go @@ -1,11 +1,10 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package jujuapi_test import ( "context" "database/sql" - "strconv" "time" petname "github.com/dustinkirkland/golang-petname" @@ -89,15 +88,17 @@ func (s *accessControlSuite) TestRemoveGroupRemovesTuples(c *gc.C) { user, group, controller, model, _, _, _, client, closeClient := createTestControllerEnvironment(ctx, c, s) defer closeClient() - db.AddGroup(ctx, "test-group2") + _, err := db.AddGroup(ctx, "test-group2") + c.Assert(err, gc.IsNil) + group2 := &dbmodel.GroupEntry{ Name: "test-group2", } - err := db.GetGroup(ctx, group2) + err = db.GetGroup(ctx, group2) c.Assert(err, gc.IsNil) tuples := []openfga.Tuple{ - //This tuple should remain as it has no relation to group2 + // This tuple should remain as it has no relation to group2 { Object: ofganames.ConvertTag(user.ResourceTag()), Relation: "member", @@ -133,7 +134,7 @@ func (s *accessControlSuite) TestRemoveGroupRemovesTuples(c *gc.C) { err = s.JIMM.OpenFGAClient.AddRelation(context.Background(), tuples...) c.Assert(err, gc.IsNil) - //Check user has access to model and controller through group2 + // Check user has access to model and controller through group2 checkResp, err := client.CheckRelation(&apiparams.CheckRelationRequest{Tuple: checkAccessTupleController}) c.Assert(err, gc.IsNil) c.Assert(checkResp.Allowed, gc.Equals, true) @@ -148,7 +149,7 @@ func (s *accessControlSuite) TestRemoveGroupRemovesTuples(c *gc.C) { c.Assert(err, gc.IsNil) c.Assert(len(resp.Tuples), gc.Equals, 13) - //Check user access has been revoked. + // Check user access has been revoked. checkResp, err = client.CheckRelation(&apiparams.CheckRelationRequest{Tuple: checkAccessTupleController}) c.Assert(err, gc.IsNil) c.Assert(checkResp.Allowed, gc.Equals, false) @@ -222,10 +223,6 @@ func createTuple(object, relation, target string) openfga.Tuple { } } -func stringGroupID(id uint) string { - return strconv.FormatUint(uint64(id), 10) -} - // TestAddRelation currently verifies the following test cases, // when new relation control is to be added, please update this comment: // user -> group @@ -249,11 +246,13 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { user, group, controller, model, offer, _, _, client, closeClient := createTestControllerEnvironment(ctx, c, s) defer closeClient() - db.AddGroup(ctx, "test-group2") + _, err := db.AddGroup(ctx, "test-group2") + c.Assert(err, gc.IsNil) + group2 := &dbmodel.GroupEntry{ Name: "test-group2", } - err := db.GetGroup(ctx, group2) + err = db.GetGroup(ctx, group2) c.Assert(err, gc.IsNil) c.Assert(err, gc.IsNil) @@ -303,7 +302,7 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { err: false, changesType: "controller", }, - //Test user -> group + // Test user -> group { input: tuple{"user-" + user.Name, "member", "group-" + group.Name}, want: createTuple( @@ -314,7 +313,7 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { err: false, changesType: "group", }, - //Test username with dots and @ -> group + // Test username with dots and @ -> group { input: tuple{"user-" + "kelvin.lina.test@canonical.com", "member", "group-" + group.Name}, want: createTuple( @@ -325,7 +324,7 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { err: false, changesType: "group", }, - //Test group -> controller + // Test group -> controller { input: tuple{"group-" + "test-group#member", "administrator", "controller-" + controller.UUID}, want: createTuple( @@ -336,7 +335,7 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { err: false, changesType: "controller", }, - //Test user -> model by name + // Test user -> model by name { input: tuple{"user-" + user.Name, "writer", "model-" + controller.Name + ":" + user.Name + "/" + model.Name}, want: createTuple( @@ -462,6 +461,10 @@ func (s *accessControlSuite) TestAddRelation(c *gc.C) { for i, tc := range tagTests { c.Logf("running test %d", i) if i != 0 { + // Needed due to removing original added relations for this test. + // Without, we cannot add the relations. + // + //nolint:errcheck s.COFGAClient.RemoveRelation(ctx, tc.want) } err := client.AddRelation(&apiparams.AddRelationRequest{ @@ -557,7 +560,7 @@ func (s *accessControlSuite) TestRemoveRelation(c *gc.C) { err: false, changesType: "controller", }, - //Test user -> group + // Test user -> group { toAdd: openfga.Tuple{ Object: ofganames.ConvertTag(user.ResourceTag()), @@ -573,7 +576,7 @@ func (s *accessControlSuite) TestRemoveRelation(c *gc.C) { err: false, changesType: "group", }, - //Test group -> controller + // Test group -> controller { toAdd: openfga.Tuple{ Object: ofganames.ConvertTagWithRelation(group.ResourceTag(), ofganames.MemberRelation), @@ -589,7 +592,7 @@ func (s *accessControlSuite) TestRemoveRelation(c *gc.C) { err: false, changesType: "controller", }, - //Test user -> model by name + // Test user -> model by name { toAdd: openfga.Tuple{ Object: ofganames.ConvertTag(user.ResourceTag()), diff --git a/internal/jujuapi/admin.go b/internal/jujuapi/admin.go index 5b75c2224..ed1b5ade8 100644 --- a/internal/jujuapi/admin.go +++ b/internal/jujuapi/admin.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/admin_test.go b/internal/jujuapi/admin_test.go index 6f45df7a1..dbaa8e3e1 100644 --- a/internal/jujuapi/admin_test.go +++ b/internal/jujuapi/admin_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test @@ -266,6 +266,8 @@ func (s *adminSuite) TestDeviceLogin(c *gc.C) { c.Assert(err, gc.ErrorMatches, "failed to decode token.*") // Test token base64 encoded passes authentication + // + //nolint:gosimple err = conn.APICall("Admin", 4, "", "LoginWithSessionToken", params.LoginWithSessionTokenRequest{SessionToken: sessionTokenResp.SessionToken}, &loginResult) c.Assert(err, gc.IsNil) c.Assert(loginResult.UserInfo.Identity, gc.Equals, "user-"+user.Email) @@ -336,7 +338,8 @@ func (s *adminSuite) TestLoginWithClientCredentials(c *gc.C) { const ( // these are valid client credentials hardcoded into the jimm realm - validClientID = "test-client-id" + validClientID = "test-client-id" + //nolint:gosec // Thinks credentials hardcoded. validClientSecret = "2M2blFbO4GX4zfggQpivQSxwWX1XGgNf" ) diff --git a/internal/jujuapi/api.go b/internal/jujuapi/api.go index 82dbd090d..188b553a5 100644 --- a/internal/jujuapi/api.go +++ b/internal/jujuapi/api.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. // Package jujuapi implements API endpoints for the juju API. package jujuapi diff --git a/internal/jujuapi/api_test.go b/internal/jujuapi/api_test.go index 360570503..c7054a927 100644 --- a/internal/jujuapi/api_test.go +++ b/internal/jujuapi/api_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test @@ -58,5 +58,7 @@ func (s *apiSuite) TestModelCommandsModelNotFoundf(c *gc.C) { if err != nil { c.Assert(err, gc.ErrorMatches, "websocket: bad handshake") } + defer response.Body.Close() + c.Assert(response.StatusCode, gc.Equals, http.StatusNotFound) } diff --git a/internal/jujuapi/applicationoffers.go b/internal/jujuapi/applicationoffers.go index bf3b70581..f7e3dc724 100644 --- a/internal/jujuapi/applicationoffers.go +++ b/internal/jujuapi/applicationoffers.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/applicationoffers_test.go b/internal/jujuapi/applicationoffers_test.go index cc37619cd..c4a248694 100644 --- a/internal/jujuapi/applicationoffers_test.go +++ b/internal/jujuapi/applicationoffers_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test import ( @@ -365,8 +365,8 @@ func (s *applicationOffersSuite) TestDestroyOffers(c *gc.C) { // i need to fetch the offer so that i can manually set read // permission for charlie // - //err = client.GrantOffer("charlie@canonical.com", "read", offerURL) - //c.Assert(err, jc.ErrorIsNil) + // err = client.GrantOffer("charlie@canonical.com", "read", offerURL) + // c.Assert(err, jc.ErrorIsNil) offer := dbmodel.ApplicationOffer{ URL: offerURL, } diff --git a/internal/jujuapi/cloud.go b/internal/jujuapi/cloud.go index fe66d3dfd..1adb9b775 100644 --- a/internal/jujuapi/cloud.go +++ b/internal/jujuapi/cloud.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -481,8 +481,8 @@ func (r *controllerRoot) UpdateCloud(ctx context.Context, args jujuparams.Update results := jujuparams.ErrorResults{ Results: make([]jujuparams.ErrorResult, len(args.Clouds)), } - for i, arg := range args.Clouds { - err := r.updateCloud(ctx, arg) + for i := range args.Clouds { + err := r.updateCloud() if err != nil { results.Results[i].Error = mapError(err) } @@ -490,7 +490,7 @@ func (r *controllerRoot) UpdateCloud(ctx context.Context, args jujuparams.Update return results, nil } -func (r *controllerRoot) updateCloud(ctx context.Context, args jujuparams.AddCloudArgs) error { +func (r *controllerRoot) updateCloud() error { // TODO(mhilton) work out how to support updating clouds, for now // tell everyone they're not allowed. return errors.E(errors.CodeForbidden, "permission denied") diff --git a/internal/jujuapi/cloud_test.go b/internal/jujuapi/cloud_test.go index 669fb6f22..58d4144e3 100644 --- a/internal/jujuapi/cloud_test.go +++ b/internal/jujuapi/cloud_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/controller.go b/internal/jujuapi/controller.go index 0d1926e91..2b3b329ad 100644 --- a/internal/jujuapi/controller.go +++ b/internal/jujuapi/controller.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -116,7 +116,7 @@ func (r *controllerRoot) WatchModelSummaries(ctx context.Context) (jujuparams.Su } return modelUUIDs, nil } - watcher, err := newModelSummaryWatcher(ctx, id, r, r.jimm.PubSubHub(), getModels) + watcher, err := newModelSummaryWatcher(ctx, id, r.jimm.PubSubHub(), getModels) if err != nil { return jujuparams.SummaryWatcherID{}, errors.E(op, err) } @@ -155,7 +155,7 @@ func (r *controllerRoot) WatchAllModelSummaries(ctx context.Context) (jujuparams return modelUUIDs, nil } - watcher, err := newModelSummaryWatcher(ctx, id, r, r.jimm.PubSubHub(), getAllModels) + watcher, err := newModelSummaryWatcher(ctx, id, r.jimm.PubSubHub(), getAllModels) if err != nil { return jujuparams.SummaryWatcherID{}, errors.E(op, err) } diff --git a/internal/jujuapi/controller_test.go b/internal/jujuapi/controller_test.go index c70073fc7..9e4cb63c7 100644 --- a/internal/jujuapi/controller_test.go +++ b/internal/jujuapi/controller_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/controllerroot.go b/internal/jujuapi/controllerroot.go index 4cba48183..ed6ddd033 100644 --- a/internal/jujuapi/controllerroot.go +++ b/internal/jujuapi/controllerroot.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/controllerroot_test.go b/internal/jujuapi/controllerroot_test.go index 362f05ab6..25939920d 100644 --- a/internal/jujuapi/controllerroot_test.go +++ b/internal/jujuapi/controllerroot_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/export_test.go b/internal/jujuapi/export_test.go index 0fa2eeb82..5d0d6d197 100644 --- a/internal/jujuapi/export_test.go +++ b/internal/jujuapi/export_test.go @@ -1,15 +1,16 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi import ( "context" + jujuparams "github.com/juju/juju/rpc/params" + "github.com/canonical/jimm/v3/internal/db" "github.com/canonical/jimm/v3/internal/jimm" "github.com/canonical/jimm/v3/internal/openfga" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" - jujuparams "github.com/juju/juju/rpc/params" ) var ( diff --git a/internal/jujuapi/jimm.go b/internal/jujuapi/jimm.go index 2ea5a2c55..e24d485f3 100644 --- a/internal/jujuapi/jimm.go +++ b/internal/jujuapi/jimm.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/jimm_test.go b/internal/jujuapi/jimm_test.go index 56adb3f25..370fa9f03 100644 --- a/internal/jujuapi/jimm_test.go +++ b/internal/jujuapi/jimm_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/modelmanager.go b/internal/jujuapi/modelmanager.go index 0736cdf2e..a79d19790 100644 --- a/internal/jujuapi/modelmanager.go +++ b/internal/jujuapi/modelmanager.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -130,10 +130,8 @@ func (r *controllerRoot) ModelInfo(ctx context.Context, args jujuparams.Entities err = errors.E(op, errors.CodeUnauthorized, "unauthorized") } results[i].Error = mapError(errors.E(op, err)) - } else { - if r.controllerUUIDMasking { - results[i].Result.ControllerUUID = r.params.ControllerUUID - } + } else if r.controllerUUIDMasking { + results[i].Result.ControllerUUID = r.params.ControllerUUID } } return jujuparams.ModelInfoResults{ diff --git a/internal/jujuapi/modelmanager_test.go b/internal/jujuapi/modelmanager_test.go index 83b08fffb..4e2c915dd 100644 --- a/internal/jujuapi/modelmanager_test.go +++ b/internal/jujuapi/modelmanager_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test @@ -258,11 +258,11 @@ func (s *modelManagerSuite) TestModelInfo(c *gc.C) { mt4 := s.AddModel(c, names.NewUserTag("charlie@canonical.com"), "model-4", names.NewCloudTag(jimmtest.TestCloudName), jimmtest.TestCloudRegionName, s.Model2.CloudCredential.ResourceTag()) // TODO (alesstimec) change once granting has been re-implemented - //conn := s.open(c, nil, "charlie") - //defer conn.Close() - //client := modelmanager.NewClient(conn) - //err := client.GrantModel("bob@canonical.com", "write", mt4.Id()) - //c.Assert(err, gc.Equals, nil) + // conn := s.open(c, nil, "charlie") + // defer conn.Close() + // client := modelmanager.NewClient(conn) + // err := client.GrantModel("bob@canonical.com", "write", mt4.Id()) + // c.Assert(err, gc.Equals, nil) bobIdentity, err := dbmodel.NewIdentity("bob@canonical.com") c.Assert(err, gc.IsNil) @@ -272,8 +272,8 @@ func (s *modelManagerSuite) TestModelInfo(c *gc.C) { mt5 := s.AddModel(c, names.NewUserTag("charlie@canonical.com"), "model-5", names.NewCloudTag(jimmtest.TestCloudName), jimmtest.TestCloudRegionName, s.Model2.CloudCredential.ResourceTag()) // TODO (alesstimec) change once granting has been re-implemented - //err = client.GrantModel("bob@canonical.com", "admin", mt5.Id()) - //c.Assert(err, gc.Equals, nil) + // err = client.GrantModel("bob@canonical.com", "admin", mt5.Id()) + // c.Assert(err, gc.Equals, nil) err = bob.SetModelAccess(context.Background(), mt5, ofganames.AdministratorRelation) c.Assert(err, gc.Equals, nil) diff --git a/internal/jujuapi/modelsummarywatcher.go b/internal/jujuapi/modelsummarywatcher.go index 17e24fbb9..0e1995574 100644 --- a/internal/jujuapi/modelsummarywatcher.go +++ b/internal/jujuapi/modelsummarywatcher.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -100,7 +100,7 @@ func (r *watcherRegistry) get(id string) (*modelSummaryWatcher, error) { return w, nil } -func newModelSummaryWatcher(ctx context.Context, id string, root *controllerRoot, pubsub *pubsub.Hub, modelGetterFunc func(context.Context) ([]string, error)) (*modelSummaryWatcher, error) { +func newModelSummaryWatcher(ctx context.Context, id string, pubsub *pubsub.Hub, modelGetterFunc func(context.Context) ([]string, error)) (*modelSummaryWatcher, error) { const op = errors.Op("jujuapi.newModelSummaryWatcher") ctx, cancelContext := context.WithCancel(ctx) @@ -186,6 +186,7 @@ func (w *modelSummaryWatcher) Stop() error { return nil } +//nolint:unused // Used in export-test. func newModelAccessWatcher(ctx context.Context, period time.Duration, modelGetterFunc func(context.Context) ([]string, error)) *modelAccessWatcher { return &modelAccessWatcher{ ctx: ctx, diff --git a/internal/jujuapi/modelsummarywatcher_test.go b/internal/jujuapi/modelsummarywatcher_test.go index 80c4496bb..4a2302057 100644 --- a/internal/jujuapi/modelsummarywatcher_test.go +++ b/internal/jujuapi/modelsummarywatcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test @@ -20,8 +20,10 @@ var _ = gc.Suite(&modelSummaryWatcherSuite{}) func (s *modelSummaryWatcherSuite) TestModelSummaryWatcher(c *gc.C) { watcher := jujuapi.NewModelSummaryWatcher() - defer watcher.Stop() - + defer func() { + err := watcher.Stop() + c.Assert(err, gc.IsNil) + }() result, err := watcher.Next() c.Assert(err, jc.ErrorIsNil) c.Assert(result, gc.DeepEquals, jujuparams.SummaryWatcherNextResults{ diff --git a/internal/jujuapi/package_test.go b/internal/jujuapi/package_test.go index e9f8e3562..a8920ec4d 100644 --- a/internal/jujuapi/package_test.go +++ b/internal/jujuapi/package_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/pinger.go b/internal/jujuapi/pinger.go index cdd90191c..f191ed3fc 100644 --- a/internal/jujuapi/pinger.go +++ b/internal/jujuapi/pinger.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/pinger_internal_test.go b/internal/jujuapi/pinger_internal_test.go index 8fbe84ece..e05efb831 100644 --- a/internal/jujuapi/pinger_internal_test.go +++ b/internal/jujuapi/pinger_internal_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/rpc/method.go b/internal/jujuapi/rpc/method.go index 7e8f67ac8..08396493b 100644 --- a/internal/jujuapi/rpc/method.go +++ b/internal/jujuapi/rpc/method.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package rpc @@ -20,7 +20,7 @@ var ( // Method converts the given function to an RPC method that can be used // with Root. The function must have a signature like: // -// f([ctx context.Context, ][objId string, ][params ParamsT]) ([ResultT, ][error]) +// f([ctx context.Context, ][objId string, ][params ParamsT]) ([ResultT, ][error]) // // Note that all parameters and return values are optional. Method will // panic if the given value is not a function of the correct type. @@ -101,10 +101,8 @@ func (c methodCaller) Call(ctx context.Context, objId string, arg reflect.Value) } if c.flags&inObjectID == inObjectID { pv = append(pv, reflect.ValueOf(objId)) - } else { - if objId != "" { - return reflect.Value{}, errors.ErrBadId - } + } else if objId != "" { + return reflect.Value{}, errors.ErrBadId } if c.flags&inParams == inParams { pv = append(pv, arg) diff --git a/internal/jujuapi/rpc/method_test.go b/internal/jujuapi/rpc/method_test.go index caa7f8a52..14129fb7a 100644 --- a/internal/jujuapi/rpc/method_test.go +++ b/internal/jujuapi/rpc/method_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package rpc_test diff --git a/internal/jujuapi/rpc/root.go b/internal/jujuapi/rpc/root.go index 91d78b42c..af1aa0014 100644 --- a/internal/jujuapi/rpc/root.go +++ b/internal/jujuapi/rpc/root.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package rpc diff --git a/internal/jujuapi/rpc/root_test.go b/internal/jujuapi/rpc/root_test.go index 3f74e275d..3482f9f3d 100644 --- a/internal/jujuapi/rpc/root_test.go +++ b/internal/jujuapi/rpc/root_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package rpc_test diff --git a/internal/jujuapi/service_account.go b/internal/jujuapi/service_account.go index 3f4bc873a..7f4c18316 100644 --- a/internal/jujuapi/service_account.go +++ b/internal/jujuapi/service_account.go @@ -1,4 +1,4 @@ -// Copyright 2024 canonical. +// Copyright 2024 Canonical. package jujuapi diff --git a/internal/jujuapi/service_account_test.go b/internal/jujuapi/service_account_test.go index b3006c9eb..b6399b9ae 100644 --- a/internal/jujuapi/service_account_test.go +++ b/internal/jujuapi/service_account_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test @@ -184,7 +184,8 @@ func TestCopyServiceAccountCredential(t *testing.T) { cr := jujuapi.NewControllerRoot(jimm, jujuapi.Params{}) jujuapi.SetUser(cr, user) if len(test.addTuples) > 0 { - ofgaClient.AddRelation(context.Background(), test.addTuples...) + err = ofgaClient.AddRelation(context.Background(), test.addTuples...) + c.Assert(err, qt.IsNil) } res, err := cr.CopyServiceAccountCredential(context.Background(), test.args) if test.expectedError == "" { @@ -265,7 +266,8 @@ func TestGetServiceAccount(t *testing.T) { jujuapi.SetUser(cr, user) if len(test.addTuples) > 0 { - ofgaClient.AddRelation(context.Background(), test.addTuples...) + err = ofgaClient.AddRelation(context.Background(), test.addTuples...) + c.Assert(err, qt.IsNil) } res, err := cr.GetServiceAccount(context.Background(), test.clientID) @@ -455,7 +457,8 @@ func TestUpdateServiceAccountCredentials(t *testing.T) { jujuapi.SetUser(cr, user) if len(test.addTuples) > 0 { - ofgaClient.AddRelation(context.Background(), test.addTuples...) + err = ofgaClient.AddRelation(context.Background(), test.addTuples...) + c.Assert(err, qt.IsNil) } res, err := cr.UpdateServiceAccountCredentials(context.Background(), test.args) @@ -588,7 +591,8 @@ func TestListServiceAccountCredentials(t *testing.T) { jujuapi.SetUser(cr, user) if len(test.addTuples) > 0 { - ofgaClient.AddRelation(context.Background(), test.addTuples...) + err = ofgaClient.AddRelation(context.Background(), test.addTuples...) + c.Assert(err, qt.IsNil) } res, err := cr.ListServiceAccountCredentials(context.Background(), test.args) @@ -701,7 +705,8 @@ func TestGrantServiceAccountAccess(t *testing.T) { jujuapi.SetUser(cr, user) if len(test.addTuples) > 0 { - ofgaClient.AddRelation(context.Background(), test.addTuples...) + err = ofgaClient.AddRelation(context.Background(), test.addTuples...) + c.Assert(err, qt.IsNil) } err = cr.GrantServiceAccountAccess(context.Background(), test.params) @@ -733,14 +738,16 @@ func (s *serviceAccountSuite) TestUpdateServiceAccountCredentialsIntegration(c * Target: ofganames.ConvertTag(serviceAccount), } - s.JIMM.OpenFGAClient.AddRelation(context.Background(), tuple) + err := s.JIMM.OpenFGAClient.AddRelation(context.Background(), tuple) + c.Assert(err, gc.IsNil) cloud := &dbmodel.Cloud{ Name: "aws", } - s.JIMM.Database.AddCloud(context.Background(), cloud) + err = s.JIMM.Database.AddCloud(context.Background(), cloud) + c.Assert(err, gc.IsNil) var credResults jujuparams.UpdateCredentialResults - err := conn.APICall("JIMM", 4, "", "UpdateServiceAccountCredentials", params.UpdateServiceAccountCredentialsRequest{ + err = conn.APICall("JIMM", 4, "", "UpdateServiceAccountCredentials", params.UpdateServiceAccountCredentialsRequest{ ClientID: "fca1f605-736e-4d1f-bcd2-aecc726923be@serviceaccount", UpdateCredentialArgs: jujuparams.UpdateCredentialArgs{ Credentials: []jujuparams.TaggedCredential{ diff --git a/internal/jujuapi/usermanager.go b/internal/jujuapi/usermanager.go index 965c6a14b..766af8eb4 100644 --- a/internal/jujuapi/usermanager.go +++ b/internal/jujuapi/usermanager.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -66,7 +66,7 @@ func (r *controllerRoot) UserInfo(ctx context.Context, req jujuparams.UserInfoRe Results: make([]jujuparams.UserInfoResult, len(req.Entities)), } for i, ent := range req.Entities { - ui, err := r.userInfo(ctx, ent.Tag) + ui, err := r.userInfo(ent.Tag) if err != nil { res.Results[i].Error = mapError(err) continue @@ -76,7 +76,7 @@ func (r *controllerRoot) UserInfo(ctx context.Context, req jujuparams.UserInfoRe return res, nil } -func (r *controllerRoot) userInfo(ctx context.Context, entity string) (*jujuparams.UserInfo, error) { +func (r *controllerRoot) userInfo(entity string) (*jujuparams.UserInfo, error) { const op = errors.Op("jujuapi.UserInfo") user, err := parseUserTag(entity) diff --git a/internal/jujuapi/usermanager_test.go b/internal/jujuapi/usermanager_test.go index 54fd5aeeb..2f1550252 100644 --- a/internal/jujuapi/usermanager_test.go +++ b/internal/jujuapi/usermanager_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuapi/websocket.go b/internal/jujuapi/websocket.go index c68db2614..6bfd1fea1 100644 --- a/internal/jujuapi/websocket.go +++ b/internal/jujuapi/websocket.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi @@ -154,7 +154,10 @@ func (s modelProxyServer) ServeWS(ctx context.Context, clientConn *websocket.Con JIMM: s.jimm, AuthenticatedIdentityID: auth.SessionIdentityFromContext(ctx), } - jimmRPC.ProxySockets(ctx, proxyHelpers) + if err := jimmRPC.ProxySockets(ctx, proxyHelpers); err != nil { + zapctx.Error(ctx, "failed to start jimm model proxy", zap.Error(err)) + } + } // controllerConnectionFunc returns a function that will be used to diff --git a/internal/jujuapi/websocket_test.go b/internal/jujuapi/websocket_test.go index fecd1922a..34a9f9b57 100644 --- a/internal/jujuapi/websocket_test.go +++ b/internal/jujuapi/websocket_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. package jujuapi_test diff --git a/internal/jujuclient/allwatcher.go b/internal/jujuclient/allwatcher.go index 39a02e0ef..b1ecc55db 100644 --- a/internal/jujuclient/allwatcher.go +++ b/internal/jujuclient/allwatcher.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/allwatcher_test.go b/internal/jujuclient/allwatcher_test.go index 4da4099a3..b04b28d5b 100644 --- a/internal/jujuclient/allwatcher_test.go +++ b/internal/jujuclient/allwatcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/applicationoffers.go b/internal/jujuclient/applicationoffers.go index 9044f4c58..335764453 100644 --- a/internal/jujuclient/applicationoffers.go +++ b/internal/jujuclient/applicationoffers.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/applicationoffers_test.go b/internal/jujuclient/applicationoffers_test.go index 5703fb7a4..4cf05d295 100644 --- a/internal/jujuclient/applicationoffers_test.go +++ b/internal/jujuclient/applicationoffers_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/client.go b/internal/jujuclient/client.go index 880ed24c4..2250473ab 100644 --- a/internal/jujuclient/client.go +++ b/internal/jujuclient/client.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/client_test.go b/internal/jujuclient/client_test.go index 63d10377d..35ebba3a6 100644 --- a/internal/jujuclient/client_test.go +++ b/internal/jujuclient/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test import ( diff --git a/internal/jujuclient/cloud.go b/internal/jujuclient/cloud.go index 6f67fd43e..16916eb0f 100644 --- a/internal/jujuclient/cloud.go +++ b/internal/jujuclient/cloud.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient @@ -147,7 +147,7 @@ func (c Connection) Cloud(ctx context.Context, tag names.CloudTag, cloud *jujupa return errors.E(op, jujuerrors.Cause(err)) } if resp.Results[0].Error != nil { - errors.E(op, resp.Results[0].Error) + return errors.E(op, resp.Results[0].Error) } return nil } diff --git a/internal/jujuclient/cloud_test.go b/internal/jujuclient/cloud_test.go index 82debae1b..6cb4a4980 100644 --- a/internal/jujuclient/cloud_test.go +++ b/internal/jujuclient/cloud_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package jujuclient_test import ( @@ -216,7 +217,7 @@ func (s *cloudSuite) TestClouds(c *gc.C) { clouds, err := s.API.Clouds(context.Background()) c.Assert(err, gc.Equals, nil) c.Assert(clouds, jc.DeepEquals, map[names.CloudTag]jujuparams.Cloud{ - names.NewCloudTag(jimmtest.TestCloudName): jujuparams.Cloud{ + names.NewCloudTag(jimmtest.TestCloudName): { Type: jimmtest.TestProviderType, AuthTypes: []string{"empty", "userpass"}, Endpoint: jimmtest.TestCloudEndpoint, diff --git a/internal/jujuclient/dial.go b/internal/jujuclient/dial.go index 3d08a0a9b..de3ab4994 100644 --- a/internal/jujuclient/dial.go +++ b/internal/jujuclient/dial.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package jujuclient is the client JIMM uses to connect to juju // controllers. The jujuclient uses the juju RPC API directly using @@ -129,6 +129,7 @@ func (d *Dialer) Dial(ctx context.Context, ctl *dbmodel.Controller, modelTag nam dialer: d, ctl: ctl, mt: modelTag, + redialCount: new(atomic.Int32), }, nil } @@ -184,7 +185,7 @@ type Connection struct { broken *uint32 dialer *Dialer - redialCount atomic.Int32 + redialCount *atomic.Int32 ctl *dbmodel.Controller mt names.ModelTag } @@ -215,6 +216,7 @@ func (c *Connection) hasFacadeVersion(facade string, version int) bool { func (c *Connection) redial(ctx context.Context, requiredPermissions map[string]string) error { const op = errors.Op("jujuclient.redial") + dialCount := c.redialCount.Add(1) if dialCount > 10 { return errors.E(op, "dial count exceeded") diff --git a/internal/jujuclient/dial_test.go b/internal/jujuclient/dial_test.go index af5708c50..4e3621b41 100644 --- a/internal/jujuclient/dial_test.go +++ b/internal/jujuclient/dial_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test @@ -90,14 +90,6 @@ func (s *dialSuite) TestDial(c *gc.C) { c.Check(addrs, jc.DeepEquals, info.Addrs) } -type cExtended struct { - *gc.C -} - -func (t *cExtended) Name() string { - return t.TestName() -} - func (s *dialSuite) TestDialWithJWT(c *gc.C) { ctx := context.Background() diff --git a/internal/jujuclient/modelmanager.go b/internal/jujuclient/modelmanager.go index b49d1b447..0fcf3160f 100644 --- a/internal/jujuclient/modelmanager.go +++ b/internal/jujuclient/modelmanager.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/modelmanager_test.go b/internal/jujuclient/modelmanager_test.go index 581209920..3d6978e02 100644 --- a/internal/jujuclient/modelmanager_test.go +++ b/internal/jujuclient/modelmanager_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/modelsummarywatcher.go b/internal/jujuclient/modelsummarywatcher.go index 21dbb3daf..4e494369d 100644 --- a/internal/jujuclient/modelsummarywatcher.go +++ b/internal/jujuclient/modelsummarywatcher.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/modelsummarywatcher_test.go b/internal/jujuclient/modelsummarywatcher_test.go index 7472c39f3..a8755e555 100644 --- a/internal/jujuclient/modelsummarywatcher_test.go +++ b/internal/jujuclient/modelsummarywatcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/modelwatcher.go b/internal/jujuclient/modelwatcher.go index 7d3ae847f..00137b572 100644 --- a/internal/jujuclient/modelwatcher.go +++ b/internal/jujuclient/modelwatcher.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/modelwatcher_test.go b/internal/jujuclient/modelwatcher_test.go index 4cd1076d2..eac3db6bc 100644 --- a/internal/jujuclient/modelwatcher_test.go +++ b/internal/jujuclient/modelwatcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/package_test.go b/internal/jujuclient/package_test.go index bbfecbcbf..9d72247eb 100644 --- a/internal/jujuclient/package_test.go +++ b/internal/jujuclient/package_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test diff --git a/internal/jujuclient/ping.go b/internal/jujuclient/ping.go index b91a4cfe7..1d527f194 100644 --- a/internal/jujuclient/ping.go +++ b/internal/jujuclient/ping.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/ping_test.go b/internal/jujuclient/ping_test.go index c3401cc08..a87257498 100644 --- a/internal/jujuclient/ping_test.go +++ b/internal/jujuclient/ping_test.go @@ -1,13 +1,14 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test import ( "context" - "github.com/canonical/jimm/v3/internal/dbmodel" "github.com/juju/names/v5" gc "gopkg.in/check.v1" + + "github.com/canonical/jimm/v3/internal/dbmodel" ) type pingSuite struct { diff --git a/internal/jujuclient/storage.go b/internal/jujuclient/storage.go index 5ffdf25e5..b96ba5442 100644 --- a/internal/jujuclient/storage.go +++ b/internal/jujuclient/storage.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient diff --git a/internal/jujuclient/storage_test.go b/internal/jujuclient/storage_test.go index 272499720..dd6b721ae 100644 --- a/internal/jujuclient/storage_test.go +++ b/internal/jujuclient/storage_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package jujuclient_test import ( diff --git a/internal/kubetest/kubetest.go b/internal/kubetest/kubetest.go index d6442e610..a57489f39 100644 --- a/internal/kubetest/kubetest.go +++ b/internal/kubetest/kubetest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Canonical Ltd. +// Copyright 2024 Canonical. package kubetest @@ -12,6 +12,7 @@ import ( const ( Username = "test-kubernetes-user" + //nolint:gosec // Thinks it's an exposed secret. Password = "test-kubernetes-password" ) @@ -32,7 +33,8 @@ func NewFakeKubernetes(c *gc.C) *httptest.Server { return } w.Header().Set("Content-Type", req.Header.Get("Content-Type")) - io.Copy(w, req.Body) + _, err := io.Copy(w, req.Body) + c.Assert(err, gc.IsNil) })) return srv } diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 3d703930a..16406109d 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // Package logger contains logger adapters for various services. package logger diff --git a/internal/openfga/export_test.go b/internal/openfga/export_test.go index a4a850133..4669e08b2 100644 --- a/internal/openfga/export_test.go +++ b/internal/openfga/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package openfga diff --git a/internal/openfga/names/export_test.go b/internal/openfga/names/export_test.go index 024e9e20e..247588021 100644 --- a/internal/openfga/names/export_test.go +++ b/internal/openfga/names/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package names diff --git a/internal/openfga/names/names.go b/internal/openfga/names/names.go index fb68c00fa..ca4206e87 100644 --- a/internal/openfga/names/names.go +++ b/internal/openfga/names/names.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. // Package names holds functions used by other jimm components to // create valid OpenFGA tags. @@ -7,12 +7,12 @@ package names import ( "fmt" - "github.com/canonical/jimm/v3/internal/errors" - jimmnames "github.com/canonical/jimm/v3/pkg/names" cofga "github.com/canonical/ofga" - "github.com/juju/juju/core/permission" "github.com/juju/names/v5" + + "github.com/canonical/jimm/v3/internal/errors" + jimmnames "github.com/canonical/jimm/v3/pkg/names" ) // Relation Types diff --git a/internal/openfga/names/names_test.go b/internal/openfga/names/names_test.go index 4152a48f4..522140c99 100644 --- a/internal/openfga/names/names_test.go +++ b/internal/openfga/names/names_test.go @@ -1,17 +1,17 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package names_test import ( "testing" + "github.com/google/uuid" + "github.com/juju/juju/core/permission" "github.com/juju/names/v5" gc "gopkg.in/check.v1" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" jimmnames "github.com/canonical/jimm/v3/pkg/names" - "github.com/google/uuid" - "github.com/juju/juju/core/permission" ) func Test(t *testing.T) { diff --git a/internal/openfga/openfga.go b/internal/openfga/openfga.go index 4b17b1094..23cc77208 100644 --- a/internal/openfga/openfga.go +++ b/internal/openfga/openfga.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package openfga @@ -6,12 +6,12 @@ import ( "context" "strings" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/servermon" cofga "github.com/canonical/ofga" "github.com/juju/names/v5" + "github.com/canonical/jimm/v3/internal/errors" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" + "github.com/canonical/jimm/v3/internal/servermon" jimmnames "github.com/canonical/jimm/v3/pkg/names" ) diff --git a/internal/openfga/openfga_test.go b/internal/openfga/openfga_test.go index 11cd5c0bb..cc4925263 100644 --- a/internal/openfga/openfga_test.go +++ b/internal/openfga/openfga_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package openfga_test import ( @@ -71,7 +72,7 @@ func (suite *openFGATestSuite) TestRemovingTuplesFromOFGASucceeds(c *gc.C) { groupUUID := uuid.NewString() - //Create tuples before writing to db + // Create tuples before writing to db user1 := ofganames.ConvertTag(names.NewUserTag("bob")) tuple1 := openfga.Tuple{ Object: user1, @@ -86,14 +87,14 @@ func (suite *openFGATestSuite) TestRemovingTuplesFromOFGASucceeds(c *gc.C) { Target: ofganames.ConvertTag(jimmnames.NewGroupTag(groupUUID)), } - //Delete before insert should fail + // Delete before insert should fail err := suite.ofgaClient.RemoveRelation(ctx, tuple1, tuple2) c.Assert(strings.Contains(err.Error(), "cannot delete a tuple which does not exist"), gc.Equals, true) err = suite.ofgaClient.AddRelation(ctx, tuple1, tuple2) c.Assert(err, gc.IsNil) - //Delete after insert should succeed. + // Delete after insert should succeed. err = suite.ofgaClient.RemoveRelation(ctx, tuple1, tuple2) c.Assert(err, gc.IsNil) changes, err := suite.cofgaClient.ReadChanges(ctx, "group", 99, "") diff --git a/internal/openfga/user.go b/internal/openfga/user.go index a87d5e900..3e62b918e 100644 --- a/internal/openfga/user.go +++ b/internal/openfga/user.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package openfga @@ -6,6 +6,7 @@ import ( "context" "strings" + "github.com/canonical/ofga" "github.com/juju/names/v5" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" @@ -14,7 +15,6 @@ import ( "github.com/canonical/jimm/v3/internal/errors" ofganames "github.com/canonical/jimm/v3/internal/openfga/names" jimmnames "github.com/canonical/jimm/v3/pkg/names" - "github.com/canonical/ofga" ) // NewUser returns a new user structure that can be used to check diff --git a/internal/openfga/user_test.go b/internal/openfga/user_test.go index e42bec85d..36c1b0cd8 100644 --- a/internal/openfga/user_test.go +++ b/internal/openfga/user_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package openfga_test diff --git a/internal/pubsub/hub.go b/internal/pubsub/hub.go index 22ec07221..828fbe9b0 100644 --- a/internal/pubsub/hub.go +++ b/internal/pubsub/hub.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. // Package pubsub contains an implementation of a simple pubsub // mechanism that passes messages about models between @@ -8,8 +8,9 @@ package pubsub import ( "sync" - "github.com/canonical/jimm/v3/internal/errors" "github.com/juju/utils/v2/parallel" + + "github.com/canonical/jimm/v3/internal/errors" ) // HandlerFunc takes two arguments - a model ID and the message about this model. diff --git a/internal/pubsub/hub_test.go b/internal/pubsub/hub_test.go index da07eecba..0a687397b 100644 --- a/internal/pubsub/hub_test.go +++ b/internal/pubsub/hub_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package pubsub_test diff --git a/internal/rpc/client.go b/internal/rpc/client.go index 366e6caad..61ec4f646 100644 --- a/internal/rpc/client.go +++ b/internal/rpc/client.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package rpc @@ -12,6 +12,8 @@ import ( "github.com/gorilla/websocket" jujuparams "github.com/juju/juju/rpc/params" + "github.com/juju/zaputil/zapctx" + "go.uber.org/zap" "github.com/canonical/jimm/v3/internal/errors" ) @@ -99,7 +101,10 @@ func (c *Client) handleError(err error) { if !c.closing { // We haven't sent a close message yet, so try to send one. cm := websocket.FormatCloseMessage(websocket.CloseProtocolError, err.Error()) - c.conn.WriteControl(websocket.CloseMessage, cm, time.Time{}) + err := c.conn.WriteControl(websocket.CloseMessage, cm, time.Time{}) + if err != nil { + zapctx.Error(context.Background(), "failed to write socket closure message", zap.Error(err)) + } } c.err = err c.conn.Close() @@ -128,7 +133,10 @@ func (c *Client) handleRequest(msg *message) { // Note we're ignoring any write error here as any subsequent write // will also error and that will be able to process the error more // appropriately. - c.conn.WriteJSON(resp) + err := c.conn.WriteJSON(resp) + if err != nil { + zapctx.Error(context.Background(), "failed to write JSON resp", zap.Error(err)) + } } func (c *Client) handleResponse(msg *message) { @@ -181,6 +189,7 @@ func (c *Client) Call(ctx context.Context, facade string, version int, id, metho return errors.E(op, err) } ch := make(chan struct{}) + //nolint:staticcheck // Not sure why Martin made this a **. Ignore for now. respMsg := new(*message) c.msgs[req.RequestID] = inflight{ ch: ch, @@ -194,28 +203,26 @@ func (c *Client) Call(ctx context.Context, facade string, version int, id, metho select { case <-ch: - if respMsg != nil { - permissionsRequired, err := checkPermissionsRequired(ctx, *respMsg) - if err != nil { - return err - } - if permissionsRequired != nil { - return &Error{ - Code: PermissionCheckRequiredErrorCode, - Info: permissionsRequired, - } + permissionsRequired, err := checkPermissionsRequired(ctx, *respMsg) + if err != nil { + return err + } + if permissionsRequired != nil { + return &Error{ + Code: PermissionCheckRequiredErrorCode, + Info: permissionsRequired, } - if (*respMsg).Error != "" { - return &Error{ - Message: (*respMsg).Error, - Code: (*respMsg).ErrorCode, - Info: (*respMsg).ErrorInfo, - } + } + if (*respMsg).Error != "" { + return &Error{ + Message: (*respMsg).Error, + Code: (*respMsg).ErrorCode, + Info: (*respMsg).ErrorInfo, } - if resp != nil { - if err := json.Unmarshal([]byte((*respMsg).Response), &resp); err != nil { - return errors.E(op, err) - } + } + if resp != nil { + if err := json.Unmarshal([]byte((*respMsg).Response), &resp); err != nil { + return errors.E(op, err) } } return nil diff --git a/internal/rpc/client_test.go b/internal/rpc/client_test.go index 66e7f0403..8fd7b26aa 100644 --- a/internal/rpc/client_test.go +++ b/internal/rpc/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package rpc_test @@ -244,9 +244,8 @@ func TestProxySockets(t *testing.T) { c := qt.New(t) ctx := context.Background() - srvController := newServer(func(conn *websocket.Conn) error { - return echo(conn) - }) + srvController := newServer(echo) + errChan := make(chan error) srvJIMM := newServer(func(connClient *websocket.Conn) error { testTokenGen := testTokenGenerator{} @@ -293,9 +292,7 @@ func TestCancelProxySockets(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - srvController := newServer(func(conn *websocket.Conn) error { - return echo(conn) - }) + srvController := newServer(echo) errChan := make(chan error) srvJIMM := newServer(func(connClient *websocket.Conn) error { @@ -335,9 +332,7 @@ func TestProxySocketsAuditLogs(t *testing.T) { ctx := context.Background() - srvController := newServer(func(conn *websocket.Conn) error { - return echo(conn) - }) + srvController := newServer(echo) auditLogs := make([]*dbmodel.AuditLogEntry, 0) errChan := make(chan error) @@ -428,7 +423,8 @@ func newServer(f func(*websocket.Conn) error) *server { cp.AddCert(srv.Certificate()) srv.dialer = &rpc.Dialer{ TLSConfig: &tls.Config{ - RootCAs: cp, + RootCAs: cp, + MinVersion: tls.VersionTLS12, }, } return &srv @@ -445,15 +441,17 @@ func handleWS(f func(*websocket.Conn) error) http.Handler { defer c.Close() err = f(c) var cm []byte - if err == nil { + switch { + case err == nil: cm = websocket.FormatCloseMessage(websocket.CloseNormalClosure, "") - } else if websocket.IsCloseError(err) { + case websocket.IsCloseError(err): ce := err.(*websocket.CloseError) cm = websocket.FormatCloseMessage(ce.Code, ce.Text) - } else { + default: cm = websocket.FormatCloseMessage(websocket.CloseInternalServerErr, err.Error()) } - c.WriteControl(websocket.CloseMessage, cm, time.Time{}) + _ = c.WriteControl(websocket.CloseMessage, cm, time.Time{}) + }) } diff --git a/internal/rpc/dial.go b/internal/rpc/dial.go index 36e095c76..eb46c0f3b 100644 --- a/internal/rpc/dial.go +++ b/internal/rpc/dial.go @@ -1,4 +1,4 @@ -// Copyright 2023 Canonical Ltd. +// Copyright 2024 Canonical. package rpc @@ -66,6 +66,7 @@ func Dial(ctx context.Context, ctl *dbmodel.Controller, modelTag names.ModelTag, tlsConfig = &tls.Config{ RootCAs: cp, ServerName: ctl.TLSHostname, + MinVersion: tls.VersionTLS12, } } dialer := Dialer{ diff --git a/internal/rpc/export_test.go b/internal/rpc/export_test.go index 0b6ae2f2f..a50d4d277 100644 --- a/internal/rpc/export_test.go +++ b/internal/rpc/export_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package rpc type Message message diff --git a/internal/rpc/proxy.go b/internal/rpc/proxy.go index ccba4548f..f781510f9 100644 --- a/internal/rpc/proxy.go +++ b/internal/rpc/proxy.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package rpc import ( @@ -162,11 +163,16 @@ func (c *writeLockConn) sendMessage(responseObject any, request *message) { responseData, err := json.Marshal(responseObject) if err != nil { errorMsg := createErrResponse(err, request) - c.writeJson(errorMsg) + if err := c.writeJson(errorMsg); err != nil { + zapctx.Error(context.Background(), "failed to send error message in proxy", zap.Error(err)) + } + } msg.Response = responseData } - c.writeJson(msg) + if err := c.writeJson(msg); err != nil { + zapctx.Error(context.Background(), "failed to write message in proxy", zap.Error(err)) + } } // inflightMsgs holds only request messages that are @@ -251,11 +257,15 @@ func (p *modelProxy) sendError(socket *writeLockConn, req *message, err error) { } msg := createErrResponse(err, req) if msg != nil { - socket.writeJson(msg) + if err := socket.writeJson(msg); err != nil { + zapctx.Error(context.Background(), "failed to create err response message", zap.Error(err)) + } } // An error message is a response back to the client. servermon.JujuCallErrorCount.WithLabelValues(req.Type, req.Request, p.msgs.controllerUUID) - p.auditLogMessage(msg, true) + if err := p.auditLogMessage(msg, true); err != nil { + zapctx.Error(context.Background(), "failed to audit log message", zap.Error(err)) + } } func (p *modelProxy) auditLogMessage(msg *message, isResponse bool) error { @@ -316,7 +326,6 @@ type clientProxy struct { // start begins the client->controller proxier. func (p *clientProxy) start(ctx context.Context) error { - const op = errors.Op("rpc.clientProxy.start") defer func() { if p.dst != nil { p.dst.conn.Close() @@ -336,7 +345,9 @@ func (p *clientProxy) start(ctx context.Context) error { p.sendError(p.src, msg, err) return err } - p.auditLogMessage(msg, false) + if err := p.auditLogMessage(msg, false); err != nil { + zapctx.Error(ctx, "failed to audit log message", zap.Error(err)) + } // All requests should be proxied as transparently as possible through to the controller // except for auth related requests like Login because JIMM is auth gateway. if msg.Type == "Admin" { @@ -443,7 +454,9 @@ func (p *controllerProxy) start(ctx context.Context) error { // Write back to the controller. msg := p.msgs.getMessage(msg.RequestID) if msg != nil { - p.src.writeJson(msg) + if err := p.src.writeJson(msg); err != nil { + zapctx.Error(context.Background(), "failed to write back to controller", zap.Error(err)) + } } continue } else { @@ -455,7 +468,9 @@ func (p *controllerProxy) start(ctx context.Context) error { } } p.msgs.removeMessage(msg.RequestID) - p.auditLogMessage(msg, true) + if err := p.auditLogMessage(msg, true); err != nil { + zapctx.Error(context.Background(), "failed to audit log message", zap.Error(err)) + } zapctx.Debug(ctx, "Writing modified message to client", zap.Any("Message", msg)) if err := p.dst.writeJson(msg); err != nil { zapctx.Error(ctx, "controllerProxy error writing to dst", zap.Error(err)) @@ -490,7 +505,7 @@ func checkPermissionsRequired(ctx context.Context, msg *message) (map[string]any var er params.ErrorResults err := json.Unmarshal(msg.Response, &er) if err != nil { - zapctx.Error(ctx, "failed to read response error") + zapctx.Error(ctx, "failed to read response error", zap.Error(err)) return permissionMap, nil } diff --git a/internal/rpc/proxy_test.go b/internal/rpc/proxy_test.go index fb948361f..77c9d7a41 100644 --- a/internal/rpc/proxy_test.go +++ b/internal/rpc/proxy_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package rpc_test @@ -263,8 +263,10 @@ func TestProxySocketsAdminFacade(t *testing.T) { }, AuthenticatedIdentityID: test.authenticateEntityID, } - go rpc.ProxySockets(ctx, helpers) - + go func() { + err = rpc.ProxySockets(ctx, helpers) + c.Assert(err, qt.IsNil) + }() data, err := json.Marshal(test.messageToSend) c.Assert(err, qt.IsNil) select { @@ -373,7 +375,11 @@ func (m *mockOAuthAuthenticator) VerifySessionToken(token string) (jwt.Token, er return nil, m.err } t := jwt.New() - t.Set(jwt.SubjectKey, m.email) + + if err := t.Set(jwt.SubjectKey, m.email); err != nil { + return nil, err + } + return t, nil } diff --git a/internal/rpc/rpc.go b/internal/rpc/rpc.go index f86733d08..4090942a3 100644 --- a/internal/rpc/rpc.go +++ b/internal/rpc/rpc.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // Package rpc implements the juju RPC protocol. The main difference // between this implementation and the implementation in diff --git a/internal/servermon/monitoring.go b/internal/servermon/monitoring.go index eec37d789..64be10227 100644 --- a/internal/servermon/monitoring.go +++ b/internal/servermon/monitoring.go @@ -1,4 +1,4 @@ -// Copyright 2016 Canonical Ltd. +// Copyright 2024 Canonical. // The servermon package is used to update statistics used // for monitoring the API server. @@ -122,13 +122,13 @@ var ( ModelCount = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: "jimm", Subsystem: "system", - Name: "model_count", + Name: "model", Help: "The number of models managed per controller attached to JIMM.", }, []string{"controller"}) ControllerCount = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: "jimm", Subsystem: "system", - Name: "controller_count", + Name: "controller", Help: "The number of controllers managed by JIMM.", }) ) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 4652cc3a8..f277a48b9 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -1,14 +1,23 @@ +// Copyright 2024 Canonical. package utils import ( + "context" "crypto/rand" "encoding/hex" + + "github.com/juju/zaputil/zapctx" + "go.uber.org/zap" ) // NewConversationID generates a unique ID that is used for the // lifetime of a websocket connection. func NewConversationID() string { buf := make([]byte, 8) - rand.Read(buf) // Can't fail + _, err := rand.Read(buf) + if err != nil { + zapctx.Error(context.Background(), "failed to generate rand", zap.Error(err)) + + } return hex.EncodeToString(buf) } diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index 20ae46ed0..f17c6f8c9 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package utils_test import ( diff --git a/internal/vault/vault.go b/internal/vault/vault.go index 5455c5d36..9406f433f 100644 --- a/internal/vault/vault.go +++ b/internal/vault/vault.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package vault @@ -29,11 +29,10 @@ const ( ) const ( - jwksKey = "jwks" - jwksExpiryKey = "jwks-expiry" - jwksPrivateKey = "jwks-private" - oAuthSecretKey = "oauth-secret" - oAuthSessionStoreSecretKey = "oauth-session-store-secret" + jwksKey = "jwks" + jwksExpiryKey = "jwks-expiry" + jwksPrivateKey = "jwks-private" + oAuthSecretKey = "oauth-secret" ) // A VaultStore stores cloud credential attributes and @@ -220,10 +219,15 @@ func (s *VaultStore) CleanupJWKS(ctx context.Context) (err error) { if err != nil { return errors.E(op, err) } - // Vault does not return errors on deletion requests where - // the secret does not exist. As such we just return the last known error. - client.KVv2(s.KVPath).Delete(ctx, s.getJWKSExpiryPath()) - client.KVv2(s.KVPath).Delete(ctx, s.getJWKSPath()) + + if err = client.KVv2(s.KVPath).Delete(ctx, s.getJWKSExpiryPath()); err != nil { + return errors.E(op, err) + } + + if err = client.KVv2(s.KVPath).Delete(ctx, s.getJWKSPath()); err != nil { + return errors.E(op, err) + } + if err = client.KVv2(s.KVPath).Delete(ctx, s.getJWKSPrivateKeyPath()); err != nil { return errors.E(op, err) } diff --git a/internal/vault/vault_test.go b/internal/vault/vault_test.go index fd8f58995..dffb4976e 100644 --- a/internal/vault/vault_test.go +++ b/internal/vault/vault_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. package vault_test diff --git a/internal/wellknownapi/api.go b/internal/wellknownapi/api.go index 62e008819..46396d656 100644 --- a/internal/wellknownapi/api.go +++ b/internal/wellknownapi/api.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package wellknownapi import ( @@ -7,12 +7,13 @@ import ( "net/http" "time" - "github.com/canonical/jimm/v3/internal/errors" - "github.com/canonical/jimm/v3/internal/jimm/credentials" "github.com/go-chi/chi/v5" "github.com/go-chi/render" "github.com/juju/zaputil/zapctx" "go.uber.org/zap" + + "github.com/canonical/jimm/v3/internal/errors" + "github.com/canonical/jimm/v3/internal/jimm/credentials" ) // WellKnownHandler holds the grouped router to be mounted and diff --git a/internal/wellknownapi/api_test.go b/internal/wellknownapi/api_test.go index 9cb0b3cb3..ddd206864 100644 --- a/internal/wellknownapi/api_test.go +++ b/internal/wellknownapi/api_test.go @@ -1,4 +1,4 @@ -// Copyright 2023 canonical. +// Copyright 2024 Canonical. package wellknownapi_test import ( @@ -11,12 +11,13 @@ import ( "testing" "time" + qt "github.com/frankban/quicktest" + "github.com/lestrrat-go/jwx/v2/jwk" + "github.com/canonical/jimm/v3/internal/errors" "github.com/canonical/jimm/v3/internal/jimmtest" "github.com/canonical/jimm/v3/internal/vault" "github.com/canonical/jimm/v3/internal/wellknownapi" - qt "github.com/frankban/quicktest" - "github.com/lestrrat-go/jwx/v2/jwk" ) func newStore(t testing.TB) *vault.VaultStore { @@ -72,6 +73,7 @@ func TestWellknownAPIJWKSJSONHandles404(t *testing.T) { rr := setupHandlerAndRecorder(c, "/jwks.json", store) resp := rr.Result() + defer resp.Body.Close() code := rr.Code b, err := io.ReadAll(resp.Body) c.Assert(err, qt.IsNil) @@ -100,6 +102,7 @@ func TestWellknownAPIJWKSJSONHandles500(t *testing.T) { rr := setupHandlerAndRecorder(c, "/jwks.json", store) resp := rr.Result() + defer resp.Body.Close() code := rr.Code b, err := io.ReadAll(resp.Body) @@ -135,6 +138,7 @@ func TestWellknownAPIJWKSJSONHandles200(t *testing.T) { rr := setupHandlerAndRecorder(c, "/jwks.json", store) resp := rr.Result() + defer resp.Body.Close() code := rr.Code b, err := io.ReadAll(resp.Body) diff --git a/local/seed_db/main.go b/local/seed_db/main.go index a9355d3ed..b2403f554 100644 --- a/local/seed_db/main.go +++ b/local/seed_db/main.go @@ -1,3 +1,4 @@ +// Copyright 2024 Canonical. package main import ( @@ -7,15 +8,16 @@ import ( "os" "time" - "github.com/canonical/jimm/v3/internal/db" - "github.com/canonical/jimm/v3/internal/dbmodel" - "github.com/canonical/jimm/v3/internal/logger" petname "github.com/dustinkirkland/golang-petname" "github.com/google/uuid" "github.com/juju/juju/core/crossmodel" "github.com/juju/juju/state" "gorm.io/driver/postgres" "gorm.io/gorm" + + "github.com/canonical/jimm/v3/internal/db" + "github.com/canonical/jimm/v3/internal/dbmodel" + "github.com/canonical/jimm/v3/internal/logger" ) // A simple script to seed a local database for schema testing. @@ -36,7 +38,7 @@ func main() { DB: gdb, } - db.Migrate(ctx, false) + err = db.Migrate(ctx, false) if err != nil { fmt.Println("failed to migrate to db ", err) os.Exit(1) diff --git a/local/vault/approle.go b/local/vault/approle.go index 8e7ad02e9..0649aa4ba 100644 --- a/local/vault/approle.go +++ b/local/vault/approle.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. // This package exists to hold files used to authenticate with Vault during tests. package vault diff --git a/openfga/auth_model.go b/openfga/auth_model.go index a851fe6b2..32105d6da 100644 --- a/openfga/auth_model.go +++ b/openfga/auth_model.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. // This package exists to hold JIMM's OpenFGA authorisation model. // It embeds the auth model and provides it for tests. diff --git a/pkg/api/client.go b/pkg/api/client.go index 3bfdc9aac..b84a75e7e 100644 --- a/pkg/api/client.go +++ b/pkg/api/client.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package api diff --git a/pkg/api/params/errors.go b/pkg/api/params/errors.go index 773ea23fd..dd46638f9 100644 --- a/pkg/api/params/errors.go +++ b/pkg/api/params/errors.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package params diff --git a/pkg/api/params/params.go b/pkg/api/params/params.go index 0d0a9f740..f890c2020 100644 --- a/pkg/api/params/params.go +++ b/pkg/api/params/params.go @@ -1,4 +1,4 @@ -// Copyright 2020 Canonical Ltd. +// Copyright 2024 Canonical. package params @@ -219,7 +219,7 @@ type FindAuditEventsRequest struct { // A ListControllersResponse is the response that is sent in a // ListControllers method. type ListControllersResponse struct { - Controllers []ControllerInfo `json:"controllers",yaml:"controllers"` + Controllers []ControllerInfo `json:"controllers" yaml:"controllers"` } // A RemoveControllerRequest is the request that is sent in a @@ -302,15 +302,15 @@ type RemoveGroupRequest struct { // Group holds the details of a group currently residing in JIMM. type Group struct { - UUID string `json:"uuid",yaml:"uuid"` - Name string `json:"name",yaml:"name"` - CreatedAt string `json:"created_at",yaml:"created_at"` - UpdatedAt string `json:"updated_at",yaml:"updated_at"` + UUID string `json:"uuid" yaml:"uuid"` + Name string `json:"name" yaml:"name"` + CreatedAt string `json:"created_at" yaml:"created_at"` + UpdatedAt string `json:"updated_at" yaml:"updated_at"` } // ListGroupResponse returns the group tuples currently residing within OpenFGA. type ListGroupResponse struct { - Groups []Group `json:"name",yaml:"name"` + Groups []Group `json:"name" yaml:"name"` } // RelationshipTuple represents a OpenFGA Tuple. @@ -343,7 +343,7 @@ type CheckRelationRequest struct { // CheckRelationResponse simple responds with an object containing a boolean of 'allowed' or not // when a check for access is requested. type CheckRelationResponse struct { - Allowed bool `json:"allowed",yaml:"allowed"` + Allowed bool `json:"allowed" yaml:"allowed"` } // ListRelationshipTuplesRequests holds the request information to list tuples. @@ -373,8 +373,8 @@ type CrossModelQueryRequest struct { // - Results - A map of each iterated JQ output result. The key for this map is the model UUID. // - Errors - A map of each iterated JQ *or* Status call error. The key for this map is the model UUID. type CrossModelQueryResponse struct { - Results map[string][]any `json:"results",yaml:"results"` - Errors map[string][]string `json:"errors",yaml:"errors"` + Results map[string][]any `json:"results" yaml:"results"` + Errors map[string][]string `json:"errors" yaml:"errors"` } // PurgeLogsRequest is the request used to purge logs. @@ -410,9 +410,9 @@ type LoginDeviceResponse struct { // VerificationURI holds the URI that the user must navigate to // when entering their "user-code" to consent to this authorisation // request. - VerificationURI string `json:"verification-uri",yaml:"verification-uri"` + VerificationURI string `json:"verification-uri" yaml:"verification-uri"` // UserCode holds the one-time use user consent code. - UserCode string `json:"user-code",yaml:"user-code"` + UserCode string `json:"user-code" yaml:"user-code"` } // GetDeviceSessionTokenResponse returns a session token to be used against @@ -422,7 +422,7 @@ type GetDeviceSessionTokenResponse struct { // SessionToken is a base64 encoded JWT capable of authenticating // a user. The JWT contains the users email address in the subject, // and this is used to identify this user. - SessionToken string `json:"session-token",yaml:"session-token"` + SessionToken string `json:"session-token" yaml:"session-token"` } // LoginWithSessionTokenRequest accepts a session token minted by JIMM and logs @@ -489,6 +489,6 @@ type GrantServiceAccountAccess struct { // WhoamiResponse holds the response for a /auth/whoami call. type WhoamiResponse struct { - DisplayName string `json:"display-name",yaml:"display-name"` - Email string `json:"email",yaml:"email"` + DisplayName string `json:"display-name" yaml:"display-name"` + Email string `json:"email" yaml:"email"` } diff --git a/pkg/names/applicationoffer.go b/pkg/names/applicationoffer.go index e4a163063..258854996 100644 --- a/pkg/names/applicationoffer.go +++ b/pkg/names/applicationoffer.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names diff --git a/pkg/names/group.go b/pkg/names/group.go index ac1d07978..ad9ecde2f 100644 --- a/pkg/names/group.go +++ b/pkg/names/group.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names diff --git a/pkg/names/group_test.go b/pkg/names/group_test.go index 3846f90d0..10f7f8b46 100644 --- a/pkg/names/group_test.go +++ b/pkg/names/group_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names_test diff --git a/pkg/names/names.go b/pkg/names/names.go index 84e61ea98..5e0b18c98 100644 --- a/pkg/names/names.go +++ b/pkg/names/names.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names diff --git a/pkg/names/service_account.go b/pkg/names/service_account.go index 009728f4a..8c1c2616a 100644 --- a/pkg/names/service_account.go +++ b/pkg/names/service_account.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names diff --git a/pkg/names/service_account_test.go b/pkg/names/service_account_test.go index b2f0132f2..98880be3e 100644 --- a/pkg/names/service_account_test.go +++ b/pkg/names/service_account_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Canonical Ltd. +// Copyright 2024 Canonical. package names_test diff --git a/version/default.go b/version/default.go index 55e1dddc9..7ec4fa5f0 100644 --- a/version/default.go +++ b/version/default.go @@ -1,4 +1,4 @@ -// Copyright 2021 Canonical Ltd. +// Copyright 2024 Canonical. // +build !version //go:build !version diff --git a/version/version.go b/version/version.go index c14d1623d..dec1d7375 100644 --- a/version/version.go +++ b/version/version.go @@ -1,4 +1,4 @@ -// Copyright 2015 Canonical Ltd. +// Copyright 2024 Canonical. package version