From 43039fefe8f0d6e575dc7571ea68c0c3b78d0c42 Mon Sep 17 00:00:00 2001 From: Jack Shaw Date: Wed, 15 Nov 2023 12:10:30 +0000 Subject: [PATCH 01/50] Update merge bot Update merge bot to reflect the new 3.4 branch, and the closing of 3.2 --- .github/workflows/merge.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 1d782d92dff..2a6e66531c4 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -1,7 +1,7 @@ name: Merge on: push: - branches: ['2.9', '3.1', '3.2', '3.3'] + branches: ['2.9', '3.1', '3.3', '3.4'] jobs: check-merge: @@ -10,9 +10,9 @@ jobs: env: MERGE_TARGETS: | 2.9: 3.1 - 3.1: 3.2 - 3.2: 3.3 - 3.3: main + 3.1: 3.3 + 3.3: 3.4 + 3.4: main steps: - name: Determine source/target branches @@ -54,7 +54,7 @@ jobs: # Need to set Git username/email to do the merge (yawn) git config user.name 'jujubot' git config user.email 'fake@address.me' - + set +e git switch "$TARGET_BRANCH" git merge "$SOURCE_BRANCH" From c0846e956a03ad4b6148f7bf4fa3988563b35ced Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 11:24:54 -0500 Subject: [PATCH 02/50] Update deploy tests run on lxd. One test was failing due to jammy not supported OS in the charm, update the charm. Not caught as the test was in proving grounds and failed before running due to nested containers not working. Move nested container tests to providers other than lxd. Specify operating system when deploying the juju-qa-lxd-profile-without-devices charm. Xenial containers do not always get past a pending state. Update the basic openstack bundle to use focal-yoga as the current charms do not support Xenial. --- .../deploy/bundles/basic-openstack.yaml | 14 +++++----- .../charms/lxd-profile-alt/manifest.yaml | 26 +++++++++++++++++++ .../charms/lxd-profile-alt/metadata.yaml | 1 + .../deploy/charms/lxd-profile/manifest.yaml | 26 +++++++++++++++++++ tests/suites/deploy/deploy_bundles.sh | 5 ++-- tests/suites/deploy/deploy_charms.sh | 16 +++++++++--- 6 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 tests/suites/deploy/charms/lxd-profile-alt/manifest.yaml create mode 100644 tests/suites/deploy/charms/lxd-profile/manifest.yaml diff --git a/tests/suites/deploy/bundles/basic-openstack.yaml b/tests/suites/deploy/bundles/basic-openstack.yaml index 5705836bf54..39f6edcd0c2 100644 --- a/tests/suites/deploy/bundles/basic-openstack.yaml +++ b/tests/suites/deploy/bundles/basic-openstack.yaml @@ -41,7 +41,7 @@ relations: - mysql:shared-db - - nova-cloud-controller:neutron-api - neutron-api:neutron-api -series: xenial +series: focal applications: glance: annotations: @@ -50,7 +50,7 @@ applications: charm: cs:glance num_units: 1 options: - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga worker-multiplier: 0.25 keystone: annotations: @@ -60,7 +60,7 @@ applications: num_units: 1 options: admin-password: openstack - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga worker-multiplier: 0.25 mysql: annotations: @@ -80,7 +80,7 @@ applications: options: neutron-security-groups: true overlay-network-type: "gre vxlan" - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga flat-network-providers: physnet1 neutron-gateway: annotations: @@ -89,7 +89,7 @@ applications: charm: cs:neutron-gateway num_units: 1 options: - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga worker-multiplier: 0.25 dns-servers: 10.101.0.1 neutron-openvswitch: @@ -106,7 +106,7 @@ applications: num_units: 1 options: network-manager: Neutron - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga worker-multiplier: 0.25 nova-compute: annotations: @@ -117,7 +117,7 @@ applications: options: enable-live-migration: False enable-resize: False - openstack-origin: cloud:xenial-queens + openstack-origin: cloud:focal-yoga rabbitmq-server: annotations: gui-x: '500' diff --git a/tests/suites/deploy/charms/lxd-profile-alt/manifest.yaml b/tests/suites/deploy/charms/lxd-profile-alt/manifest.yaml new file mode 100644 index 00000000000..218f3f846c6 --- /dev/null +++ b/tests/suites/deploy/charms/lxd-profile-alt/manifest.yaml @@ -0,0 +1,26 @@ +bases: + - name: ubuntu + channel: 22.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 20.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 18.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 16.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 12.04/stable + architectures: + - amd64 + - arm64 diff --git a/tests/suites/deploy/charms/lxd-profile-alt/metadata.yaml b/tests/suites/deploy/charms/lxd-profile-alt/metadata.yaml index cdf42882d5e..b96205ce25c 100644 --- a/tests/suites/deploy/charms/lxd-profile-alt/metadata.yaml +++ b/tests/suites/deploy/charms/lxd-profile-alt/metadata.yaml @@ -13,6 +13,7 @@ tags: - application_development subordinate: false series: + - jammy - focal - bionic - xenial diff --git a/tests/suites/deploy/charms/lxd-profile/manifest.yaml b/tests/suites/deploy/charms/lxd-profile/manifest.yaml new file mode 100644 index 00000000000..218f3f846c6 --- /dev/null +++ b/tests/suites/deploy/charms/lxd-profile/manifest.yaml @@ -0,0 +1,26 @@ +bases: + - name: ubuntu + channel: 22.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 20.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 18.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 16.04/stable + architectures: + - amd64 + - arm64 + - name: ubuntu + channel: 12.04/stable + architectures: + - amd64 + - arm64 diff --git a/tests/suites/deploy/deploy_bundles.sh b/tests/suites/deploy/deploy_bundles.sh index 930bd0a5d5f..2abc71d841f 100644 --- a/tests/suites/deploy/deploy_bundles.sh +++ b/tests/suites/deploy/deploy_bundles.sh @@ -322,11 +322,12 @@ test_deploy_bundles() { case "${BOOTSTRAP_PROVIDER:-}" in "lxd" | "localhost") run "run_deploy_lxd_profile_bundle_openstack" - run "run_deploy_lxd_profile_bundle" + echo "==> TEST SKIPPED: deploy_lxd_profile_bundle - tests for non LXD only" ;; *) echo "==> TEST SKIPPED: deploy_lxd_profile_bundle_openstack - tests for LXD only" - echo "==> TEST SKIPPED: deploy_lxd_profile_bundle - tests for LXD only" + run "run_deploy_lxd_profile_bundle" + ;; esac diff --git a/tests/suites/deploy/deploy_charms.sh b/tests/suites/deploy/deploy_charms.sh index 32f06c815aa..1554f1bd6d3 100644 --- a/tests/suites/deploy/deploy_charms.sh +++ b/tests/suites/deploy/deploy_charms.sh @@ -45,7 +45,10 @@ run_deploy_lxd_profile_charm() { ensure "test-deploy-lxd-profile" "${file}" - juju deploy juju-qa-lxd-profile-without-devices + # This charm deploys to Xenial by default, which doesn't + # always result in a machine which becomes fully deployed + # with the lxd provider. + juju deploy juju-qa-lxd-profile-without-devices --series jammy wait_for "lxd-profile-without-devices" "$(idle_condition "lxd-profile-without-devices")" juju status --format=json | jq '.machines | .["0"] | .["lxd-profiles"] | keys[0]' | check "juju-test-deploy-lxd-profile-lxd-profile" @@ -60,7 +63,10 @@ run_deploy_lxd_profile_charm_container() { ensure "test-deploy-lxd-profile-container" "${file}" - juju deploy juju-qa-lxd-profile-without-devices --to lxd + # This charm deploys to Xenial by default, which doesn't + # always result in a machine which becomes fully deployed + # with the lxd provider. + juju deploy juju-qa-lxd-profile-without-devices --to lxd --series jammy wait_for "lxd-profile-without-devices" "$(idle_condition "lxd-profile-without-devices")" juju status --format=json | jq '.machines | .["0"] | .containers | .["0/lxd/0"] | .["lxd-profiles"] | keys[0]' | @@ -269,8 +275,6 @@ test_deploy_charms() { run "run_deploy_charm" run "run_deploy_specific_series" - run "run_deploy_lxd_to_container" - run "run_deploy_lxd_profile_charm_container" run "run_resolve_charm" case "${BOOTSTRAP_PROVIDER:-}" in @@ -278,11 +282,15 @@ test_deploy_charms() { run "run_deploy_lxd_to_machine" run "run_deploy_lxd_profile_charm" run "run_deploy_local_lxd_profile_charm" + echo "==> TEST SKIPPED: deploy_lxd_to_container - tests for non LXD only" + echo "==> TEST SKIPPED: deploy_lxd_profile_charm_container - tests for non LXD only" ;; *) echo "==> TEST SKIPPED: deploy_lxd_to_machine - tests for LXD only" echo "==> TEST SKIPPED: deploy_lxd_profile_charm - tests for LXD only" echo "==> TEST SKIPPED: deploy_local_lxd_profile_charm - tests for LXD only" + run "run_deploy_lxd_to_container" + run "run_deploy_lxd_profile_charm_container" ;; esac ) From 743ae39ecff51da8ac00cff930719f949ecd1a48 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 15:20:00 -0500 Subject: [PATCH 03/50] Remove test to deploy centos8. Juju no longer supports centos8, nor can it be deployed in aws. --- tests/suites/deploy/os.sh | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/tests/suites/deploy/os.sh b/tests/suites/deploy/os.sh index 5fca430e404..b68943d5ccc 100644 --- a/tests/suites/deploy/os.sh +++ b/tests/suites/deploy/os.sh @@ -16,7 +16,6 @@ test_deploy_os() { # https://wiki.centos.org/Cloud/AWS # run "run_deploy_centos7" - run "run_deploy_centos8" ;; *) echo "==> TEST SKIPPED: deploy_centos - tests for AWS only" @@ -59,34 +58,3 @@ run_deploy_centos7() { destroy_model "${name}" destroy_model "test-deploy-centos-west2" } - -run_deploy_centos8() { - echo - - echo "==> Checking for dependencies" - check_juju_dependencies metadata - - name="test-deploy-centos8" - file="${TEST_DIR}/${name}.log" - - ensure "${name}" "${file}" - - # - # Images have been setup and and subscribed for juju-qa aws - # in us-east-1. Take care editing the details. - # - juju metadata add-image --series centos8 ami-0d6e9a57f6259ba3a - - # - # The disk size must be >= 10G to cover the image above. - # Ensure we use an instance with enough disk space. - # - juju deploy ./tests/suites/deploy/charms/centos-dummy-sink --series centos8 --constraints root-disk=10G - - series=$(juju status --format=json | jq '.applications."dummy-sink".series') - echo "$series" | check "centos8" - - wait_for "dummy-sink" "$(idle_condition "dummy-sink")" - - destroy_model "${name}" -} From 6dbb5088f617d5d7ca99d30ad1c36e6120cfb994 Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Fri, 10 Nov 2023 12:53:09 +0000 Subject: [PATCH 04/50] Ensure we check the core facadeas when migrating. --- api/apiclient.go | 3 +- api/controller/migrationmaster/client.go | 5 +- api/export_test.go | 2 - api/facadeversions.go | 20 ++-- api/facadeversions_test.go | 15 +-- apiserver/allfacades.go | 11 +- apiserver/facades/agent/machine/register.go | 9 ++ apiserver/facades/agent/uniter/register.go | 9 ++ .../controller/migrationmaster/facade.go | 40 ++++--- .../controller/migrationmaster/register.go | 14 ++- core/facades/facade.go | 48 ++++++++ core/facades/facade_test.go | 106 ++++++++++++++++++ core/facades/package_test.go | 14 +++ rpc/params/migration.go | 3 +- 14 files changed, 250 insertions(+), 49 deletions(-) create mode 100644 core/facades/facade.go create mode 100644 core/facades/facade_test.go create mode 100644 core/facades/package_test.go diff --git a/api/apiclient.go b/api/apiclient.go index c284d95b36c..5e292dff226 100644 --- a/api/apiclient.go +++ b/api/apiclient.go @@ -35,6 +35,7 @@ import ( "gopkg.in/retry.v1" "github.com/juju/juju/api/base" + "github.com/juju/juju/core/facades" coremacaroon "github.com/juju/juju/core/macaroon" "github.com/juju/juju/core/network" jujuproxy "github.com/juju/juju/proxy" @@ -1380,7 +1381,7 @@ func (s *state) PublicDNSName() string { // Facade we will want to use. It needs to line up the versions that the server // reports to us, with the versions that our client knows how to use. func (s *state) BestFacadeVersion(facade string) int { - return bestVersion(facadeVersions[facade], s.facadeVersions[facade]) + return facades.BestVersion(facadeVersions[facade], s.facadeVersions[facade]) } // serverRoot returns the cached API server address and port used diff --git a/api/controller/migrationmaster/client.go b/api/controller/migrationmaster/client.go index 8a85a659566..06ddfa9f913 100644 --- a/api/controller/migrationmaster/client.go +++ b/api/controller/migrationmaster/client.go @@ -18,6 +18,7 @@ import ( "gopkg.in/httprequest.v1" "gopkg.in/macaroon.v2" + "github.com/juju/juju/api" "github.com/juju/juju/api/base" "github.com/juju/juju/api/common" "github.com/juju/juju/core/migration" @@ -174,7 +175,9 @@ func (c *Client) SourceControllerInfo() (migration.SourceControllerInfo, []strin // Prechecks verifies that the source controller and model are healthy // and able to participate in a migration. func (c *Client) Prechecks() error { - return c.caller.FacadeCall("Prechecks", params.PrechecksArgs{}, nil) + return c.caller.FacadeCall("Prechecks", params.PrechecksArgs{ + FacadeVersions: api.SupportedFacadeVersions(), + }, nil) } // Export returns a serialized representation of the model associated diff --git a/api/export_test.go b/api/export_test.go index d16be991019..cb67796ec21 100644 --- a/api/export_test.go +++ b/api/export_test.go @@ -21,8 +21,6 @@ import ( var ( CertDir = &certDir SlideAddressToFront = slideAddressToFront - BestVersion = bestVersion - FacadeVersions = &facadeVersions ) func DialAPI(info *Info, opts DialOpts) (jsoncodec.JSONConn, string, error) { diff --git a/api/facadeversions.go b/api/facadeversions.go index 6a534f44e44..47334cfb5c3 100644 --- a/api/facadeversions.go +++ b/api/facadeversions.go @@ -3,7 +3,12 @@ package api -import "github.com/juju/collections/set" +import "github.com/juju/juju/core/facades" + +// SupportedFacadeVersions returns the list of facades that the api supports. +func SupportedFacadeVersions() facades.FacadeVersions { + return facadeVersions +} // facadeVersions lists the best version of facades that we want to support. This // will be used to pick out a default version for communication, given the list @@ -15,7 +20,7 @@ import "github.com/juju/collections/set" // FullStatus (client facade) and Migration (controller facade) is needed. // New facades should start at 1. // We no longer support facade versions at 0. -var facadeVersions = map[string][]int{ +var facadeVersions = facades.FacadeVersions{ "Action": {7}, "ActionPruner": {1}, "Agent": {3}, @@ -135,14 +140,3 @@ var facadeVersions = map[string][]int{ "VolumeAttachmentsWatcher": {2}, "VolumeAttachmentPlansWatcher": {1}, } - -// bestVersion tries to find the newest version in the version list that we can -// use. -func bestVersion(desired []int, versions []int) int { - intersection := set.NewInts(desired...).Intersection(set.NewInts(versions...)) - if intersection.Size() == 0 { - return 0 - } - sorted := intersection.SortedValues() - return sorted[len(sorted)-1] -} diff --git a/api/facadeversions_test.go b/api/facadeversions_test.go index d2257d60fe7..68b45549b1f 100644 --- a/api/facadeversions_test.go +++ b/api/facadeversions_test.go @@ -10,6 +10,7 @@ import ( "github.com/juju/juju/api" "github.com/juju/juju/apiserver" + "github.com/juju/juju/core/facades" coretesting "github.com/juju/juju/testing" ) @@ -24,7 +25,7 @@ func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) { // code just to list out what versions are available. However, we do // want to make sure that the two sides are kept in sync. clientFacadeNames := set.NewStrings() - for name, versions := range *api.FacadeVersions { + for name, versions := range api.SupportedFacadeVersions() { clientFacadeNames.Add(name) // All versions should now be non-zero. c.Check(set.NewInts(versions...).Contains(0), jc.IsFalse) @@ -40,11 +41,11 @@ func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) { c.Check(serverFacadeNames.Difference(clientFacadeNames).SortedValues(), gc.HasLen, 0) c.Check(clientFacadeNames.Difference(serverFacadeNames).SortedValues(), gc.HasLen, 0) // Next check that the best versions match - c.Check(*api.FacadeVersions, jc.DeepEquals, serverFacadeBestVersions) + c.Check(api.SupportedFacadeVersions(), jc.DeepEquals, serverFacadeBestVersions) } func checkBestVersion(c *gc.C, desiredVersion, versions []int, expectedVersion int) { - resultVersion := api.BestVersion(desiredVersion, versions) + resultVersion := facades.BestVersion(desiredVersion, versions) c.Check(resultVersion, gc.Equals, expectedVersion) } @@ -78,7 +79,7 @@ func (*facadeVersionSuite) TestBestVersionNotSorted(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionExactMatch(c *gc.C) { - s.PatchValue(api.FacadeVersions, map[string][]int{"Client": {1}}) + s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, @@ -87,7 +88,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionExactMatch(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionNewerServer(c *gc.C) { - s.PatchValue(api.FacadeVersions, map[string][]int{"Client": {1}}) + s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1, 2}, @@ -96,7 +97,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionNewerServer(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionNewerClient(c *gc.C) { - s.PatchValue(api.FacadeVersions, map[string][]int{"Client": {1, 2}}) + s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1, 2}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, @@ -105,7 +106,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionNewerClient(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionServerUnknown(c *gc.C) { - s.PatchValue(api.FacadeVersions, map[string][]int{"TestingAPI": {1, 2}}) + s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"TestingAPI": {1, 2}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, diff --git a/apiserver/allfacades.go b/apiserver/allfacades.go index 7b6144ffba4..ffe746e9d1c 100644 --- a/apiserver/allfacades.go +++ b/apiserver/allfacades.go @@ -45,6 +45,8 @@ import ( "github.com/juju/juju/apiserver/facades/client/action" "github.com/juju/juju/apiserver/facades/client/annotations" // ModelUser Write "github.com/juju/juju/apiserver/facades/client/application" + "github.com/juju/juju/core/facades" + // ModelUser Write "github.com/juju/juju/apiserver/facades/client/applicationoffers" "github.com/juju/juju/apiserver/facades/client/backups" // ModelUser Write @@ -109,6 +111,13 @@ import ( "github.com/juju/juju/apiserver/facades/controller/undertaker" ) +func requiredMigrationFacadeVersions() facades.FacadeVersions { + return facades.FacadeVersions{}.Merge( + machine.FacadesVersions(), + uniter.FacadesVersions(), + ) +} + // AllFacades returns a registry containing all known API facades. // // This will panic if facade registration fails, but there is a unit @@ -182,7 +191,7 @@ func AllFacades() *facade.Registry { metricsdebug.Register(registry) metricsmanager.Register(registry) migrationflag.Register(registry) - migrationmaster.Register(registry) + migrationmaster.Register(requiredMigrationFacadeVersions())(registry) migrationminion.Register(registry) migrationtarget.Register(registry) modelconfig.Register(registry) diff --git a/apiserver/facades/agent/machine/register.go b/apiserver/facades/agent/machine/register.go index ddd2ca4dd88..1279a19b125 100644 --- a/apiserver/facades/agent/machine/register.go +++ b/apiserver/facades/agent/machine/register.go @@ -9,6 +9,7 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) // Register is called to expose a package of facades onto a given registry. @@ -18,6 +19,14 @@ func Register(registry facade.FacadeRegistry) { }, reflect.TypeOf((*MachinerAPI)(nil))) } +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.FacadeVersions { + return facades.FacadeVersions{ + "Machiner": []int{5}, + } +} + // newMachinerAPI creates a new instance of the Machiner API. func newMachinerAPI(ctx facade.Context) (*MachinerAPI, error) { systemState, err := ctx.StatePool().SystemState() diff --git a/apiserver/facades/agent/uniter/register.go b/apiserver/facades/agent/uniter/register.go index a6ed822e6c1..e7f81eb78b5 100644 --- a/apiserver/facades/agent/uniter/register.go +++ b/apiserver/facades/agent/uniter/register.go @@ -15,6 +15,7 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/apiserver/facades/agent/meterstatus" "github.com/juju/juju/apiserver/facades/agent/secretsmanager" + "github.com/juju/juju/core/facades" ) // Register is called to expose a package of facades onto a given registry. @@ -27,6 +28,14 @@ func Register(registry facade.FacadeRegistry) { }, reflect.TypeOf((*UniterAPI)(nil))) } +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.FacadeVersions { + return facades.FacadeVersions{ + "Uniter": []int{18, 19}, + } +} + func newUniterAPIv18(context facade.Context) (*UniterAPIv18, error) { api, err := newUniterAPI(context) if err != nil { diff --git a/apiserver/facades/controller/migrationmaster/facade.go b/apiserver/facades/controller/migrationmaster/facade.go index 2f00740c16c..3b6b0a63e9f 100644 --- a/apiserver/facades/controller/migrationmaster/facade.go +++ b/apiserver/facades/controller/migrationmaster/facade.go @@ -16,6 +16,7 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/core/leadership" coremigration "github.com/juju/juju/core/migration" coremodel "github.com/juju/juju/core/model" @@ -28,15 +29,16 @@ import ( // API implements the API required for the model migration // master worker. type API struct { - controllerState ControllerState - backend Backend - precheckBackend migration.PrecheckBackend - pool migration.Pool - authorizer facade.Authorizer - resources facade.Resources - presence facade.Presence - environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error) - leadership leadership.Reader + controllerState ControllerState + backend Backend + precheckBackend migration.PrecheckBackend + pool migration.Pool + authorizer facade.Authorizer + resources facade.Resources + presence facade.Presence + environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error) + leadership leadership.Reader + requiredMigrationFacadeVersions facades.FacadeVersions } // NewAPI creates a new API server endpoint for the model migration @@ -51,20 +53,22 @@ func NewAPI( presence facade.Presence, environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error), leadership leadership.Reader, + requiredMigrationFacadeVersions facades.FacadeVersions, ) (*API, error) { if !authorizer.AuthController() { return nil, apiservererrors.ErrPerm } return &API{ - controllerState: controllerState, - backend: backend, - precheckBackend: precheckBackend, - pool: pool, - authorizer: authorizer, - resources: resources, - presence: presence, - environscloudspecGetter: environscloudspecGetter, - leadership: leadership, + controllerState: controllerState, + backend: backend, + precheckBackend: precheckBackend, + pool: pool, + authorizer: authorizer, + resources: resources, + presence: presence, + environscloudspecGetter: environscloudspecGetter, + leadership: leadership, + requiredMigrationFacadeVersions: requiredMigrationFacadeVersions, }, nil } diff --git a/apiserver/facades/controller/migrationmaster/register.go b/apiserver/facades/controller/migrationmaster/register.go index 75f9935aff4..e1ae17e739c 100644 --- a/apiserver/facades/controller/migrationmaster/register.go +++ b/apiserver/facades/controller/migrationmaster/register.go @@ -10,19 +10,22 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/migration" ) // Register is called to expose a package of facades onto a given registry. -func Register(registry facade.FacadeRegistry) { - registry.MustRegister("MigrationMaster", 3, func(ctx facade.Context) (facade.Facade, error) { - return newMigrationMasterFacade(ctx) // Adds MinionReportTimeout. - }, reflect.TypeOf((*API)(nil))) +func Register(requiredMigrationFacadeVersions facades.FacadeVersions) func(registry facade.FacadeRegistry) { + return func(registry facade.FacadeRegistry) { + registry.MustRegister("MigrationMaster", 3, func(ctx facade.Context) (facade.Facade, error) { + return newMigrationMasterFacade(ctx, requiredMigrationFacadeVersions) // Adds MinionReportTimeout. + }, reflect.TypeOf((*API)(nil))) + } } // newMigrationMasterFacade exists to provide the required signature for API // registration, converting st to backend. -func newMigrationMasterFacade(ctx facade.Context) (*API, error) { +func newMigrationMasterFacade(ctx facade.Context, requiredMigrationFacadeVersions facades.FacadeVersions) (*API, error) { pool := ctx.StatePool() modelState := ctx.State() @@ -51,5 +54,6 @@ func newMigrationMasterFacade(ctx facade.Context) (*API, error) { ctx.Presence(), cloudspec.MakeCloudSpecGetter(pool), leadership, + requiredMigrationFacadeVersions, ) } diff --git a/core/facades/facade.go b/core/facades/facade.go new file mode 100644 index 00000000000..d6a4b6fb953 --- /dev/null +++ b/core/facades/facade.go @@ -0,0 +1,48 @@ +// Copyright 2023 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package facades + +import "github.com/juju/collections/set" + +// FacadeVersions is a map of facade name to version numbers. The facade version +// numbers contain each version of the facade that the API server is capable of +// supporting. This supports having holes in the version numbers, so that we can +// depreciate broken versions of the facade. +type FacadeVersions map[string][]int + +// Merge adds the other facade versions to the current facade versions. +func (f FacadeVersions) Merge(others ...FacadeVersions) FacadeVersions { + for _, other := range others { + for name, versions := range other { + f[name] = set.NewInts(f[name]...).Union(set.NewInts(versions...)).SortedValues() + } + } + return f +} + +// BestVersion finds the newest version in the version list that we can +// use. +func BestVersion(desired []int, versions []int) int { + intersection := set.NewInts(desired...).Intersection(set.NewInts(versions...)) + if intersection.Size() == 0 { + return 0 + } + sorted := intersection.SortedValues() + return sorted[len(sorted)-1] +} + +// CompleteIntersection returns true if the src and dest facades have a +// complete intersection. This means that the dest facades support all of +// the src facades. +func CompleteIntersection(src, dest FacadeVersions) bool { + for name, versions := range src { + if _, ok := dest[name]; !ok { + return false + } + if BestVersion(versions, dest[name]) == 0 { + return false + } + } + return true +} diff --git a/core/facades/facade_test.go b/core/facades/facade_test.go new file mode 100644 index 00000000000..de74dfa76d5 --- /dev/null +++ b/core/facades/facade_test.go @@ -0,0 +1,106 @@ +// Copyright 2023 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package facades + +import ( + gc "gopkg.in/check.v1" + + "github.com/juju/juju/testing" +) + +type FacadeSuite struct { + testing.BaseSuite +} + +var _ = gc.Suite(&FacadeSuite{}) + +func (s *FacadeSuite) TestBestVersion(c *gc.C) { + tests := []struct { + versions []int + desired []int + expected int + }{{ + versions: []int{1, 2, 3}, + desired: []int{1}, + expected: 1, + }, { + versions: []int{1, 2, 3}, + desired: []int{1, 2}, + expected: 2, + }, { + versions: []int{1, 2, 3}, + desired: []int{1, 2, 3}, + expected: 3, + }, { + versions: []int{}, + desired: []int{0, 1, 2}, + expected: 0, + }} + for i, test := range tests { + c.Logf("test %d", i) + c.Check(BestVersion(test.desired, test.versions), gc.Equals, test.expected) + } +} + +func (s *FacadeSuite) TestCompleteIntersection(c *gc.C) { + tests := []struct { + src FacadeVersions + dst FacadeVersions + expected bool + }{{ + src: FacadeVersions{ + "foo": []int{1, 2, 3}, + }, + dst: FacadeVersions{ + "foo": []int{1, 2, 3}, + }, + expected: true, + }, { + src: FacadeVersions{ + "bar": []int{1, 2, 3}, + }, + dst: FacadeVersions{ + "foo": []int{1, 2, 3}, + }, + expected: false, + }, { + src: FacadeVersions{ + "foo": []int{3, 4, 5}, + }, + dst: FacadeVersions{ + "foo": []int{1, 2, 3}, + }, + expected: true, + }, { + src: FacadeVersions{ + "foo": []int{4, 5}, + }, + dst: FacadeVersions{ + "foo": []int{1, 2, 3}, + }, + expected: false, + }, { + src: FacadeVersions{ + "foo": []int{2, 3, 4}, + }, + dst: FacadeVersions{ + "foo": []int{1}, + }, + expected: false, + }, { + src: FacadeVersions{ + "foo": []int{1, 2, 3}, + "bar": []int{3}, + }, + dst: FacadeVersions{ + "foo": []int{1, 2, 3}, + "bar": []int{1, 3}, + }, + expected: true, + }} + for i, test := range tests { + c.Logf("test %d", i) + c.Check(CompleteIntersection(test.src, test.dst), gc.Equals, test.expected) + } +} diff --git a/core/facades/package_test.go b/core/facades/package_test.go new file mode 100644 index 00000000000..87166c5f86e --- /dev/null +++ b/core/facades/package_test.go @@ -0,0 +1,14 @@ +// Copyright 2023 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package facades + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func TestPackage(t *testing.T) { + gc.TestingT(t) +} diff --git a/rpc/params/migration.go b/rpc/params/migration.go index eafded950b7..72ad8d426d1 100644 --- a/rpc/params/migration.go +++ b/rpc/params/migration.go @@ -78,7 +78,8 @@ type SetMigrationStatusMessageArgs struct { // PrechecksArgs provides the target controller version // to the migrationmaster.Prechecks API method. type PrechecksArgs struct { - TargetControllerVersion version.Number `json:"target-controller-version"` + TargetControllerVersion version.Number `json:"target-controller-version"` + FacadeVersions map[string][]int `json:"facade-versions"` } // SerializedModel wraps a buffer contain a serialised Juju model. It From f3829cd811e2aca5b3ed05bae1c142d796520a9a Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Mon, 13 Nov 2023 12:36:40 +0000 Subject: [PATCH 05/50] Add agent facades for the migration pre-check The following forces that all agent facades are correctly registered in the pre-source migration check. We currently don't block the check yet, that will come in another PR. This just sets up registering them and ensuring that there is a complete overlap between registered and reported versions. It's a shame that the registry doesn't give the information readily, otherwise we could just use that! --- api/controller/migrationmaster/client.go | 12 +++- api/controller/migrationmaster/client_test.go | 20 +++---- apiserver/allfacades.go | 55 ++++++++++++++++++- apiserver/allfacades_test.go | 42 ++++++++++++-- apiserver/facades/agent/agent/register.go | 10 ++++ .../facades/agent/caasadmission/register.go | 10 ++++ apiserver/facades/agent/caasagent/register.go | 10 ++++ .../facades/agent/caasapplication/register.go | 10 ++++ .../facades/agent/caasoperator/register.go | 10 ++++ .../agent/credentialvalidator/register.go | 10 ++++ apiserver/facades/agent/deployer/register.go | 10 ++++ .../facades/agent/diskmanager/register.go | 10 ++++ .../facades/agent/fanconfigurer/register.go | 10 ++++ .../facades/agent/hostkeyreporter/register.go | 10 ++++ .../facades/agent/instancemutater/register.go | 10 ++++ .../facades/agent/keyupdater/register.go | 10 ++++ .../facades/agent/leadership/register.go | 10 ++++ apiserver/facades/agent/lifeflag/register.go | 10 ++++ apiserver/facades/agent/logger/register.go | 10 ++++ apiserver/facades/agent/machine/register.go | 17 +++--- .../facades/agent/machineactions/register.go | 10 ++++ .../facades/agent/meterstatus/register.go | 10 ++++ .../facades/agent/metricsadder/register.go | 10 ++++ .../facades/agent/migrationflag/register.go | 10 ++++ .../facades/agent/migrationminion/register.go | 10 ++++ .../agent/payloadshookcontext/register.go | 10 ++++ .../facades/agent/provisioner/register.go | 10 ++++ .../facades/agent/proxyupdater/register.go | 10 ++++ apiserver/facades/agent/reboot/register.go | 10 ++++ .../agent/resourceshookcontext/register.go | 10 ++++ .../facades/agent/retrystrategy/register.go | 10 ++++ .../facades/agent/secretsdrain/register.go | 10 ++++ .../facades/agent/secretsmanager/register.go | 10 ++++ .../agent/storageprovisioner/register.go | 10 ++++ .../facades/agent/unitassigner/register.go | 10 ++++ apiserver/facades/agent/uniter/register.go | 17 +++--- apiserver/facades/agent/upgrader/register.go | 10 ++++ .../facades/agent/upgradeseries/register.go | 10 ++++ .../facades/agent/upgradesteps/register.go | 10 ++++ apiserver/facades/client/client/register.go | 10 ++++ .../facades/client/modelmanager/register.go | 10 ++++ .../facades/controller/agenttools/register.go | 10 ++++ .../controller/migrationmaster/facade_test.go | 2 + core/facades/facade.go | 19 +++++-- core/facades/facade_test.go | 48 ++++++++-------- 45 files changed, 530 insertions(+), 62 deletions(-) diff --git a/api/controller/migrationmaster/client.go b/api/controller/migrationmaster/client.go index 06ddfa9f913..9998ea1311b 100644 --- a/api/controller/migrationmaster/client.go +++ b/api/controller/migrationmaster/client.go @@ -175,8 +175,18 @@ func (c *Client) SourceControllerInfo() (migration.SourceControllerInfo, []strin // Prechecks verifies that the source controller and model are healthy // and able to participate in a migration. func (c *Client) Prechecks() error { + // Pass all the known facade versions to the controller so that it + // can check that the target controller supports them. Passing all of them + // ensures that we don't have to update this code when new facades are + // added, or if the controller wants to change the logic service side. + supported := api.SupportedFacadeVersions() + versions := make(map[string][]int, len(supported)) + for name, version := range supported { + versions[name] = version + } + return c.caller.FacadeCall("Prechecks", params.PrechecksArgs{ - FacadeVersions: api.SupportedFacadeVersions(), + FacadeVersions: versions, }, nil) } diff --git a/api/controller/migrationmaster/client_test.go b/api/controller/migrationmaster/client_test.go index 38493399b90..31bf3865232 100644 --- a/api/controller/migrationmaster/client_test.go +++ b/api/controller/migrationmaster/client_test.go @@ -59,7 +59,7 @@ func (s *ClientSuite) TestWatch(c *gc.C) { w, err := client.Watch() c.Check(err, jc.ErrorIsNil) c.Check(w, gc.Equals, expectWatch) - stub.CheckCalls(c, []jujutesting.StubCall{{"MigrationMaster.Watch", []interface{}{"", nil}}}) + stub.CheckCalls(c, []jujutesting.StubCall{{FuncName: "MigrationMaster.Watch", Args: []interface{}{"", nil}}}) } func (s *ClientSuite) TestWatchCallError(c *gc.C) { @@ -136,7 +136,7 @@ func (s *ClientSuite) TestSetPhase(c *gc.C) { c.Assert(err, jc.ErrorIsNil) expectedArg := params.SetMigrationPhaseArgs{Phase: "QUIESCE"} stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.SetPhase", []interface{}{"", expectedArg}}, + {FuncName: "MigrationMaster.SetPhase", Args: []interface{}{"", expectedArg}}, }) } @@ -160,7 +160,7 @@ func (s *ClientSuite) TestSetStatusMessage(c *gc.C) { c.Assert(err, jc.ErrorIsNil) expectedArg := params.SetMigrationStatusMessageArgs{Message: "foo"} stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.SetStatusMessage", []interface{}{"", expectedArg}}, + {FuncName: "MigrationMaster.SetStatusMessage", Args: []interface{}{"", expectedArg}}, }) } @@ -190,7 +190,7 @@ func (s *ClientSuite) TestModelInfo(c *gc.C) { client := migrationmaster.NewClient(apiCaller, nil) model, err := client.ModelInfo() stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.ModelInfo", []interface{}{"", nil}}, + {FuncName: "MigrationMaster.ModelInfo", Args: []interface{}{"", nil}}, }) c.Check(err, jc.ErrorIsNil) c.Check(model, jc.DeepEquals, migration.ModelInfo{ @@ -218,7 +218,7 @@ func (s *ClientSuite) TestSourceControllerInfo(c *gc.C) { client := migrationmaster.NewClient(apiCaller, nil) info, relatedModels, err := client.SourceControllerInfo() stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.SourceControllerInfo", []interface{}{"", nil}}, + {FuncName: "MigrationMaster.SourceControllerInfo", Args: []interface{}{"", nil}}, }) c.Check(err, jc.ErrorIsNil) c.Check(info, jc.DeepEquals, migration.SourceControllerInfo{ @@ -241,7 +241,7 @@ func (s *ClientSuite) TestPrechecks(c *gc.C) { c.Check(err, gc.ErrorMatches, "blam") expectedArg := params.PrechecksArgs{} stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.Prechecks", []interface{}{"", expectedArg}}, + {FuncName: "MigrationMaster.Prechecks", Args: []interface{}{"", expectedArg}}, }) } @@ -332,7 +332,7 @@ func (s *ClientSuite) TestExport(c *gc.C) { out, err := client.Export() c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.Export", []interface{}{"", nil}}, + {FuncName: "MigrationMaster.Export", Args: []interface{}{"", nil}}, }) c.Assert(out, gc.DeepEquals, migration.SerializedModel{ Bytes: []byte("foo"), @@ -441,7 +441,7 @@ func (s *ClientSuite) TestReap(c *gc.C) { err := client.Reap() c.Check(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.Reap", []interface{}{"", nil}}, + {FuncName: "MigrationMaster.Reap", Args: []interface{}{"", nil}}, }) } @@ -474,7 +474,7 @@ func (s *ClientSuite) TestWatchMinionReports(c *gc.C) { w, err := client.WatchMinionReports() c.Check(err, jc.ErrorIsNil) c.Check(w, gc.Equals, expectWatch) - stub.CheckCalls(c, []jujutesting.StubCall{{"MigrationMaster.WatchMinionReports", []interface{}{"", nil}}}) + stub.CheckCalls(c, []jujutesting.StubCall{{FuncName: "MigrationMaster.WatchMinionReports", Args: []interface{}{"", nil}}}) } func (s *ClientSuite) TestWatchMinionReportsError(c *gc.C) { @@ -515,7 +515,7 @@ func (s *ClientSuite) TestMinionReports(c *gc.C) { out, err := client.MinionReports() c.Assert(err, jc.ErrorIsNil) stub.CheckCalls(c, []jujutesting.StubCall{ - {"MigrationMaster.MinionReports", []interface{}{"", nil}}, + {FuncName: "MigrationMaster.MinionReports", Args: []interface{}{"", nil}}, }) c.Assert(out, gc.DeepEquals, migration.MinionReports{ MigrationId: "id", diff --git a/apiserver/allfacades.go b/apiserver/allfacades.go index ffe746e9d1c..e3ee0a3eadf 100644 --- a/apiserver/allfacades.go +++ b/apiserver/allfacades.go @@ -111,10 +111,63 @@ import ( "github.com/juju/juju/apiserver/facades/controller/undertaker" ) +// requiredMigrationFacadeVersions returns the facade versions that +// must be available for the migration master to function. +// This is a separate function so that it can be used in the +// migrationmaster facade registration as a dependency. +// +// A lot of the agent facades aren't actually required, but they are +// included here to keep the agent alive during migration. func requiredMigrationFacadeVersions() facades.FacadeVersions { - return facades.FacadeVersions{}.Merge( + return facades.FacadeVersions{}.Add( + // Client and modelmanager facades are required for the migration + // master to function correctly. Missing a model manager causes the + // status to error out. + client.FacadesVersions(), + modelmanager.FacadesVersions(), + + // The following are required to keep the agent alive during + // migration. + agent.FacadesVersions(), + caasadmission.FacadesVersions(), + caasagent.FacadesVersions(), + caasapplication.FacadesVersions(), + caasoperator.FacadesVersions(), + credentialvalidator.FacadesVersions(), + deployer.FacadesVersions(), + diskmanager.FacadesVersions(), + fanconfigurer.FacadesVersions(), + hostkeyreporter.FacadesVersions(), + instancemutater.FacadesVersions(), + keyupdater.FacadesVersions(), + leadership.FacadesVersions(), + agentlifeflag.FacadesVersions(), + loggerapi.FacadesVersions(), machine.FacadesVersions(), + machineactions.FacadesVersions(), + meterstatus.FacadesVersions(), + metricsadder.FacadesVersions(), + migrationflag.FacadesVersions(), + migrationminion.FacadesVersions(), + payloadshookcontext.FacadesVersions(), + provisioner.FacadesVersions(), + proxyupdater.FacadesVersions(), + reboot.FacadesVersions(), + resourceshookcontext.FacadesVersions(), + retrystrategy.FacadesVersions(), + secretsdrain.FacadesVersions(), + secretsmanager.FacadesVersions(), + storageprovisioner.FacadesVersions(), + unitassigner.FacadesVersions(), uniter.FacadesVersions(), + upgrader.FacadesVersions(), + upgradeseries.FacadesVersions(), + upgradesteps.FacadesVersions(), + + facades.NamedFacadeVersion{ + Name: "Pinger", + Versions: facades.FacadeVersion{1}, + }, ) } diff --git a/apiserver/allfacades_test.go b/apiserver/allfacades_test.go index e9e41642183..d211ffbc8da 100644 --- a/apiserver/allfacades_test.go +++ b/apiserver/allfacades_test.go @@ -1,13 +1,15 @@ // Copyright 2017 Canonical Ltd. // Licensed under the AGPLv3, see LICENCE file for details. -package apiserver_test +package apiserver import ( + "sort" + + "github.com/juju/collections/set" "github.com/juju/testing" + jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" - - "github.com/juju/juju/apiserver" ) type AllFacadesSuite struct { @@ -18,6 +20,38 @@ var _ = gc.Suite(&AllFacadesSuite{}) func (s *AllFacadesSuite) TestNoPanic(c *gc.C) { // AllFacades will panic on error so check it by calling it. - r := apiserver.AllFacades() + r := AllFacades() c.Assert(r, gc.NotNil) } + +func (s *AllFacadesSuite) TestFacadeVersionsInSync(c *gc.C) { + // Ensure that there is a complete overlap between the registered + // facade versions and the required facade versions. + facadeVersions := requiredMigrationFacadeVersions() + registeredFacades := AllFacades().List() + + m := make(map[string]set.Ints) + for _, desc := range registeredFacades { + if m[desc.Name] == nil { + m[desc.Name] = set.NewInts() + } + for _, version := range desc.Versions { + m[desc.Name].Add(version) + } + } + + for name, facadeVersion := range facadeVersions { + c.Logf("checking %q", name) + + // Force the versions to be sorted. + sort.Slice(facadeVersion, func(i, j int) bool { + return facadeVersion[i] < facadeVersion[j] + }) + + versions, ok := m[name] + c.Assert(ok, jc.IsTrue, gc.Commentf("facade %q not registered", name)) + + // Ensure there is a complete overlap. + c.Check(versions.Intersection(set.NewInts(facadeVersion...)).SortedValues(), gc.DeepEquals, []int(facadeVersion), gc.Commentf("facade %q versions not in sync", name)) + } +} diff --git a/apiserver/facades/agent/agent/register.go b/apiserver/facades/agent/agent/register.go index 7aa66118251..b6458f46f03 100644 --- a/apiserver/facades/agent/agent/register.go +++ b/apiserver/facades/agent/agent/register.go @@ -12,8 +12,18 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Agent", + Versions: facades.FacadeVersion{3}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Agent", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasadmission/register.go b/apiserver/facades/agent/caasadmission/register.go index 14d4051741c..d947a6f87de 100644 --- a/apiserver/facades/agent/caasadmission/register.go +++ b/apiserver/facades/agent/caasadmission/register.go @@ -11,8 +11,18 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "CAASAdmission", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASAdmission", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasagent/register.go b/apiserver/facades/agent/caasagent/register.go index c3f22f5795d..3daa10a34b0 100644 --- a/apiserver/facades/agent/caasagent/register.go +++ b/apiserver/facades/agent/caasagent/register.go @@ -12,8 +12,18 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "CAASAgent", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASAgent", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasapplication/register.go b/apiserver/facades/agent/caasapplication/register.go index 93d88239f62..3704e511c2c 100644 --- a/apiserver/facades/agent/caasapplication/register.go +++ b/apiserver/facades/agent/caasapplication/register.go @@ -10,9 +10,19 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state/stateenvirons" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "CAASApplication", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASApplication", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasoperator/register.go b/apiserver/facades/agent/caasoperator/register.go index 9d9e8408b47..18a9a37c048 100644 --- a/apiserver/facades/agent/caasoperator/register.go +++ b/apiserver/facades/agent/caasoperator/register.go @@ -11,9 +11,19 @@ import ( "github.com/juju/juju/apiserver/common/unitcommon" "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state/stateenvirons" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "CAASOperator", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASOperator", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/credentialvalidator/register.go b/apiserver/facades/agent/credentialvalidator/register.go index 854a012b89c..83cf9ecee23 100644 --- a/apiserver/facades/agent/credentialvalidator/register.go +++ b/apiserver/facades/agent/credentialvalidator/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "CredentialValidator", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CredentialValidator", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/deployer/register.go b/apiserver/facades/agent/deployer/register.go index 809aa7d5eec..ac644430545 100644 --- a/apiserver/facades/agent/deployer/register.go +++ b/apiserver/facades/agent/deployer/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Deployer", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Deployer", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/diskmanager/register.go b/apiserver/facades/agent/diskmanager/register.go index a0f709ccf8e..3ebeef431e5 100644 --- a/apiserver/facades/agent/diskmanager/register.go +++ b/apiserver/facades/agent/diskmanager/register.go @@ -11,8 +11,18 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "DiskManager", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("DiskManager", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/fanconfigurer/register.go b/apiserver/facades/agent/fanconfigurer/register.go index 4f0a7ad2cbe..ed28ee94cea 100644 --- a/apiserver/facades/agent/fanconfigurer/register.go +++ b/apiserver/facades/agent/fanconfigurer/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "FanConfigurer", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("FanConfigurer", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/hostkeyreporter/register.go b/apiserver/facades/agent/hostkeyreporter/register.go index 261c6fe0815..f1b4a3fbd54 100644 --- a/apiserver/facades/agent/hostkeyreporter/register.go +++ b/apiserver/facades/agent/hostkeyreporter/register.go @@ -9,8 +9,18 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "HostKeyReporter", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("HostKeyReporter", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/instancemutater/register.go b/apiserver/facades/agent/instancemutater/register.go index a4a2c50c659..8c401a70539 100644 --- a/apiserver/facades/agent/instancemutater/register.go +++ b/apiserver/facades/agent/instancemutater/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "InstanceMutater", + Versions: facades.FacadeVersion{3}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("InstanceMutater", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/keyupdater/register.go b/apiserver/facades/agent/keyupdater/register.go index 2a9eaa722b0..4287eb5a487 100644 --- a/apiserver/facades/agent/keyupdater/register.go +++ b/apiserver/facades/agent/keyupdater/register.go @@ -11,8 +11,18 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "KeyUpdater", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("KeyUpdater", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/leadership/register.go b/apiserver/facades/agent/leadership/register.go index f9ed626a51c..0bc23c4a5c4 100644 --- a/apiserver/facades/agent/leadership/register.go +++ b/apiserver/facades/agent/leadership/register.go @@ -9,8 +9,18 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "LeadershipService", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("LeadershipService", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/lifeflag/register.go b/apiserver/facades/agent/lifeflag/register.go index e6a6d6b561a..526b2003310 100644 --- a/apiserver/facades/agent/lifeflag/register.go +++ b/apiserver/facades/agent/lifeflag/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "AgentLifeFlag", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("AgentLifeFlag", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/logger/register.go b/apiserver/facades/agent/logger/register.go index 0763cdaebe2..c366f09a296 100644 --- a/apiserver/facades/agent/logger/register.go +++ b/apiserver/facades/agent/logger/register.go @@ -8,8 +8,18 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Logger", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Logger", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/machine/register.go b/apiserver/facades/agent/machine/register.go index 1279a19b125..5f98e80093d 100644 --- a/apiserver/facades/agent/machine/register.go +++ b/apiserver/facades/agent/machine/register.go @@ -12,6 +12,15 @@ import ( "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Machiner", + Versions: facades.FacadeVersion{5}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Machiner", 5, func(ctx facade.Context) (facade.Facade, error) { @@ -19,14 +28,6 @@ func Register(registry facade.FacadeRegistry) { }, reflect.TypeOf((*MachinerAPI)(nil))) } -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.FacadeVersions { - return facades.FacadeVersions{ - "Machiner": []int{5}, - } -} - // newMachinerAPI creates a new instance of the Machiner API. func newMachinerAPI(ctx facade.Context) (*MachinerAPI, error) { systemState, err := ctx.StatePool().SystemState() diff --git a/apiserver/facades/agent/machineactions/register.go b/apiserver/facades/agent/machineactions/register.go index 0c1c7a2da5c..cf378e0feed 100644 --- a/apiserver/facades/agent/machineactions/register.go +++ b/apiserver/facades/agent/machineactions/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "MachineActions", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MachineActions", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/meterstatus/register.go b/apiserver/facades/agent/meterstatus/register.go index e59f41e0441..fb222ad9ea1 100644 --- a/apiserver/facades/agent/meterstatus/register.go +++ b/apiserver/facades/agent/meterstatus/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "MeterStatus", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MeterStatus", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/metricsadder/register.go b/apiserver/facades/agent/metricsadder/register.go index 178298b6392..d7dae1dcc3b 100644 --- a/apiserver/facades/agent/metricsadder/register.go +++ b/apiserver/facades/agent/metricsadder/register.go @@ -8,8 +8,18 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "MetricsAdder", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MetricsAdder", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/migrationflag/register.go b/apiserver/facades/agent/migrationflag/register.go index 9ff11fc2ce9..dc590b27350 100644 --- a/apiserver/facades/agent/migrationflag/register.go +++ b/apiserver/facades/agent/migrationflag/register.go @@ -9,8 +9,18 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "MigrationFlag", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MigrationFlag", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/migrationminion/register.go b/apiserver/facades/agent/migrationminion/register.go index cf6134461e1..b7bd2169545 100644 --- a/apiserver/facades/agent/migrationminion/register.go +++ b/apiserver/facades/agent/migrationminion/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "MigrationMinion", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MigrationMinion", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/payloadshookcontext/register.go b/apiserver/facades/agent/payloadshookcontext/register.go index af92f4e20f5..b517f3eb483 100644 --- a/apiserver/facades/agent/payloadshookcontext/register.go +++ b/apiserver/facades/agent/payloadshookcontext/register.go @@ -11,9 +11,19 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "PayloadsHookContext", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("PayloadsHookContext", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/provisioner/register.go b/apiserver/facades/agent/provisioner/register.go index d4ecedc80af..7cdfc764a3c 100644 --- a/apiserver/facades/agent/provisioner/register.go +++ b/apiserver/facades/agent/provisioner/register.go @@ -9,8 +9,18 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Provisioner", + Versions: facades.FacadeVersion{11}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Provisioner", 11, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/proxyupdater/register.go b/apiserver/facades/agent/proxyupdater/register.go index 413d4547d38..3ef2284a82e 100644 --- a/apiserver/facades/agent/proxyupdater/register.go +++ b/apiserver/facades/agent/proxyupdater/register.go @@ -9,8 +9,18 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "ProxyUpdater", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ProxyUpdater", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/reboot/register.go b/apiserver/facades/agent/reboot/register.go index 595f9e24986..4760f408715 100644 --- a/apiserver/facades/agent/reboot/register.go +++ b/apiserver/facades/agent/reboot/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Reboot", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Reboot", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/resourceshookcontext/register.go b/apiserver/facades/agent/resourceshookcontext/register.go index e69486b42d3..c7ba4ef6cf8 100644 --- a/apiserver/facades/agent/resourceshookcontext/register.go +++ b/apiserver/facades/agent/resourceshookcontext/register.go @@ -11,9 +11,19 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "ResourcesHookContext", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ResourcesHookContext", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/retrystrategy/register.go b/apiserver/facades/agent/retrystrategy/register.go index 045e1d8e9c0..e4d6be02166 100644 --- a/apiserver/facades/agent/retrystrategy/register.go +++ b/apiserver/facades/agent/retrystrategy/register.go @@ -11,8 +11,18 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "RetryStrategy", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("RetryStrategy", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/secretsdrain/register.go b/apiserver/facades/agent/secretsdrain/register.go index 16f5bdb2eae..ad28be3d4a6 100644 --- a/apiserver/facades/agent/secretsdrain/register.go +++ b/apiserver/facades/agent/secretsdrain/register.go @@ -10,9 +10,19 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "SecretsDrain", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("SecretsDrain", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/secretsmanager/register.go b/apiserver/facades/agent/secretsmanager/register.go index ba90237716c..115aa0bb7e8 100644 --- a/apiserver/facades/agent/secretsmanager/register.go +++ b/apiserver/facades/agent/secretsmanager/register.go @@ -16,6 +16,7 @@ import ( "github.com/juju/juju/apiserver/common/secrets" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" coresecrets "github.com/juju/juju/core/secrets" "github.com/juju/juju/rpc/params" "github.com/juju/juju/secrets/provider" @@ -23,6 +24,15 @@ import ( "github.com/juju/juju/worker/apicaller" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "SecretsManager", + Versions: facades.FacadeVersion{1, 2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("SecretsManager", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/storageprovisioner/register.go b/apiserver/facades/agent/storageprovisioner/register.go index 59a14a7e8cb..f8ad5c0bed0 100644 --- a/apiserver/facades/agent/storageprovisioner/register.go +++ b/apiserver/facades/agent/storageprovisioner/register.go @@ -10,12 +10,22 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" + "github.com/juju/juju/core/facades" "github.com/juju/juju/environs" "github.com/juju/juju/state" "github.com/juju/juju/state/stateenvirons" "github.com/juju/juju/storage/poolmanager" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "StorageProvisioner", + Versions: facades.FacadeVersion{4}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("StorageProvisioner", 4, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/unitassigner/register.go b/apiserver/facades/agent/unitassigner/register.go index 375b87461a7..3facb3bc41c 100644 --- a/apiserver/facades/agent/unitassigner/register.go +++ b/apiserver/facades/agent/unitassigner/register.go @@ -8,8 +8,18 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "UnitAssigner", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UnitAssigner", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/uniter/register.go b/apiserver/facades/agent/uniter/register.go index e7f81eb78b5..cc1dbd55659 100644 --- a/apiserver/facades/agent/uniter/register.go +++ b/apiserver/facades/agent/uniter/register.go @@ -18,6 +18,15 @@ import ( "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Uniter", + Versions: facades.FacadeVersion{18, 19}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Uniter", 18, func(ctx facade.Context) (facade.Facade, error) { @@ -28,14 +37,6 @@ func Register(registry facade.FacadeRegistry) { }, reflect.TypeOf((*UniterAPI)(nil))) } -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.FacadeVersions { - return facades.FacadeVersions{ - "Uniter": []int{18, 19}, - } -} - func newUniterAPIv18(context facade.Context) (*UniterAPIv18, error) { api, err := newUniterAPI(context) if err != nil { diff --git a/apiserver/facades/agent/upgrader/register.go b/apiserver/facades/agent/upgrader/register.go index e67bb079d2a..bb18085a7d7 100644 --- a/apiserver/facades/agent/upgrader/register.go +++ b/apiserver/facades/agent/upgrader/register.go @@ -11,9 +11,19 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Upgrader", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Upgrader", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/upgradeseries/register.go b/apiserver/facades/agent/upgradeseries/register.go index c2c7a7036e3..0977a5ea8ee 100644 --- a/apiserver/facades/agent/upgradeseries/register.go +++ b/apiserver/facades/agent/upgradeseries/register.go @@ -10,8 +10,18 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "UpgradeSeries", + Versions: facades.FacadeVersion{3}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UpgradeSeries", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/upgradesteps/register.go b/apiserver/facades/agent/upgradesteps/register.go index 36783fd0658..97eb79d64a9 100644 --- a/apiserver/facades/agent/upgradesteps/register.go +++ b/apiserver/facades/agent/upgradesteps/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "UpgradeSteps", + Versions: facades.FacadeVersion{2}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UpgradeSteps", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/client/client/register.go b/apiserver/facades/client/client/register.go index 420aeebd904..731bf431b6b 100644 --- a/apiserver/facades/client/client/register.go +++ b/apiserver/facades/client/client/register.go @@ -7,8 +7,18 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "Client", + Versions: facades.FacadeVersion{6}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Client", 6, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/client/modelmanager/register.go b/apiserver/facades/client/modelmanager/register.go index f45d5a089d0..604eb9e28f4 100644 --- a/apiserver/facades/client/modelmanager/register.go +++ b/apiserver/facades/client/modelmanager/register.go @@ -13,10 +13,20 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" + "github.com/juju/juju/core/facades" "github.com/juju/juju/environs/context" "github.com/juju/juju/state/stateenvirons" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "ModelManager", + Versions: facades.FacadeVersion{9}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ModelManager", 9, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/controller/agenttools/register.go b/apiserver/facades/controller/agenttools/register.go index b0630a94311..4ef46fe9324 100644 --- a/apiserver/facades/controller/agenttools/register.go +++ b/apiserver/facades/controller/agenttools/register.go @@ -9,10 +9,20 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" + "github.com/juju/juju/core/facades" "github.com/juju/juju/environs" "github.com/juju/juju/state/stateenvirons" ) +// FacadesVersions returns the versions of the facades that this package +// implements. +func FacadesVersions() facades.NamedFacadeVersion { + return facades.NamedFacadeVersion{ + Name: "AgentTools", + Versions: facades.FacadeVersion{1}, + } +} + // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("AgentTools", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/controller/migrationmaster/facade_test.go b/apiserver/facades/controller/migrationmaster/facade_test.go index 5c90966070f..4f22208e39e 100644 --- a/apiserver/facades/controller/migrationmaster/facade_test.go +++ b/apiserver/facades/controller/migrationmaster/facade_test.go @@ -24,6 +24,7 @@ import ( "github.com/juju/juju/apiserver/facades/controller/migrationmaster/mocks" apiservertesting "github.com/juju/juju/apiserver/testing" "github.com/juju/juju/controller" + "github.com/juju/juju/core/facades" coremigration "github.com/juju/juju/core/migration" "github.com/juju/juju/core/network" "github.com/juju/juju/core/presence" @@ -597,6 +598,7 @@ func (s *Suite) makeAPI() (*migrationmaster.API, error) { &stubPresence{}, func(names.ModelTag) (environscloudspec.CloudSpec, error) { return s.cloudSpec, nil }, stubLeadership{}, + facades.FacadeVersions{}, ) } diff --git a/core/facades/facade.go b/core/facades/facade.go index d6a4b6fb953..ea969f64b27 100644 --- a/core/facades/facade.go +++ b/core/facades/facade.go @@ -5,25 +5,32 @@ package facades import "github.com/juju/collections/set" +// FacadeVersion is a list of version numbers for a single facade. +type FacadeVersion []int + +// NamedFacadeVersion is a map of facade name to version numbers. +type NamedFacadeVersion struct { + Name string + Versions FacadeVersion +} + // FacadeVersions is a map of facade name to version numbers. The facade version // numbers contain each version of the facade that the API server is capable of // supporting. This supports having holes in the version numbers, so that we can // depreciate broken versions of the facade. -type FacadeVersions map[string][]int +type FacadeVersions map[string]FacadeVersion // Merge adds the other facade versions to the current facade versions. -func (f FacadeVersions) Merge(others ...FacadeVersions) FacadeVersions { +func (f FacadeVersions) Add(others ...NamedFacadeVersion) FacadeVersions { for _, other := range others { - for name, versions := range other { - f[name] = set.NewInts(f[name]...).Union(set.NewInts(versions...)).SortedValues() - } + f[other.Name] = set.NewInts(f[other.Name]...).Union(set.NewInts(other.Versions...)).SortedValues() } return f } // BestVersion finds the newest version in the version list that we can // use. -func BestVersion(desired []int, versions []int) int { +func BestVersion(desired FacadeVersion, versions FacadeVersion) int { intersection := set.NewInts(desired...).Intersection(set.NewInts(versions...)) if intersection.Size() == 0 { return 0 diff --git a/core/facades/facade_test.go b/core/facades/facade_test.go index de74dfa76d5..5032cba2113 100644 --- a/core/facades/facade_test.go +++ b/core/facades/facade_test.go @@ -17,24 +17,24 @@ var _ = gc.Suite(&FacadeSuite{}) func (s *FacadeSuite) TestBestVersion(c *gc.C) { tests := []struct { - versions []int - desired []int + versions FacadeVersion + desired FacadeVersion expected int }{{ - versions: []int{1, 2, 3}, - desired: []int{1}, + versions: FacadeVersion{1, 2, 3}, + desired: FacadeVersion{1}, expected: 1, }, { - versions: []int{1, 2, 3}, - desired: []int{1, 2}, + versions: FacadeVersion{1, 2, 3}, + desired: FacadeVersion{1, 2}, expected: 2, }, { - versions: []int{1, 2, 3}, - desired: []int{1, 2, 3}, + versions: FacadeVersion{1, 2, 3}, + desired: FacadeVersion{1, 2, 3}, expected: 3, }, { - versions: []int{}, - desired: []int{0, 1, 2}, + versions: FacadeVersion{}, + desired: FacadeVersion{0, 1, 2}, expected: 0, }} for i, test := range tests { @@ -50,52 +50,52 @@ func (s *FacadeSuite) TestCompleteIntersection(c *gc.C) { expected bool }{{ src: FacadeVersions{ - "foo": []int{1, 2, 3}, + "foo": FacadeVersion{1, 2, 3}, }, dst: FacadeVersions{ - "foo": []int{1, 2, 3}, + "foo": FacadeVersion{1, 2, 3}, }, expected: true, }, { src: FacadeVersions{ - "bar": []int{1, 2, 3}, + "bar": FacadeVersion{1, 2, 3}, }, dst: FacadeVersions{ - "foo": []int{1, 2, 3}, + "foo": FacadeVersion{1, 2, 3}, }, expected: false, }, { src: FacadeVersions{ - "foo": []int{3, 4, 5}, + "foo": FacadeVersion{3, 4, 5}, }, dst: FacadeVersions{ - "foo": []int{1, 2, 3}, + "foo": FacadeVersion{1, 2, 3}, }, expected: true, }, { src: FacadeVersions{ - "foo": []int{4, 5}, + "foo": FacadeVersion{4, 5}, }, dst: FacadeVersions{ - "foo": []int{1, 2, 3}, + "foo": FacadeVersion{1, 2, 3}, }, expected: false, }, { src: FacadeVersions{ - "foo": []int{2, 3, 4}, + "foo": FacadeVersion{2, 3, 4}, }, dst: FacadeVersions{ - "foo": []int{1}, + "foo": FacadeVersion{1}, }, expected: false, }, { src: FacadeVersions{ - "foo": []int{1, 2, 3}, - "bar": []int{3}, + "foo": FacadeVersion{1, 2, 3}, + "bar": FacadeVersion{3}, }, dst: FacadeVersions{ - "foo": []int{1, 2, 3}, - "bar": []int{1, 3}, + "foo": FacadeVersion{1, 2, 3}, + "bar": FacadeVersion{1, 3}, }, expected: true, }} From 1a135fca03be513de8f4d12f0f43ae0ff4610a7e Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Mon, 13 Nov 2023 12:48:58 +0000 Subject: [PATCH 06/50] Reuse the registry to locate versions The following locates all the versions from the registry. This simplifies a lot of the versions that can drift over time. --- api/controller/migrationmaster/client.go | 15 +- api/controller/migrationtarget/client.go | 14 ++ api/facadeversions.go | 2 +- apiserver/allfacades.go | 168 +++++++++--------- apiserver/facades/agent/agent/register.go | 10 -- .../facades/agent/caasadmission/register.go | 10 -- apiserver/facades/agent/caasagent/register.go | 10 -- .../facades/agent/caasapplication/register.go | 10 -- .../facades/agent/caasoperator/register.go | 10 -- .../agent/credentialvalidator/register.go | 10 -- apiserver/facades/agent/deployer/register.go | 10 -- .../facades/agent/diskmanager/register.go | 10 -- .../facades/agent/fanconfigurer/register.go | 10 -- .../facades/agent/hostkeyreporter/register.go | 10 -- .../facades/agent/instancemutater/register.go | 10 -- .../facades/agent/keyupdater/register.go | 10 -- .../facades/agent/leadership/register.go | 10 -- apiserver/facades/agent/lifeflag/register.go | 10 -- apiserver/facades/agent/logger/register.go | 10 -- apiserver/facades/agent/machine/register.go | 10 -- .../facades/agent/machineactions/register.go | 10 -- .../facades/agent/meterstatus/register.go | 10 -- .../facades/agent/metricsadder/register.go | 10 -- .../facades/agent/migrationflag/register.go | 10 -- .../facades/agent/migrationminion/register.go | 10 -- .../agent/payloadshookcontext/register.go | 10 -- .../facades/agent/provisioner/register.go | 10 -- .../facades/agent/proxyupdater/register.go | 10 -- apiserver/facades/agent/reboot/register.go | 10 -- .../agent/resourceshookcontext/register.go | 10 -- .../facades/agent/retrystrategy/register.go | 10 -- .../facades/agent/secretsdrain/register.go | 10 -- .../facades/agent/secretsmanager/register.go | 10 -- .../agent/storageprovisioner/register.go | 10 -- .../facades/agent/unitassigner/register.go | 10 -- apiserver/facades/agent/uniter/register.go | 10 -- apiserver/facades/agent/upgrader/register.go | 10 -- .../facades/agent/upgradeseries/register.go | 10 -- .../facades/agent/upgradesteps/register.go | 10 -- apiserver/facades/client/client/register.go | 10 -- .../facades/client/modelmanager/register.go | 10 -- .../facades/controller/agenttools/register.go | 10 -- .../controller/migrationmaster/facade.go | 40 ++--- .../controller/migrationmaster/facade_test.go | 2 - .../controller/migrationmaster/register.go | 14 +- .../migrationtarget/migrationtarget.go | 76 ++++++-- .../migrationtarget/migrationtarget_test.go | 71 ++++++-- .../controller/migrationtarget/register.go | 44 +++-- apiserver/facades/schema.json | 24 ++- core/facades/facade.go | 6 +- migration/precheck.go | 4 +- rpc/params/migration.go | 14 +- 52 files changed, 315 insertions(+), 559 deletions(-) diff --git a/api/controller/migrationmaster/client.go b/api/controller/migrationmaster/client.go index 9998ea1311b..8a85a659566 100644 --- a/api/controller/migrationmaster/client.go +++ b/api/controller/migrationmaster/client.go @@ -18,7 +18,6 @@ import ( "gopkg.in/httprequest.v1" "gopkg.in/macaroon.v2" - "github.com/juju/juju/api" "github.com/juju/juju/api/base" "github.com/juju/juju/api/common" "github.com/juju/juju/core/migration" @@ -175,19 +174,7 @@ func (c *Client) SourceControllerInfo() (migration.SourceControllerInfo, []strin // Prechecks verifies that the source controller and model are healthy // and able to participate in a migration. func (c *Client) Prechecks() error { - // Pass all the known facade versions to the controller so that it - // can check that the target controller supports them. Passing all of them - // ensures that we don't have to update this code when new facades are - // added, or if the controller wants to change the logic service side. - supported := api.SupportedFacadeVersions() - versions := make(map[string][]int, len(supported)) - for name, version := range supported { - versions[name] = version - } - - return c.caller.FacadeCall("Prechecks", params.PrechecksArgs{ - FacadeVersions: versions, - }, nil) + return c.caller.FacadeCall("Prechecks", params.PrechecksArgs{}, nil) } // Export returns a serialized representation of the model associated diff --git a/api/controller/migrationtarget/client.go b/api/controller/migrationtarget/client.go index 108952716be..1331a3c9435 100644 --- a/api/controller/migrationtarget/client.go +++ b/api/controller/migrationtarget/client.go @@ -17,6 +17,7 @@ import ( "github.com/juju/version/v2" "gopkg.in/httprequest.v1" + "github.com/juju/juju/api" "github.com/juju/juju/api/base" coremigration "github.com/juju/juju/core/migration" "github.com/juju/juju/core/resources" @@ -47,13 +48,26 @@ func (c *Client) BestFacadeVersion() int { return c.caller.BestAPIVersion() } +// Prechecks checks that the target controller is able to accept the +// model being migrated. func (c *Client) Prechecks(model coremigration.ModelInfo) error { + // Pass all the known facade versions to the controller so that it + // can check that the target controller supports them. Passing all of them + // ensures that we don't have to update this code when new facades are + // added, or if the controller wants to change the logic service side. + supported := api.SupportedFacadeVersions() + versions := make(map[string][]int, len(supported)) + for name, version := range supported { + versions[name] = version + } + args := params.MigrationModelInfo{ UUID: model.UUID, Name: model.Name, OwnerTag: model.Owner.String(), AgentVersion: model.AgentVersion, ControllerAgentVersion: model.ControllerAgentVersion, + FacadeVersions: versions, } return errors.Trace(c.caller.FacadeCall("Prechecks", args, nil)) } diff --git a/api/facadeversions.go b/api/facadeversions.go index 47334cfb5c3..a9d50d77848 100644 --- a/api/facadeversions.go +++ b/api/facadeversions.go @@ -92,7 +92,7 @@ var facadeVersions = facades.FacadeVersions{ "MigrationMaster": {3}, "MigrationMinion": {1}, "MigrationStatusWatcher": {1}, - "MigrationTarget": {1, 2}, + "MigrationTarget": {1, 2, 3}, "ModelConfig": {3}, "ModelGeneration": {4}, "ModelManager": {9}, diff --git a/apiserver/allfacades.go b/apiserver/allfacades.go index e3ee0a3eadf..713bb848da3 100644 --- a/apiserver/allfacades.go +++ b/apiserver/allfacades.go @@ -45,12 +45,9 @@ import ( "github.com/juju/juju/apiserver/facades/client/action" "github.com/juju/juju/apiserver/facades/client/annotations" // ModelUser Write "github.com/juju/juju/apiserver/facades/client/application" - "github.com/juju/juju/core/facades" - - // ModelUser Write - "github.com/juju/juju/apiserver/facades/client/applicationoffers" - "github.com/juju/juju/apiserver/facades/client/backups" // ModelUser Write - "github.com/juju/juju/apiserver/facades/client/block" // ModelUser Write + "github.com/juju/juju/apiserver/facades/client/applicationoffers" // ModelUser Write + "github.com/juju/juju/apiserver/facades/client/backups" // ModelUser Write + "github.com/juju/juju/apiserver/facades/client/block" // ModelUser Write "github.com/juju/juju/apiserver/facades/client/bundle" "github.com/juju/juju/apiserver/facades/client/charms" // ModelUser Write "github.com/juju/juju/apiserver/facades/client/client" // ModelUser Write @@ -109,6 +106,7 @@ import ( "github.com/juju/juju/apiserver/facades/controller/singular" "github.com/juju/juju/apiserver/facades/controller/statushistory" "github.com/juju/juju/apiserver/facades/controller/undertaker" + "github.com/juju/juju/core/facades" ) // requiredMigrationFacadeVersions returns the facade versions that @@ -119,56 +117,60 @@ import ( // A lot of the agent facades aren't actually required, but they are // included here to keep the agent alive during migration. func requiredMigrationFacadeVersions() facades.FacadeVersions { - return facades.FacadeVersions{}.Add( - // Client and modelmanager facades are required for the migration - // master to function correctly. Missing a model manager causes the - // status to error out. - client.FacadesVersions(), - modelmanager.FacadesVersions(), + registry := new(facade.Registry) + + // Client and modelmanager facades are required for the migration + // master to function correctly. Missing a model manager causes the + // status to error out. + client.Register(registry) + modelmanager.Register(registry) + + // The following are required to keep the agent alive during + // migration. + agent.Register(registry) + caasadmission.Register(registry) + caasagent.Register(registry) + caasapplication.Register(registry) + caasoperator.Register(registry) + credentialvalidator.Register(registry) + deployer.Register(registry) + diskmanager.Register(registry) + fanconfigurer.Register(registry) + hostkeyreporter.Register(registry) + instancemutater.Register(registry) + keyupdater.Register(registry) + leadership.Register(registry) + agentlifeflag.Register(registry) + loggerapi.Register(registry) + machine.Register(registry) + machineactions.Register(registry) + meterstatus.Register(registry) + metricsadder.Register(registry) + migrationflag.Register(registry) + migrationminion.Register(registry) + payloadshookcontext.Register(registry) + provisioner.Register(registry) + proxyupdater.Register(registry) + reboot.Register(registry) + resourceshookcontext.Register(registry) + retrystrategy.Register(registry) + secretsdrain.Register(registry) + secretsmanager.Register(registry) + storageprovisioner.Register(registry) + unitassigner.Register(registry) + uniter.Register(registry) + upgrader.Register(registry) + upgradeseries.Register(registry) + upgradesteps.Register(registry) - // The following are required to keep the agent alive during - // migration. - agent.FacadesVersions(), - caasadmission.FacadesVersions(), - caasagent.FacadesVersions(), - caasapplication.FacadesVersions(), - caasoperator.FacadesVersions(), - credentialvalidator.FacadesVersions(), - deployer.FacadesVersions(), - diskmanager.FacadesVersions(), - fanconfigurer.FacadesVersions(), - hostkeyreporter.FacadesVersions(), - instancemutater.FacadesVersions(), - keyupdater.FacadesVersions(), - leadership.FacadesVersions(), - agentlifeflag.FacadesVersions(), - loggerapi.FacadesVersions(), - machine.FacadesVersions(), - machineactions.FacadesVersions(), - meterstatus.FacadesVersions(), - metricsadder.FacadesVersions(), - migrationflag.FacadesVersions(), - migrationminion.FacadesVersions(), - payloadshookcontext.FacadesVersions(), - provisioner.FacadesVersions(), - proxyupdater.FacadesVersions(), - reboot.FacadesVersions(), - resourceshookcontext.FacadesVersions(), - retrystrategy.FacadesVersions(), - secretsdrain.FacadesVersions(), - secretsmanager.FacadesVersions(), - storageprovisioner.FacadesVersions(), - unitassigner.FacadesVersions(), - uniter.FacadesVersions(), - upgrader.FacadesVersions(), - upgradeseries.FacadesVersions(), - upgradesteps.FacadesVersions(), + registerWatchers(registry) - facades.NamedFacadeVersion{ - Name: "Pinger", - Versions: facades.FacadeVersion{1}, - }, - ) + list := registry.List() + versions := make(facades.FacadeVersions, len(list)) + for _, details := range list { + versions[details.Name] = details.Versions + } + return versions } // AllFacades returns a registry containing all known API facades. @@ -244,9 +246,9 @@ func AllFacades() *facade.Registry { metricsdebug.Register(registry) metricsmanager.Register(registry) migrationflag.Register(registry) - migrationmaster.Register(requiredMigrationFacadeVersions())(registry) + migrationmaster.Register(registry) migrationminion.Register(registry) - migrationtarget.Register(registry) + migrationtarget.Register(requiredMigrationFacadeVersions())(registry) modelconfig.Register(registry) modelgeneration.Register(registry) modelmanager.Register(registry) @@ -281,6 +283,35 @@ func AllFacades() *facade.Registry { upgradesteps.Register(registry) usermanager.Register(registry) + registerWatchers(registry) + + return registry +} + +// adminAPIFactories holds methods used to create +// admin APIs with specific versions. +var adminAPIFactories = map[int]adminAPIFactory{ + 3: newAdminAPIV3, +} + +// AdminFacadeDetails returns information on the Admin facade provided +// at login time. The Facade field of the returned slice elements will +// be nil. +func AdminFacadeDetails() []facade.Details { + var fs []facade.Details + for v, f := range adminAPIFactories { + api := f(nil, nil, nil) + t := reflect.TypeOf(api) + fs = append(fs, facade.Details{ + Name: "Admin", + Version: v, + Type: t, + }) + } + return fs +} + +func registerWatchers(registry *facade.Registry) { // TODO (stickupkid): The following should be moved into a package. registry.MustRegister("Pinger", 1, func(ctx facade.Context) (facade.Facade, error) { return NewPinger(ctx) @@ -307,29 +338,4 @@ func AllFacades() *facade.Registry { registry.MustRegister("SecretsTriggerWatcher", 1, newSecretsTriggerWatcher, reflect.TypeOf((*srvSecretTriggerWatcher)(nil))) registry.MustRegister("SecretBackendsRotateWatcher", 1, newSecretBackendsRotateWatcher, reflect.TypeOf((*srvSecretBackendsRotateWatcher)(nil))) registry.MustRegister("SecretsRevisionWatcher", 1, newSecretsRevisionWatcher, reflect.TypeOf((*srvSecretsRevisionWatcher)(nil))) - - return registry -} - -// adminAPIFactories holds methods used to create -// admin APIs with specific versions. -var adminAPIFactories = map[int]adminAPIFactory{ - 3: newAdminAPIV3, -} - -// AdminFacadeDetails returns information on the Admin facade provided -// at login time. The Facade field of the returned slice elements will -// be nil. -func AdminFacadeDetails() []facade.Details { - var fs []facade.Details - for v, f := range adminAPIFactories { - api := f(nil, nil, nil) - t := reflect.TypeOf(api) - fs = append(fs, facade.Details{ - Name: "Admin", - Version: v, - Type: t, - }) - } - return fs } diff --git a/apiserver/facades/agent/agent/register.go b/apiserver/facades/agent/agent/register.go index b6458f46f03..7aa66118251 100644 --- a/apiserver/facades/agent/agent/register.go +++ b/apiserver/facades/agent/agent/register.go @@ -12,18 +12,8 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Agent", - Versions: facades.FacadeVersion{3}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Agent", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasadmission/register.go b/apiserver/facades/agent/caasadmission/register.go index d947a6f87de..14d4051741c 100644 --- a/apiserver/facades/agent/caasadmission/register.go +++ b/apiserver/facades/agent/caasadmission/register.go @@ -11,18 +11,8 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "CAASAdmission", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASAdmission", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasagent/register.go b/apiserver/facades/agent/caasagent/register.go index 3daa10a34b0..c3f22f5795d 100644 --- a/apiserver/facades/agent/caasagent/register.go +++ b/apiserver/facades/agent/caasagent/register.go @@ -12,18 +12,8 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "CAASAgent", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASAgent", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasapplication/register.go b/apiserver/facades/agent/caasapplication/register.go index 3704e511c2c..93d88239f62 100644 --- a/apiserver/facades/agent/caasapplication/register.go +++ b/apiserver/facades/agent/caasapplication/register.go @@ -10,19 +10,9 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state/stateenvirons" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "CAASApplication", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASApplication", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/caasoperator/register.go b/apiserver/facades/agent/caasoperator/register.go index 18a9a37c048..9d9e8408b47 100644 --- a/apiserver/facades/agent/caasoperator/register.go +++ b/apiserver/facades/agent/caasoperator/register.go @@ -11,19 +11,9 @@ import ( "github.com/juju/juju/apiserver/common/unitcommon" "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state/stateenvirons" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "CAASOperator", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CAASOperator", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/credentialvalidator/register.go b/apiserver/facades/agent/credentialvalidator/register.go index 83cf9ecee23..854a012b89c 100644 --- a/apiserver/facades/agent/credentialvalidator/register.go +++ b/apiserver/facades/agent/credentialvalidator/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "CredentialValidator", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("CredentialValidator", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/deployer/register.go b/apiserver/facades/agent/deployer/register.go index ac644430545..809aa7d5eec 100644 --- a/apiserver/facades/agent/deployer/register.go +++ b/apiserver/facades/agent/deployer/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Deployer", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Deployer", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/diskmanager/register.go b/apiserver/facades/agent/diskmanager/register.go index 3ebeef431e5..a0f709ccf8e 100644 --- a/apiserver/facades/agent/diskmanager/register.go +++ b/apiserver/facades/agent/diskmanager/register.go @@ -11,18 +11,8 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "DiskManager", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("DiskManager", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/fanconfigurer/register.go b/apiserver/facades/agent/fanconfigurer/register.go index ed28ee94cea..4f0a7ad2cbe 100644 --- a/apiserver/facades/agent/fanconfigurer/register.go +++ b/apiserver/facades/agent/fanconfigurer/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "FanConfigurer", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("FanConfigurer", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/hostkeyreporter/register.go b/apiserver/facades/agent/hostkeyreporter/register.go index f1b4a3fbd54..261c6fe0815 100644 --- a/apiserver/facades/agent/hostkeyreporter/register.go +++ b/apiserver/facades/agent/hostkeyreporter/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "HostKeyReporter", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("HostKeyReporter", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/instancemutater/register.go b/apiserver/facades/agent/instancemutater/register.go index 8c401a70539..a4a2c50c659 100644 --- a/apiserver/facades/agent/instancemutater/register.go +++ b/apiserver/facades/agent/instancemutater/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "InstanceMutater", - Versions: facades.FacadeVersion{3}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("InstanceMutater", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/keyupdater/register.go b/apiserver/facades/agent/keyupdater/register.go index 4287eb5a487..2a9eaa722b0 100644 --- a/apiserver/facades/agent/keyupdater/register.go +++ b/apiserver/facades/agent/keyupdater/register.go @@ -11,18 +11,8 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "KeyUpdater", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("KeyUpdater", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/leadership/register.go b/apiserver/facades/agent/leadership/register.go index 0bc23c4a5c4..f9ed626a51c 100644 --- a/apiserver/facades/agent/leadership/register.go +++ b/apiserver/facades/agent/leadership/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "LeadershipService", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("LeadershipService", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/lifeflag/register.go b/apiserver/facades/agent/lifeflag/register.go index 526b2003310..e6a6d6b561a 100644 --- a/apiserver/facades/agent/lifeflag/register.go +++ b/apiserver/facades/agent/lifeflag/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "AgentLifeFlag", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("AgentLifeFlag", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/logger/register.go b/apiserver/facades/agent/logger/register.go index c366f09a296..0763cdaebe2 100644 --- a/apiserver/facades/agent/logger/register.go +++ b/apiserver/facades/agent/logger/register.go @@ -8,18 +8,8 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Logger", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Logger", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/machine/register.go b/apiserver/facades/agent/machine/register.go index 5f98e80093d..ddd2ca4dd88 100644 --- a/apiserver/facades/agent/machine/register.go +++ b/apiserver/facades/agent/machine/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Machiner", - Versions: facades.FacadeVersion{5}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Machiner", 5, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/machineactions/register.go b/apiserver/facades/agent/machineactions/register.go index cf378e0feed..0c1c7a2da5c 100644 --- a/apiserver/facades/agent/machineactions/register.go +++ b/apiserver/facades/agent/machineactions/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "MachineActions", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MachineActions", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/meterstatus/register.go b/apiserver/facades/agent/meterstatus/register.go index fb222ad9ea1..e59f41e0441 100644 --- a/apiserver/facades/agent/meterstatus/register.go +++ b/apiserver/facades/agent/meterstatus/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "MeterStatus", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MeterStatus", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/metricsadder/register.go b/apiserver/facades/agent/metricsadder/register.go index d7dae1dcc3b..178298b6392 100644 --- a/apiserver/facades/agent/metricsadder/register.go +++ b/apiserver/facades/agent/metricsadder/register.go @@ -8,18 +8,8 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "MetricsAdder", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MetricsAdder", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/migrationflag/register.go b/apiserver/facades/agent/migrationflag/register.go index dc590b27350..9ff11fc2ce9 100644 --- a/apiserver/facades/agent/migrationflag/register.go +++ b/apiserver/facades/agent/migrationflag/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "MigrationFlag", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MigrationFlag", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/migrationminion/register.go b/apiserver/facades/agent/migrationminion/register.go index b7bd2169545..cf6134461e1 100644 --- a/apiserver/facades/agent/migrationminion/register.go +++ b/apiserver/facades/agent/migrationminion/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "MigrationMinion", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("MigrationMinion", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/payloadshookcontext/register.go b/apiserver/facades/agent/payloadshookcontext/register.go index b517f3eb483..af92f4e20f5 100644 --- a/apiserver/facades/agent/payloadshookcontext/register.go +++ b/apiserver/facades/agent/payloadshookcontext/register.go @@ -11,19 +11,9 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "PayloadsHookContext", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("PayloadsHookContext", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/provisioner/register.go b/apiserver/facades/agent/provisioner/register.go index 7cdfc764a3c..d4ecedc80af 100644 --- a/apiserver/facades/agent/provisioner/register.go +++ b/apiserver/facades/agent/provisioner/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Provisioner", - Versions: facades.FacadeVersion{11}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Provisioner", 11, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/proxyupdater/register.go b/apiserver/facades/agent/proxyupdater/register.go index 3ef2284a82e..413d4547d38 100644 --- a/apiserver/facades/agent/proxyupdater/register.go +++ b/apiserver/facades/agent/proxyupdater/register.go @@ -9,18 +9,8 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "ProxyUpdater", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ProxyUpdater", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/reboot/register.go b/apiserver/facades/agent/reboot/register.go index 4760f408715..595f9e24986 100644 --- a/apiserver/facades/agent/reboot/register.go +++ b/apiserver/facades/agent/reboot/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Reboot", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Reboot", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/resourceshookcontext/register.go b/apiserver/facades/agent/resourceshookcontext/register.go index c7ba4ef6cf8..e69486b42d3 100644 --- a/apiserver/facades/agent/resourceshookcontext/register.go +++ b/apiserver/facades/agent/resourceshookcontext/register.go @@ -11,19 +11,9 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "ResourcesHookContext", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ResourcesHookContext", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/retrystrategy/register.go b/apiserver/facades/agent/retrystrategy/register.go index e4d6be02166..045e1d8e9c0 100644 --- a/apiserver/facades/agent/retrystrategy/register.go +++ b/apiserver/facades/agent/retrystrategy/register.go @@ -11,18 +11,8 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "RetryStrategy", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("RetryStrategy", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/secretsdrain/register.go b/apiserver/facades/agent/secretsdrain/register.go index ad28be3d4a6..16f5bdb2eae 100644 --- a/apiserver/facades/agent/secretsdrain/register.go +++ b/apiserver/facades/agent/secretsdrain/register.go @@ -10,19 +10,9 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "SecretsDrain", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("SecretsDrain", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/secretsmanager/register.go b/apiserver/facades/agent/secretsmanager/register.go index 115aa0bb7e8..ba90237716c 100644 --- a/apiserver/facades/agent/secretsmanager/register.go +++ b/apiserver/facades/agent/secretsmanager/register.go @@ -16,7 +16,6 @@ import ( "github.com/juju/juju/apiserver/common/secrets" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" coresecrets "github.com/juju/juju/core/secrets" "github.com/juju/juju/rpc/params" "github.com/juju/juju/secrets/provider" @@ -24,15 +23,6 @@ import ( "github.com/juju/juju/worker/apicaller" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "SecretsManager", - Versions: facades.FacadeVersion{1, 2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("SecretsManager", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/storageprovisioner/register.go b/apiserver/facades/agent/storageprovisioner/register.go index f8ad5c0bed0..59a14a7e8cb 100644 --- a/apiserver/facades/agent/storageprovisioner/register.go +++ b/apiserver/facades/agent/storageprovisioner/register.go @@ -10,22 +10,12 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" - "github.com/juju/juju/core/facades" "github.com/juju/juju/environs" "github.com/juju/juju/state" "github.com/juju/juju/state/stateenvirons" "github.com/juju/juju/storage/poolmanager" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "StorageProvisioner", - Versions: facades.FacadeVersion{4}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("StorageProvisioner", 4, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/unitassigner/register.go b/apiserver/facades/agent/unitassigner/register.go index 3facb3bc41c..375b87461a7 100644 --- a/apiserver/facades/agent/unitassigner/register.go +++ b/apiserver/facades/agent/unitassigner/register.go @@ -8,18 +8,8 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "UnitAssigner", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UnitAssigner", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/uniter/register.go b/apiserver/facades/agent/uniter/register.go index cc1dbd55659..a6ed822e6c1 100644 --- a/apiserver/facades/agent/uniter/register.go +++ b/apiserver/facades/agent/uniter/register.go @@ -15,18 +15,8 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/apiserver/facades/agent/meterstatus" "github.com/juju/juju/apiserver/facades/agent/secretsmanager" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Uniter", - Versions: facades.FacadeVersion{18, 19}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Uniter", 18, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/upgrader/register.go b/apiserver/facades/agent/upgrader/register.go index bb18085a7d7..e67bb079d2a 100644 --- a/apiserver/facades/agent/upgrader/register.go +++ b/apiserver/facades/agent/upgrader/register.go @@ -11,19 +11,9 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/state" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Upgrader", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Upgrader", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/upgradeseries/register.go b/apiserver/facades/agent/upgradeseries/register.go index 0977a5ea8ee..c2c7a7036e3 100644 --- a/apiserver/facades/agent/upgradeseries/register.go +++ b/apiserver/facades/agent/upgradeseries/register.go @@ -10,18 +10,8 @@ import ( "github.com/juju/juju/apiserver/common" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "UpgradeSeries", - Versions: facades.FacadeVersion{3}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UpgradeSeries", 3, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/agent/upgradesteps/register.go b/apiserver/facades/agent/upgradesteps/register.go index 97eb79d64a9..36783fd0658 100644 --- a/apiserver/facades/agent/upgradesteps/register.go +++ b/apiserver/facades/agent/upgradesteps/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "UpgradeSteps", - Versions: facades.FacadeVersion{2}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("UpgradeSteps", 2, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/client/client/register.go b/apiserver/facades/client/client/register.go index 731bf431b6b..420aeebd904 100644 --- a/apiserver/facades/client/client/register.go +++ b/apiserver/facades/client/client/register.go @@ -7,18 +7,8 @@ import ( "reflect" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "Client", - Versions: facades.FacadeVersion{6}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("Client", 6, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/client/modelmanager/register.go b/apiserver/facades/client/modelmanager/register.go index 604eb9e28f4..f45d5a089d0 100644 --- a/apiserver/facades/client/modelmanager/register.go +++ b/apiserver/facades/client/modelmanager/register.go @@ -13,20 +13,10 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" - "github.com/juju/juju/core/facades" "github.com/juju/juju/environs/context" "github.com/juju/juju/state/stateenvirons" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "ModelManager", - Versions: facades.FacadeVersion{9}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("ModelManager", 9, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/controller/agenttools/register.go b/apiserver/facades/controller/agenttools/register.go index 4ef46fe9324..b0630a94311 100644 --- a/apiserver/facades/controller/agenttools/register.go +++ b/apiserver/facades/controller/agenttools/register.go @@ -9,20 +9,10 @@ import ( "github.com/juju/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/environs" "github.com/juju/juju/state/stateenvirons" ) -// FacadesVersions returns the versions of the facades that this package -// implements. -func FacadesVersions() facades.NamedFacadeVersion { - return facades.NamedFacadeVersion{ - Name: "AgentTools", - Versions: facades.FacadeVersion{1}, - } -} - // Register is called to expose a package of facades onto a given registry. func Register(registry facade.FacadeRegistry) { registry.MustRegister("AgentTools", 1, func(ctx facade.Context) (facade.Facade, error) { diff --git a/apiserver/facades/controller/migrationmaster/facade.go b/apiserver/facades/controller/migrationmaster/facade.go index 3b6b0a63e9f..2f00740c16c 100644 --- a/apiserver/facades/controller/migrationmaster/facade.go +++ b/apiserver/facades/controller/migrationmaster/facade.go @@ -16,7 +16,6 @@ import ( "github.com/juju/juju/apiserver/common" apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/core/leadership" coremigration "github.com/juju/juju/core/migration" coremodel "github.com/juju/juju/core/model" @@ -29,16 +28,15 @@ import ( // API implements the API required for the model migration // master worker. type API struct { - controllerState ControllerState - backend Backend - precheckBackend migration.PrecheckBackend - pool migration.Pool - authorizer facade.Authorizer - resources facade.Resources - presence facade.Presence - environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error) - leadership leadership.Reader - requiredMigrationFacadeVersions facades.FacadeVersions + controllerState ControllerState + backend Backend + precheckBackend migration.PrecheckBackend + pool migration.Pool + authorizer facade.Authorizer + resources facade.Resources + presence facade.Presence + environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error) + leadership leadership.Reader } // NewAPI creates a new API server endpoint for the model migration @@ -53,22 +51,20 @@ func NewAPI( presence facade.Presence, environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error), leadership leadership.Reader, - requiredMigrationFacadeVersions facades.FacadeVersions, ) (*API, error) { if !authorizer.AuthController() { return nil, apiservererrors.ErrPerm } return &API{ - controllerState: controllerState, - backend: backend, - precheckBackend: precheckBackend, - pool: pool, - authorizer: authorizer, - resources: resources, - presence: presence, - environscloudspecGetter: environscloudspecGetter, - leadership: leadership, - requiredMigrationFacadeVersions: requiredMigrationFacadeVersions, + controllerState: controllerState, + backend: backend, + precheckBackend: precheckBackend, + pool: pool, + authorizer: authorizer, + resources: resources, + presence: presence, + environscloudspecGetter: environscloudspecGetter, + leadership: leadership, }, nil } diff --git a/apiserver/facades/controller/migrationmaster/facade_test.go b/apiserver/facades/controller/migrationmaster/facade_test.go index 4f22208e39e..5c90966070f 100644 --- a/apiserver/facades/controller/migrationmaster/facade_test.go +++ b/apiserver/facades/controller/migrationmaster/facade_test.go @@ -24,7 +24,6 @@ import ( "github.com/juju/juju/apiserver/facades/controller/migrationmaster/mocks" apiservertesting "github.com/juju/juju/apiserver/testing" "github.com/juju/juju/controller" - "github.com/juju/juju/core/facades" coremigration "github.com/juju/juju/core/migration" "github.com/juju/juju/core/network" "github.com/juju/juju/core/presence" @@ -598,7 +597,6 @@ func (s *Suite) makeAPI() (*migrationmaster.API, error) { &stubPresence{}, func(names.ModelTag) (environscloudspec.CloudSpec, error) { return s.cloudSpec, nil }, stubLeadership{}, - facades.FacadeVersions{}, ) } diff --git a/apiserver/facades/controller/migrationmaster/register.go b/apiserver/facades/controller/migrationmaster/register.go index e1ae17e739c..75f9935aff4 100644 --- a/apiserver/facades/controller/migrationmaster/register.go +++ b/apiserver/facades/controller/migrationmaster/register.go @@ -10,22 +10,19 @@ import ( "github.com/juju/juju/apiserver/common/cloudspec" "github.com/juju/juju/apiserver/facade" - "github.com/juju/juju/core/facades" "github.com/juju/juju/migration" ) // Register is called to expose a package of facades onto a given registry. -func Register(requiredMigrationFacadeVersions facades.FacadeVersions) func(registry facade.FacadeRegistry) { - return func(registry facade.FacadeRegistry) { - registry.MustRegister("MigrationMaster", 3, func(ctx facade.Context) (facade.Facade, error) { - return newMigrationMasterFacade(ctx, requiredMigrationFacadeVersions) // Adds MinionReportTimeout. - }, reflect.TypeOf((*API)(nil))) - } +func Register(registry facade.FacadeRegistry) { + registry.MustRegister("MigrationMaster", 3, func(ctx facade.Context) (facade.Facade, error) { + return newMigrationMasterFacade(ctx) // Adds MinionReportTimeout. + }, reflect.TypeOf((*API)(nil))) } // newMigrationMasterFacade exists to provide the required signature for API // registration, converting st to backend. -func newMigrationMasterFacade(ctx facade.Context, requiredMigrationFacadeVersions facades.FacadeVersions) (*API, error) { +func newMigrationMasterFacade(ctx facade.Context) (*API, error) { pool := ctx.StatePool() modelState := ctx.State() @@ -54,6 +51,5 @@ func newMigrationMasterFacade(ctx facade.Context, requiredMigrationFacadeVersion ctx.Presence(), cloudspec.MakeCloudSpecGetter(pool), leadership, - requiredMigrationFacadeVersions, ) } diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget.go b/apiserver/facades/controller/migrationtarget/migrationtarget.go index f5e81cd8bff..2301dba4974 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget.go @@ -4,6 +4,7 @@ package migrationtarget import ( + "fmt" "time" "github.com/juju/errors" @@ -13,6 +14,7 @@ import ( apiservererrors "github.com/juju/juju/apiserver/errors" "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/core/crossmodel" + "github.com/juju/juju/core/facades" coremigration "github.com/juju/juju/core/migration" "github.com/juju/juju/core/permission" "github.com/juju/juju/core/status" @@ -27,14 +29,15 @@ import ( // API implements the API required for the model migration // master worker when communicating with the target controller. type API struct { - state *state.State - pool *state.StatePool - authorizer facade.Authorizer - resources facade.Resources - presence facade.Presence - getClaimer migration.ClaimerFunc - getEnviron stateenvirons.NewEnvironFunc - getCAASBroker stateenvirons.NewCAASBrokerFunc + state *state.State + pool *state.StatePool + authorizer facade.Authorizer + resources facade.Resources + presence facade.Presence + getClaimer migration.ClaimerFunc + getEnviron stateenvirons.NewEnvironFunc + getCAASBroker stateenvirons.NewCAASBrokerFunc + requiredMigrationFacadeVersions facades.FacadeVersions } // APIV1 implements the V1 version of the API facade. @@ -42,23 +45,34 @@ type APIV1 struct { *API } +// APIV2 implements the V2 version of the API facade. +type APIV2 struct { + *APIV1 +} + // NewAPI returns a new APIV1. Accepts a NewEnvironFunc and context.ProviderCallContext // for testing purposes. -func NewAPI(ctx facade.Context, getEnviron stateenvirons.NewEnvironFunc, getCAASBroker stateenvirons.NewCAASBrokerFunc) (*API, error) { +func NewAPI( + ctx facade.Context, + getEnviron stateenvirons.NewEnvironFunc, + getCAASBroker stateenvirons.NewCAASBrokerFunc, + requiredMigrationFacadeVersions facades.FacadeVersions, +) (*API, error) { auth := ctx.Auth() st := ctx.State() if err := checkAuth(auth, st); err != nil { return nil, errors.Trace(err) } return &API{ - state: st, - pool: ctx.StatePool(), - authorizer: auth, - resources: ctx.Resources(), - presence: ctx.Presence(), - getClaimer: ctx.LeadershipClaimer, - getEnviron: getEnviron, - getCAASBroker: getCAASBroker, + state: st, + pool: ctx.StatePool(), + authorizer: auth, + resources: ctx.Resources(), + presence: ctx.Presence(), + getClaimer: ctx.LeadershipClaimer, + getEnviron: getEnviron, + getCAASBroker: getCAASBroker, + requiredMigrationFacadeVersions: requiredMigrationFacadeVersions, }, nil } @@ -79,6 +93,34 @@ func checkAuth(authorizer facade.Authorizer, st *state.State) error { // Prechecks ensure that the target controller is ready to accept a // model migration. func (api *API) Prechecks(model params.MigrationModelInfo) error { + // If there are no required migration facade versions, then we + // don't need to check anything. + if len(api.requiredMigrationFacadeVersions) > 0 { + // Ensure that when attempting to migrate a model, the source + // controller has the required facades for the migration. + sourceFacadeVersions := facades.FacadeVersions{} + for name, versions := range model.FacadeVersions { + sourceFacadeVersions[name] = versions + } + if !facades.CompleteIntersection(api.requiredMigrationFacadeVersions, sourceFacadeVersions) { + majorMinor := fmt.Sprintf("%d.%d", + model.ControllerAgentVersion.Major, + model.ControllerAgentVersion.Minor, + ) + + // If the patch is zero, then we don't need to mention it. + var patchMessage string + if model.ControllerAgentVersion.Patch > 0 { + patchMessage = fmt.Sprintf(", that is greater than %s.%d", majorMinor, model.ControllerAgentVersion.Patch) + } + + return errors.Errorf(` +Source controller does not support required facades for performing migration. +Upgrade the controller to a newer version of %s%s and try again. +`[1:], majorMinor, patchMessage) + } + } + ownerTag, err := names.ParseUserTag(model.OwnerTag) if err != nil { return errors.Trace(err) diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go index 940d8c2ef20..ea6c2b127da 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go @@ -25,6 +25,7 @@ import ( "github.com/juju/juju/caas" "github.com/juju/juju/cloud" "github.com/juju/juju/core/crossmodel" + "github.com/juju/juju/core/facades" "github.com/juju/juju/core/instance" "github.com/juju/juju/core/leadership" "github.com/juju/juju/environs" @@ -104,11 +105,11 @@ func (s *Suite) TestNotControllerAdmin(c *gc.C) { c.Assert(errors.Cause(err), gc.Equals, apiservererrors.ErrPerm) } -func (s *Suite) importModel(c *gc.C, api *migrationtarget.API) names.ModelTag { - uuid, bytes := s.makeExportedModel(c) - err := api.Import(params.SerializedModel{Bytes: bytes}) +func (s *Suite) TestCACert(c *gc.C) { + api := s.mustNewAPI(c) + r, err := api.CACert() c.Assert(err, jc.ErrorIsNil) - return names.NewModelTag(uuid) + c.Assert(string(r.Result), gc.Equals, jujutesting.CACert) } func (s *Suite) TestPrechecks(c *gc.C) { @@ -124,13 +125,6 @@ func (s *Suite) TestPrechecks(c *gc.C) { c.Assert(err, jc.ErrorIsNil) } -func (s *Suite) TestCACert(c *gc.C) { - api := s.mustNewAPI(c) - r, err := api.CACert() - c.Assert(err, jc.ErrorIsNil) - c.Assert(string(r.Result), gc.Equals, jujutesting.CACert) -} - func (s *Suite) TestPrechecksFail(c *gc.C) { controllerVersion := s.controllerVersion(c) @@ -146,6 +140,41 @@ func (s *Suite) TestPrechecksFail(c *gc.C) { c.Assert(err, gc.NotNil) } +func (s *Suite) TestPrechecksFacadeVersionsFail(c *gc.C) { + controllerVersion := s.controllerVersion(c) + + api := s.mustNewAPIWithFacadeVersions(c, facades.FacadeVersions{ + "MigrationTarget": []int{1}, + }) + args := params.MigrationModelInfo{ + AgentVersion: controllerVersion, + ControllerAgentVersion: controllerVersion, + } + err := api.Prechecks(args) + c.Assert(err, gc.ErrorMatches, ` +Source controller does not support required facades for performing migration. +Upgrade the controller to a newer version of .* and try again. +`[1:]) +} + +func (s *Suite) TestPrechecksFacadeVersionsWithPatchFail(c *gc.C) { + controllerVersion := s.controllerVersion(c) + controllerVersion.Patch++ + + api := s.mustNewAPIWithFacadeVersions(c, facades.FacadeVersions{ + "MigrationTarget": []int{1}, + }) + args := params.MigrationModelInfo{ + AgentVersion: controllerVersion, + ControllerAgentVersion: controllerVersion, + } + err := api.Prechecks(args) + c.Assert(err, gc.ErrorMatches, ` +Source controller does not support required facades for performing migration. +Upgrade the controller to a newer version of .* and try again. +`[1:]) +} + func (s *Suite) TestImport(c *gc.C) { api := s.mustNewAPI(c) tag := s.importModel(c, api) @@ -490,7 +519,7 @@ func (s *Suite) TestCheckMachinesManualCloud(c *gc.C) { } func (s *Suite) newAPI(environFunc stateenvirons.NewEnvironFunc, brokerFunc stateenvirons.NewCAASBrokerFunc) (*migrationtarget.API, error) { - api, err := migrationtarget.NewAPI(&s.facadeContext, environFunc, brokerFunc) + api, err := migrationtarget.NewAPI(&s.facadeContext, environFunc, brokerFunc, facades.FacadeVersions{}) return api, err } @@ -500,6 +529,17 @@ func (s *Suite) mustNewAPI(c *gc.C) *migrationtarget.API { return api } +func (s *Suite) newAPIWithFacadeVersions(environFunc stateenvirons.NewEnvironFunc, brokerFunc stateenvirons.NewCAASBrokerFunc, versions facades.FacadeVersions) (*migrationtarget.API, error) { + api, err := migrationtarget.NewAPI(&s.facadeContext, environFunc, brokerFunc, versions) + return api, err +} + +func (s *Suite) mustNewAPIWithFacadeVersions(c *gc.C, versions facades.FacadeVersions) *migrationtarget.API { + api, err := s.newAPIWithFacadeVersions(nil, nil, versions) + c.Assert(err, jc.ErrorIsNil) + return api +} + func (s *Suite) mustNewAPIWithModel(c *gc.C, env environs.Environ, broker caas.Broker) *migrationtarget.API { api, err := s.newAPI(func(stateenvirons.Model) (environs.Environ, error) { return env, nil @@ -533,6 +573,13 @@ func (s *Suite) controllerVersion(c *gc.C) version.Number { return vers } +func (s *Suite) importModel(c *gc.C, api *migrationtarget.API) names.ModelTag { + uuid, bytes := s.makeExportedModel(c) + err := api.Import(params.SerializedModel{Bytes: bytes}) + c.Assert(err, jc.ErrorIsNil) + return names.NewModelTag(uuid) +} + type mockEnv struct { environs.Environ *testing.Stub diff --git a/apiserver/facades/controller/migrationtarget/register.go b/apiserver/facades/controller/migrationtarget/register.go index 2275e868b46..b810369b683 100644 --- a/apiserver/facades/controller/migrationtarget/register.go +++ b/apiserver/facades/controller/migrationtarget/register.go @@ -10,18 +10,24 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/caas" + "github.com/juju/juju/core/facades" "github.com/juju/juju/environs" "github.com/juju/juju/state/stateenvirons" ) // Register is called to expose a package of facades onto a given registry. -func Register(registry facade.FacadeRegistry) { - registry.MustRegister("MigrationTarget", 1, func(ctx facade.Context) (facade.Facade, error) { - return newFacadeV1(ctx) - }, reflect.TypeOf((*APIV1)(nil))) - registry.MustRegister("MigrationTarget", 2, func(ctx facade.Context) (facade.Facade, error) { - return newFacade(ctx) - }, reflect.TypeOf((*API)(nil))) +func Register(requiredMigrationFacadeVersions facades.FacadeVersions) func(registry facade.FacadeRegistry) { + return func(registry facade.FacadeRegistry) { + registry.MustRegister("MigrationTarget", 1, func(ctx facade.Context) (facade.Facade, error) { + return newFacadeV1(ctx) + }, reflect.TypeOf((*APIV1)(nil))) + registry.MustRegister("MigrationTarget", 2, func(ctx facade.Context) (facade.Facade, error) { + return newFacadeV2(ctx) + }, reflect.TypeOf((*APIV2)(nil))) + registry.MustRegister("MigrationTarget", 3, func(ctx facade.Context) (facade.Facade, error) { + return newFacade(ctx, requiredMigrationFacadeVersions) + }, reflect.TypeOf((*API)(nil))) + } } // newFacadeV1 is used for APIV1 registration. @@ -29,17 +35,35 @@ func newFacadeV1(ctx facade.Context) (*APIV1, error) { api, err := NewAPI( ctx, stateenvirons.GetNewEnvironFunc(environs.New), - stateenvirons.GetNewCAASBrokerFunc(caas.New)) + stateenvirons.GetNewCAASBrokerFunc(caas.New), + facades.FacadeVersions{}, + ) if err != nil { return nil, errors.Trace(err) } return &APIV1{API: api}, nil } +// newFacadeV2 is used for APIV2 registration. +func newFacadeV2(ctx facade.Context) (*APIV2, error) { + api, err := NewAPI( + ctx, + stateenvirons.GetNewEnvironFunc(environs.New), + stateenvirons.GetNewCAASBrokerFunc(caas.New), + facades.FacadeVersions{}, + ) + if err != nil { + return nil, errors.Trace(err) + } + return &APIV2{APIV1: &APIV1{API: api}}, nil +} + // newFacade is used for API registration. -func newFacade(ctx facade.Context) (*API, error) { +func newFacade(ctx facade.Context, facadeVersions facades.FacadeVersions) (*API, error) { return NewAPI( ctx, stateenvirons.GetNewEnvironFunc(environs.New), - stateenvirons.GetNewCAASBrokerFunc(caas.New)) + stateenvirons.GetNewCAASBrokerFunc(caas.New), + facadeVersions, + ) } diff --git a/apiserver/facades/schema.json b/apiserver/facades/schema.json index cf02cdeb4b3..820563a6778 100644 --- a/apiserver/facades/schema.json +++ b/apiserver/facades/schema.json @@ -30052,6 +30052,17 @@ "controller-agent-version": { "$ref": "#/definitions/Number" }, + "facade-versions": { + "type": "object", + "patternProperties": { + ".*": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "name": { "type": "string" }, @@ -30604,7 +30615,7 @@ { "Name": "MigrationTarget", "Description": "API implements the API required for the model migration\nmaster worker when communicating with the target controller.", - "Version": 2, + "Version": 3, "AvailableTo": [ "controller-user" ], @@ -30818,6 +30829,17 @@ "controller-agent-version": { "$ref": "#/definitions/Number" }, + "facade-versions": { + "type": "object", + "patternProperties": { + ".*": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "name": { "type": "string" }, diff --git a/core/facades/facade.go b/core/facades/facade.go index ea969f64b27..f704bc56cb6 100644 --- a/core/facades/facade.go +++ b/core/facades/facade.go @@ -3,7 +3,9 @@ package facades -import "github.com/juju/collections/set" +import ( + "github.com/juju/collections/set" +) // FacadeVersion is a list of version numbers for a single facade. type FacadeVersion []int @@ -42,6 +44,8 @@ func BestVersion(desired FacadeVersion, versions FacadeVersion) int { // CompleteIntersection returns true if the src and dest facades have a // complete intersection. This means that the dest facades support all of // the src facades. +// src is the facades that are required, dest is the full set of facades +// that are supported. func CompleteIntersection(src, dest FacadeVersions) bool { for name, versions := range src { if _, ok := dest[name]; !ok { diff --git a/migration/precheck.go b/migration/precheck.go index a3755b9dbae..9280d7c0b61 100644 --- a/migration/precheck.go +++ b/migration/precheck.go @@ -98,8 +98,8 @@ func TargetPrecheck(backend PrecheckBackend, pool Pool, modelInfo coremigration. modelInfo.ControllerAgentVersion, controllerVersion) } - // The MigrateToAllowed check is the same as validating if a model can be migrated - // to a controller running a newer Juju version. + // The MigrateToAllowed check is the same as validating if a model can be + // migrated to a controller running a newer Juju version. allowed, minVer, err := upgradevalidation.MigrateToAllowed(modelInfo.AgentVersion, controllerVersion) if err != nil { return errors.Maskf(err, "unknown target controller version %v", controllerVersion) diff --git a/rpc/params/migration.go b/rpc/params/migration.go index 72ad8d426d1..1926802b328 100644 --- a/rpc/params/migration.go +++ b/rpc/params/migration.go @@ -78,8 +78,7 @@ type SetMigrationStatusMessageArgs struct { // PrechecksArgs provides the target controller version // to the migrationmaster.Prechecks API method. type PrechecksArgs struct { - TargetControllerVersion version.Number `json:"target-controller-version"` - FacadeVersions map[string][]int `json:"facade-versions"` + TargetControllerVersion version.Number `json:"target-controller-version"` } // SerializedModel wraps a buffer contain a serialised Juju model. It @@ -164,11 +163,12 @@ type MasterMigrationStatus struct { // MigrationModelInfo is used to report basic model information to the // migrationmaster worker. type MigrationModelInfo struct { - UUID string `json:"uuid"` - Name string `json:"name"` - OwnerTag string `json:"owner-tag"` - AgentVersion version.Number `json:"agent-version"` - ControllerAgentVersion version.Number `json:"controller-agent-version"` + UUID string `json:"uuid"` + Name string `json:"name"` + OwnerTag string `json:"owner-tag"` + AgentVersion version.Number `json:"agent-version"` + ControllerAgentVersion version.Number `json:"controller-agent-version"` + FacadeVersions map[string][]int `json:"facade-versions,omitempty"` } // MigrationStatus reports the current status of a model migration. From 7ac215b7446c7b431c8c90fffbec1e5071af410c Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Thu, 16 Nov 2023 12:27:11 +0000 Subject: [PATCH 07/50] Ensure we handle the facade versions in the client Add tests to ensure that we see the facade versions, but we don't care what is in the facade versions. --- api/controller/migrationtarget/client_test.go | 11 +++-- api/export_test.go | 1 + api/facadeversions_test.go | 10 ++--- api/package_test.go | 3 +- .../migrationtarget/migrationtarget_test.go | 15 ++++++- cmd/containeragent/initialize/package_test.go | 1 + worker/migrationmaster/worker_test.go | 40 +++++++++++++++++-- 7 files changed, 67 insertions(+), 14 deletions(-) diff --git a/api/controller/migrationtarget/client_test.go b/api/controller/migrationtarget/client_test.go index f2b19df472d..f88d23b92df 100644 --- a/api/controller/migrationtarget/client_test.go +++ b/api/controller/migrationtarget/client_test.go @@ -74,9 +74,14 @@ func (s *ClientSuite) TestPrechecks(c *gc.C) { AgentVersion: vers, ControllerAgentVersion: controllerVers, } - stub.CheckCalls(c, []jujutesting.StubCall{ - {FuncName: "MigrationTarget.Prechecks", Args: []interface{}{"", expectedArg}}, - }) + stub.CheckCallNames(c, "MigrationTarget.Prechecks") + + arg := stub.Calls()[0].Args[1].(params.MigrationModelInfo) + + mc := jc.NewMultiChecker() + mc.AddExpr("_.FacadeVersions", gc.Not(gc.HasLen), 0) + + c.Assert(arg, mc, expectedArg) } func (s *ClientSuite) TestImport(c *gc.C) { diff --git a/api/export_test.go b/api/export_test.go index cb67796ec21..6eaccb980f8 100644 --- a/api/export_test.go +++ b/api/export_test.go @@ -21,6 +21,7 @@ import ( var ( CertDir = &certDir SlideAddressToFront = slideAddressToFront + FacadeVersions = &facadeVersions ) func DialAPI(info *Info, opts DialOpts) (jsoncodec.JSONConn, string, error) { diff --git a/api/facadeversions_test.go b/api/facadeversions_test.go index 68b45549b1f..4d7df7fcfb0 100644 --- a/api/facadeversions_test.go +++ b/api/facadeversions_test.go @@ -32,7 +32,7 @@ func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) { } allServerFacades := apiserver.AllFacades().List() serverFacadeNames := set.NewStrings() - serverFacadeBestVersions := make(map[string][]int, len(allServerFacades)) + serverFacadeBestVersions := make(facades.FacadeVersions, len(allServerFacades)) for _, facade := range allServerFacades { serverFacadeNames.Add(facade.Name) serverFacadeBestVersions[facade.Name] = facade.Versions @@ -79,7 +79,7 @@ func (*facadeVersionSuite) TestBestVersionNotSorted(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionExactMatch(c *gc.C) { - s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1}}) + s.PatchValue(api.FacadeVersions, map[string]facades.FacadeVersion{"Client": {1}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, @@ -88,7 +88,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionExactMatch(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionNewerServer(c *gc.C) { - s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1}}) + s.PatchValue(api.FacadeVersions, map[string]facades.FacadeVersion{"Client": {1}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1, 2}, @@ -97,7 +97,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionNewerServer(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionNewerClient(c *gc.C) { - s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"Client": {1, 2}}) + s.PatchValue(api.FacadeVersions, map[string]facades.FacadeVersion{"Client": {1, 2}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, @@ -106,7 +106,7 @@ func (s *facadeVersionSuite) TestBestFacadeVersionNewerClient(c *gc.C) { } func (s *facadeVersionSuite) TestBestFacadeVersionServerUnknown(c *gc.C) { - s.PatchValue(api.SupportedFacadeVersions(), map[string][]int{"TestingAPI": {1, 2}}) + s.PatchValue(api.FacadeVersions, map[string]facades.FacadeVersion{"TestingAPI": {1, 2}}) st := api.NewTestingState(api.TestingStateParams{ FacadeVersions: map[string][]int{ "Client": {0, 1}, diff --git a/api/package_test.go b/api/package_test.go index eaaf6761e50..89d223696f9 100644 --- a/api/package_test.go +++ b/api/package_test.go @@ -27,8 +27,10 @@ func (*ImportSuite) TestImports(c *gc.C) { "api/agent/keyupdater", "api/base", "api/watcher", + "core/base", "core/constraints", "core/devices", + "core/facades", "core/instance", "core/life", "core/macaroon", @@ -40,7 +42,6 @@ func (*ImportSuite) TestImports(c *gc.C) { "core/relation", "core/resources", "core/secrets", - "core/base", "core/status", "core/watcher", "docker", diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go index ea6c2b127da..630ad79e6e7 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go @@ -81,7 +81,7 @@ func (s *Suite) SetUpTest(c *gc.C) { } func (s *Suite) TestFacadeRegistered(c *gc.C) { - aFactory, err := apiserver.AllFacades().GetFactory("MigrationTarget", 2) + aFactory, err := apiserver.AllFacades().GetFactory("MigrationTarget", 3) c.Assert(err, jc.ErrorIsNil) api, err := aFactory(&facadetest.Context{ @@ -93,6 +93,19 @@ func (s *Suite) TestFacadeRegistered(c *gc.C) { c.Assert(api, gc.FitsTypeOf, new(migrationtarget.API)) } +func (s *Suite) TestFacadeRegisteredV2(c *gc.C) { + aFactory, err := apiserver.AllFacades().GetFactory("MigrationTarget", 2) + c.Assert(err, jc.ErrorIsNil) + + api, err := aFactory(&facadetest.Context{ + State_: s.State, + Resources_: s.resources, + Auth_: s.authorizer, + }) + c.Assert(err, jc.ErrorIsNil) + c.Assert(api, gc.FitsTypeOf, new(migrationtarget.APIV2)) +} + func (s *Suite) TestNotUser(c *gc.C) { s.authorizer.Tag = names.NewMachineTag("0") _, err := s.newAPI(nil, nil) diff --git a/cmd/containeragent/initialize/package_test.go b/cmd/containeragent/initialize/package_test.go index 7ec4f7c80b7..dc6c7583275 100644 --- a/cmd/containeragent/initialize/package_test.go +++ b/cmd/containeragent/initialize/package_test.go @@ -51,6 +51,7 @@ func (*importSuite) TestImports(c *gc.C) { "core/charm/metrics", "core/constraints", "core/devices", + "core/facades", "core/instance", "core/leadership", "core/lease", diff --git a/worker/migrationmaster/worker_test.go b/worker/migrationmaster/worker_test.go index 62ca45cdde5..c03a66165a4 100644 --- a/worker/migrationmaster/worker_test.go +++ b/worker/migrationmaster/worker_test.go @@ -228,7 +228,7 @@ func (s *Suite) TestSuccessfulMigration(c *gc.C) { // Observe that the migration was seen, the model exported, an API // connection to the target controller was made, the model was // imported and then the migration completed. - s.stub.CheckCalls(c, joinCalls( + assertExpectedCallArgs(c, s.stub, joinCalls( // Wait for migration to start. watchStatusLockdownCalls, []jujutesting.StubCall{ @@ -457,7 +457,8 @@ func (s *Suite) TestQUIESCEFailedAgent(c *gc.C) { }) s.checkWorkerReturns(c, migrationmaster.ErrInactive) - s.stub.CheckCalls(c, joinCalls( + + expectedCalls := joinCalls( watchStatusLockdownCalls, []jujutesting.StubCall{ {"facade.MinionReportTimeout", nil}, @@ -468,7 +469,9 @@ func (s *Suite) TestQUIESCEFailedAgent(c *gc.C) { {"facade.MinionReports", nil}, }, abortCalls, - )) + ) + + assertExpectedCallArgs(c, s.stub, expectedCalls) } func (s *Suite) TestQUIESCEWrongController(c *gc.C) { @@ -525,7 +528,7 @@ func (s *Suite) TestQUIESCETargetChecksFail(c *gc.C) { s.connection.prechecksErr = errors.New("boom") s.checkWorkerReturns(c, migrationmaster.ErrInactive) - s.stub.CheckCalls(c, joinCalls( + assertExpectedCallArgs(c, s.stub, joinCalls( watchStatusLockdownCalls, []jujutesting.StubCall{ {"facade.MinionReportTimeout", nil}, @@ -1141,6 +1144,27 @@ func (s *Suite) checkMinionWaitGetError(c *gc.C, phase coremigration.Phase) { s.checkWorkerErr(c, "boom") } +// assertExpectedCallArgs checks that the stub has been called with the +// expected arguments. It ignores the facade versions map on the Prechecks +// call because that's an implementation detail of the api facade, not the +// worker. As long as it's non-zero, otherwise we don't care. +func assertExpectedCallArgs(c *gc.C, stub *jujutesting.Stub, expectedCalls []jujutesting.StubCall) { + stub.CheckCallNames(c, callNames(expectedCalls)...) + for i, call := range expectedCalls { + stubCall := stub.Calls()[i] + + if call.FuncName == "MigrationTarget.Prechecks" { + mc := jc.NewMultiChecker() + mc.AddExpr("_.FacadeVersions", gc.Not(gc.HasLen), 0) + + c.Assert(stubCall.Args, mc, call.Args, gc.Commentf("call %s", call.FuncName)) + continue + } + + c.Assert(stubCall, jc.DeepEquals, call, gc.Commentf("call %s", call.FuncName)) + } +} + func stubCallNames(stub *jujutesting.Stub) []string { var out []string for _, call := range stub.Calls() { @@ -1505,6 +1529,14 @@ func joinCalls(allCalls ...[]jujutesting.StubCall) (out []jujutesting.StubCall) return } +func callNames(calls []jujutesting.StubCall) []string { + var out []string + for _, call := range calls { + out = append(out, call.FuncName) + } + return out +} + func makeMinionReports(p coremigration.Phase) coremigration.MinionReports { return coremigration.MinionReports{ MigrationId: "model-uuid:2", From 9d13af26938da5e8ef39914af31ae19d4237d7ef Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Thu, 16 Nov 2023 09:22:42 -0500 Subject: [PATCH 08/50] Reorder operating systems in lxd profile charms. The order of specification comes into play with choosing the operating system to deploy a charm with. Make it newest to oldest to help avoid deploying with Xenial during CI tests. Xenial does not always deploy cleanly on containers these days and is EOL. --- testcharms/charms/lxd-profile-subordinate/charmcraft.yaml | 8 ++++---- testcharms/charms/lxd-profile-subordinate/metadata.yaml | 8 ++++---- .../charms/lxd-profile-without-devices/charmcraft.yaml | 8 ++++---- .../charms/lxd-profile-without-devices/metadata.yaml | 7 ++++--- testcharms/charms/lxd-profile/charmcraft.yaml | 8 ++++---- testcharms/charms/lxd-profile/metadata.yaml | 6 +++--- 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/testcharms/charms/lxd-profile-subordinate/charmcraft.yaml b/testcharms/charms/lxd-profile-subordinate/charmcraft.yaml index 490e3ea46e3..8250bcd9aa9 100644 --- a/testcharms/charms/lxd-profile-subordinate/charmcraft.yaml +++ b/testcharms/charms/lxd-profile-subordinate/charmcraft.yaml @@ -6,28 +6,28 @@ bases: architectures: ["amd64", "arm64"] run-on: - name: "ubuntu" - channel: "16.04" + channel: "22.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "18.04" + channel: "20.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "20.04" + channel: "18.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "22.04" + channel: "16.04" architectures: - amd64 - aarch64 diff --git a/testcharms/charms/lxd-profile-subordinate/metadata.yaml b/testcharms/charms/lxd-profile-subordinate/metadata.yaml index 0b44d6ef3f4..1e9bc537a1a 100644 --- a/testcharms/charms/lxd-profile-subordinate/metadata.yaml +++ b/testcharms/charms/lxd-profile-subordinate/metadata.yaml @@ -15,8 +15,8 @@ requires: interface: juju-info scope: container series: - - quantal - - xenial - - bionic - - focal - jammy + - focal + - bionic + - xenial + - quantal diff --git a/testcharms/charms/lxd-profile-without-devices/charmcraft.yaml b/testcharms/charms/lxd-profile-without-devices/charmcraft.yaml index e9c0f138282..bcce8076215 100644 --- a/testcharms/charms/lxd-profile-without-devices/charmcraft.yaml +++ b/testcharms/charms/lxd-profile-without-devices/charmcraft.yaml @@ -6,28 +6,28 @@ bases: architectures: ["amd64", "arm64"] run-on: - name: "ubuntu" - channel: "16.04" + channel: "22.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "18.04" + channel: "20.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "20.04" + channel: "16.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "22.04" + channel: "18.04" architectures: - amd64 - aarch64 diff --git a/testcharms/charms/lxd-profile-without-devices/metadata.yaml b/testcharms/charms/lxd-profile-without-devices/metadata.yaml index 2a30fb52ad7..b7b9fad25b0 100644 --- a/testcharms/charms/lxd-profile-without-devices/metadata.yaml +++ b/testcharms/charms/lxd-profile-without-devices/metadata.yaml @@ -13,8 +13,9 @@ tags: - application_development subordinate: false series: - - xenial - - bionic - - focal - jammy + - focal + - bionic + - xenial + diff --git a/testcharms/charms/lxd-profile/charmcraft.yaml b/testcharms/charms/lxd-profile/charmcraft.yaml index b40b7c97845..db01eb51f47 100644 --- a/testcharms/charms/lxd-profile/charmcraft.yaml +++ b/testcharms/charms/lxd-profile/charmcraft.yaml @@ -6,28 +6,28 @@ bases: architectures: ["amd64", "arm64"] run-on: - name: "ubuntu" - channel: "16.04" + channel: "22.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "18.04" + channel: "20.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "20.04" + channel: 18.04" architectures: - amd64 - aarch64 - arm64 - s390x - name: "ubuntu" - channel: "22.04" + channel: "16.04" architectures: - amd64 - aarch64 diff --git a/testcharms/charms/lxd-profile/metadata.yaml b/testcharms/charms/lxd-profile/metadata.yaml index 152eb98a2df..4aedca92d10 100644 --- a/testcharms/charms/lxd-profile/metadata.yaml +++ b/testcharms/charms/lxd-profile/metadata.yaml @@ -13,8 +13,8 @@ tags: - application_development subordinate: false series: - - xenial - - bionic - - focal - jammy + - focal + - bionic + - xenial From bd5f5ea15e7f7e37a6834d80776a2e982b4c7fbe Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Thu, 16 Nov 2023 17:10:21 -0500 Subject: [PATCH 09/50] Move subordinate lxd profile testing. Test subordinate lxd profiles on lxd machines and containers only in other substraits. --- tests/suites/deploy/deploy_charms.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/suites/deploy/deploy_charms.sh b/tests/suites/deploy/deploy_charms.sh index 1554f1bd6d3..ab9fc9f27f7 100644 --- a/tests/suites/deploy/deploy_charms.sh +++ b/tests/suites/deploy/deploy_charms.sh @@ -107,14 +107,6 @@ run_deploy_local_lxd_profile_charm() { juju status --format=json | jq "${machine_1}" | check "${lxd_profile_name}" juju status --format=json | jq "${machine_1}" | check "${lxd_profile_sub_name}" - juju add-unit "lxd-profile" --to lxd - - machine_2="$(machine_container_path 2 2/lxd/0)" - wait_for "${lxd_profile_sub_name}" "${machine_2}" - - juju status --format=json | jq "${machine_2}" | check "${lxd_profile_name}" - juju status --format=json | jq "${machine_2}" | check "${lxd_profile_sub_name}" - destroy_model "test-deploy-local-lxd-profile" } @@ -184,6 +176,8 @@ run_deploy_lxd_to_machine() { } run_deploy_lxd_to_container() { + # Ensure profiles get applied correctly to containers + # and 1 gets added if a subordinate is added. echo model_name="test-deploy-lxd-container" @@ -194,7 +188,20 @@ run_deploy_lxd_to_container() { charm=./tests/suites/deploy/charms/lxd-profile-alt juju deploy "${charm}" --to lxd --series=bionic + juju deploy ./testcharms/charms/lxd-profile-subordinate + juju add-relation lxd-profile-subordinate lxd-profile-alt + wait_for "lxd-profile-alt" "$(idle_condition "lxd-profile-alt")" + wait_for "lxd-profile-subordinate" ".applications | keys[1]" + + machine_0="$(machine_container_path 0 0/lxd/0)" + wait_for "lxd-profile-subordinate" "${machine_0}" + + lxd_profile_name="juju-test-deploy-lxd-container-lxd-profile-alt" + lxd_profile_sub_name="juju-test-deploy-lxd-container-lxd-profile-subordinate" + + juju status --format=json | jq "${machine_0}" | check "${lxd_profile_name}" + juju status --format=json | jq "${machine_0}" | check "${lxd_profile_sub_name}" OUT=$(juju exec --machine 0 -- sh -c 'sudo lxc profile show "juju-test-deploy-lxd-container-lxd-profile-alt-0"') echo "${OUT}" | grep -E "linux.kernel_modules: ([a-zA-Z0-9\_,]+)?ip_tables,ip6_tables([a-zA-Z0-9\_,]+)?" From 6e85fbea5297812b245006f3e266a72e489ae3e4 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 20 Nov 2023 15:35:39 +0100 Subject: [PATCH 10/50] Changes cloud references to plain structs. There is no particular need to use pointers here. Simply using a value instead prevents panics for poorly formed YAML for clouds, because we can rely on zero values instead of getting nil-ref panics. As a drive-by, we drop use of the the deprecated ioutil package. --- cloud/clouds.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cloud/clouds.go b/cloud/clouds.go index ebba6f3b0e5..ed29b2b8402 100644 --- a/cloud/clouds.go +++ b/cloud/clouds.go @@ -5,7 +5,6 @@ package cloud import ( "fmt" - "io/ioutil" "os" "reflect" "sort" @@ -241,7 +240,7 @@ func (r Region) IsEmpty() bool { // unmarshalling. type cloudSet struct { // Clouds is a map of cloud definitions, keyed on cloud name. - Clouds map[string]*cloud `yaml:"clouds"` + Clouds map[string]cloud `yaml:"clouds"` } // cloud is equivalent to Cloud, for marshalling and unmarshalling. @@ -369,7 +368,7 @@ func JujuPublicCloudsPath() string { // are found, returns the fallback public cloud metadata. func PublicCloudMetadata(searchPath ...string) (result map[string]Cloud, fallbackUsed bool, err error) { for _, file := range searchPath { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil && os.IsNotExist(err) { continue } @@ -388,7 +387,7 @@ func PublicCloudMetadata(searchPath ...string) (result map[string]Cloud, fallbac // ParseOneCloud parses the given yaml bytes into a single Cloud metadata. func ParseOneCloud(data []byte) (Cloud, error) { - c := &cloud{} + var c cloud if err := yaml.Unmarshal(data, &c); err != nil { return Cloud{}, errors.Annotate(err, "cannot unmarshal yaml cloud metadata") } @@ -444,7 +443,7 @@ func ParseCloudMetadata(data []byte) (map[string]Cloud, error) { } } else { // Unable to coerce cloudSet, try to unmarshal into a map[string]*cloud - cloudMap := make(map[string]*cloud) + cloudMap := make(map[string]cloud) if errCloudMap := yaml.Unmarshal(data, &cloudMap); errCloudMap != nil { return nil, errors.Errorf("Invalid cloud metadata %s", yamlMap) } @@ -515,7 +514,7 @@ func IsSameCloudMetadata(meta1, meta2 map[string]Cloud) (bool, error) { // marshalCloudMetadata marshals the given clouds to YAML. func marshalCloudMetadata(cloudsMap map[string]Cloud) ([]byte, error) { - clouds := cloudSet{make(map[string]*cloud)} + clouds := cloudSet{make(map[string]cloud)} for name, metadata := range cloudsMap { clouds.Clouds[name] = cloudToInternal(metadata, false) } @@ -537,10 +536,10 @@ func UnmarshalCloud(in []byte) (Cloud, error) { if err := yaml.Unmarshal(in, &internal); err != nil { return Cloud{}, errors.Annotate(err, "cannot unmarshal yaml cloud metadata") } - return cloudFromInternal(&internal), nil + return cloudFromInternal(internal), nil } -func cloudToInternal(in Cloud, withName bool) *cloud { +func cloudToInternal(in Cloud, withName bool) cloud { var regions regions for _, r := range in.Regions { regions.Slice = append(regions.Slice, yaml.MapItem{ @@ -556,7 +555,7 @@ func cloudToInternal(in Cloud, withName bool) *cloud { if !withName { name = "" } - return &cloud{ + return cloud{ Name: name, Type: in.Type, HostCloudRegion: in.HostCloudRegion, @@ -573,7 +572,7 @@ func cloudToInternal(in Cloud, withName bool) *cloud { } } -func cloudFromInternal(in *cloud) Cloud { +func cloudFromInternal(in cloud) Cloud { var regions []Region if len(in.Regions.Map) > 0 { for _, item := range in.Regions.Slice { From ee437eb1b5464784d40552363e10d9072a7cd945 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Tue, 21 Nov 2023 10:17:32 +1000 Subject: [PATCH 11/50] Treat owners of secrets the same as other consumers when reading secret content --- apiserver/common/secrets/access.go | 44 ++-- apiserver/common/secrets/access_test.go | 3 +- .../facades/agent/secretsmanager/secrets.go | 121 +++++------ .../agent/secretsmanager/secrets_test.go | 191 ++++++++++++++---- state/migration_import_tasks.go | 12 +- state/migration_import_test.go | 45 +++++ state/secrets.go | 17 +- state/upgrades.go | 43 ++++ state/upgrades_test.go | 75 +++++++ upgrades/backend.go | 5 + upgrades/steps_317.go | 6 + upgrades/steps_317_test.go | 5 + 12 files changed, 432 insertions(+), 135 deletions(-) diff --git a/apiserver/common/secrets/access.go b/apiserver/common/secrets/access.go index adee92a70d7..5a4e42cd2d0 100644 --- a/apiserver/common/secrets/access.go +++ b/apiserver/common/secrets/access.go @@ -29,11 +29,6 @@ func IsSameApplication(authTag names.Tag, tag names.Tag) bool { return AuthTagApp(authTag) == AuthTagApp(tag) } -func hasRole(api SecretsConsumer, uri *coresecrets.URI, entity names.Tag, role coresecrets.SecretRole) bool { - hasRole, err := api.SecretAccess(uri, entity) - return err == nil && hasRole.Allowed(role) -} - // CanManage checks that the authenticated caller can manage the secret, and returns a // token to ensure leadership if that is required; ie if the request is for a secret // owned by an application, the entity must be the unit leader. @@ -47,17 +42,32 @@ func CanManage( switch authTag.(type) { case names.UnitTag: - if hasRole(api, uri, authTag, coresecrets.RoleManage) { + hasRole, err := api.SecretAccess(uri, authTag) + if err != nil { + // Typically not found error. + return nil, errors.Trace(err) + } + if hasRole.Allowed(coresecrets.RoleManage) { // owner unit. return successfulToken{}, nil } - if hasRole(api, uri, appTag, coresecrets.RoleManage) { + hasRole, err = api.SecretAccess(uri, appTag) + if err != nil { + // Typically not found error. + return nil, errors.Trace(err) + } + if hasRole.Allowed(coresecrets.RoleManage) { // leader unit can manage app owned secret. return LeadershipToken(authTag, leadershipChecker) } case names.ApplicationTag: // TODO(wallyworld) - remove auth tag kind check when podspec charms are gone. - if hasRole(api, uri, appTag, coresecrets.RoleManage) { + hasRole, err := api.SecretAccess(uri, appTag) + if err != nil { + // Typically not found error. + return nil, errors.Trace(err) + } + if hasRole.Allowed(coresecrets.RoleManage) { return successfulToken{}, nil } } @@ -65,18 +75,26 @@ func CanManage( } // CanRead returns true if the specified entity can read the secret. -func CanRead(api SecretsConsumer, authTag names.Tag, uri *coresecrets.URI, entity names.Tag) bool { +func CanRead(api SecretsConsumer, authTag names.Tag, uri *coresecrets.URI, entity names.Tag) (bool, error) { // First try looking up unit access. - hasRole, _ := api.SecretAccess(uri, entity) + hasRole, err := api.SecretAccess(uri, entity) + if err != nil { + // Typically not found error. + return false, errors.Trace(err) + } if hasRole.Allowed(coresecrets.RoleView) { - return true + return true, nil } // 1. all units can read secrets owned by application. // 2. units of podspec applications can do this as well. appName := AuthTagApp(authTag) - hasRole, _ = api.SecretAccess(uri, names.NewApplicationTag(appName)) - return hasRole.Allowed(coresecrets.RoleView) + hasRole, err = api.SecretAccess(uri, names.NewApplicationTag(appName)) + if err != nil { + // Typically not found error. + return false, errors.Trace(err) + } + return hasRole.Allowed(coresecrets.RoleView), nil } // OwnerToken returns a token used to determine if the specified entity diff --git a/apiserver/common/secrets/access_test.go b/apiserver/common/secrets/access_test.go index e2a041218cf..f0bf8011a8d 100644 --- a/apiserver/common/secrets/access_test.go +++ b/apiserver/common/secrets/access_test.go @@ -4,7 +4,6 @@ package secrets_test import ( - "github.com/juju/errors" "github.com/juju/names/v4" jc "github.com/juju/testing/checkers" "go.uber.org/mock/gomock" @@ -44,7 +43,7 @@ func (s *secretsSuite) TestCanManageLeaderUnitAppSecret(c *gc.C) { uri := coresecrets.NewURI() gomock.InOrder( - secretsConsumer.EXPECT().SecretAccess(uri, authTag).Return(coresecrets.RoleNone, errors.NotFoundf("")), + secretsConsumer.EXPECT().SecretAccess(uri, authTag).Return(coresecrets.RoleNone, nil), secretsConsumer.EXPECT().SecretAccess(uri, names.NewApplicationTag("mariadb")).Return(coresecrets.RoleManage, nil), leadershipChecker.EXPECT().LeadershipCheck("mariadb", "mariadb/0").Return(token), token.EXPECT().Check().Return(nil), diff --git a/apiserver/facades/agent/secretsmanager/secrets.go b/apiserver/facades/agent/secretsmanager/secrets.go index 003dc2d9321..130ddbd297a 100644 --- a/apiserver/facades/agent/secretsmanager/secrets.go +++ b/apiserver/facades/agent/secretsmanager/secrets.go @@ -64,7 +64,7 @@ type SecretsManagerAPIV1 struct { *SecretsManagerAPI } -func (s *SecretsManagerAPI) canRead(uri *coresecrets.URI, entity names.Tag) bool { +func (s *SecretsManagerAPI) canRead(uri *coresecrets.URI, entity names.Tag) (bool, error) { return commonsecrets.CanRead(s.secretsConsumer, s.authTag, uri, entity) } @@ -335,10 +335,6 @@ func (s *SecretsManagerAPI) updateSecret(arg params.UpdateSecretArg) error { arg.Label == nil && len(arg.Params) == 0 && len(arg.Content.Data) == 0 && arg.Content.ValueRef == nil { return errors.New("at least one attribute to update must be specified") } - if _, err := s.secretsState.GetSecret(uri); err != nil { - // Check if the uri exists or not. - return errors.Trace(err) - } token, err := s.canManage(uri) if err != nil { @@ -456,8 +452,14 @@ func (s *SecretsManagerAPI) getSecretConsumerInfo(consumerTag names.Tag, uriStr } // We only check read permissions for local secrets. // For CMR secrets, the remote model manages the permissions. - if uri.IsLocal(s.modelUUID) && !s.canRead(uri, consumerTag) { - return nil, apiservererrors.ErrPerm + if uri.IsLocal(s.modelUUID) { + canRead, err := s.canRead(uri, consumerTag) + if err != nil { + return nil, errors.Trace(err) + } + if !canRead { + return nil, apiservererrors.ErrPerm + } } consumer, err := s.secretsConsumer.GetSecretConsumer(uri, consumerTag) if err != nil { @@ -466,7 +468,7 @@ func (s *SecretsManagerAPI) getSecretConsumerInfo(consumerTag names.Tag, uriStr if consumer.Label != "" { return consumer, nil } - md, err := s.getAppOwnedOrUnitOwnedSecretMetadata(uri, "", false, false) + md, err := s.getAppOwnedOrUnitOwnedSecretMetadata(uri, "") if errors.Is(err, errors.NotFound) { // The secret is owned by a different application. return consumer, nil @@ -645,74 +647,43 @@ func (s *SecretsManagerAPI) GetSecretRevisionContentInfo(arg params.SecretRevisi return result, nil } -// For the application owned secret, if the caller is a peer unit, we create a fake consumer doc for triggering events to notify the uniters. -// The peer units should get the secret using owner label but should not set a consumer label. -func (s *SecretsManagerAPI) ensureConsumerMetadataForAppOwnedSecretsForPeerUnits(md *coresecrets.SecretMetadata) (*coresecrets.SecretMetadata, error) { - consumer, err := s.secretsConsumer.GetSecretConsumer(md.URI, s.authTag) - if err != nil && !errors.Is(err, errors.NotFound) { - return nil, errors.Trace(err) - } - - if consumer == nil { - // Create a fake consumer doc for triggering secret-changed event for uniter. - consumer = &coresecrets.SecretConsumerMetadata{} - } - logger.Debugf("saving consumer doc for application owned secret %q for peer units %q", md.URI, s.authTag) - if err := s.secretsConsumer.SaveSecretConsumer(md.URI, s.authTag, consumer); err != nil { - return nil, errors.Trace(err) - } - return md, nil -} - -func (s *SecretsManagerAPI) updateLabelForAppOwnedOrUnitOwnedSecret(uri *coresecrets.URI, label string, md *coresecrets.SecretMetadata) error { +func (s *SecretsManagerAPI) updateLabelForAppOwnedOrUnitOwnedSecret(uri *coresecrets.URI, label string, owner string) error { if uri == nil || label == "" { // We have done this check before, but it doesn't hurt to do it again. return nil } - ownerTag, err := names.ParseTag(md.OwnerTag) - if err != nil { - return errors.Trace(err) - } - isLeaderUnit, err := commonsecrets.IsLeaderUnit(s.authTag, s.leadershipChecker) + ownerTag, err := names.ParseTag(owner) if err != nil { return errors.Trace(err) } - if ownerTag == s.authTag || commonsecrets.IsSameApplication(ownerTag, s.authTag) && isLeaderUnit { - // The secret is owned by the caller or the caller is the leader unit of the application owning the secret. - token, err := commonsecrets.LeadershipToken(s.authTag, s.leadershipChecker) + if ownerTag != s.authTag { + isLeaderUnit, err := commonsecrets.IsLeaderUnit(s.authTag, s.leadershipChecker) if err != nil { return errors.Trace(err) } - // Update the label. - _, err = s.secretsState.UpdateSecret(uri, state.UpdateSecretParams{ - LeaderToken: token, - Label: &label, - }) + if !isLeaderUnit { + return errors.New("only unit leaders can update an application owned secret label") + } + } + + token, err := commonsecrets.OwnerToken(s.authTag, ownerTag, s.leadershipChecker) + if err != nil { return errors.Trace(err) } - return nil + // Update the label. + _, err = s.secretsState.UpdateSecret(uri, state.UpdateSecretParams{ + LeaderToken: token, + Label: &label, + }) + return errors.Trace(err) } -func (s *SecretsManagerAPI) getAppOwnedOrUnitOwnedSecretMetadata(uri *coresecrets.URI, label string, ensureConsumerMetaData, updateLabel bool) (md *coresecrets.SecretMetadata, err error) { +func (s *SecretsManagerAPI) getAppOwnedOrUnitOwnedSecretMetadata(uri *coresecrets.URI, label string) (*coresecrets.SecretMetadata, error) { notFoundErr := errors.NotFoundf("secret %q", uri) if label != "" { notFoundErr = errors.NotFoundf("secret with label %q", label) } - defer func() { - if md == nil { - return - } - if updateLabel { - if err = s.updateLabelForAppOwnedOrUnitOwnedSecret(uri, label, md); err != nil { - return - } - } - if md.OwnerTag == s.authTag.String() || !ensureConsumerMetaData { - return - } - md, err = s.ensureConsumerMetadataForAppOwnedSecretsForPeerUnits(md) - }() filter := state.SecretsFilter{ OwnerTags: []names.Tag{s.authTag}, @@ -761,27 +732,29 @@ func (s *SecretsManagerAPI) getSecretContent(arg params.GetSecretContentArg) ( // arg.Label could be the consumer label for consumers or the owner label for owners. possibleUpdateLabel := arg.Label != "" && uri != nil + labelToUpdate := arg.Label // For local secrets, check those which may be owned by the caller. if uri == nil || uri.IsLocal(s.modelUUID) { - // Owner units should always have the URI because we resolved the label to URI on uniter side already. - md, err := s.getAppOwnedOrUnitOwnedSecretMetadata(uri, arg.Label, true, possibleUpdateLabel) + md, err := s.getAppOwnedOrUnitOwnedSecretMetadata(uri, arg.Label) if err != nil && !errors.Is(err, errors.NotFound) { return nil, nil, false, errors.Trace(err) } if md != nil { + // If the label has is to be changed by the secret owner, update the secret metadata. + // TODO(wallyworld) - the label staying the same should be asserted in a txn. + possibleUpdateLabel = possibleUpdateLabel && labelToUpdate != md.Label + if possibleUpdateLabel { + if err = s.updateLabelForAppOwnedOrUnitOwnedSecret(uri, labelToUpdate, md.OwnerTag); err != nil { + return nil, nil, false, errors.Trace(err) + } + } // 1. secrets can be accessed by the owner; // 2. application owned secrets can be accessed by all the units of the application using owner label or URI. - val, valueRef, err := s.secretsState.GetSecretValue(md.URI, md.LatestRevision) - if err != nil { - return nil, nil, false, errors.Trace(err) - } - content := &secrets.ContentParams{SecretValue: val, ValueRef: valueRef} - if err != nil || content.ValueRef == nil { - return content, nil, false, errors.Trace(err) - } - backend, draining, err := s.getBackend(content.ValueRef.BackendID) - return content, backend, draining, errors.Trace(err) + uri = md.URI + // We don't update the consumer label in this case since the label comes + // from the owner metadata and we don't want to violate uniqueness checks. + labelToUpdate = "" } } @@ -801,16 +774,16 @@ func (s *SecretsManagerAPI) getSecretContent(arg params.GetSecretContentArg) ( return s.getRemoteSecretContent(uri, arg.Refresh, arg.Peek, arg.Label, possibleUpdateLabel) } - if _, err := s.secretsState.GetSecret(uri); err != nil { - // Check if the uri exists or not. + canRead, err := s.canRead(uri, s.authTag) + if err != nil { return nil, nil, false, errors.Trace(err) } - if !s.canRead(uri, s.authTag) { + if !canRead { return nil, nil, false, apiservererrors.ErrPerm } - // arg.Label is the consumer label for consumers. - consumedRevision, err := s.getConsumedRevision(uri, arg.Refresh, arg.Peek, arg.Label, possibleUpdateLabel) + // labelToUpdate is the consumer label for consumers. + consumedRevision, err := s.getConsumedRevision(uri, arg.Refresh, arg.Peek, labelToUpdate, possibleUpdateLabel) if err != nil { return nil, nil, false, errors.Annotate(err, "getting latest secret revision") } diff --git a/apiserver/facades/agent/secretsmanager/secrets_test.go b/apiserver/facades/agent/secretsmanager/secrets_test.go index 3db7b2feef4..587d13e1482 100644 --- a/apiserver/facades/agent/secretsmanager/secrets_test.go +++ b/apiserver/facades/agent/secretsmanager/secrets_test.go @@ -22,6 +22,7 @@ import ( facademocks "github.com/juju/juju/apiserver/facade/mocks" "github.com/juju/juju/apiserver/facades/agent/secretsmanager" "github.com/juju/juju/apiserver/facades/agent/secretsmanager/mocks" + "github.com/juju/juju/core/leadership" coresecrets "github.com/juju/juju/core/secrets" corewatcher "github.com/juju/juju/core/watcher" "github.com/juju/juju/rpc/params" @@ -387,7 +388,6 @@ func (s *SecretsManagerSuite) TestUpdateSecrets(c *gc.C) { ) s.leadership.EXPECT().LeadershipCheck("mariadb", "mariadb/0").Return(s.token).Times(2) s.token.EXPECT().Check().Return(nil).Times(2) - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil).Times(2) s.expectSecretAccessQuery(4) results, err := s.facade.UpdateSecrets(params.UpdateSecretArgs{ @@ -435,7 +435,6 @@ func (s *SecretsManagerSuite) TestUpdateSecretDuplicateLabel(c *gc.C) { } uri := coresecrets.NewURI() expectURI := *uri - s.secretsState.EXPECT().GetSecret(&expectURI).Return(&coresecrets.SecretMetadata{}, nil) s.secretsState.EXPECT().UpdateSecret(&expectURI, p).Return( nil, fmt.Errorf("dup label %w", state.LabelExists), ) @@ -715,18 +714,27 @@ func (s *SecretsManagerSuite) TestGetSecretContentForOwnerSecretURIArg(c *gc.C) data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() + md := coresecrets.SecretMetadata{ + URI: uri, + LatestRevision: 668, + OwnerTag: s.authTag.String(), + } + + s.expectSecretAccessQuery(1) + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ OwnerTags: []names.Tag{ names.NewUnitTag("mariadb/0"), names.NewApplicationTag("mariadb"), }, - }).Return([]*coresecrets.SecretMetadata{ - { - URI: uri, - LatestRevision: 668, - OwnerTag: s.authTag.String(), - }, - }, nil) + }).Return([]*coresecrets.SecretMetadata{&md}, nil) + + s.secretsState.EXPECT().GetSecret(uri).Return(&md, nil) + s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). + Return(nil, errors.NotFoundf("secret consumer")) + s.secretsConsumer.EXPECT().SaveSecretConsumer( + uri, s.authTag, &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) + s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( val, nil, nil, ) @@ -750,19 +758,28 @@ func (s *SecretsManagerSuite) TestGetSecretContentForOwnerSecretLabelArg(c *gc.C data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() + md := coresecrets.SecretMetadata{ + URI: uri, + LatestRevision: 668, + Label: "foo", + OwnerTag: s.authTag.String(), + } + + s.expectSecretAccessQuery(1) + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ OwnerTags: []names.Tag{ names.NewUnitTag("mariadb/0"), names.NewApplicationTag("mariadb"), }, - }).Return([]*coresecrets.SecretMetadata{ - { - URI: uri, - LatestRevision: 668, - Label: "foo", - OwnerTag: s.authTag.String(), - }, - }, nil) + }).Return([]*coresecrets.SecretMetadata{&md}, nil) + + s.secretsState.EXPECT().GetSecret(uri).Return(&md, nil) + s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). + Return(nil, errors.NotFoundf("secret consumer")) + s.secretsConsumer.EXPECT().SaveSecretConsumer( + uri, s.authTag, &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) + s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( val, nil, nil, ) @@ -786,25 +803,38 @@ func (s *SecretsManagerSuite) TestGetSecretContentForUnitOwnedSecretUpdateLabel( data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() + md := coresecrets.SecretMetadata{ + URI: uri, + LatestRevision: 668, + Label: "foz", + OwnerTag: s.authTag.String(), + } + + s.expectSecretAccessQuery(1) + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ OwnerTags: []names.Tag{ names.NewUnitTag("mariadb/0"), names.NewApplicationTag("mariadb"), }, - }).Return([]*coresecrets.SecretMetadata{ - { - URI: uri, - LatestRevision: 668, - Label: "foo", - OwnerTag: s.authTag.String(), + }).Return([]*coresecrets.SecretMetadata{&md}, nil) + + // Label is updated on owner metadata, not consumer metadata since it is a secret owned by the caller. + s.secretsState.EXPECT().UpdateSecret(uri, gomock.Any()).DoAndReturn( + func(uri *coresecrets.URI, p state.UpdateSecretParams) (*coresecrets.SecretMetadata, error) { + c.Assert(p.LeaderToken, gc.NotNil) + c.Assert(p.LeaderToken.Check(), jc.ErrorIsNil) + c.Assert(p.Label, gc.NotNil) + c.Assert(*p.Label, gc.Equals, "foo") + return nil, nil }, - }, nil) - s.leadership.EXPECT().LeadershipCheck("mariadb", "mariadb/0").Return(s.token).Times(2) - s.token.EXPECT().Check().Return(nil).Times(2) - s.secretsState.EXPECT().UpdateSecret(uri, state.UpdateSecretParams{ - LeaderToken: s.token, - Label: ptr("foo"), - }).Return(nil, nil) + ) + + s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). + Return(nil, errors.NotFoundf("secret consumer")) + s.secretsState.EXPECT().GetSecret(uri).Return(&md, nil) + s.secretsConsumer.EXPECT().SaveSecretConsumer( + uri, s.authTag, &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( val, nil, nil, @@ -829,6 +859,9 @@ func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretUpdateLabel(c *gc. data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() + + s.expectSecretAccessQuery(1) + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ OwnerTags: []names.Tag{ names.NewUnitTag("mariadb/0"), @@ -838,7 +871,7 @@ func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretUpdateLabel(c *gc. { URI: uri, LatestRevision: 668, - Label: "foo", + Label: "foz", OwnerTag: names.NewApplicationTag("mariadb").String(), }, }, nil) @@ -851,9 +884,9 @@ func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretUpdateLabel(c *gc. s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). Return(nil, errors.NotFoundf("secret consumer")) + s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{LatestRevision: 668}, nil) s.secretsConsumer.EXPECT().SaveSecretConsumer( - uri, names.NewUnitTag("mariadb/0"), &coresecrets.SecretConsumerMetadata{}).Return(nil) - + uri, names.NewUnitTag("mariadb/0"), &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( val, nil, nil, ) @@ -871,12 +904,49 @@ func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretUpdateLabel(c *gc. }) } -func (s *SecretsManagerSuite) TestGetSecretContentForUnitAccessApplicationOwnedSecret(c *gc.C) { +func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretUpdateLabelNotLeader(c *gc.C) { + defer s.setup(c).Finish() + + uri := coresecrets.NewURI() + + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ + OwnerTags: []names.Tag{ + names.NewUnitTag("mariadb/0"), + names.NewApplicationTag("mariadb"), + }, + }).Return([]*coresecrets.SecretMetadata{ + { + URI: uri, + LatestRevision: 668, + Label: "foz", + OwnerTag: names.NewApplicationTag("mariadb").String(), + }, + }, nil) + s.leadership.EXPECT().LeadershipCheck("mariadb", "mariadb/0").Return(s.token) + s.token.EXPECT().Check().Return(leadership.NewNotLeaderError("mariadb/0", "mariadb")) + + results, err := s.facade.GetSecretContentInfo(params.GetSecretContentArgs{ + Args: []params.GetSecretContentArg{ + {URI: uri.String(), Label: "foo"}, + }, + }) + c.Assert(err, jc.ErrorIsNil) + c.Assert(results, jc.DeepEquals, params.SecretContentResults{ + Results: []params.SecretContentResult{{ + Error: ¶ms.Error{Message: "only unit leaders can update an application owned secret label"}, + }}, + }) +} + +func (s *SecretsManagerSuite) TestGetSecretContentForAppSecretSameLabel(c *gc.C) { defer s.setup(c).Finish() data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() + + s.expectSecretAccessQuery(1) + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ OwnerTags: []names.Tag{ names.NewUnitTag("mariadb/0"), @@ -893,8 +963,53 @@ func (s *SecretsManagerSuite) TestGetSecretContentForUnitAccessApplicationOwnedS s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). Return(nil, errors.NotFoundf("secret consumer")) + s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{LatestRevision: 668}, nil) s.secretsConsumer.EXPECT().SaveSecretConsumer( - uri, names.NewUnitTag("mariadb/0"), &coresecrets.SecretConsumerMetadata{}).Return(nil) + uri, names.NewUnitTag("mariadb/0"), &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) + s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( + val, nil, nil, + ) + + results, err := s.facade.GetSecretContentInfo(params.GetSecretContentArgs{ + Args: []params.GetSecretContentArg{ + {URI: uri.String(), Label: "foo"}, + }, + }) + c.Assert(err, jc.ErrorIsNil) + c.Assert(results, jc.DeepEquals, params.SecretContentResults{ + Results: []params.SecretContentResult{{ + Content: params.SecretContentParams{Data: data}, + }}, + }) +} + +func (s *SecretsManagerSuite) TestGetSecretContentForUnitAccessApplicationOwnedSecret(c *gc.C) { + defer s.setup(c).Finish() + + data := map[string]string{"foo": "bar"} + val := coresecrets.NewSecretValue(data) + uri := coresecrets.NewURI() + md := coresecrets.SecretMetadata{ + URI: uri, + LatestRevision: 668, + Label: "foo", + OwnerTag: names.NewApplicationTag("mariadb").String(), + } + + s.expectSecretAccessQuery(1) + + s.secretsState.EXPECT().ListSecrets(state.SecretsFilter{ + OwnerTags: []names.Tag{ + names.NewUnitTag("mariadb/0"), + names.NewApplicationTag("mariadb"), + }, + }).Return([]*coresecrets.SecretMetadata{&md}, nil) + + s.secretsState.EXPECT().GetSecret(uri).Return(&md, nil) + s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). + Return(nil, errors.NotFoundf("secret consumer")) + s.secretsConsumer.EXPECT().SaveSecretConsumer( + uri, names.NewUnitTag("mariadb/0"), &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) s.secretsState.EXPECT().GetSecretValue(uri, 668).Return( val, nil, nil, @@ -933,7 +1048,6 @@ func (s *SecretsManagerSuite) assertGetSecretContentConsumer(c *gc.C, isUnitAgen data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.secretsState.EXPECT().ListSecrets(filter).Return([]*coresecrets.SecretMetadata{}, nil) @@ -973,7 +1087,6 @@ func (s *SecretsManagerSuite) TestGetSecretContentConsumerLabelOnly(c *gc.C) { data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.secretsConsumer.EXPECT().GetURIByConsumerLabel("label", names.NewUnitTag("mariadb/0")).Return(uri, nil) @@ -1011,7 +1124,6 @@ func (s *SecretsManagerSuite) TestGetSecretContentConsumerFirstTime(c *gc.C) { data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.expectgetAppOwnedOrUnitOwnedSecretMetadataNotFound() @@ -1048,7 +1160,6 @@ func (s *SecretsManagerSuite) TestGetSecretContentConsumerUpdateLabel(c *gc.C) { data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.expectgetAppOwnedOrUnitOwnedSecretMetadataNotFound() @@ -1104,7 +1215,6 @@ func (s *SecretsManagerSuite) TestGetSecretContentConsumerUpdateArg(c *gc.C) { data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.expectgetAppOwnedOrUnitOwnedSecretMetadataNotFound() @@ -1142,7 +1252,6 @@ func (s *SecretsManagerSuite) TestGetSecretContentConsumerPeekArg(c *gc.C) { data := map[string]string{"foo": "bar"} val := coresecrets.NewSecretValue(data) uri := coresecrets.NewURI() - s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{}, nil) s.expectSecretAccessQuery(1) s.expectgetAppOwnedOrUnitOwnedSecretMetadataNotFound() diff --git a/state/migration_import_tasks.go b/state/migration_import_tasks.go index 4c44534b435..e0724f06d48 100644 --- a/state/migration_import_tasks.go +++ b/state/migration_import_tasks.go @@ -671,6 +671,14 @@ func (ImportSecrets) Execute(src SecretsInput, runner TransactionRunner, knownSe return errors.Annotatef(err, "invalid consumer for secret %q", secret.Id()) } key := src.SecretConsumerKey(uri, consumer.String()) + currentRev := info.CurrentRevision() + latestRev := info.LatestRevision() + // Older models may have set the consumed rev info to 0 (assuming the latest revision always). + // So set the latest values explicitly. + if currentRev == 0 { + currentRev = secret.LatestRevision() + latestRev = secret.LatestRevision() + } ops = append(ops, txn.Op{ C: secretConsumersC, Id: key, @@ -679,8 +687,8 @@ func (ImportSecrets) Execute(src SecretsInput, runner TransactionRunner, knownSe DocID: key, ConsumerTag: consumer.String(), Label: info.Label(), - CurrentRevision: info.CurrentRevision(), - LatestRevision: info.LatestRevision(), + CurrentRevision: currentRev, + LatestRevision: latestRev, }, }) } diff --git a/state/migration_import_test.go b/state/migration_import_test.go index 130505fac05..0281bae26ae 100644 --- a/state/migration_import_test.go +++ b/state/migration_import_test.go @@ -3285,6 +3285,51 @@ func (s *MigrationImportSuite) TestSecrets(c *gc.C) { c.Assert(backendRefCount, gc.Equals, 2) } +func (s *MigrationImportSuite) TestSecretsEnsureConsumerRevisionInfo(c *gc.C) { + store := state.NewSecrets(s.State) + owner := s.Factory.MakeApplication(c, nil) + uri := secrets.NewURI() + p := state.CreateSecretParams{ + Version: 1, + Owner: owner.Tag(), + UpdateSecretParams: state.UpdateSecretParams{ + LeaderToken: &fakeToken{}, + RotatePolicy: ptr(secrets.RotateNever), + Data: map[string]string{"foo": "bar"}, + }, + } + md, err := store.CreateSecret(uri, p) + c.Assert(err, jc.ErrorIsNil) + + consumer := s.Factory.MakeApplication(c, &factory.ApplicationParams{ + Charm: s.Factory.MakeCharm(c, &factory.CharmParams{ + Name: "wordpress", + }), + }) + err = s.State.SaveSecretConsumer(uri, consumer.Tag(), &secrets.SecretConsumerMetadata{ + Label: "consumer label", + CurrentRevision: 0, + LatestRevision: 0, + }) + c.Assert(err, jc.ErrorIsNil) + + _, newSt := s.importModel(c, s.State) + + store = state.NewSecrets(newSt) + all, err := store.ListSecrets(state.SecretsFilter{}) + c.Assert(err, jc.ErrorIsNil) + c.Assert(all, gc.HasLen, 1) + c.Assert(all[0], jc.DeepEquals, md) + + info, err := newSt.GetSecretConsumer(uri, consumer.Tag()) + c.Assert(err, jc.ErrorIsNil) + c.Assert(info, jc.DeepEquals, &secrets.SecretConsumerMetadata{ + Label: "consumer label", + CurrentRevision: 1, + LatestRevision: 1, + }) +} + func (s *MigrationImportSuite) TestSecretsMissingBackend(c *gc.C) { store := state.NewSecrets(s.State) owner := s.Factory.MakeApplication(c, nil) diff --git a/state/secrets.go b/state/secrets.go index 81cd858a46d..d2b33493b2f 100644 --- a/state/secrets.go +++ b/state/secrets.go @@ -1232,18 +1232,28 @@ func (st *State) uniqueSecretConsumerLabelOps(consumerTag names.Tag, label strin return append(ops, ops2...), nil } +// uniqueSecretLabelBaseOps is used when creating or updating a secret with an owner label, or +// when saving a secret consumer record. It checks that the label is not used twice: +// - a unit of the same application consuming an application owned secret cannot use the same label +// as is used in the secret metadata of any application owned secret. +// The check is done when creating a new application owned secret, or saving a consumer record. func (st *State) uniqueSecretLabelBaseOps(tag names.Tag, label string) (ops []txn.Op, _ error) { col, close := st.db().GetCollection(refcountsC) defer close() - var keyPattern string + var ( + keyPattern string + errorMsg string + ) + switch tag := tag.(type) { case names.ApplicationTag: - // Ensure no units use this label for both owner and consumer label.. + // Ensure no units use this label for both owner and consumer label. keyPattern = fmt.Sprintf( "^%s:(%s|%s)#unit-%s-[0-9]+#%s$", st.ModelUUID(), secretOwnerLabelKeyPrefix, secretConsumerLabelKeyPrefix, tag.Name, label, ) + errorMsg = fmt.Sprintf("secret label %q for a unit of application %q already exists", label, tag.Name) case names.UnitTag: // Ensure no application owned secret uses this label. applicationName, _ := names.UnitApplication(tag.Id()) @@ -1253,6 +1263,7 @@ func (st *State) uniqueSecretLabelBaseOps(tag names.Tag, label string) (ops []tx "^%s:(%s|%s)#%s#%s$", st.ModelUUID(), secretOwnerLabelKeyPrefix, secretConsumerLabelKeyPrefix, appTag.String(), label, ) + errorMsg = fmt.Sprintf("secret label %q for application %q already exists", label, applicationName) default: return nil, errors.NotSupportedf("tag type %T", tag) } @@ -1262,7 +1273,7 @@ func (st *State) uniqueSecretLabelBaseOps(tag names.Tag, label string) (ops []tx return nil, errors.Trace(err) } if count > 0 { - return nil, errors.WithType(errors.Errorf("secret label %q for %q already exists", label, tag), LabelExists) + return nil, errors.WithType(errors.New(errorMsg), LabelExists) } return []txn.Op{ diff --git a/state/upgrades.go b/state/upgrades.go index 00da348d1cc..a84c8999afe 100644 --- a/state/upgrades.go +++ b/state/upgrades.go @@ -331,3 +331,46 @@ func EnsureApplicationCharmOriginsNormalised(pool *StatePool) error { return nil })) } + +// FixOwnerConsumedSecretInfo updates consuming info for app owned secrets +// where the tracked revision is 0, setting it to the latest revision number. +func FixOwnerConsumedSecretInfo(pool *StatePool) error { + return errors.Trace(runForAllModelStates(pool, func(st *State) error { + secretConsumers, closer := st.db().GetCollection(secretConsumersC) + defer closer() + docs := []secretConsumerDoc{} + if err := secretConsumers.Find(bson.D{{"current-revision", 0}}).All(&docs); err != nil { + return errors.Trace(err) + } + + secretState := NewSecrets(st) + + var ops []txn.Op + for _, doc := range docs { + uriStr, _ := splitSecretConsumerKey(st.localID(doc.DocID)) + uri, err := secrets.ParseURI(uriStr) + if err != nil { + return errors.Trace(err) + } + md, err := secretState.GetSecret(uri) + if err != nil { + return errors.Trace(err) + } + + ops = append(ops, txn.Op{ + C: secretConsumersC, + Id: doc.DocID, + Update: bson.D{ + {Name: "$set", Value: bson.D{ + {Name: "current-revision", Value: md.LatestRevision}, + {Name: "latest-revision", Value: md.LatestRevision}, + }}, + }, + }) + } + if len(ops) > 0 { + return errors.Trace(st.runRawTransaction(ops)) + } + return nil + })) +} diff --git a/state/upgrades_test.go b/state/upgrades_test.go index 531095124d2..9e8553534c6 100644 --- a/state/upgrades_test.go +++ b/state/upgrades_test.go @@ -15,6 +15,7 @@ import ( gc "gopkg.in/check.v1" corecharm "github.com/juju/juju/core/charm" + "github.com/juju/juju/core/secrets" "github.com/juju/juju/storage/provider" coretesting "github.com/juju/juju/testing" ) @@ -476,3 +477,77 @@ func (s *upgradesSuite) TestEnsureApplicationCharmOriginsNormaliseCH(c *gc.C) { expectedData := upgradedData(appColl, expected) s.assertUpgradedData(c, EnsureApplicationCharmOriginsNormalised, expectedData) } + +// fakeToken implements leadership.Token. +type fakeToken struct { +} + +func (t *fakeToken) Check() error { + return nil +} + +func (s *upgradesSuite) TestFixOwnerConsumedSecretInfo(c *gc.C) { + consumerColl, closer := s.state.db().GetRawCollection(secretConsumersC) + defer closer() + + model1 := s.makeModel(c, "model-1", coretesting.Attrs{}) + model2 := s.makeModel(c, "model-2", coretesting.Attrs{}) + model3 := s.makeModel(c, "model-3", coretesting.Attrs{}) + defer func() { + _ = model1.Close() + _ = model2.Close() + _ = model3.Close() + }() + + var expected bsonMById + + for i, st := range []*State{model1, model2, model3} { + app := AddTestingApplication(c, st, "mysql", AddTestingCharm(c, st, "mysql")) + secretState := NewSecrets(st) + uri := secrets.NewURI() + p := CreateSecretParams{ + Version: 1, + Owner: app.Tag(), + UpdateSecretParams: UpdateSecretParams{ + LeaderToken: &fakeToken{}, + Data: map[string]string{"foo": "bar"}, + }, + } + + _, err := secretState.CreateSecret(uri, p) + c.Assert(err, jc.ErrorIsNil) + + insertRev := 0 + expectRev := 1 + if i == 2 { + _, err = secretState.UpdateSecret( + uri, UpdateSecretParams{ + LeaderToken: &fakeToken{}, + Data: map[string]string{"foo": "bar2"}}) + c.Assert(err, jc.ErrorIsNil) + insertRev = 2 + expectRev = 2 + } + + docID := ensureModelUUID(st.ModelUUID(), s.state.secretConsumerKey(uri, "application-wordpress")) + err = consumerColl.Insert(bson.M{ + "_id": docID, + "model-uuid": st.ModelUUID(), + "consumer-tag": "application-wordpress", + "current-revision": insertRev, + "latest-revision": insertRev, + }) + c.Assert(err, jc.ErrorIsNil) + expected = append(expected, bson.M{ + "_id": docID, + "model-uuid": st.ModelUUID(), + "consumer-tag": "application-wordpress", + "current-revision": expectRev, + "latest-revision": expectRev, + }) + } + + sort.Sort(expected) + expectedData := upgradedData(consumerColl, expected) + s.assertUpgradedData(c, FixOwnerConsumedSecretInfo, expectedData) +} diff --git a/upgrades/backend.go b/upgrades/backend.go index 1d0bc8b4060..ea95d3ccf5b 100644 --- a/upgrades/backend.go +++ b/upgrades/backend.go @@ -15,6 +15,7 @@ type StateBackend interface { MigrateApplicationOpenedPortsToUnitScope() error EnsureInitalRefCountForExternalSecretBackends() error EnsureApplicationCharmOriginsNormalised() error + FixOwnerConsumedSecretInfo() error } // Model is an interface providing access to the details of a model within the @@ -48,3 +49,7 @@ func (s stateBackend) EnsureInitalRefCountForExternalSecretBackends() error { func (s stateBackend) EnsureApplicationCharmOriginsNormalised() error { return state.EnsureApplicationCharmOriginsNormalised(s.pool) } + +func (s stateBackend) FixOwnerConsumedSecretInfo() error { + return state.FixOwnerConsumedSecretInfo(s.pool) +} diff --git a/upgrades/steps_317.go b/upgrades/steps_317.go index 4f85f445cff..bab360bff10 100644 --- a/upgrades/steps_317.go +++ b/upgrades/steps_317.go @@ -15,6 +15,12 @@ func stateStepsFor317() []Step { run: func(context Context) error { return context.State().EnsureApplicationCharmOriginsNormalised() }, + }, &upgradeStep{ + description: "fix owner consumed secret info", + targets: []Target{DatabaseMaster}, + run: func(context Context) error { + return context.State().FixOwnerConsumedSecretInfo() + }, }, } } diff --git a/upgrades/steps_317_test.go b/upgrades/steps_317_test.go index dbcc4e06ac0..4f2d2b3e85a 100644 --- a/upgrades/steps_317_test.go +++ b/upgrades/steps_317_test.go @@ -24,3 +24,8 @@ func (s *steps317Suite) TestEnsureApplicationCharmOriginsHaveRevisions(c *gc.C) step := findStateStep(c, v317, "ensure application charm origins have revisions") c.Assert(step.Targets(), jc.DeepEquals, []upgrades.Target{upgrades.DatabaseMaster}) } + +func (s *steps317Suite) TestFixOwnerConsumedSecretInfo(c *gc.C) { + step := findStateStep(c, v317, "fix owner consumed secret info") + c.Assert(step.Targets(), jc.DeepEquals, []upgrades.Target{upgrades.DatabaseMaster}) +} From dfe343ed51d92961aae6badb5dcbb6b51157d767 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 20 Nov 2023 15:58:22 +0100 Subject: [PATCH 12/50] Adds test to verify that bad YAML indentation does not cause a panic. --- cloud/clouds_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cloud/clouds_test.go b/cloud/clouds_test.go index b8e686f1159..0d3e19960e2 100644 --- a/cloud/clouds_test.go +++ b/cloud/clouds_test.go @@ -276,6 +276,19 @@ clouds: s.assertCompareClouds(c, metadata, false) } +func (s *cloudSuite) TestMalformedYAMLNoPanic(_ *gc.C) { + // Note the bad indentation. This case was reported under LP:2039322. + metadata := ` +clouds: +manual-cloud: + type: manual + endpoint: ubuntu@some-host-fqdn +`[1:] + + // We don't care about the result, just that there is no panic. + _, _ = cloud.ParseCloudMetadata([]byte(metadata)) +} + func (s *cloudSuite) TestRegionNames(c *gc.C) { regions := []cloud.Region{ {Name: "mars"}, From 1ee200244adf88cb0bb65ff81956fce4f9bf7dd7 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Wed, 22 Nov 2023 12:51:24 +1000 Subject: [PATCH 13/50] Add support for owner secret --refresh for secrets created/updated in the same hook --- api/agent/uniter/unit.go | 9 + .../facades/agent/secretsmanager/secrets.go | 18 ++ .../agent/secretsmanager/secrets_test.go | 17 ++ apiserver/facades/agent/uniter/uniter.go | 27 ++- apiserver/facades/agent/uniter/uniter_test.go | 11 +- apiserver/facades/schema.json | 6 + rpc/params/internal.go | 1 + worker/uniter/runner/context/context.go | 77 ++++++-- worker/uniter/runner/context/context_test.go | 183 ++++++++++++++---- worker/uniter/runner/context/export_test.go | 4 + worker/uniter/runner/context/secrets.go | 25 +-- 11 files changed, 303 insertions(+), 75 deletions(-) diff --git a/api/agent/uniter/unit.go b/api/agent/uniter/unit.go index 06eac42701f..f40a4bbbef1 100644 --- a/api/agent/uniter/unit.go +++ b/api/agent/uniter/unit.go @@ -1042,6 +1042,15 @@ func (b *CommitHookParamsBuilder) AddSecretUpdates(updates []SecretUpsertArg) { } } +// AddTrackLatest records the URIs for which the latest revision should be tracked. +func (b *CommitHookParamsBuilder) AddTrackLatest(trackLatest []string) { + if len(trackLatest) == 0 { + return + } + b.arg.TrackLatest = make([]string, len(trackLatest)) + copy(b.arg.TrackLatest, trackLatest) +} + // SecretGrantRevokeArgs holds parameters for updating a secret's access. type SecretGrantRevokeArgs struct { URI *secrets.URI diff --git a/apiserver/facades/agent/secretsmanager/secrets.go b/apiserver/facades/agent/secretsmanager/secrets.go index 130ddbd297a..f02c1aa00c7 100644 --- a/apiserver/facades/agent/secretsmanager/secrets.go +++ b/apiserver/facades/agent/secretsmanager/secrets.go @@ -797,6 +797,24 @@ func (s *SecretsManagerAPI) getSecretContent(arg params.GetSecretContentArg) ( return content, backend, draining, errors.Trace(err) } +// UpdateTrackedRevisions updates the consumer info to track the latest +// revisions for the specified secrets. +func (s *SecretsManagerAPI) UpdateTrackedRevisions(uris []string) (params.ErrorResults, error) { + result := params.ErrorResults{ + Results: make([]params.ErrorResult, len(uris)), + } + for i, uriStr := range uris { + uri, err := coresecrets.ParseURI(uriStr) + if err != nil { + result.Results[i].Error = apiservererrors.ServerError(err) + continue + } + _, err = s.getConsumedRevision(uri, true, false, "", false) + result.Results[i].Error = apiservererrors.ServerError(err) + } + return result, nil +} + func (s *SecretsManagerAPI) getConsumedRevision(uri *coresecrets.URI, refresh, peek bool, label string, possibleUpdateLabel bool) (int, error) { consumerInfo, err := s.secretsConsumer.GetSecretConsumer(uri, s.authTag) if err != nil && !errors.Is(err, errors.NotFound) { diff --git a/apiserver/facades/agent/secretsmanager/secrets_test.go b/apiserver/facades/agent/secretsmanager/secrets_test.go index 587d13e1482..f6d4a42b350 100644 --- a/apiserver/facades/agent/secretsmanager/secrets_test.go +++ b/apiserver/facades/agent/secretsmanager/secrets_test.go @@ -1928,3 +1928,20 @@ func (s *SecretsManagerSuite) TestSecretsRevoke(c *gc.C) { }, }) } + +func (s *SecretsManagerSuite) TestUpdateTrackedRevisions(c *gc.C) { + defer s.setup(c).Finish() + + uri := coresecrets.NewURI() + s.secretsState.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{ + LatestRevision: 668, + }, nil).AnyTimes() + s.secretsConsumer.EXPECT().GetSecretConsumer(uri, s.authTag). + Return(nil, errors.NotFoundf("secret consumer")) + s.secretsConsumer.EXPECT().SaveSecretConsumer( + uri, s.authTag, &coresecrets.SecretConsumerMetadata{LatestRevision: 668, CurrentRevision: 668}).Return(nil) + + result, err := s.facade.UpdateTrackedRevisions([]string{uri.ID}) + c.Assert(err, jc.ErrorIsNil) + c.Assert(result, jc.DeepEquals, params.ErrorResults{Results: []params.ErrorResult{{}}}) +} diff --git a/apiserver/facades/agent/uniter/uniter.go b/apiserver/facades/agent/uniter/uniter.go index 34a04e72907..c9ac9eb6c02 100644 --- a/apiserver/facades/agent/uniter/uniter.go +++ b/apiserver/facades/agent/uniter/uniter.go @@ -2811,15 +2811,6 @@ func (u *UniterAPI) commitHookChangesForOneUnit(unitTag names.UnitTag, changes p } // TODO - do in txn once we have support for that - if len(changes.SecretDeletes) > 0 { - result, err := u.SecretsManagerAPI.RemoveSecrets(params.DeleteSecretArgs{Args: changes.SecretDeletes}) - if err == nil { - err = result.Combine() - } - if err != nil { - return errors.Annotate(err, "removing secrets") - } - } if len(changes.SecretCreates) > 0 { result, err := u.SecretsManagerAPI.CreateSecrets(params.CreateSecretArgs{Args: changes.SecretCreates}) if err == nil { @@ -2846,6 +2837,15 @@ func (u *UniterAPI) commitHookChangesForOneUnit(unitTag names.UnitTag, changes p return errors.Annotate(err, "updating secrets") } } + if len(changes.TrackLatest) > 0 { + result, err := u.SecretsManagerAPI.UpdateTrackedRevisions(changes.TrackLatest) + if err == nil { + err = result.Combine() + } + if err != nil { + return errors.Annotate(err, "updating secret tracked revisions") + } + } if len(changes.SecretGrants) > 0 { result, err := u.SecretsManagerAPI.SecretsGrant(params.GrantRevokeSecretArgs{Args: changes.SecretGrants}) if err == nil { @@ -2864,6 +2864,15 @@ func (u *UniterAPI) commitHookChangesForOneUnit(unitTag names.UnitTag, changes p return errors.Annotate(err, "revoking secrets access") } } + if len(changes.SecretDeletes) > 0 { + result, err := u.SecretsManagerAPI.RemoveSecrets(params.DeleteSecretArgs{Args: changes.SecretDeletes}) + if err == nil { + err = result.Combine() + } + if err != nil { + return errors.Annotate(err, "removing secrets") + } + } // Apply all changes in a single transaction. return u.st.ApplyOperation(state.ComposeModelOperations(modelOps...)) diff --git a/apiserver/facades/agent/uniter/uniter_test.go b/apiserver/facades/agent/uniter/uniter_test.go index 68f09be50ee..9794e64aa55 100644 --- a/apiserver/facades/agent/uniter/uniter_test.go +++ b/apiserver/facades/agent/uniter/uniter_test.go @@ -4731,7 +4731,11 @@ func (s *uniterSuite) TestCommitHookChangesWithSecrets(c *gc.C) { Description: ptr("a secret"), Label: ptr("foobar"), Value: secrets.NewSecretValue(map[string]string{"foo": "bar2"}), + }, { + URI: uri3, + Value: secrets.NewSecretValue(map[string]string{"foo3": "bar3"}), }}) + b.AddTrackLatest([]string{uri3.ID}) b.AddSecretDeletes([]apiuniter.SecretDeleteArg{{URI: uri3, Revision: ptr(1)}}) b.AddSecretGrants([]apiuniter.SecretGrantRevokeArgs{{ URI: uri, @@ -4757,7 +4761,7 @@ func (s *uniterSuite) TestCommitHookChangesWithSecrets(c *gc.C) { }) // Verify state - _, err = store.GetSecret(uri3) + _, _, err = store.GetSecretValue(uri3, 1) c.Assert(err, jc.Satisfies, errors.IsNotFound) md, err := store.GetSecret(uri) c.Assert(err, jc.ErrorIsNil) @@ -4773,6 +4777,11 @@ func (s *uniterSuite) TestCommitHookChangesWithSecrets(c *gc.C) { access, err = s.State.SecretAccess(uri2, s.mysql.Tag()) c.Assert(err, jc.ErrorIsNil) c.Assert(access, gc.Equals, secrets.RoleNone) + + info, err := s.State.GetSecretConsumer(uri3, s.wordpressUnit.Tag()) + c.Assert(err, jc.ErrorIsNil) + c.Assert(info.CurrentRevision, gc.Equals, 2) + c.Assert(info.LatestRevision, gc.Equals, 2) } func (s *uniterSuite) TestCommitHookChangesWithStorage(c *gc.C) { diff --git a/apiserver/facades/schema.json b/apiserver/facades/schema.json index cf02cdeb4b3..b78f391f49f 100644 --- a/apiserver/facades/schema.json +++ b/apiserver/facades/schema.json @@ -47931,6 +47931,12 @@ "$ref": "#/definitions/GrantRevokeSecretArg" } }, + "secret-track-latest": { + "type": "array", + "items": { + "type": "string" + } + }, "secret-updates": { "type": "array", "items": { diff --git a/rpc/params/internal.go b/rpc/params/internal.go index 4223602b38e..ea47a496e25 100644 --- a/rpc/params/internal.go +++ b/rpc/params/internal.go @@ -316,6 +316,7 @@ type CommitHookChangesArg struct { SetPodSpec *PodSpec `json:"pod-spec,omitempty"` SetRawK8sSpec *PodSpec `json:"set-raw-k8s-spec,omitempty"` SecretCreates []CreateSecretArg `json:"secret-creates,omitempty"` + TrackLatest []string `json:"secret-track-latest,omitempty"` SecretUpdates []UpdateSecretArg `json:"secret-updates,omitempty"` SecretGrants []GrantRevokeSecretArg `json:"secret-grants,omitempty"` SecretRevokes []GrantRevokeSecretArg `json:"secret-revokes,omitempty"` diff --git a/worker/uniter/runner/context/context.go b/worker/uniter/runner/context/context.go index 182b6b47656..5fe729c46ac 100644 --- a/worker/uniter/runner/context/context.go +++ b/worker/uniter/runner/context/context.go @@ -849,27 +849,28 @@ func (ctx *HookContext) GetSecret(uri *coresecrets.URI, label string, refresh, p if uri == nil && label == "" { return nil, errors.NotValidf("empty URI and label") } + if uri != nil { + if v, got := ctx.getPendingSecretValue(uri, label, refresh, peek); got { + return v, nil + } + } if label != "" { + if v, got := ctx.getPendingSecretValue(nil, label, refresh, peek); got { + return v, nil + } + } + if uri == nil && label != "" { // try to resolve label to URI by looking up owned secrets. ownedSecretURI, err := ctx.lookupOwnedSecretURIByLabel(label) if err != nil && !errors.Is(err, errors.NotFound) { return nil, err } if ownedSecretURI != nil { - if uri != nil { - return nil, errors.NewNotValid(nil, "either URI or label should be used for getting an owned secret but not both") - } - if refresh { - return nil, errors.NewNotValid(nil, "secret owner cannot use --refresh") - } // Found owned secret, no need label anymore. uri = ownedSecretURI label = "" } } - if v, got := ctx.getPendingSecretValue(uri); got { - return v, nil - } backend, err := ctx.getSecretsBackend() if err != nil { return nil, err @@ -881,18 +882,46 @@ func (ctx *HookContext) GetSecret(uri *coresecrets.URI, label string, refresh, p return v, nil } -func (ctx *HookContext) getPendingSecretValue(uri *coresecrets.URI) (coresecrets.SecretValue, bool) { - if uri == nil { +func (ctx *HookContext) getPendingSecretValue(uri *coresecrets.URI, label string, refresh, peek bool) (coresecrets.SecretValue, bool) { + if uri == nil && label == "" { return nil, false } - for _, v := range ctx.secretChanges.pendingCreates { - if v.URI != nil && v.URI.ID == uri.ID { + for i, v := range ctx.secretChanges.pendingCreates { + if uri != nil && v.URI != nil && v.URI.ID == uri.ID { + if label != "" { + pending := ctx.secretChanges.pendingCreates[i] + pending.Label = &label + ctx.secretChanges.pendingCreates[i] = pending + } + // The initial value of the secret is not stored in the database yet. + return v.Value, true + } + if label != "" && v.Label != nil && label == *v.Label { // The initial value of the secret is not stored in the database yet. return v.Value, true } } - for _, v := range ctx.secretChanges.pendingUpdates { - if v.URI != nil && v.URI.ID == uri.ID { + if !refresh && !peek { + return nil, false + } + + for i, v := range ctx.secretChanges.pendingUpdates { + if uri != nil && v.URI != nil && v.URI.ID == uri.ID { + if label != "" { + pending := ctx.secretChanges.pendingUpdates[i] + pending.Label = &label + ctx.secretChanges.pendingUpdates[i] = pending + } + if refresh { + ctx.secretChanges.pendingTrackLatest[v.URI.ID] = true + } + // The new value of the secret is going to be updated to the database. + return v.Value, v.Value != nil && !v.Value.IsEmpty() + } + if label != "" && v.Label != nil && label == *v.Label { + if refresh { + ctx.secretChanges.pendingTrackLatest[v.URI.ID] = true + } // The new value of the secret is going to be updated to the database. return v.Value, v.Value != nil && !v.Value.IsEmpty() } @@ -1512,12 +1541,13 @@ func (ctx *HookContext) doFlush(process string) error { } var ( - cleanups []coresecrets.ValueRef - pendingCreates []uniter.SecretCreateArg - pendingUpdates []uniter.SecretUpsertArg - pendingDeletes []uniter.SecretDeleteArg - pendingGrants []uniter.SecretGrantRevokeArgs - pendingRevokes []uniter.SecretGrantRevokeArgs + cleanups []coresecrets.ValueRef + pendingCreates []uniter.SecretCreateArg + pendingUpdates []uniter.SecretUpsertArg + pendingDeletes []uniter.SecretDeleteArg + pendingGrants []uniter.SecretGrantRevokeArgs + pendingRevokes []uniter.SecretGrantRevokeArgs + pendingTrackLatest []string ) for _, c := range ctx.secretChanges.pendingCreates { ref, err := secretsBackend.SaveContent(c.URI, 1, c.Value) @@ -1585,11 +1615,16 @@ func (ctx *HookContext) doFlush(process string) error { pendingRevokes = append(pendingRevokes, r) } + for uri := range ctx.secretChanges.pendingTrackLatest { + pendingTrackLatest = append(pendingTrackLatest, uri) + } + b.AddSecretCreates(pendingCreates) b.AddSecretUpdates(pendingUpdates) b.AddSecretDeletes(pendingDeletes) b.AddSecretGrants(pendingGrants) b.AddSecretRevokes(pendingRevokes) + b.AddTrackLatest(pendingTrackLatest) if ctx.modelType == model.CAAS { if err := ctx.addCommitHookChangesForCAAS(b, process); err != nil { diff --git a/worker/uniter/runner/context/context_test.go b/worker/uniter/runner/context/context_test.go index 2eaf3e73660..5506fbb8eb0 100644 --- a/worker/uniter/runner/context/context_test.go +++ b/worker/uniter/runner/context/context_test.go @@ -1080,6 +1080,7 @@ func (s *mockHookContextSuite) TestMissingAction(c *gc.C) { } func (s *mockHookContextSuite) assertSecretGetFromPendingChanges(c *gc.C, + refresh, peek bool, setPendingSecretChanges func(hc *context.HookContext, uri *coresecrets.URI, label string, value map[string]string), ) { defer s.setupMocks(c).Finish() @@ -1089,16 +1090,32 @@ func (s *mockHookContextSuite) assertSecretGetFromPendingChanges(c *gc.C, uri := coresecrets.NewURI() label := "label" data := map[string]string{"foo": "bar"} + if !refresh && !peek { + data["foo"] = "existing" + } setPendingSecretChanges(hookContext, uri, label, data) - context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, mockBackendClient{}) - value, err := hookContext.GetSecret(nil, label, false, false) + value, err := hookContext.GetSecret(nil, label, refresh, peek) c.Assert(err, jc.ErrorIsNil) c.Assert(value.EncodedValues(), jc.DeepEquals, data) } +func (s *mockHookContextSuite) TestSecretGetFromPendingChangesExisting(c *gc.C) { + s.assertSecretGetFromPendingChanges(c, false, false, + func(hc *context.HookContext, uri *coresecrets.URI, label string, value map[string]string) { + arg := uniter.SecretCreateArg{OwnerTag: s.mockUnit.Tag()} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(value) + hc.SetPendingSecretCreates( + map[string]uniter.SecretCreateArg{uri.ID: arg}) + }, + ) +} + func (s *mockHookContextSuite) TestSecretGetFromPendingCreateChanges(c *gc.C) { - s.assertSecretGetFromPendingChanges(c, + s.assertSecretGetFromPendingChanges(c, false, true, func(hc *context.HookContext, uri *coresecrets.URI, label string, value map[string]string) { arg := uniter.SecretCreateArg{OwnerTag: s.mockUnit.Tag()} arg.URI = uri @@ -1111,7 +1128,7 @@ func (s *mockHookContextSuite) TestSecretGetFromPendingCreateChanges(c *gc.C) { } func (s *mockHookContextSuite) TestAppSecretGetFromPendingCreateChanges(c *gc.C) { - s.assertSecretGetFromPendingChanges(c, + s.assertSecretGetFromPendingChanges(c, false, true, func(hc *context.HookContext, uri *coresecrets.URI, label string, value map[string]string) { arg := uniter.SecretCreateArg{OwnerTag: names.NewApplicationTag(s.mockUnit.ApplicationName())} arg.URI = uri @@ -1124,7 +1141,7 @@ func (s *mockHookContextSuite) TestAppSecretGetFromPendingCreateChanges(c *gc.C) } func (s *mockHookContextSuite) TestSecretGetFromPendingUpdateChanges(c *gc.C) { - s.assertSecretGetFromPendingChanges(c, + s.assertSecretGetFromPendingChanges(c, false, true, func(hc *context.HookContext, uri *coresecrets.URI, label string, value map[string]string) { arg := uniter.SecretUpdateArg{} arg.URI = uri @@ -1147,6 +1164,14 @@ func (mockBackend) GetContent(_ stdcontext.Context, revisionId string) (coresecr return coresecrets.NewSecretValue(map[string]string{"foo": "bar"}), nil } +type mockBackendClient struct { + secrets.BackendsClient +} + +func (mockBackendClient) GetContent(uri *coresecrets.URI, label string, refresh, peek bool) (coresecrets.SecretValue, error) { + return coresecrets.NewSecretValue(map[string]string{"foo": "existing"}), nil +} + func (s *mockHookContextSuite) TestSecretGet(c *gc.C) { ctrl := s.setupMocks(c) defer ctrl.Finish() @@ -1205,34 +1230,6 @@ func (s *mockHookContextSuite) TestSecretGet(c *gc.C) { }) } -func (s *mockHookContextSuite) TestSecretGetOwnedSecretFailedBothURIAndLabel(c *gc.C) { - defer s.setupMocks(c).Finish() - - uri := coresecrets.NewURI() - hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) - context.SetEnvironmentHookContextSecret(hookContext, uri.String(), - map[string]jujuc.SecretMetadata{ - uri.ID: {Label: "label", Owner: s.mockUnit.Tag()}, - }, nil, nil) - - _, err := hookContext.GetSecret(uri, "label", false, false) - c.Assert(err, gc.ErrorMatches, `either URI or label should be used for getting an owned secret but not both`) -} - -func (s *mockHookContextSuite) TestSecretGetOwnedSecretFailedWithUpdate(c *gc.C) { - defer s.setupMocks(c).Finish() - - uri := coresecrets.NewURI() - hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) - context.SetEnvironmentHookContextSecret(hookContext, uri.String(), - map[string]jujuc.SecretMetadata{ - uri.ID: {Label: "label", Owner: s.mockUnit.Tag()}, - }, nil, nil) - - _, err := hookContext.GetSecret(nil, "label", true, false) - c.Assert(err, gc.ErrorMatches, `secret owner cannot use --refresh`) -} - func (s *mockHookContextSuite) assertSecretGetOwnedSecretURILookup( c *gc.C, patchContext func(*context.HookContext, *coresecrets.URI, string, context.SecretsAccessor, secrets.BackendsClient), ) { @@ -1301,6 +1298,54 @@ func (s *mockHookContextSuite) TestSecretGetOwnedSecretURILookupFromPendingCreat ) } +func (s *mockHookContextSuite) TestSecretGetOwnedSecretLabelLookupFromPendingCreates(c *gc.C) { + defer s.setupMocks(c).Finish() + + hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) + uri := coresecrets.NewURI() + label := "label-" + uri.String() + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + + arg := uniter.SecretCreateArg{OwnerTag: s.mockUnit.Tag()} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(map[string]string{"foo": "bar"}) + hookContext.SetPendingSecretCreates( + map[string]uniter.SecretCreateArg{uri.ID: arg}) + + value, err := hookContext.GetSecret(nil, label, false, false) + c.Assert(err, jc.ErrorIsNil) + c.Assert(value.EncodedValues(), jc.DeepEquals, map[string]string{ + "foo": "bar", + }) +} + +func (s *mockHookContextSuite) TestSecretGetOwnedSecretUpdatePendingCreateLabel(c *gc.C) { + defer s.setupMocks(c).Finish() + + hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) + uri := coresecrets.NewURI() + label := "label-" + uri.String() + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + + arg := uniter.SecretCreateArg{OwnerTag: s.mockUnit.Tag()} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(map[string]string{"foo": "bar"}) + hookContext.SetPendingSecretCreates( + map[string]uniter.SecretCreateArg{uri.ID: arg}) + + value, err := hookContext.GetSecret(uri, "foobar", false, true) + c.Assert(err, jc.ErrorIsNil) + c.Assert(value.EncodedValues(), jc.DeepEquals, map[string]string{ + "foo": "bar", + }) + arg.Label = ptr("foobar") + c.Assert(hookContext.PendingSecretCreates(), jc.DeepEquals, map[string]uniter.SecretCreateArg{ + uri.ID: arg, + }) +} + func (s *mockHookContextSuite) TestSecretGetOwnedSecretURILookupFromPendingUpdate(c *gc.C) { s.assertSecretGetOwnedSecretURILookup(c, func(ctx *context.HookContext, uri *coresecrets.URI, label string, client context.SecretsAccessor, backend secrets.BackendsClient) { @@ -1314,6 +1359,78 @@ func (s *mockHookContextSuite) TestSecretGetOwnedSecretURILookupFromPendingUpdat ) } +func (s *mockHookContextSuite) TestSecretGetOwnedSecretLabelLookupFromPendingUpdatesPeek(c *gc.C) { + defer s.setupMocks(c).Finish() + + hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) + uri := coresecrets.NewURI() + label := "label-" + uri.String() + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + + arg := uniter.SecretUpdateArg{} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(map[string]string{"foo": "bar"}) + hookContext.SetPendingSecretUpdates( + map[string]uniter.SecretUpdateArg{uri.ID: arg}) + + value, err := hookContext.GetSecret(nil, label, false, true) + c.Assert(err, jc.ErrorIsNil) + c.Assert(value.EncodedValues(), jc.DeepEquals, map[string]string{ + "foo": "bar", + }) + c.Assert(hookContext.PendingSecretTrackLatest(), gc.HasLen, 0) +} + +func (s *mockHookContextSuite) TestSecretGetOwnedSecretLabelLookupFromPendingUpdatesRefresh(c *gc.C) { + defer s.setupMocks(c).Finish() + + hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) + uri := coresecrets.NewURI() + label := "label-" + uri.String() + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + + arg := uniter.SecretUpdateArg{} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(map[string]string{"foo": "bar"}) + hookContext.SetPendingSecretUpdates( + map[string]uniter.SecretUpdateArg{uri.ID: arg}) + + value, err := hookContext.GetSecret(nil, label, true, false) + c.Assert(err, jc.ErrorIsNil) + c.Assert(value.EncodedValues(), jc.DeepEquals, map[string]string{ + "foo": "bar", + }) + c.Assert(hookContext.PendingSecretTrackLatest(), jc.DeepEquals, map[string]bool{uri.ID: true}) +} + +func (s *mockHookContextSuite) TestSecretGetOwnedSecretUpdatePendingLabel(c *gc.C) { + defer s.setupMocks(c).Finish() + + hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) + uri := coresecrets.NewURI() + label := "label-" + uri.String() + context.SetEnvironmentHookContextSecret(hookContext, uri.String(), nil, nil, nil) + + arg := uniter.SecretUpdateArg{} + arg.URI = uri + arg.Label = ptr(label) + arg.Value = coresecrets.NewSecretValue(map[string]string{"foo": "bar"}) + hookContext.SetPendingSecretUpdates( + map[string]uniter.SecretUpdateArg{uri.ID: arg}) + + value, err := hookContext.GetSecret(uri, "foobar", false, true) + c.Assert(err, jc.ErrorIsNil) + c.Assert(value.EncodedValues(), jc.DeepEquals, map[string]string{ + "foo": "bar", + }) + arg.Label = ptr("foobar") + c.Assert(hookContext.PendingSecretUpdates(), jc.DeepEquals, map[string]uniter.SecretUpdateArg{ + uri.ID: arg, + }) +} + func ptr[T any](v T) *T { return &v } diff --git a/worker/uniter/runner/context/export_test.go b/worker/uniter/runner/context/export_test.go index 7b651ce9a11..f8283e3965d 100644 --- a/worker/uniter/runner/context/export_test.go +++ b/worker/uniter/runner/context/export_test.go @@ -356,3 +356,7 @@ func (ctx *HookContext) PendingSecretGrants() map[string]uniter.SecretGrantRevok func (ctx *HookContext) PendingSecretRevokes() map[string]uniter.SecretGrantRevokeArgs { return ctx.secretChanges.pendingRevokes } + +func (ctx *HookContext) PendingSecretTrackLatest() map[string]bool { + return ctx.secretChanges.pendingTrackLatest +} diff --git a/worker/uniter/runner/context/secrets.go b/worker/uniter/runner/context/secrets.go index 2f6787e2c77..e825629cd2e 100644 --- a/worker/uniter/runner/context/secrets.go +++ b/worker/uniter/runner/context/secrets.go @@ -16,21 +16,23 @@ import ( type secretsChangeRecorder struct { logger loggo.Logger - pendingCreates map[string]uniter.SecretCreateArg - pendingUpdates map[string]uniter.SecretUpdateArg - pendingDeletes map[string]uniter.SecretDeleteArg - pendingGrants map[string]uniter.SecretGrantRevokeArgs - pendingRevokes map[string]uniter.SecretGrantRevokeArgs + pendingCreates map[string]uniter.SecretCreateArg + pendingUpdates map[string]uniter.SecretUpdateArg + pendingDeletes map[string]uniter.SecretDeleteArg + pendingGrants map[string]uniter.SecretGrantRevokeArgs + pendingRevokes map[string]uniter.SecretGrantRevokeArgs + pendingTrackLatest map[string]bool } func newSecretsChangeRecorder(logger loggo.Logger) *secretsChangeRecorder { return &secretsChangeRecorder{ - logger: logger, - pendingCreates: make(map[string]uniter.SecretCreateArg), - pendingUpdates: make(map[string]uniter.SecretUpdateArg), - pendingDeletes: make(map[string]uniter.SecretDeleteArg), - pendingGrants: make(map[string]uniter.SecretGrantRevokeArgs), - pendingRevokes: make(map[string]uniter.SecretGrantRevokeArgs), + logger: logger, + pendingCreates: make(map[string]uniter.SecretCreateArg), + pendingUpdates: make(map[string]uniter.SecretUpdateArg), + pendingDeletes: make(map[string]uniter.SecretDeleteArg), + pendingGrants: make(map[string]uniter.SecretGrantRevokeArgs), + pendingRevokes: make(map[string]uniter.SecretGrantRevokeArgs), + pendingTrackLatest: make(map[string]bool), } } @@ -79,6 +81,7 @@ func (s *secretsChangeRecorder) remove(uri *secrets.URI, revision *int) { delete(s.pendingUpdates, uri.ID) delete(s.pendingGrants, uri.ID) delete(s.pendingRevokes, uri.ID) + delete(s.pendingTrackLatest, uri.ID) s.pendingDeletes[uri.ID] = uniter.SecretDeleteArg{URI: uri, Revision: revision} } From 1bb2c9648d703dbe83d36bc77e71470adf66e7df Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Wed, 22 Nov 2023 13:45:47 +1000 Subject: [PATCH 14/50] Ensure a secret owner can set a label back to a previous value --- state/application.go | 8 ++++---- state/secrets.go | 34 ++++++++++++++++++++++++++++++++-- state/secrets_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/state/application.go b/state/application.go index 36ee71569d1..41c5a22af29 100644 --- a/state/application.go +++ b/state/application.go @@ -767,13 +767,13 @@ func (a *Application) removeOps(asserts bson.D, op *ForcedOperation) ([]txn.Op, return nil, errors.Trace(err) } ops = append(ops, secretConsumerPermissionsOps...) - secretLabelOps, err := a.st.removeOwnerSecretLabelOps(a.ApplicationTag()) + secretLabelOps, err := a.st.removeOwnerSecretLabelsOps(a.ApplicationTag()) if err != nil { return nil, errors.Trace(err) } ops = append(ops, secretLabelOps...) - secretLabelOps, err = a.st.removeConsumerSecretLabelOps(a.ApplicationTag()) + secretLabelOps, err = a.st.removeConsumerSecretLabelsOps(a.ApplicationTag()) if err != nil { return nil, errors.Trace(err) } @@ -3035,11 +3035,11 @@ func (a *Application) removeUnitOps(u *Unit, asserts bson.D, op *ForcedOperation if op.FatalError(err) { return nil, errors.Trace(err) } - secretOwnerLabelOps, err := a.st.removeOwnerSecretLabelOps(u.Tag()) + secretOwnerLabelOps, err := a.st.removeOwnerSecretLabelsOps(u.Tag()) if op.FatalError(err) { return nil, errors.Trace(err) } - secretConsumerLabelOps, err := a.st.removeConsumerSecretLabelOps(u.Tag()) + secretConsumerLabelOps, err := a.st.removeConsumerSecretLabelsOps(u.Tag()) if op.FatalError(err) { return nil, errors.Trace(err) } diff --git a/state/secrets.go b/state/secrets.go index d2b33493b2f..c80022e7aac 100644 --- a/state/secrets.go +++ b/state/secrets.go @@ -377,6 +377,13 @@ func (s *secretsStore) UpdateSecret(uri *secrets.URI, p UpdateSecretParams) (*se if p.Label != nil && *p.Label != metadataDoc.Label { // OwnerTag has already been validated. owner, _ := names.ParseTag(metadataDoc.OwnerTag) + if metadataDoc.Label != "" { + removeOldLabelOps, err := s.st.removeOwnerSecretLabelOps(owner, metadataDoc.Label) + if err != nil { + return nil, errors.Trace(err) + } + ops = append(ops, removeOldLabelOps...) + } uniqueLabelOps, err := s.st.uniqueSecretOwnerLabelOps(owner, *p.Label) if err != nil { return nil, errors.Trace(err) @@ -1308,11 +1315,34 @@ func (st *State) uniqueSecretLabelOpsRaw(tag names.Tag, label, role string, keyG return []txn.Op{countOp, incOp}, nil } -func (st *State) removeOwnerSecretLabelOps(ownerTag names.Tag) ([]txn.Op, error) { +func (st *State) removeOwnerSecretLabelOps(ownerTag names.Tag, label string) ([]txn.Op, error) { + refCountCollection, ccloser := st.db().GetCollection(refcountsC) + defer ccloser() + + key := secretOwnerLabelKey(ownerTag, label) + countOp, count, err := nsRefcounts.CurrentOp(refCountCollection, key) + if err != nil { + return nil, errors.Trace(err) + } + if count == 0 { + return []txn.Op{countOp}, nil + } + + return []txn.Op{ + { + C: refcountsC, + Id: secretOwnerLabelKey(ownerTag, label), + Assert: txn.DocExists, + Remove: true, + }, + }, nil +} + +func (st *State) removeOwnerSecretLabelsOps(ownerTag names.Tag) ([]txn.Op, error) { return st.removeSecretLabelOps(ownerTag, secretOwnerLabelKey) } -func (st *State) removeConsumerSecretLabelOps(consumerTag names.Tag) ([]txn.Op, error) { +func (st *State) removeConsumerSecretLabelsOps(consumerTag names.Tag) ([]txn.Op, error) { return st.removeSecretLabelOps(consumerTag, secretConsumerLabelKey) } diff --git a/state/secrets_test.go b/state/secrets_test.go index 57d7f0836df..39928b6b43c 100644 --- a/state/secrets_test.go +++ b/state/secrets_test.go @@ -762,6 +762,33 @@ func (s *SecretsSuite) TestUpdateDataSetsLatestConsumerRevision(c *gc.C) { }) } +func (s *SecretsSuite) TestUpdateOwnerLabel(c *gc.C) { + uri := secrets.NewURI() + now := s.Clock.Now().Round(time.Second).UTC() + next := now.Add(time.Minute).Round(time.Second).UTC() + cp := state.CreateSecretParams{ + Version: 1, + Owner: s.owner.Tag(), + UpdateSecretParams: state.UpdateSecretParams{ + LeaderToken: &fakeToken{}, + RotatePolicy: ptr(secrets.RotateDaily), + NextRotateTime: ptr(next), + Data: map[string]string{"foo": "bar"}, + }, + } + md, err := s.store.CreateSecret(uri, cp) + c.Assert(err, jc.ErrorIsNil) + s.assertUpdatedSecret(c, md, 1, state.UpdateSecretParams{ + LeaderToken: &fakeToken{}, + Label: ptr("foobar2"), + }) + // Ensure it can be reset back to an older value. + s.assertUpdatedSecret(c, md, 1, state.UpdateSecretParams{ + LeaderToken: &fakeToken{}, + Label: ptr("foobar"), + }) +} + func (s *SecretsSuite) TestUpdateDataSetsLatestConsumerRevisionConcurrentAdd(c *gc.C) { uri := secrets.NewURI() now := s.Clock.Now().Round(time.Second).UTC() From 6111853f4a0672495ecba91e2d010ab59b4e0fed Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Thu, 23 Nov 2023 14:59:32 +0000 Subject: [PATCH 15/50] Improve the error message when precheck fails The precheck can fail in a user is trying to leap frog, so we should point out they might need to migrate to an earlier version of juju. --- apiserver/allfacades.go | 2 ++ .../facades/controller/migrationtarget/migrationtarget.go | 4 +++- .../controller/migrationtarget/migrationtarget_test.go | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apiserver/allfacades.go b/apiserver/allfacades.go index 713bb848da3..ca5bac843bd 100644 --- a/apiserver/allfacades.go +++ b/apiserver/allfacades.go @@ -127,6 +127,8 @@ func requiredMigrationFacadeVersions() facades.FacadeVersions { // The following are required to keep the agent alive during // migration. + // This list is extremely conservative, and should be trimmed down + // once we have a better idea of what is actually required. agent.Register(registry) caasadmission.Register(registry) caasagent.Register(registry) diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget.go b/apiserver/facades/controller/migrationtarget/migrationtarget.go index 2301dba4974..757162c04af 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget.go @@ -116,7 +116,9 @@ func (api *API) Prechecks(model params.MigrationModelInfo) error { return errors.Errorf(` Source controller does not support required facades for performing migration. -Upgrade the controller to a newer version of %s%s and try again. +Upgrade the controller to a newer version of %s%s or migrate to a controller +with an earlier version of the target controller and try again. + `[1:], majorMinor, patchMessage) } } diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go index 630ad79e6e7..7b7de5a7ec0 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go @@ -166,7 +166,9 @@ func (s *Suite) TestPrechecksFacadeVersionsFail(c *gc.C) { err := api.Prechecks(args) c.Assert(err, gc.ErrorMatches, ` Source controller does not support required facades for performing migration. -Upgrade the controller to a newer version of .* and try again. +Upgrade the controller to a newer version of .* or migrate to a controller +with an earlier version of the target controller and try again. + `[1:]) } @@ -184,7 +186,9 @@ func (s *Suite) TestPrechecksFacadeVersionsWithPatchFail(c *gc.C) { err := api.Prechecks(args) c.Assert(err, gc.ErrorMatches, ` Source controller does not support required facades for performing migration. -Upgrade the controller to a newer version of .* and try again. +Upgrade the controller to a newer version of .* or migrate to a controller +with an earlier version of the target controller and try again. + `[1:]) } From 920cf610d302f317ec9aabcd0f7c255dde6eb54a Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Thu, 23 Nov 2023 17:34:14 +0000 Subject: [PATCH 16/50] Prevent panic in wait-for command The following was spotted when using wait-for without quoting a string correctly. --- cmd/juju/waitfor/errors.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/juju/waitfor/errors.go b/cmd/juju/waitfor/errors.go index 64da295a81e..b0da24a6d73 100644 --- a/cmd/juju/waitfor/errors.go +++ b/cmd/juju/waitfor/errors.go @@ -102,8 +102,10 @@ func helpLineError(input string, pos query.Position) string { if leading+offset > len(input) { offset = leading - len(input) } - builder.WriteString(strings.Repeat("^", offset)) - builder.WriteString("\n") + if offset > 0 { + builder.WriteString(strings.Repeat("^", offset)) + builder.WriteString("\n") + } return builder.String() } From 362ba95796e0320662ff65fac835119d91204a74 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Fri, 24 Nov 2023 13:05:07 +1000 Subject: [PATCH 17/50] Small CLI help text fixes for relate, debug-log, model-defaults commands --- cmd/juju/application/integrate.go | 2 +- cmd/juju/commands/debuglog.go | 34 ++----------------------------- cmd/juju/model/defaults.go | 2 +- 3 files changed, 4 insertions(+), 34 deletions(-) diff --git a/cmd/juju/application/integrate.go b/cmd/juju/application/integrate.go index 5dbd218a700..9d3a9d935fb 100644 --- a/cmd/juju/application/integrate.go +++ b/cmd/juju/application/integrate.go @@ -176,7 +176,7 @@ See also: consume find-offers set-firewall-rule - suspend-integration + suspend-relation ` var localEndpointRegEx = regexp.MustCompile("^" + names.RelationSnippet + "$") diff --git a/cmd/juju/commands/debuglog.go b/cmd/juju/commands/debuglog.go index c0b1650df51..9846f4da20e 100644 --- a/cmd/juju/commands/debuglog.go +++ b/cmd/juju/commands/debuglog.go @@ -22,7 +22,6 @@ import ( "github.com/juju/juju/api/common" jujucmd "github.com/juju/juju/cmd" "github.com/juju/juju/cmd/modelcmd" - "github.com/juju/juju/core/model" "github.com/juju/juju/jujuclient" ) @@ -79,10 +78,6 @@ exit: juju debug-log --include mysql/0 --limit 50 -Include only messages from the gitlab-k8s application: - - juju debug-log --include gitlab-k8s - Show all messages from the apache/2 unit or machine 1 and then exit: juju debug-log --replay --include apache/2 --include machine-1 --no-tail @@ -201,18 +196,8 @@ func (c *debugLogCommand) Init(args []string) error { if c.ms { c.format = c.format + ".000" } - modelType, err := c.ModelType() - if err != nil { - return errors.Trace(err) - } - isCaas := modelType == model.CAAS - if isCaas { - c.params.IncludeEntity = transform.Slice(c.params.IncludeEntity, c.parseCAASEntity) - c.params.ExcludeEntity = transform.Slice(c.params.ExcludeEntity, c.parseCAASEntity) - } else { - c.params.IncludeEntity = transform.Slice(c.params.IncludeEntity, c.parseEntity) - c.params.ExcludeEntity = transform.Slice(c.params.ExcludeEntity, c.parseEntity) - } + c.params.IncludeEntity = transform.Slice(c.params.IncludeEntity, c.parseEntity) + c.params.ExcludeEntity = transform.Slice(c.params.ExcludeEntity, c.parseEntity) return cmd.CheckEmpty(args) } @@ -237,21 +222,6 @@ func (c *debugLogCommand) parseEntity(entity string) string { } } -func (c *debugLogCommand) parseCAASEntity(entity string) string { - tag, err := names.ParseTag(entity) - switch { - case strings.Contains(entity, "*"): - return entity - case err == nil && tag.Kind() == names.ApplicationTagKind: - return tag.String() - case names.IsValidApplication(entity): - return names.NewApplicationTag(entity).String() - default: - logger.Warningf("%q was not recognised as a valid application name. Only applications produce logs for CAAS models application", entity) - return entity - } -} - type DebugLogAPI interface { WatchDebugLog(params common.DebugLogParams) (<-chan common.LogMessage, error) Close() error diff --git a/cmd/juju/model/defaults.go b/cmd/juju/model/defaults.go index 45a25d31049..f294997d43e 100644 --- a/cmd/juju/model/defaults.go +++ b/cmd/juju/model/defaults.go @@ -254,7 +254,7 @@ type defaultsCommandAPI interface { // Info implements part of the cmd.Command interface. func (c *defaultsCommand) Info() *cmd.Info { return jujucmd.Info(&cmd.Info{ - Args: "[[/] ][<=value>] ...]", + Args: "[<=value>] ...]", Doc: modelDefaultsHelpDoc, Name: "model-defaults", Purpose: modelDefaultsSummary, From 942f573cf0e4e9fc4f2d683d5bc41d67c5d48578 Mon Sep 17 00:00:00 2001 From: Harry Pidcock Date: Thu, 19 Oct 2023 21:06:06 +1000 Subject: [PATCH 18/50] Fix WWW-Authenticate challenge handling with docker registries. --- docker/auth.go | 4 +- docker/auth_test.go | 2 +- docker/registry/internal/base_client.go | 4 +- docker/registry/internal/package_test.go | 1 + docker/registry/internal/transports.go | 88 ++++++- docker/registry/internal/transports_test.go | 272 ++++++++++++++++++++ make_functions.sh | 12 +- 7 files changed, 364 insertions(+), 19 deletions(-) diff --git a/docker/auth.go b/docker/auth.go index b18cb5ec2ea..8615017e1a3 100644 --- a/docker/auth.go +++ b/docker/auth.go @@ -10,6 +10,7 @@ import ( "fmt" "os" "reflect" + "strings" "time" "github.com/docker/distribution/reference" @@ -166,6 +167,7 @@ func (rid ImageRepoDetails) SecretData() ([]byte, error) { if rid.BasicAuthConfig.Empty() && rid.TokenAuthConfig.Empty() { return nil, nil } + repo := strings.Split(rid.Repository, "/")[0] rid.Repository = "" if !rid.BasicAuthConfig.Empty() && rid.BasicAuthConfig.Auth.Empty() { rid.BasicAuthConfig.Auth = NewToken( @@ -173,7 +175,7 @@ func (rid ImageRepoDetails) SecretData() ([]byte, error) { } o := dockerConfigData{ Auths: map[string]ImageRepoDetails{ - rid.ServerAddress: rid, + repo: rid, }, } return json.Marshal(o) diff --git a/docker/auth_test.go b/docker/auth_test.go index a955b1108a6..ad5db8ce304 100644 --- a/docker/auth_test.go +++ b/docker/auth_test.go @@ -113,7 +113,7 @@ func (s *authSuite) TestValidateImageRepoDetails(c *gc.C) { func (s *authSuite) TestSecretData(c *gc.C) { imageRepoDetails := docker.ImageRepoDetails{ - Repository: "test-account", + Repository: "quay.io/test-account", ServerAddress: "quay.io", BasicAuthConfig: docker.BasicAuthConfig{ Auth: docker.NewToken("xxxxx=="), diff --git a/docker/registry/internal/base_client.go b/docker/registry/internal/base_client.go index c799f6eb1e5..9335d54811f 100644 --- a/docker/registry/internal/base_client.go +++ b/docker/registry/internal/base_client.go @@ -113,8 +113,8 @@ func transportCommon(transport http.RoundTripper, repoDetails *docker.ImageRepoD ), ) } - return newTokenTransport( - transport, repoDetails.Username, repoDetails.Password, repoDetails.Auth.Content(), "", false, + return newChallengeTransport( + transport, repoDetails.Username, repoDetails.Password, repoDetails.Auth.Content(), ), nil } diff --git a/docker/registry/internal/package_test.go b/docker/registry/internal/package_test.go index 86d017c6844..96ce8307f67 100644 --- a/docker/registry/internal/package_test.go +++ b/docker/registry/internal/package_test.go @@ -29,6 +29,7 @@ type ( var ( NewErrorTransport = newErrorTransport + NewChallengeTransport = newChallengeTransport NewBasicTransport = newBasicTransport NewTokenTransport = newTokenTransport NewElasticContainerRegistryForTest = newElasticContainerRegistryForTest diff --git a/docker/registry/internal/transports.go b/docker/registry/internal/transports.go index a28957d5dd7..acfc7767159 100644 --- a/docker/registry/internal/transports.go +++ b/docker/registry/internal/transports.go @@ -27,6 +27,78 @@ func (f dynamicTransportFunc) RoundTrip(req *http.Request) (*http.Response, erro return transport.RoundTrip(req) } +type challengeTransport struct { + baseTransport http.RoundTripper + currentTransport http.RoundTripper + + username string + password string + authToken string +} + +func newChallengeTransport( + transport http.RoundTripper, username string, password string, authToken string, +) http.RoundTripper { + return &challengeTransport{ + baseTransport: transport, + username: username, + password: password, + authToken: authToken, + } +} + +func (t *challengeTransport) RoundTrip(req *http.Request) (*http.Response, error) { + transport := t.baseTransport + if t.currentTransport != nil { + transport = t.currentTransport + } + resp, err := transport.RoundTrip(req) + if err != nil { + return nil, errors.Trace(err) + } + originalResp := resp + if !isUnauthorizedResponse(originalResp) { + return resp, nil + } + for _, c := range challenge.ResponseChallenges(originalResp) { + if err != nil { + logger.Warningf("authentication failed: %s", err.Error()) + err = nil + } + switch strings.ToLower(c.Scheme) { + case "bearer": + tokenTransport := &tokenTransport{ + transport: t.baseTransport, + username: t.password, + password: t.password, + authToken: t.authToken, + } + err = tokenTransport.refreshOAuthToken(originalResp) + if err != nil { + continue + } + transport = tokenTransport + case "basic": + transport = newBasicTransport(t.baseTransport, t.username, t.password, t.authToken) + default: + err = fmt.Errorf("unknown WWW-Authenticate challenge scheme: %s", c.Scheme) + continue + } + resp, err = transport.RoundTrip(req) + if err == nil && !isUnauthorizedResponse(resp) { + t.currentTransport = transport + return resp, nil + } + } + if err != nil { + return nil, errors.Trace(err) + } + if t.password == "" && t.authToken == "" { + return nil, errors.NewUnauthorized(err, "authorization is required for a private registry") + } + return resp, nil +} + type basicTransport struct { transport http.RoundTripper username string @@ -75,19 +147,19 @@ type tokenTransport struct { username string password string authToken string - OAuthToken string + oauthToken string reuseOAuthToken bool } func newTokenTransport( - transport http.RoundTripper, username, password, authToken, OAuthToken string, reuseOAuthToken bool, + transport http.RoundTripper, username, password, authToken, oauthToken string, reuseOAuthToken bool, ) http.RoundTripper { return &tokenTransport{ transport: transport, username: username, password: password, authToken: authToken, - OAuthToken: OAuthToken, + oauthToken: oauthToken, reuseOAuthToken: reuseOAuthToken, } } @@ -131,8 +203,6 @@ func (t tokenResponse) token() string { } func (t *tokenTransport) refreshOAuthToken(failedResp *http.Response) error { - t.OAuthToken = "" - parameters := getChallengeParameters(t.scheme(), failedResp) if len(parameters) == 0 { return errors.NewForbidden(nil, "failed to refresh bearer token") @@ -180,13 +250,13 @@ func (t *tokenTransport) refreshOAuthToken(failedResp *http.Response) error { if err = decoder.Decode(&tr); err != nil { return fmt.Errorf("unable to decode token response: %s", err) } - t.OAuthToken = tr.token() + t.oauthToken = tr.token() return nil } func (t *tokenTransport) authorizeRequest(req *http.Request) error { - if t.OAuthToken != "" { - req.Header.Set("Authorization", fmt.Sprintf("%s %s", t.scheme(), t.OAuthToken)) + if t.oauthToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("%s %s", t.scheme(), t.oauthToken)) } return nil } @@ -197,7 +267,7 @@ func (t *tokenTransport) RoundTrip(req *http.Request) (*http.Response, error) { if !t.reuseOAuthToken { // We usually do not re-use the OAuth token because each API call might have different scope. // But some of the provider use long life token and there is no need to refresh. - t.OAuthToken = "" + t.oauthToken = "" } }() diff --git a/docker/registry/internal/transports_test.go b/docker/registry/internal/transports_test.go index efa5410b9d1..91f7d118d85 100644 --- a/docker/registry/internal/transports_test.go +++ b/docker/registry/internal/transports_test.go @@ -271,3 +271,275 @@ func (s *transportSuite) TestUnwrapNetError(c *gc.C) { c.Assert(unwrapedErr, jc.Satisfies, errors.IsNotFound) c.Assert(unwrapedErr, gc.ErrorMatches, `Get "https://example.com": jujud-operator:2.6.6 not found`) } + +func (s *transportSuite) TestChallengeTransportTokenRefresh(c *gc.C) { + ctrl := gomock.NewController(c) + defer ctrl.Finish() + mockRoundTripper := mocks.NewMockRoundTripper(ctrl) + + url, err := url.Parse(`https://example.com`) + c.Assert(err, jc.ErrorIsNil) + + gomock.InOrder( + // 1st try failed - bearer token was missing. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, + }, + }, + }, nil + }, + ), + // Refresh OAuth Token. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://auth.example.com/token?scope=repository%3Ajujuqa%2Fjujud-operator%3Apull&service=registry.example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + }, nil + }, + ), + // retry. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + }, + ), + ) + t := internal.NewChallengeTransport(mockRoundTripper, "", "", "dXNlcm5hbWU6cHdkMQ==") + _, err = t.RoundTrip(&http.Request{ + Header: http.Header{}, + URL: url, + }) + c.Assert(err, jc.ErrorIsNil) +} + +func (s *transportSuite) TestChallengeTransportBasic(c *gc.C) { + ctrl := gomock.NewController(c) + defer ctrl.Finish() + mockRoundTripper := mocks.NewMockRoundTripper(ctrl) + + url, err := url.Parse(`https://example.com`) + c.Assert(err, jc.ErrorIsNil) + + gomock.InOrder( + // 1st try failed - bearer token was missing. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Basic realm="my realm"`, + }, + }, + }, nil + }, + ), + // retry. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + }, + ), + ) + t := internal.NewChallengeTransport(mockRoundTripper, "", "", "dXNlcm5hbWU6cHdkMQ==") + _, err = t.RoundTrip(&http.Request{ + Header: http.Header{}, + URL: url, + }) + c.Assert(err, jc.ErrorIsNil) +} + +func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { + ctrl := gomock.NewController(c) + defer ctrl.Finish() + mockRoundTripper := mocks.NewMockRoundTripper(ctrl) + + url, err := url.Parse(`https://example.com`) + c.Assert(err, jc.ErrorIsNil) + + gomock.InOrder( + // 1st try failed - bearer token was missing. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Basic realm="my realm"`, + `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, + }, + }, + }, nil + }, + ), + // retry. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusUnauthorized, Body: ioutil.NopCloser(nil)}, nil + }, + ), + // Refresh OAuth Token. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://auth.example.com/token?scope=repository%3Ajujuqa%2Fjujud-operator%3Apull&service=registry.example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + }, nil + }, + ), + // retry. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + }, + ), + + // re-use last successful + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Basic realm="my realm"`, + `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, + }, + }, + }, nil + }, + ), + // Refresh OAuth Token. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://auth.example.com/token?scope=repository%3Ajujuqa%2Fjujud-operator%3Apull&service=registry.example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + }, nil + }, + ), + // retry. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + }, + ), + + // re-use last successful + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Basic realm="my realm"`, + `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, + }, + }, + }, nil + }, + ), + // Refresh OAuth Token. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://auth.example.com/token?scope=repository%3Ajujuqa%2Fjujud-operator%3Apull&service=registry.example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + }, nil + }, + ), + // still bad + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{ + Request: req, + StatusCode: http.StatusUnauthorized, + Body: ioutil.NopCloser(nil), + Header: http.Header{ + http.CanonicalHeaderKey("WWW-Authenticate"): []string{ + `Basic realm="my realm"`, + `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, + }, + }, + }, nil + }, + ), + // retry with basic again. + mockRoundTripper.EXPECT().RoundTrip(gomock.Any()).DoAndReturn( + func(req *http.Request) (*http.Response, error) { + c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) + c.Assert(req.URL.String(), gc.Equals, `https://example.com`) + return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + }, + ), + ) + t := internal.NewChallengeTransport(mockRoundTripper, "", "", "dXNlcm5hbWU6cHdkMQ==") + _, err = t.RoundTrip(&http.Request{ + Header: http.Header{}, + URL: url, + }) + c.Assert(err, jc.ErrorIsNil) + + // Reuse + _, err = t.RoundTrip(&http.Request{ + Header: http.Header{}, + URL: url, + }) + c.Assert(err, jc.ErrorIsNil) + + // Reauth + _, err = t.RoundTrip(&http.Request{ + Header: http.Header{}, + URL: url, + }) + c.Assert(err, jc.ErrorIsNil) +} diff --git a/make_functions.sh b/make_functions.sh index 762a51af7a8..5fd71c46902 100755 --- a/make_functions.sh +++ b/make_functions.sh @@ -152,15 +152,15 @@ build_push_operator_image() { seed_repository() { set -x - docker pull "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}" - docker tag "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}" "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}" - docker push "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}" + "$DOCKER_BIN" pull "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}" + "$DOCKER_BIN" tag "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}" "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}" + "$DOCKER_BIN" push "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}" # copy all the lts that are available for (( i = 18; ; i += 2 )); do - if docker pull "docker.io/jujusolutions/charm-base:ubuntu-$i.04" ; then - docker tag "docker.io/jujusolutions/charm-base:ubuntu-$i.04" "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04" - docker push "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04" + if "$DOCKER_BIN" pull "docker.io/jujusolutions/charm-base:ubuntu-$i.04" ; then + "$DOCKER_BIN" tag "docker.io/jujusolutions/charm-base:ubuntu-$i.04" "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04" + "$DOCKER_BIN" push "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04" else break fi From 57331382566b217bdbf2f7b3ac2b0b851d6ac3e9 Mon Sep 17 00:00:00 2001 From: Allan Vidal Date: Fri, 17 Nov 2023 15:57:56 +0000 Subject: [PATCH 19/50] Add support for downloading a specific revision with juju download --- cmd/juju/charmhub/download.go | 52 +++++++++++++++++++----- cmd/juju/charmhub/download_test.go | 63 ++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 10 deletions(-) diff --git a/cmd/juju/charmhub/download.go b/cmd/juju/charmhub/download.go index d3da4b95a6a..4b3ea834244 100644 --- a/cmd/juju/charmhub/download.go +++ b/cmd/juju/charmhub/download.go @@ -37,6 +37,12 @@ by a specified name. Downloading for a specific base can be done via --base. --base can be specified using the OS name and the version of the OS, separated by @. For example, --base ubuntu@22.04. +By default, the latest revision in the default channel will be +downloaded. To download the latest revision from another channel, +use --channel. To download a specific revision, use --revision, +which cannot be used together with --arch, --base, --channel or +--series. + Adding a hyphen as the second argument allows the download to be piped to stdout. @@ -64,6 +70,7 @@ type downloadCommand struct { channel string charmOrBundle string + revision int archivePath string pipeToStdout bool noProgress bool @@ -90,6 +97,7 @@ func (c *downloadCommand) SetFlags(f *gnuflag.FlagSet) { f.StringVar(&c.series, "series", SeriesAll, "specify a series. DEPRECATED use --base") f.StringVar(&c.base, "base", "", "specify a base") f.StringVar(&c.channel, "channel", "", "specify a channel to use instead of the default release") + f.IntVar(&c.revision, "revision", -1, "specify a revision of the charm to download") f.StringVar(&c.archivePath, "filepath", "", "filepath location of the charm to download to") f.BoolVar(&c.noProgress, "no-progress", false, "disable the progress bar") } @@ -101,6 +109,14 @@ func (c *downloadCommand) Init(args []string) error { return errors.New("--series and --base cannot be specified together") } + hasArch := c.arch != ArchAll && c.arch != "" + hasBase := c.base != "" + hasChannel := c.channel != "" + hasSeries := c.series != SeriesAll && c.series != "" + if c.revision != -1 && (hasArch || hasBase || hasChannel || hasSeries) { + return errors.New("--revision cannot be specified together with --arch, --base, --channel or --series") + } + if err := c.charmHubCommand.Init(args); err != nil { return errors.Trace(err) } @@ -191,7 +207,7 @@ func (c *downloadCommand) Run(cmdContext *cmd.Context) error { } pArch := c.arch - if pArch == "all" || pArch == "" { + if pArch == ArchAll || pArch == "" { pArch = arch.DefaultArchitecture } if base.Empty() { @@ -217,8 +233,13 @@ func (c *downloadCommand) Run(cmdContext *cmd.Context) error { path = fmt.Sprintf("%s_r%d.%s", entity.Name, entity.Revision, entityType) } - cmdContext.Infof("Fetching %s %q revision %d using %q channel and base %q", - entityType, entity.Name, entity.Revision, normChannel, normBase) + if c.revision == -1 { + cmdContext.Infof("Fetching %s %q revision %d using %q channel and base %q", + entityType, entity.Name, entity.Revision, normChannel, normBase) + } else { + cmdContext.Infof("Fetching %s %q revision %d", + entityType, entity.Name, entity.Revision) + } resourceURL, err := url.Parse(entity.Download.URL) if err != nil { @@ -280,13 +301,21 @@ func (c *downloadCommand) refresh( return nil, nil, errors.Trace(err) } - refreshConfig, err := charmhub.InstallOneFromChannel(c.charmOrBundle, normChannel.String(), charmhub.RefreshBase{ - Architecture: normBase.Architecture, - Name: normBase.OS, - Channel: normBase.Channel, - }) - if err != nil { - return nil, nil, errors.Trace(err) + var refreshConfig charmhub.RefreshConfig + if c.revision == -1 { + refreshConfig, err = charmhub.InstallOneFromChannel(c.charmOrBundle, normChannel.String(), charmhub.RefreshBase{ + Architecture: normBase.Architecture, + Name: normBase.OS, + Channel: normBase.Channel, + }) + if err != nil { + return nil, nil, errors.Trace(err) + } + } else { + refreshConfig, err = charmhub.InstallOneFromRevision(c.charmOrBundle, c.revision) + if err != nil { + return nil, nil, errors.Trace(err) + } } results, err := client.Refresh(ctx, refreshConfig) @@ -302,6 +331,9 @@ func (c *downloadCommand) refresh( for _, res := range results { if res.Error != nil { if res.Error.Code == transport.ErrorCodeRevisionNotFound { + if c.revision != -1 { + return nil, nil, errors.Errorf("unable to locate %s revison %d: %s", c.charmOrBundle, c.revision, res.Error.Message) + } possibleBases, err := c.suggested(cmdContext, base, normChannel.String(), res.Error.Extra.Releases) // The following will attempt to refresh the charm with the // suggested series. If it can't do that, it will give up after diff --git a/cmd/juju/charmhub/download_test.go b/cmd/juju/charmhub/download_test.go index 4a43ddf4260..d0eddc0f804 100644 --- a/cmd/juju/charmhub/download_test.go +++ b/cmd/juju/charmhub/download_test.go @@ -218,6 +218,69 @@ func (s *downloadSuite) TestRunWithInvalidStdout(c *gc.C) { c.Assert(err, gc.ErrorMatches, `expected a charm or bundle name, followed by hyphen to pipe to stdout`) } +func (s *downloadSuite) TestRunWithRevision(c *gc.C) { + defer s.setUpMocks(c).Finish() + + url := "http://example.org/" + + s.expectRefresh(url) + s.expectDownload(c, url) + s.expectFilesystem(c) + + command := &downloadCommand{ + charmHubCommand: s.newCharmHubCommand(), + } + command.SetFilesystem(s.filesystem) + err := cmdtesting.InitCommand(command, []string{"test", "--revision=123"}) + c.Assert(err, jc.ErrorIsNil) + + ctx := commandContextForTest(c) + err = command.Run(ctx) + c.Assert(err, jc.ErrorIsNil) + c.Assert(cmdtesting.Stderr(ctx), gc.Matches, "(?s)"+` +Fetching charm "test" revision 123 +Install the "test" charm with: + juju deploy ./test_r123\.charm +`[1:]) +} + +func (s *downloadSuite) TestRunWithRevisionNotFound(c *gc.C) { + defer s.setUpMocks(c).Finish() + + s.expectRefreshUnsupportedBase() + + command := &downloadCommand{ + charmHubCommand: s.newCharmHubCommand(), + } + command.SetFilesystem(s.filesystem) + err := cmdtesting.InitCommand(command, []string{"test", "--revision=99"}) + c.Assert(err, jc.ErrorIsNil) + + ctx := commandContextForTest(c) + err = command.Run(ctx) + c.Assert(err, gc.ErrorMatches, `unable to locate test revison 99: No revision was found in the Store.`) +} + +func (s *downloadSuite) TestRunWithRevisionAndOtherArgs(c *gc.C) { + defer s.setUpMocks(c).Finish() + + command := &downloadCommand{ + charmHubCommand: s.newCharmHubCommand(), + } + + err := cmdtesting.InitCommand(command, []string{"test", "--arch=amd64", "--revision=99"}) + c.Check(err, gc.ErrorMatches, `--revision cannot be specified together with --arch, --base, --channel or --series`) + + err = cmdtesting.InitCommand(command, []string{"test", "--base=ubuntu@22.04", "--revision=99"}) + c.Check(err, gc.ErrorMatches, `--revision cannot be specified together with --arch, --base, --channel or --series`) + + err = cmdtesting.InitCommand(command, []string{"test", "--channel=edge", "--revision=99"}) + c.Check(err, gc.ErrorMatches, `--revision cannot be specified together with --arch, --base, --channel or --series`) + + err = cmdtesting.InitCommand(command, []string{"test", "--series=jammy", "--revision=99"}) + c.Check(err, gc.ErrorMatches, `--revision cannot be specified together with --arch, --base, --channel or --series`) +} + func (s *downloadSuite) newCharmHubCommand() *charmHubCommand { return &charmHubCommand{ arches: arch.AllArches(), From 0f507dccc6243b5fbeda136c740bae6b021e8de4 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Mon, 27 Nov 2023 11:17:11 +1000 Subject: [PATCH 20/50] Fix constaints processing on k8s to handle case where just topology-key is specfied without any other label selection terms --- .../provider/application/constraints.go | 4 +- .../provider/application/constraints_test.go | 213 ++++++++++++++++++ 2 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 caas/kubernetes/provider/application/constraints_test.go diff --git a/caas/kubernetes/provider/application/constraints.go b/caas/kubernetes/provider/application/constraints.go index 45cc4176aa9..4e77a718e46 100644 --- a/caas/kubernetes/provider/application/constraints.go +++ b/caas/kubernetes/provider/application/constraints.go @@ -245,7 +245,7 @@ func processPodAffinity(pod *core.PodSpec, affinityLabels map[string]string) err } var affinityTerm core.PodAffinityTerm updateAffinityTerm(&affinityTerm, affinityTags) - if len(affinityTerm.LabelSelector.MatchExpressions) > 0 { + if len(affinityTerm.LabelSelector.MatchExpressions) > 0 || affinityTerm.TopologyKey != "" { pod.Affinity.PodAffinity = &core.PodAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{affinityTerm}, } @@ -253,7 +253,7 @@ func processPodAffinity(pod *core.PodSpec, affinityLabels map[string]string) err var antiAffinityTerm core.PodAffinityTerm updateAffinityTerm(&antiAffinityTerm, antiAffinityTags) - if len(antiAffinityTerm.LabelSelector.MatchExpressions) > 0 { + if len(antiAffinityTerm.LabelSelector.MatchExpressions) > 0 || antiAffinityTerm.TopologyKey != "" { pod.Affinity.PodAntiAffinity = &core.PodAntiAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{antiAffinityTerm}, } diff --git a/caas/kubernetes/provider/application/constraints_test.go b/caas/kubernetes/provider/application/constraints_test.go new file mode 100644 index 00000000000..ce39bb93c58 --- /dev/null +++ b/caas/kubernetes/provider/application/constraints_test.go @@ -0,0 +1,213 @@ +// Copyright 2023 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package application_test + +import ( + "errors" + + jc "github.com/juju/testing/checkers" + gc "gopkg.in/check.v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/juju/juju/caas/kubernetes/provider/application" + "github.com/juju/juju/core/constraints" + "github.com/juju/juju/testing" +) + +type applyConstraintsSuite struct { + testing.BaseSuite +} + +var _ = gc.Suite(&applyConstraintsSuite{}) + +func (s *applyConstraintsSuite) TestMemory(c *gc.C) { + pod := &corev1.PodSpec{} + configureConstraint := func(got *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + c.Assert(got, gc.Equals, pod) + c.Assert(resourceName, gc.Equals, corev1.ResourceName("memory")) + c.Assert(value, gc.Equals, "4096Mi") + return errors.New("boom") + } + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("mem=4G"), configureConstraint) + c.Assert(err, gc.ErrorMatches, "configuring memory constraint for foo: boom") +} + +func (s *applyConstraintsSuite) TestCPU(c *gc.C) { + pod := &corev1.PodSpec{} + configureConstraint := func(got *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + c.Assert(got, gc.Equals, pod) + c.Assert(resourceName, gc.Equals, corev1.ResourceName("cpu")) + c.Assert(value, gc.Equals, "2m") + return errors.New("boom") + } + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("cpu-power=2"), configureConstraint) + c.Assert(err, gc.ErrorMatches, "configuring cpu constraint for foo: boom") +} + +func (s *applyConstraintsSuite) TestArch(c *gc.C) { + configureConstraint := func(got *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("arch=arm64"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.NodeSelector, jc.DeepEquals, map[string]string{"kubernetes.io/arch": "arm64"}) +} + +func (s *applyConstraintsSuite) TestPodAffinityJustTopologyKey(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=pod.topology-key=foo"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAffinity, jc.DeepEquals, &corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{}, + TopologyKey: "foo", + }}, + }) +} + +func (s *applyConstraintsSuite) TestAffinityPod(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=pod.hello=world|universe,pod.^goodbye=world"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAffinity, jc.DeepEquals, &corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: nil, + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: "goodbye", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"world"}, + }, { + Key: "hello", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"world", "universe"}, + }}, + }, + }}, + }) +} + +func (s *applyConstraintsSuite) TestPodAffinityAll(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=pod.hello=world,pod.^goodbye=world,pod.topology-key=foo"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAffinity, jc.DeepEquals, &corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: nil, + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: "goodbye", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"world"}, + }, { + Key: "hello", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"world"}, + }}, + }, + TopologyKey: "foo", + }}, + }) +} + +func (s *applyConstraintsSuite) TestAntiPodAffinityJustTopologyKey(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=anti-pod.topology-key=foo"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAntiAffinity, jc.DeepEquals, &corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{}, + TopologyKey: "foo", + }}, + }) +} + +func (s *applyConstraintsSuite) TestAntiPodAffinity(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=anti-pod.hello=world|universe,anti-pod.^goodbye=world"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAntiAffinity, jc.DeepEquals, &corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: nil, + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: "goodbye", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"world"}, + }, { + Key: "hello", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"world", "universe"}, + }}, + }, + }}, + }) +} + +func (s *applyConstraintsSuite) TestAntiPodAffinityAll(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=anti-pod.hello=world,anti-pod.^goodbye=world,anti-pod.topology-key=foo"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.PodAntiAffinity, jc.DeepEquals, &corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: nil, + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: "goodbye", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"world"}, + }, { + Key: "hello", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"world"}, + }}, + }, + TopologyKey: "foo", + }}, + }) +} + +func (s *applyConstraintsSuite) TestNodeAntiAffinity(c *gc.C) { + configureConstraint := func(pod *corev1.PodSpec, resourceName corev1.ResourceName, value string) (err error) { + return errors.New("unexpected") + } + pod := &corev1.PodSpec{} + err := application.ApplyConstraints(pod, "foo", constraints.MustParse("tags=node.hello=world|universe,node.^goodbye=world"), configureConstraint) + c.Assert(err, jc.ErrorIsNil) + c.Assert(pod.Affinity.NodeAffinity, jc.DeepEquals, &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{{ + MatchExpressions: []corev1.NodeSelectorRequirement{{ + Key: "goodbye", + Operator: corev1.NodeSelectorOpNotIn, + Values: []string{"world"}, + }, { + Key: "hello", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"world", "universe"}, + }}, + }}, + }, + }) +} From 0fe2b13d5a50bfa9ea1806b366b9d4d1b683f393 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Mon, 27 Nov 2023 16:43:19 +1000 Subject: [PATCH 21/50] Ensure placeholder port is removed from k8s service when open-port is used --- .../provider/application/application.go | 21 ++++++++++++++----- .../provider/application/application_test.go | 4 ++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/caas/kubernetes/provider/application/application.go b/caas/kubernetes/provider/application/application.go index 04a309f5030..1aab85e8f9c 100644 --- a/caas/kubernetes/provider/application/application.go +++ b/caas/kubernetes/provider/application/application.go @@ -658,6 +658,11 @@ func (a *app) configureHeadlessService(name string, annotation annotations.Annot return svc.Apply(context.Background(), a.client) } +const ( + placeholderPortName = "placeholder" + placeholderPort = 65535 +) + // configureDefaultService configures the default service for the application. // It's only configured once when the application was deployed in the first time. func (a *app) configureDefaultService(annotation annotations.Annotation) (err error) { @@ -670,8 +675,8 @@ func (a *app) configureDefaultService(annotation annotations.Annotation) (err er Selector: a.selectorLabels(), Type: corev1.ServiceTypeClusterIP, Ports: []corev1.ServicePort{{ - Name: "placeholder", - Port: 65535, + Name: placeholderPortName, + Port: placeholderPort, }}, }, }) @@ -749,10 +754,16 @@ func (a *app) UpdatePorts(ports []caas.ServicePort, updateContainerPorts bool) e var expectedPorts []corev1.ServicePort for _, p := range svc.Service.Spec.Ports { - if !strings.HasPrefix(p.Name, portNamePrefix) { - // The ports are not mamanged by Juju should be kept. - expectedPorts = append(expectedPorts, p) + if p.Name == placeholderPortName && len(ports) > 0 { + // Ignore placeholder port if there are ports supplied by the charm. + continue + } + if strings.HasPrefix(p.Name, portNamePrefix) { + // Port managed by Juju - will be replaced, + continue } + // The ports that are not managed by Juju should be kept. + expectedPorts = append(expectedPorts, p) } for _, port := range ports { sp, err := convertServicePort(port) diff --git a/caas/kubernetes/provider/application/application_test.go b/caas/kubernetes/provider/application/application_test.go index f6b3f2e6908..d17e2db2054 100644 --- a/caas/kubernetes/provider/application/application_test.go +++ b/caas/kubernetes/provider/application/application_test.go @@ -1475,6 +1475,10 @@ func getDefaultSvc() *corev1.Service { Selector: map[string]string{"app.kubernetes.io/name": "gitlab"}, Type: corev1.ServiceTypeClusterIP, + Ports: []corev1.ServicePort{{ + Name: "placeholder", + Port: 65535, + }}, }, } } From 92a47d21d2dcdf700082157c4005ff22bef25474 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 27 Nov 2023 10:22:10 +0100 Subject: [PATCH 22/50] Adds --destroy-storage to integration test controller cleanup. Teardown has been observed to fail with a prompt to include it. --- tests/includes/juju.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/includes/juju.sh b/tests/includes/juju.sh index 333c50beced..bfd7e9658d8 100644 --- a/tests/includes/juju.sh +++ b/tests/includes/juju.sh @@ -401,7 +401,7 @@ destroy_controller() { echo "====> Destroying juju ($(green "${name}"))" if [[ ${KILL_CONTROLLER:-} != "true" ]]; then - echo "${name}" | xargs -I % juju destroy-controller --destroy-all-models -y % 2>&1 | OUTPUT "${output}" + echo "${name}" | xargs -I % juju destroy-controller --destroy-all-models --destroy-storage -y % 2>&1 | OUTPUT "${output}" else echo "${name}" | xargs -I % juju kill-controller -t 0 -y % 2>&1 | OUTPUT "${output}" fi From 1ee1252cd69faf31ea02e101ca383fda6d5b9855 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 27 Nov 2023 12:21:20 +0100 Subject: [PATCH 23/50] Removes println testing artefact from CAAS applciation provisioner DestroyUnits API. --- api/controller/caasapplicationprovisioner/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/controller/caasapplicationprovisioner/client.go b/api/controller/caasapplicationprovisioner/client.go index e47a84da808..756f9a51644 100644 --- a/api/controller/caasapplicationprovisioner/client.go +++ b/api/controller/caasapplicationprovisioner/client.go @@ -415,7 +415,6 @@ func (c *Client) DestroyUnits(unitNames []string) error { args := params.DestroyUnitsParams{} args.Units = make([]params.DestroyUnitParams, 0, len(unitNames)) - fmt.Println(unitNames) for _, unitName := range unitNames { tag := names.NewUnitTag(unitName) args.Units = append(args.Units, params.DestroyUnitParams{ From e32ca0e2b2003b01aa88393bb3382a3264806e45 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 27 Nov 2023 12:24:38 +0100 Subject: [PATCH 24/50] Replaces ioutil with io for NopCloser in transport tests. --- docker/registry/internal/transports_test.go | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docker/registry/internal/transports_test.go b/docker/registry/internal/transports_test.go index 45833c4cf01..afe75bb6a3b 100644 --- a/docker/registry/internal/transports_test.go +++ b/docker/registry/internal/transports_test.go @@ -289,7 +289,7 @@ func (s *transportSuite) TestChallengeTransportTokenRefresh(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Bearer realm="https://auth.example.com/token",service="registry.example.com",scope="repository:jujuqa/jujud-operator:pull"`, @@ -306,7 +306,7 @@ func (s *transportSuite) TestChallengeTransportTokenRefresh(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + Body: io.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), }, nil }, ), @@ -315,7 +315,7 @@ func (s *transportSuite) TestChallengeTransportTokenRefresh(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(nil)}, nil }, ), ) @@ -344,7 +344,7 @@ func (s *transportSuite) TestChallengeTransportBasic(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Basic realm="my realm"`, @@ -358,7 +358,7 @@ func (s *transportSuite) TestChallengeTransportBasic(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(nil)}, nil }, ), ) @@ -387,7 +387,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Basic realm="my realm"`, @@ -402,7 +402,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusUnauthorized, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusUnauthorized, Body: io.NopCloser(nil)}, nil }, ), // Refresh OAuth Token. @@ -413,7 +413,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + Body: io.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), }, nil }, ), @@ -422,7 +422,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(nil)}, nil }, ), @@ -434,7 +434,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Basic realm="my realm"`, @@ -452,7 +452,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + Body: io.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), }, nil }, ), @@ -461,7 +461,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Bearer " + `OAuth-jwt-token`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(nil)}, nil }, ), @@ -473,7 +473,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Basic realm="my realm"`, @@ -491,7 +491,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), + Body: io.NopCloser(strings.NewReader(`{"token": "OAuth-jwt-token", "access_token": "OAuth-jwt-token","expires_in": 300}`)), }, nil }, ), @@ -503,7 +503,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { return &http.Response{ Request: req, StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(nil), + Body: io.NopCloser(nil), Header: http.Header{ http.CanonicalHeaderKey("WWW-Authenticate"): []string{ `Basic realm="my realm"`, @@ -518,7 +518,7 @@ func (s *transportSuite) TestChallengeTransportMulti(c *gc.C) { func(req *http.Request) (*http.Response, error) { c.Assert(req.Header, jc.DeepEquals, http.Header{"Authorization": []string{"Basic " + `dXNlcm5hbWU6cHdkMQ==`}}) c.Assert(req.URL.String(), gc.Equals, `https://example.com`) - return &http.Response{StatusCode: http.StatusOK, Body: ioutil.NopCloser(nil)}, nil + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(nil)}, nil }, ), ) From aa4579717cf7c3c3460e50e53694c6ffb214f82b Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Mon, 27 Nov 2023 10:03:13 -0500 Subject: [PATCH 25/50] Formatting --- tests/suites/deploy/deploy_charms.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/deploy/deploy_charms.sh b/tests/suites/deploy/deploy_charms.sh index ab9fc9f27f7..6f5ae38f77f 100644 --- a/tests/suites/deploy/deploy_charms.sh +++ b/tests/suites/deploy/deploy_charms.sh @@ -176,8 +176,8 @@ run_deploy_lxd_to_machine() { } run_deploy_lxd_to_container() { - # Ensure profiles get applied correctly to containers - # and 1 gets added if a subordinate is added. + # Ensure profiles get applied correctly to containers + # and 1 gets added if a subordinate is added. echo model_name="test-deploy-lxd-container" From 606c98e2a798bdf3245ae5a45f1ff8b06d5c8eff Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Tue, 25 Jul 2023 20:43:17 +0100 Subject: [PATCH 26/50] Output controller and model logs to archive The following will tail the log files for the controller and any model that uses the add_model function. This should make it easier to see if there is a problem with the controller/model whilst a test is running. This does it's best to ensure we clean the pids up, but it's not 100% acurate. Also if the pid has been replaced with the same id, then you're SOL'd. For most if not all CI jobs this will be fine. --- tests/includes/juju.sh | 56 +++++++++++++++++++++++++----- tests/includes/pids.sh | 14 ++++++++ tests/main.sh | 1 + tests/suites/ck/ck.sh | 2 +- tests/suites/secrets_iaas/cmr.sh | 4 +-- tests/suites/secrets_iaas/juju.sh | 2 +- tests/suites/secrets_iaas/vault.sh | 6 ++-- 7 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 tests/includes/pids.sh diff --git a/tests/includes/juju.sh b/tests/includes/juju.sh index 6c3b5013832..c094981bd2a 100644 --- a/tests/includes/juju.sh +++ b/tests/includes/juju.sh @@ -137,7 +137,7 @@ bootstrap() { exit 1 fi - add_model "${model}" "${cloud}" "${bootstrapped_name}" "${output}" + juju_add_model "${model}" "${cloud}" "${bootstrapped_name}" "${output}" name="${bootstrapped_name}" BOOTSTRAPPED_CLOUD=$(juju show-model controller | yq -o=j | jq -r '.[] | .cloud') export BOOTSTRAPPED_CLOUD @@ -163,9 +163,9 @@ bootstrap() { export BOOTSTRAPPED_JUJU_CTRL_NAME="${name}" } -# add_model is used to add a model for tracking. This is for internal use only -# and shouldn't be used by any of the tests directly. -add_model() { +# juju_add_model is used to add a model for tracking. This is for internal use +# only and shouldn't be used by any of the tests directly. +juju_add_model() { local model cloud controller model=${1} @@ -175,16 +175,25 @@ add_model() { OUT=$(juju controllers --format=json | jq '.controllers | .["${bootstrapped_name}"] | .cloud' | grep "${cloud}" || true) if [[ -n ${OUT} ]]; then - juju add-model -c "${controller}" "${model}" 2>&1 | OUTPUT "${output}" + juju add-model --show-log -c "${controller}" "${model}" 2>&1 | OUTPUT "${output}" else - juju add-model -c "${controller}" "${model}" "${cloud}" 2>&1 | OUTPUT "${output}" + juju add-model --show-log -c "${controller}" "${model}" "${cloud}" 2>&1 | OUTPUT "${output}" fi - post_add_model + post_add_model "${controller}" "${model}" echo "${model}" >>"${TEST_DIR}/models" } +add_model() { + local model + + model=${1} + + juju add-model --show-log "${model}" 2>&1 + post_add_model "" "${model}" +} + # add_images_for_vsphere is used to add-image with known vSphere template paths for LTS series # and shouldn't be used by any of the tests directly. add_images_for_vsphere() { @@ -248,7 +257,7 @@ juju_bootstrap() { ${command} "$@" 2>&1 | OUTPUT "${output}" echo "${name}" >>"${TEST_DIR}/jujus" - post_bootstrap + post_bootstrap "${name}" "${model}" } # pre_bootstrap contains setup required before bootstrap specific to providers @@ -300,17 +309,46 @@ pre_bootstrap() { # and shouldn't be used by any of the tests directly. Calls post_add_model # models are added during bootstrap. post_bootstrap() { + local name model + + name=${1} + model=${2} + + # Setup up log tailing on the controller. + # shellcheck disable=SC2069 + juju debug-log -m "${name}:controller" --replay --tail 2>&1 >"${TEST_DIR}/controller-debug.log" & + CMD_PID=$! + echo "${CMD_PID}" >>"${TEST_DIR}/pids" + case "${BOOTSTRAP_PROVIDER:-}" in "vsphere") rm -r "${TEST_DIR}"/image-streams ;; esac - post_add_model + post_add_model "${name}" "${model}" } # post_add_model does provider specific config required after a new model is added # and shouldn't be used by any of the tests directly. post_add_model() { + local controller model + + controller=${1} + model=${2} + + ctrl_arg="${controller}:${model}" + log_file="${controller}-${model}.log" + if [[ -z ${controller} ]]; then + ctrl_arg="${model}" + log_file="${model}.log" + fi + + # Setup up log tailing on the controller. + # shellcheck disable=SC2069 + juju debug-log -m "${ctrl_arg}" --replay --tail 2>&1 >"${TEST_DIR}/${log_file}" & + CMD_PID=$! + echo "${CMD_PID}" >>"${TEST_DIR}/pids" + case "${BOOTSTRAP_PROVIDER:-}" in "vsphere") add_images_for_vsphere diff --git a/tests/includes/pids.sh b/tests/includes/pids.sh new file mode 100644 index 00000000000..7a1695296af --- /dev/null +++ b/tests/includes/pids.sh @@ -0,0 +1,14 @@ +cleanup_pids() { + if [[ -f "${TEST_DIR}/pids" ]]; then + echo "====> Cleaning up pids" + + while read -r pid; do + if ps -p "${pid}" >/dev/null; then + kill -9 "${pid}" || true + fi + done <"${TEST_DIR}/pids" + rm -f "${TEST_DIR}/pids" || true + + fi + echo "====> Completed cleaning up pids" +} diff --git a/tests/main.sh b/tests/main.sh index f582a0fc365..29563ffb190 100755 --- a/tests/main.sh +++ b/tests/main.sh @@ -277,6 +277,7 @@ cleanup() { archive_logs "partial" + cleanup_pids cleanup_jujus cleanup_funcs diff --git a/tests/suites/ck/ck.sh b/tests/suites/ck/ck.sh index 86c1f1e19d5..63967d8761a 100644 --- a/tests/suites/ck/ck.sh +++ b/tests/suites/ck/ck.sh @@ -107,7 +107,7 @@ run_deploy_caas_workload() { controller_name=$(juju controllers --format json | jq -r '.controllers | keys[0]') juju add-k8s "${k8s_cloud_name}" --storage "${storage}" --controller "${controller_name}" 2>&1 | OUTPUT "${file}" - add_model "${model_name}" "${k8s_cloud_name}" "${controller_name}" "${file}" + juju_add_model "${model_name}" "${k8s_cloud_name}" "${controller_name}" "${file}" juju deploy snappass-test diff --git a/tests/suites/secrets_iaas/cmr.sh b/tests/suites/secrets_iaas/cmr.sh index 5f88a58fb06..a52be9fd661 100644 --- a/tests/suites/secrets_iaas/cmr.sh +++ b/tests/suites/secrets_iaas/cmr.sh @@ -2,12 +2,12 @@ run_secrets_cmr() { echo echo "First set up a cross model relation" - juju --show-log add-model "model-secrets-offer" + add_model "model-secrets-offer" juju --show-log deploy juju-qa-dummy-source juju --show-log offer dummy-source:sink wait_for "dummy-source" "$(idle_condition "dummy-source")" - juju --show-log add-model "model-secrets-consume" + add_model "model-secrets-consume" juju --show-log deploy juju-qa-dummy-sink juju --show-log integrate dummy-sink model-secrets-offer.dummy-source diff --git a/tests/suites/secrets_iaas/juju.sh b/tests/suites/secrets_iaas/juju.sh index 312b290dfdb..75374ea41f2 100644 --- a/tests/suites/secrets_iaas/juju.sh +++ b/tests/suites/secrets_iaas/juju.sh @@ -69,7 +69,7 @@ check_secrets() { run_secrets_juju() { echo - juju --show-log add-model "model-secrets-juju" + add_model "model-secrets-juju" check_secrets destroy_model "model-secrets-juju" } diff --git a/tests/suites/secrets_iaas/vault.sh b/tests/suites/secrets_iaas/vault.sh index 17263d0756e..bce44e1a555 100644 --- a/tests/suites/secrets_iaas/vault.sh +++ b/tests/suites/secrets_iaas/vault.sh @@ -5,7 +5,7 @@ run_secrets_vault() { model_name='model-secrets-vault' juju add-secret-backend myvault vault endpoint="$VAULT_ADDR" token="$VAULT_TOKEN" - juju --show-log add-model "$model_name" --config secret-backend=myvault + add_model "$model_name" --config secret-backend=myvault check_secrets @@ -19,7 +19,7 @@ run_secret_drain() { prepare_vault model_name='model-secrets-drain' - juju --show-log add-model "$model_name" + add_model "$model_name" vault_backend_name='myvault' juju add-secret-backend "$vault_backend_name" vault endpoint="$VAULT_ADDR" token="$VAULT_TOKEN" @@ -68,7 +68,7 @@ run_secret_drain() { } prepare_vault() { - juju add-model "model-vault-provider" + add_model "model-vault-provider" if ! which "vault" >/dev/null 2>&1; then sudo snap install vault From 73d347075139b18c094d387e78e2810349e888d1 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 13:54:06 -0500 Subject: [PATCH 27/50] Fix LP 2003971. The logic for handling a revision-not-found error from charmhub is wrong and can result in deploying a charm to an unsupported operating system when the operating system requested by the user isn't found in the channel requested. Fix by always failing on that error rather than checking to see if a user requested a specific channel for the charm. This was missed as we never tested on a charm which had support for only one operating system in a channel, where we tried to deploy a different operating system. Adding a new test once we have a new channel for our test charms. --- core/charm/repository/charmhub.go | 83 +++------- core/charm/repository/charmhub_test.go | 214 ++----------------------- 2 files changed, 35 insertions(+), 262 deletions(-) diff --git a/core/charm/repository/charmhub.go b/core/charm/repository/charmhub.go index 1ced4675c3b..4bacfea0c00 100644 --- a/core/charm/repository/charmhub.go +++ b/core/charm/repository/charmhub.go @@ -261,7 +261,7 @@ func (c *CharmHubRepository) retryResolveWithPreferredChannel(charmURL *charm.UR ) switch resErr.Code { case transport.ErrorCodeInvalidCharmPlatform, transport.ErrorCodeInvalidCharmBase: - c.logger.Tracef("Invalid charm platform %q %v - Default Base: %v", charmURL, origin, resErr.Extra.DefaultBases) + c.logger.Tracef("Invalid charm base %q %v - Default Base: %v", charmURL, origin, resErr.Extra.DefaultBases) if bases, err = c.selectNextBases(resErr.Extra.DefaultBases, origin); err != nil { return nil, errors.Annotatef(err, "selecting next bases") @@ -270,9 +270,7 @@ func (c *CharmHubRepository) retryResolveWithPreferredChannel(charmURL *charm.UR case transport.ErrorCodeRevisionNotFound: c.logger.Tracef("Revision not found %q %v - Releases: %v", charmURL, origin, resErr.Extra.Releases) - if bases, err = c.selectNextBasesFromReleases(resErr.Extra.Releases, origin); err != nil { - return nil, errors.Annotatef(err, "selecting releases") - } + return nil, errors.Annotatef(c.handleRevisionNotFound(resErr.Extra.Releases, origin), "selecting releases") default: return nil, errors.Errorf("resolving error: %s", resErr.Message) @@ -572,36 +570,30 @@ func (c *CharmHubRepository) selectNextBases(bases []transport.Base, origin core return results, nil } -func (c *CharmHubRepository) selectNextBasesFromReleases(releases []transport.Release, origin corecharm.Origin) ([]corecharm.Platform, error) { +func (c *CharmHubRepository) handleRevisionNotFound(releases []transport.Release, origin corecharm.Origin) error { if len(releases) == 0 { - return nil, errors.Errorf("no releases available") + return errors.Errorf("no releases available") } - if origin.Platform.Channel == "" { - // If the user passed in a branch, but not enough information about the - // arch and channel, then we can help by giving a better error message. - if origin.Channel != nil && origin.Channel.Branch != "" { - return nil, errors.Errorf("ambiguous arch and series with channel %q, specify both arch and series along with channel", origin.Channel.String()) - } - // If the origin is empty, then we want to help the user out - // by display a series of suggestions to try. - suggestions := c.composeSuggestions(releases, origin) - var s string - if len(suggestions) > 0 { - s = fmt.Sprintf("\navailable releases are:\n %v", strings.Join(suggestions, "\n ")) - } - var channelName string - if origin.Channel != nil { - channelName = origin.Channel.String() - } - return nil, errSelection{ - err: errors.Errorf( - "charm or bundle not found for channel %q, platform %q%s", - channelName, origin.Platform.String(), s), - } + // If the user passed in a branch, but not enough information about the + // arch and channel, then we can help by giving a better error message. + if origin.Channel != nil && origin.Channel.Branch != "" { + return errors.Errorf("ambiguous arch and series with channel %q, specify both arch and series along with channel", origin.Channel.String()) + } + // Help the user out by creating a list of channel/base suggestions to try. + suggestions := c.composeSuggestions(releases, origin) + var s string + if len(suggestions) > 0 { + s = fmt.Sprintf("\navailable releases are:\n %v", strings.Join(suggestions, "\n ")) + } + var channelName string + if origin.Channel != nil { + channelName = origin.Channel.String() + } + return errSelection{ + err: errors.Errorf( + "charm or bundle not found for channel %q, base %q%s", + channelName, origin.Platform.String(), s), } - - // From the suggestion list, go look up a release that we can retry. - return selectReleaseByArchAndChannel(releases, origin) } type errSelection struct { @@ -755,35 +747,6 @@ func (c *CharmHubRepository) composeSuggestions(releases []transport.Release, or return suggestions } -func selectReleaseByArchAndChannel(releases []transport.Release, origin corecharm.Origin) ([]corecharm.Platform, error) { - var ( - empty = origin.Channel == nil - channel charm.Channel - ) - if !empty { - channel = origin.Channel.Normalize() - } - var results []corecharm.Platform - for _, release := range releases { - base := release.Base - - arch, os := base.Architecture, base.Name - track, err := corecharm.ChannelTrack(base.Channel) - if err != nil { - return nil, errors.Trace(err) - } - platform := corecharm.NormalisePlatformSeries(corecharm.Platform{ - Architecture: origin.Platform.Architecture, - OS: os, - Channel: track, - }) - if (empty || channel.String() == release.Channel) && (arch == "all" || arch == origin.Platform.Architecture) { - results = append(results, platform) - } - } - return results, nil -} - // TODO (stickupkid) - Find a common place for this as it's duplicated from // apiserver/client/resources func resourceFromRevision(rev transport.ResourceRevision) (charmresource.Resource, error) { diff --git a/core/charm/repository/charmhub_test.go b/core/charm/repository/charmhub_test.go index f7b0db54642..4073cdcee33 100644 --- a/core/charm/repository/charmhub_test.go +++ b/core/charm/repository/charmhub_test.go @@ -279,7 +279,7 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundErrorWithNoSeries(c repo := NewCharmHubRepository(s.logger, s.client) _, _, _, err := repo.ResolveWithPreferredChannel(curl, origin, nil) c.Assert(err, gc.ErrorMatches, - `(?m)selecting releases: charm or bundle not found for channel "", platform "amd64" + `(?m)selecting releases: charm or bundle not found for channel "", base "amd64" available releases are: channel "stable": available series are: focal`) } @@ -287,7 +287,6 @@ available releases are: func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundError(c *gc.C) { defer s.setupMocks(c).Finish() s.expectedRefreshRevisionNotFoundError(c) - s.expectCharmRefreshInstallOneFromChannel(c) curl := charm.MustParseURL("ch:wordpress") origin := corecharm.Origin{ @@ -299,26 +298,11 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundError(c *gc.C) { } repo := NewCharmHubRepository(s.logger, s.client) - obtainedCurl, obtainedOrigin, obtainedSeries, err := repo.ResolveWithPreferredChannel(curl, origin, nil) - c.Assert(err, jc.ErrorIsNil) - - curl.Revision = 16 - - origin.Type = "charm" - origin.Revision = &curl.Revision - origin.Channel = &charm.Channel{ - Track: "latest", - Risk: "stable", - } - origin.Platform.Architecture = arch.DefaultArchitecture - origin.Platform.OS = "ubuntu" - origin.Platform.Channel = "20.04" - - expected := s.expectedCURL(curl, 16, arch.DefaultArchitecture, "focal") - - c.Assert(obtainedCurl, jc.DeepEquals, expected) - c.Assert(obtainedOrigin, jc.DeepEquals, origin) - c.Assert(obtainedSeries, jc.SameContents, []string{"focal"}) + _, _, _, err := repo.ResolveWithPreferredChannel(curl, origin, nil) + c.Assert(err, gc.ErrorMatches, + `(?m)selecting releases: charm or bundle not found for channel "", base "amd64/ubuntu/18.04" +available releases are: + channel "stable": available series are: focal`) } func (s *charmHubRepositorySuite) TestDownloadCharm(c *gc.C) { @@ -832,7 +816,7 @@ func (*selectNextBaseSuite) TestSelectNextBaseWithCentosBase(c *gc.C) { func (*selectNextBaseSuite) TestSelectNextBasesFromReleasesNoReleasesError(c *gc.C) { channel := corecharm.MustParseChannel("stable/foo") repo := new(CharmHubRepository) - _, err := repo.selectNextBasesFromReleases([]transport.Release{}, corecharm.Origin{ + err := repo.handleRevisionNotFound([]transport.Release{}, corecharm.Origin{ Channel: &channel, }) c.Assert(err, gc.ErrorMatches, `no releases available`) @@ -841,7 +825,7 @@ func (*selectNextBaseSuite) TestSelectNextBasesFromReleasesNoReleasesError(c *gc func (*selectNextBaseSuite) TestSelectNextBasesFromReleasesAmbiguousMatchError(c *gc.C) { channel := corecharm.MustParseChannel("stable/foo") repo := new(CharmHubRepository) - _, err := repo.selectNextBasesFromReleases([]transport.Release{ + err := repo.handleRevisionNotFound([]transport.Release{ {}, }, corecharm.Origin{ Channel: &channel, @@ -854,7 +838,7 @@ func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestionError(c * repo := NewCharmHubRepository(s.logger, nil) channel := corecharm.MustParseChannel("stable") - _, err := repo.selectNextBasesFromReleases([]transport.Release{{ + err := repo.handleRevisionNotFound([]transport.Release{{ Base: transport.Base{ Name: "os", Channel: "series", @@ -864,14 +848,13 @@ func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestionError(c * }}, corecharm.Origin{ Channel: &channel, }) - c.Assert(err, gc.ErrorMatches, `charm or bundle not found for channel "stable", platform ""`) + c.Assert(err, gc.ErrorMatches, `charm or bundle not found for channel "stable", base ""`) } func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestion(c *gc.C) { defer s.setupMocks(c).Finish() repo := NewCharmHubRepository(s.logger, nil) - - _, err := repo.selectNextBasesFromReleases([]transport.Release{{ + err := repo.handleRevisionNotFound([]transport.Release{{ Base: transport.Base{ Name: "os", Channel: "20.04", @@ -884,7 +867,7 @@ func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestion(c *gc.C) }, }) c.Assert(err, gc.ErrorMatches, - `charm or bundle not found for channel "", platform "arch" + `charm or bundle not found for channel "", base "arch" available releases are: channel "stable": available series are: focal`) } @@ -1034,176 +1017,3 @@ func (s *composeSuggestionsSuite) setupMocks(c *gc.C) *gomock.Controller { s.logger.EXPECT().Tracef(gomock.Any(), gomock.Any()).AnyTimes() return ctrl } - -type selectReleaseByChannelSuite struct { - testing.IsolationSuite -} - -var _ = gc.Suite(&selectReleaseByChannelSuite{}) - -func (selectReleaseByChannelSuite) TestNoReleases(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{}, corecharm.Origin{}) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform(nil)) -} - -func (selectReleaseByChannelSuite) TestSelection(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{{ - Base: transport.Base{ - Name: "os", - Channel: "20.04", - Architecture: "arch", - }, - Channel: "stable", - }}, corecharm.Origin{ - Platform: corecharm.Platform{ - Architecture: "arch", - }, - Channel: &charm.Channel{ - Risk: "stable", - }, - }) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform{{ - Architecture: "arch", - OS: "os", - Channel: "20.04", - }}) -} - -func (selectReleaseByChannelSuite) TestSelectionWithCentos(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{{ - Base: transport.Base{ - Name: "centos", - Channel: "7", - Architecture: "arch", - }, - Channel: "stable", - }}, corecharm.Origin{ - Platform: corecharm.Platform{ - Architecture: "arch", - }, - Channel: &charm.Channel{ - Risk: "stable", - }, - }) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform{{ - Architecture: "arch", - OS: "centos", - Channel: "centos7", - }}) -} - -func (selectReleaseByChannelSuite) TestAllSelection(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{{ - Base: transport.Base{ - Name: "os", - Channel: "16.04", - Architecture: "all", - }, - Channel: "stable", - }}, corecharm.Origin{ - Platform: corecharm.Platform{ - Architecture: "arch", - }, - Channel: &charm.Channel{ - Risk: "stable", - }, - }) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform{{ - Architecture: "arch", - OS: "os", - Channel: "16.04", - }}) -} - -func (selectReleaseByChannelSuite) TestMultipleSelectionMultipleReturned(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{{ - Base: transport.Base{ - Name: "a", - Channel: "14.04", - Architecture: "c", - }, - Channel: "1.0/edge", - }, { - Base: transport.Base{ - Name: "d", - Channel: "16.04", - Architecture: "all", - }, - Channel: "2.0/stable", - }, { - Base: transport.Base{ - Name: "f", - Channel: "18.04", - Architecture: "h", - }, - Channel: "3.0/stable", - }, { - Base: transport.Base{ - Name: "g", - Channel: "20.04", - Architecture: "h", - }, - Channel: "3.0/stable", - }}, corecharm.Origin{ - Platform: corecharm.Platform{ - Architecture: "h", - }, - Channel: &charm.Channel{ - Track: "3.0", - Risk: "stable", - }, - }) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform{{ - Architecture: "h", - OS: "f", - Channel: "18.04", - }, { - Architecture: "h", - OS: "g", - Channel: "20.04", - }}) -} - -func (selectReleaseByChannelSuite) TestMultipleSelection(c *gc.C) { - release, err := selectReleaseByArchAndChannel([]transport.Release{{ - Base: transport.Base{ - Name: "a", - Channel: "14.04", - Architecture: "c", - }, - Channel: "1.0/edge", - }, { - Base: transport.Base{ - Name: "d", - Channel: "16.04", - Architecture: "all", - }, - Channel: "2.0/stable", - }, { - Base: transport.Base{ - Name: "f", - Channel: "18.04", - Architecture: "h", - }, - Channel: "3.0/stable", - }}, corecharm.Origin{ - Platform: corecharm.Platform{ - Architecture: "h", - }, - Channel: &charm.Channel{ - Track: "3.0", - Risk: "stable", - }, - }) - c.Assert(err, jc.ErrorIsNil) - c.Assert(release, gc.DeepEquals, []corecharm.Platform{{ - Architecture: "h", - OS: "f", - Channel: "18.04", - }}) -} From 3dcf5dc96bf1a1bbdbd2eeb677ded05f2807dfb3 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 14:32:41 -0500 Subject: [PATCH 28/50] composeSuggestions include latest. Now that default channels are available for charm authors to be set, add `latest/` where a risk only is provided by charmhub. Asking charmhub for a risk only channel, indicated we want the default channel. However data returned by charmhub with a risk only is really the lastest/risk channel, rather than the default. This is very confusing for users, especially where a default channel has been defined. At this point in the code, we cannot determine the actual default channel without another charmhub call which too much overhead at this point. Also due to this change, no longer parse the output to put latest at the top. Instead, keep the order provided by charmhub which usually puts the default channel at the top. --- core/charm/repository/charmhub.go | 27 +++++++++++++++----------- core/charm/repository/charmhub_test.go | 14 ++++++------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/core/charm/repository/charmhub.go b/core/charm/repository/charmhub.go index 4bacfea0c00..dccca059b80 100644 --- a/core/charm/repository/charmhub.go +++ b/core/charm/repository/charmhub.go @@ -12,6 +12,7 @@ import ( "github.com/juju/charm/v8" charmresource "github.com/juju/charm/v8/resource" + "github.com/juju/collections/set" "github.com/juju/errors" "gopkg.in/macaroon.v2" @@ -700,6 +701,10 @@ func refreshConfig(charmURL *charm.URL, origin corecharm.Origin) (charmhub.Refre } func (c *CharmHubRepository) composeSuggestions(releases []transport.Release, origin corecharm.Origin) []string { + charmRisks := set.NewStrings() + for _, v := range charm.Risks { + charmRisks.Add(string(v)) + } channelSeries := make(map[string][]string) for _, release := range releases { base := corecharm.NormalisePlatformSeries(corecharm.Platform{ @@ -727,20 +732,20 @@ func (c *CharmHubRepository) composeSuggestions(releases []transport.Release, or if arch != origin.Platform.Architecture { continue } - channelSeries[release.Channel] = append(channelSeries[release.Channel], series) - } - - var suggestions []string - // Sort for latest channels to be suggested first. - // Assumes that releases have normalized channels. - for _, r := range charm.Risks { - risk := string(r) - if values, ok := channelSeries[risk]; ok { - suggestions = append(suggestions, fmt.Sprintf("channel %q: available series are: %s", risk, strings.Join(values, ", "))) - delete(channelSeries, risk) + // Now that we have default tracks other than latest: + // If a channel is risk only, add latest as the track + // to be more clear for the user facing error message. + // At this point, we do not know the default channel, + // or if the charm has one, therefore risk only output + // is ambiguous. + charmChannel := release.Channel + if charmRisks.Contains(charmChannel) { + charmChannel = "latest/" + charmChannel } + channelSeries[charmChannel] = append(channelSeries[charmChannel], series) } + var suggestions []string for channel, values := range channelSeries { suggestions = append(suggestions, fmt.Sprintf("channel %q: available series are: %s", channel, strings.Join(values, ", "))) } diff --git a/core/charm/repository/charmhub_test.go b/core/charm/repository/charmhub_test.go index 4073cdcee33..c1b5f12f1ca 100644 --- a/core/charm/repository/charmhub_test.go +++ b/core/charm/repository/charmhub_test.go @@ -281,7 +281,7 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundErrorWithNoSeries(c c.Assert(err, gc.ErrorMatches, `(?m)selecting releases: charm or bundle not found for channel "", base "amd64" available releases are: - channel "stable": available series are: focal`) + channel "latest/stable": available series are: focal`) } func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundError(c *gc.C) { @@ -302,7 +302,7 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundError(c *gc.C) { c.Assert(err, gc.ErrorMatches, `(?m)selecting releases: charm or bundle not found for channel "", base "amd64/ubuntu/18.04" available releases are: - channel "stable": available series are: focal`) + channel "latest/stable": available series are: focal`) } func (s *charmHubRepositorySuite) TestDownloadCharm(c *gc.C) { @@ -869,7 +869,7 @@ func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestion(c *gc.C) c.Assert(err, gc.ErrorMatches, `charm or bundle not found for channel "", base "arch" available releases are: - channel "stable": available series are: focal`) + channel "latest/stable": available series are: focal`) } func (s *selectNextBaseSuite) setupMocks(c *gc.C) *gomock.Controller { @@ -924,7 +924,7 @@ func (s *composeSuggestionsSuite) TestSuggestion(c *gc.C) { }, }) c.Assert(suggestions, gc.DeepEquals, []string{ - `channel "stable": available series are: focal`, + `channel "latest/stable": available series are: focal`, }) } @@ -944,7 +944,7 @@ func (s *composeSuggestionsSuite) TestSuggestionWithRisk(c *gc.C) { }, }) c.Assert(suggestions, gc.DeepEquals, []string{ - `channel "stable": available series are: focal`, + `channel "latest/stable": available series are: focal`, }) } @@ -985,7 +985,7 @@ func (s *composeSuggestionsSuite) TestMultipleSuggestion(c *gc.C) { }, }) c.Assert(suggestions, gc.DeepEquals, []string{ - `channel "stable": available series are: focal, bionic`, + `channel "latest/stable": available series are: focal, bionic`, `channel "2.0/stable": available series are: bionic`, }) } @@ -1006,7 +1006,7 @@ func (s *composeSuggestionsSuite) TestCentosSuggestion(c *gc.C) { }, }) c.Assert(suggestions, gc.DeepEquals, []string{ - `channel "stable": available series are: centos7`, + `channel "latest/stable": available series are: centos7`, }) } From 4b877897eb71cfa39bcca89bac48381499f0e749 Mon Sep 17 00:00:00 2001 From: Jack Shaw Date: Tue, 18 Jul 2023 18:27:06 +0100 Subject: [PATCH 29/50] juju-qa-test supports focal with arm64 Our arm bundle unit tests were failing with arch arm64 because our test charm juju-qa-test doesn't support any series more recent than Bionic Edit the charm to support both amd and arm, and submit another revision --- .../charm-hub/charms/juju-qa-test/README.md | 4 ++-- .../charms/juju-qa-test/charmcraft.yaml | 17 ++++++++++++++++- .../charms/juju-qa-test/stable/charmcraft.yaml | 5 ++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/testcharms/charm-hub/charms/juju-qa-test/README.md b/testcharms/charm-hub/charms/juju-qa-test/README.md index b0b123c6a25..ec771240baa 100644 --- a/testcharms/charm-hub/charms/juju-qa-test/README.md +++ b/testcharms/charm-hub/charms/juju-qa-test/README.md @@ -6,7 +6,7 @@ A container-based V2 metadata charm to use in testing juju. ## Usage -Basic deploy: +Basic deploy: `juju deploy juju-qa-test` Set the unit status to the first line of the resource, if available, one time: @@ -19,7 +19,7 @@ Get your fortune ## Version, Channel, Series and History | Version | Revision | Channel | Series | | ---------- | -------- | ---------------- | ------------------------------------ | -| 1.1-stable | 19 | latest/stable | focal, bionic, xenial | +| 1.1-stable | 26 | latest/stable | focal, bionic, xenial | | 1.4-cand | 20 | latest/candidate | jammy, focal, bionic, xenial | | 2.0-edge | 21 | latest/edge | groovy, jammy, focal, bionic, xenial | | 2.0-stable | 22 | 2.0/stable | disco, bionic, xenial, trusty | diff --git a/testcharms/charm-hub/charms/juju-qa-test/charmcraft.yaml b/testcharms/charm-hub/charms/juju-qa-test/charmcraft.yaml index cfdb27cfc57..26272195fd4 100644 --- a/testcharms/charm-hub/charms/juju-qa-test/charmcraft.yaml +++ b/testcharms/charm-hub/charms/juju-qa-test/charmcraft.yaml @@ -1,14 +1,29 @@ type: charm +parts: + charm: + prime: + - dispatch + - hooks + - README.md + - LICENSE + - version + - src + - actions.yaml + - metadata.yaml + - config.yaml bases: - build-on: - name: "ubuntu" channel: "20.04" - name: "ubuntu" channel: "22.04" - run-on: + run-on: - name: "ubuntu" channel: "16.04" + architectures: ["amd64", "arm64"] - name: "ubuntu" channel: "18.04" + architectures: ["amd64", "arm64"] - name: "ubuntu" channel: "20.04" + architectures: ["amd64", "arm64"] diff --git a/testcharms/charm-hub/charms/juju-qa-test/stable/charmcraft.yaml b/testcharms/charm-hub/charms/juju-qa-test/stable/charmcraft.yaml index 140ffdfef85..26272195fd4 100644 --- a/testcharms/charm-hub/charms/juju-qa-test/stable/charmcraft.yaml +++ b/testcharms/charm-hub/charms/juju-qa-test/stable/charmcraft.yaml @@ -17,10 +17,13 @@ bases: channel: "20.04" - name: "ubuntu" channel: "22.04" - run-on: + run-on: - name: "ubuntu" channel: "16.04" + architectures: ["amd64", "arm64"] - name: "ubuntu" channel: "18.04" + architectures: ["amd64", "arm64"] - name: "ubuntu" channel: "20.04" + architectures: ["amd64", "arm64"] From 15cdab4af64ab604bc1ed5196de506472be055ff Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 15:03:32 -0500 Subject: [PATCH 30/50] Add files for a 3.0/stable channel for this charm. The 3.0/stable channel is for testing LP 2003971. We need a channel which has only had charms supporting a single operating system. Then try to deploy specifying a different one. --- .../juju-qa-test/3-0-stable/charmcraft.yaml | 21 +++++++++++++++++++ .../charms/juju-qa-test/3-0-stable/version | 1 + .../charm-hub/charms/juju-qa-test/Makefile | 6 ++++++ .../charm-hub/charms/juju-qa-test/README.md | 1 + 4 files changed, 29 insertions(+) create mode 100644 testcharms/charm-hub/charms/juju-qa-test/3-0-stable/charmcraft.yaml create mode 100644 testcharms/charm-hub/charms/juju-qa-test/3-0-stable/version diff --git a/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/charmcraft.yaml b/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/charmcraft.yaml new file mode 100644 index 00000000000..684e6403ada --- /dev/null +++ b/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/charmcraft.yaml @@ -0,0 +1,21 @@ +type: charm +parts: + charm: + prime: + - dispatch + - hooks + - README.md + - LICENSE + - version + - src + - actions.yaml + - metadata.yaml + - config.yaml +bases: + - build-on: + - name: "ubuntu" + channel: "22.04" + run-on: + - name: "ubuntu" + channel: "22.04" + architectures: ["amd64", "arm64"] diff --git a/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/version b/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/version new file mode 100644 index 00000000000..956a31b8059 --- /dev/null +++ b/testcharms/charm-hub/charms/juju-qa-test/3-0-stable/version @@ -0,0 +1 @@ +3.0-stable diff --git a/testcharms/charm-hub/charms/juju-qa-test/Makefile b/testcharms/charm-hub/charms/juju-qa-test/Makefile index 393eec0535a..be34c9ed000 100644 --- a/testcharms/charm-hub/charms/juju-qa-test/Makefile +++ b/testcharms/charm-hub/charms/juju-qa-test/Makefile @@ -30,3 +30,9 @@ stable: @echo Creating the '2.0/edge' version of juju-qa-test cp -r 2-0-edge/* . charmcraft pack + +30stable: + @echo Creating the '3.0/stable' version of juju-qa-test + cp -r 3-0-stable/* . + charmcraft pack + diff --git a/testcharms/charm-hub/charms/juju-qa-test/README.md b/testcharms/charm-hub/charms/juju-qa-test/README.md index ec771240baa..afc5f601550 100644 --- a/testcharms/charm-hub/charms/juju-qa-test/README.md +++ b/testcharms/charm-hub/charms/juju-qa-test/README.md @@ -24,6 +24,7 @@ Get your fortune | 2.0-edge | 21 | latest/edge | groovy, jammy, focal, bionic, xenial | | 2.0-stable | 22 | 2.0/stable | disco, bionic, xenial, trusty | | 2.0-edge | 23 | 2.0/edge | disco, bionic, xenial, trusty | +| 3.0-stable | 27 | 2.3/stable | jammy | To publish new versions of stable/candidate/edge see the files in the subdirectories 'stable', 'candidate', 'edge' respectively. You should be able From 4ad9a871c0a7783182ad80252476b5451ff12a7f Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Wed, 15 Nov 2023 15:41:24 -0500 Subject: [PATCH 31/50] Add test to cover LP 2003971. Test that we fail to deploy when the operating system requested isn't available in the channel. --- tests/suites/deploy/deploy_charms.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/suites/deploy/deploy_charms.sh b/tests/suites/deploy/deploy_charms.sh index 6f5ae38f77f..e2fbce685b4 100644 --- a/tests/suites/deploy/deploy_charms.sh +++ b/tests/suites/deploy/deploy_charms.sh @@ -14,6 +14,23 @@ run_deploy_charm() { destroy_model "test-deploy-charm" } +run_deploy_charm_unsupported_series() { + # Test trying to deploy a charmhub charm to an operating system + # never supported in the specified channel. It should fail. + echo + + testname="test-deploy-charm-unsupported-series" + file="${TEST_DIR}/${testname}.log" + + ensure "${testname}" "${file}" + + # The charm in 3.0/stable only supports jammy and only + # one charm has been released to that channel. + juju deploy juju-qa-test --channel 3.0/stable --series focal | grep -q 'charm or bundle not found for channel' || true + + destroy_model "${testname}" +} + run_deploy_specific_series() { echo @@ -283,6 +300,7 @@ test_deploy_charms() { run "run_deploy_charm" run "run_deploy_specific_series" run "run_resolve_charm" + run "run_deploy_charm_unsupported_series" case "${BOOTSTRAP_PROVIDER:-}" in "lxd" | "localhost") From 3de67a1db0919fc3fe79374e445fc453621f52c6 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Thu, 16 Nov 2023 13:24:13 -0500 Subject: [PATCH 32/50] Update user facing message when revision-not-found error hit. Displaying a channel of empty string isn't helpful, tell the user the charm's default channel was used instead. --- core/charm/repository/charmhub.go | 15 +++++++++++---- core/charm/repository/charmhub_test.go | 6 +++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/charm/repository/charmhub.go b/core/charm/repository/charmhub.go index dccca059b80..1af2823e715 100644 --- a/core/charm/repository/charmhub.go +++ b/core/charm/repository/charmhub.go @@ -586,14 +586,21 @@ func (c *CharmHubRepository) handleRevisionNotFound(releases []transport.Release if len(suggestions) > 0 { s = fmt.Sprintf("\navailable releases are:\n %v", strings.Join(suggestions, "\n ")) } - var channelName string + // If the origin's channel is nil, one wasn't specified by the user, + // so we requested "stable", which indicates the charm's default channel. + // However, at the time we're writing this message, we do not know what + // the charm's default channel is. + var channelString string if origin.Channel != nil { - channelName = origin.Channel.String() + channelString = fmt.Sprintf("for channel %q", origin.Channel.String()) + } else { + channelString = "in the charm's default channel" } + return errSelection{ err: errors.Errorf( - "charm or bundle not found for channel %q, base %q%s", - channelName, origin.Platform.String(), s), + "charm or bundle not found %s, base %q%s", + channelString, origin.Platform.String(), s), } } diff --git a/core/charm/repository/charmhub_test.go b/core/charm/repository/charmhub_test.go index c1b5f12f1ca..319ad74ac53 100644 --- a/core/charm/repository/charmhub_test.go +++ b/core/charm/repository/charmhub_test.go @@ -279,7 +279,7 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundErrorWithNoSeries(c repo := NewCharmHubRepository(s.logger, s.client) _, _, _, err := repo.ResolveWithPreferredChannel(curl, origin, nil) c.Assert(err, gc.ErrorMatches, - `(?m)selecting releases: charm or bundle not found for channel "", base "amd64" + `(?m)selecting releases: charm or bundle not found in the charm's default channel, base "amd64" available releases are: channel "latest/stable": available series are: focal`) } @@ -300,7 +300,7 @@ func (s *charmHubRepositorySuite) TestResolveRevisionNotFoundError(c *gc.C) { repo := NewCharmHubRepository(s.logger, s.client) _, _, _, err := repo.ResolveWithPreferredChannel(curl, origin, nil) c.Assert(err, gc.ErrorMatches, - `(?m)selecting releases: charm or bundle not found for channel "", base "amd64/ubuntu/18.04" + `(?m)selecting releases: charm or bundle not found in the charm's default channel, base "amd64/ubuntu/18.04" available releases are: channel "latest/stable": available series are: focal`) } @@ -867,7 +867,7 @@ func (s *selectNextBaseSuite) TestSelectNextBasesFromReleasesSuggestion(c *gc.C) }, }) c.Assert(err, gc.ErrorMatches, - `charm or bundle not found for channel "", base "arch" + `charm or bundle not found in the charm's default channel, base "arch" available releases are: channel "latest/stable": available series are: focal`) } From 15bd5a491bbe9a2d1be96acf9417dd815b93a7a2 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Mon, 27 Nov 2023 15:29:17 -0500 Subject: [PATCH 33/50] Fix spelling in a method comment. --- core/charm/repository/charmhub.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/charm/repository/charmhub.go b/core/charm/repository/charmhub.go index 1af2823e715..0ce97803c23 100644 --- a/core/charm/repository/charmhub.go +++ b/core/charm/repository/charmhub.go @@ -253,7 +253,7 @@ type retryResolveResult struct { } // retryResolveWithPreferredChannel will attempt to inspect the transport -// APIError and deterimine if a retry is possible with the information gathered +// APIError and determine if a retry is possible with the information gathered // from the error. func (c *CharmHubRepository) retryResolveWithPreferredChannel(charmURL *charm.URL, origin corecharm.Origin, macaroons macaroon.Slice, resErr *transport.APIError) (*retryResolveResult, error) { var ( From 52ed6be6d18f9d7015c930903c1ff09f335f23a5 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Tue, 28 Nov 2023 10:23:00 +1000 Subject: [PATCH 34/50] Backport #15918 which tracks upstream canonical/lxd --- api/client/client/client.go | 18 +- api/client/client/client_test.go | 12 +- apiserver/admin_test.go | 18 +- .../facades/client/client/client_test.go | 14 +- apiserver/facades/client/client/perm_test.go | 15 +- .../facades/client/client/status_test.go | 58 ++-- cmd/juju/application/deploy.go | 2 +- cmd/juju/application/deploy_test.go | 2 +- cmd/juju/application/diffbundle.go | 2 +- cmd/juju/application/refresh.go | 2 +- cmd/juju/commands/ssh_machine.go | 2 +- cmd/juju/machine/add.go | 2 +- cmd/juju/model/constraints.go | 4 +- cmd/juju/model/retryprovisioning.go | 2 +- cmd/juju/storage/filesystemlist_test.go | 20 +- cmd/juju/storage/list_test.go | 26 +- cmd/juju/storage/poollist_test.go | 2 - cmd/juju/storage/volumelist_test.go | 20 +- cmd/juju/user/list.go | 2 +- cmd/jujud/agent/machine_test.go | 2 +- cmd/modelcmd/modelcommand.go | 2 +- container/kvm/sync_internal_test.go | 2 +- container/lxd/certificate.go | 4 +- container/lxd/connection.go | 4 +- container/lxd/container.go | 6 +- container/lxd/container_test.go | 4 +- container/lxd/export_test.go | 2 +- container/lxd/image.go | 4 +- container/lxd/image_test.go | 4 +- container/lxd/initialisation_linux.go | 2 +- container/lxd/initialisation_test.go | 4 +- container/lxd/instance.go | 4 +- container/lxd/logger.go | 2 +- container/lxd/manager.go | 4 +- container/lxd/manager_test.go | 6 +- container/lxd/network.go | 2 +- container/lxd/network_test.go | 2 +- container/lxd/server.go | 6 +- container/lxd/server_test.go | 2 +- container/lxd/storage.go | 2 +- container/lxd/storage_test.go | 2 +- container/lxd/testing/doc.go | 2 +- container/lxd/testing/lxd_mock.go | 264 +++++++++++++++++- container/lxd/testing/suite.go | 2 +- core/lxdprofile/doc.go | 2 +- environs/jujutest/livetests.go | 2 +- featuretests/dblog_test.go | 4 +- go.mod | 46 +-- go.sum | 101 ++++--- provider/lxd/credentials.go | 4 +- provider/lxd/credentials_test.go | 2 +- provider/lxd/environ.go | 2 +- provider/lxd/environ_broker.go | 2 +- provider/lxd/environ_broker_test.go | 2 +- provider/lxd/environ_network.go | 2 +- provider/lxd/environ_network_test.go | 2 +- provider/lxd/environ_policy_test.go | 2 +- provider/lxd/environ_test.go | 2 +- provider/lxd/instance.go | 2 +- provider/lxd/package_mock_test.go | 34 +-- provider/lxd/server.go | 4 +- provider/lxd/server_integration_test.go | 4 +- provider/lxd/storage.go | 4 +- provider/lxd/storage_test.go | 2 +- provider/lxd/testing_test.go | 4 +- state/charm.go | 2 +- state/storage_test.go | 2 +- upgrades/upgradevalidation/mocks/lxd_mock.go | 48 ++-- 68 files changed, 562 insertions(+), 282 deletions(-) diff --git a/api/client/client/client.go b/api/client/client/client.go index 77fb951fda9..d073825f4da 100644 --- a/api/client/client/client.go +++ b/api/client/client/client.go @@ -15,7 +15,6 @@ import ( "github.com/juju/errors" "github.com/juju/names/v4" "github.com/juju/version/v2" - "github.com/lxc/lxd/shared/logger" "gopkg.in/macaroon.v2" "github.com/juju/juju/api" @@ -29,18 +28,29 @@ import ( "github.com/juju/juju/tools" ) +// Logger is the interface used by the client to log errors. +type Logger interface { + Errorf(string, ...interface{}) +} + // Client represents the client-accessible part of the state. type Client struct { base.ClientFacade facade base.FacadeCaller conn api.Connection + logger Logger } // NewClient returns an object that can be used to access client-specific // functionality. -func NewClient(c api.Connection) *Client { +func NewClient(c api.Connection, logger Logger) *Client { frontend, backend := base.NewClientFacade(c, "Client") - return &Client{ClientFacade: frontend, facade: backend, conn: c} + return &Client{ + ClientFacade: frontend, + facade: backend, + conn: c, + logger: logger, + } } // Status returns the status of the juju model. @@ -108,7 +118,7 @@ func (c *Client) StatusHistory(kind status.HistoryKind, tag names.Tag, filter st } // TODO(perrito666) https://launchpad.net/bugs/1577589 if !history[i].Kind.Valid() { - logger.Errorf("history returned an unknown status kind %q", h.Kind) + c.logger.Errorf("history returned an unknown status kind %q", h.Kind) } } return history, nil diff --git a/api/client/client/client_test.go b/api/client/client/client_test.go index bd2a6684fba..6dc70653bb6 100644 --- a/api/client/client/client_test.go +++ b/api/client/client/client_test.go @@ -53,7 +53,7 @@ func (s *clientSuite) SetUpTest(c *gc.C) { } func (s *clientSuite) TestCloseMultipleOk(c *gc.C) { - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, coretesting.NoopLogger{}) c.Assert(client.Close(), gc.IsNil) c.Assert(client.Close(), gc.IsNil) c.Assert(client.Close(), gc.IsNil) @@ -63,7 +63,7 @@ func (s *clientSuite) TestUploadToolsOtherModel(c *gc.C) { otherSt, otherAPISt := s.otherModel(c) defer otherSt.Close() defer otherAPISt.Close() - client := client.NewClient(otherAPISt) + client := client.NewClient(otherAPISt, coretesting.NoopLogger{}) newVersion := version.MustParseBinary("5.4.3-ubuntu-amd64") var called bool @@ -133,14 +133,14 @@ func (s *clientSuite) TestClientModelUUID(c *gc.C) { model, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, coretesting.NoopLogger{}) uuid, ok := client.ModelUUID() c.Assert(ok, jc.IsTrue) c.Assert(uuid, gc.Equals, model.Tag().Id()) } func (s *clientSuite) TestWatchDebugLogConnected(c *gc.C) { - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, coretesting.NoopLogger{}) // Use the no tail option so we don't try to start a tailing cursor // on the oplog when there is no oplog configured in mongo as the tests // don't set up mongo in replicaset mode. @@ -237,7 +237,7 @@ func (s *clientSuite) TestWatchDebugLogParamsEncoded(c *gc.C) { StartTime: time.Date(2016, 11, 30, 11, 48, 0, 100, time.UTC), } - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, coretesting.NoopLogger{}) _, err := client.WatchDebugLog(params) c.Assert(err, jc.ErrorIsNil) @@ -301,7 +301,7 @@ func (s *clientSuite) TestOpenUsesModelUUIDPaths(c *gc.C) { } func (s *clientSuite) TestAbortCurrentUpgrade(c *gc.C) { - cl := client.NewClient(s.APIState) + cl := client.NewClient(s.APIState, coretesting.NoopLogger{}) someErr := errors.New("random") cleanup := client.PatchClientFacadeCall(cl, func(request string, args interface{}, response interface{}) error { diff --git a/apiserver/admin_test.go b/apiserver/admin_test.go index e0f826e628a..6e77a4ee3fe 100644 --- a/apiserver/admin_test.go +++ b/apiserver/admin_test.go @@ -150,7 +150,7 @@ func (s *loginSuite) TestLoginAsDeactivatedUser(c *gc.C) { password := "password" u := s.Factory.MakeUser(c, &factory.UserParams{Password: password, Disabled: true}) - _, err := apiclient.NewClient(st).Status([]string{}) + _, err := apiclient.NewClient(st, coretesting.NoopLogger{}).Status([]string{}) c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{ Message: `unknown object type "Client"`, Code: "not implemented", @@ -163,7 +163,7 @@ func (s *loginSuite) TestLoginAsDeactivatedUser(c *gc.C) { Code: "unauthorized access", }) - _, err = apiclient.NewClient(st).Status([]string{}) + _, err = apiclient.NewClient(st, coretesting.NoopLogger{}).Status([]string{}) c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{ Message: `unknown object type "Client"`, Code: "not implemented", @@ -177,7 +177,7 @@ func (s *loginSuite) TestLoginAsDeletedUser(c *gc.C) { password := "password" u := s.Factory.MakeUser(c, &factory.UserParams{Password: password}) - _, err := apiclient.NewClient(st).Status([]string{}) + _, err := apiclient.NewClient(st, coretesting.NoopLogger{}).Status([]string{}) c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{ Message: `unknown object type "Client"`, Code: "not implemented", @@ -193,7 +193,7 @@ func (s *loginSuite) TestLoginAsDeletedUser(c *gc.C) { Code: "unauthorized access", }) - _, err = apiclient.NewClient(st).Status([]string{}) + _, err = apiclient.NewClient(st, coretesting.NoopLogger{}).Status([]string{}) c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{ Message: `unknown object type "Client"`, Code: "not implemented", @@ -935,7 +935,7 @@ func (s *loginSuite) assertRemoteModel(c *gc.C, conn api.Connection, expected na c.Assert(ok, jc.IsTrue) c.Assert(tag, gc.Equals, expected) // Look at what the api Client thinks it has. - client := apiclient.NewClient(conn) + client := apiclient.NewClient(conn, coretesting.NoopLogger{}) // ModelUUID looks at the model tag on the api state connection. uuid, ok := client.ModelUUID() @@ -1443,7 +1443,7 @@ func (s *migrationSuite) TestImportingModel(c *gc.C) { info := s.APIInfo(c) userConn := s.OpenAPIAs(c, info.Tag, info.Password) defer userConn.Close() - _, err = apiclient.NewClient(userConn).Status(nil) + _, err = apiclient.NewClient(userConn, coretesting.NoopLogger{}).Status(nil) c.Check(err, gc.ErrorMatches, "migration in progress, model is importing") // Machines should be able to use the API. @@ -1465,7 +1465,7 @@ func (s *migrationSuite) TestExportingModel(c *gc.C) { defer userConn.Close() // Status is fine. - _, err = apiclient.NewClient(userConn).Status(nil) + _, err = apiclient.NewClient(userConn, coretesting.NoopLogger{}).Status(nil) c.Check(err, jc.ErrorIsNil) // Modifying commands like destroy machines are not. @@ -1485,7 +1485,7 @@ func (s *loginV3Suite) TestClientLoginToModel(c *gc.C) { c.Assert(err, jc.ErrorIsNil) defer apiState.Close() - client := apiclient.NewClient(apiState) + client := apiclient.NewClient(apiState, coretesting.NoopLogger{}) _, err = client.GetModelConstraints() c.Assert(err, jc.ErrorIsNil) } @@ -1497,7 +1497,7 @@ func (s *loginV3Suite) TestClientLoginToController(c *gc.C) { c.Assert(err, jc.ErrorIsNil) defer apiState.Close() - client := apiclient.NewClient(apiState) + client := apiclient.NewClient(apiState, coretesting.NoopLogger{}) _, err = client.GetModelConstraints() c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{ Message: `facade "Client" not supported for controller API connection`, diff --git a/apiserver/facades/client/client/client_test.go b/apiserver/facades/client/client/client_test.go index d9bcda245a9..7c91f53bd0f 100644 --- a/apiserver/facades/client/client/client_test.go +++ b/apiserver/facades/client/client/client_test.go @@ -600,7 +600,7 @@ func (s *clientSuite) TestClientStatus(c *gc.C) { loggo.GetLogger("juju.core.cache").SetLogLevel(loggo.TRACE) loggo.GetLogger("juju.state.allwatcher").SetLogLevel(loggo.TRACE) s.setUpScenario(c) - status, err := apiclient.NewClient(s.APIState).Status(nil) + status, err := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).Status(nil) clearSinceTimes(status) clearContollerTimestamp(status) c.Assert(err, jc.ErrorIsNil) @@ -609,7 +609,7 @@ func (s *clientSuite) TestClientStatus(c *gc.C) { func (s *clientSuite) TestClientStatusControllerTimestamp(c *gc.C) { s.setUpScenario(c) - status, err := apiclient.NewClient(s.APIState).Status(nil) + status, err := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).Status(nil) clearSinceTimes(status) c.Assert(err, jc.ErrorIsNil) c.Assert(status.ControllerTimestamp, gc.NotNil) @@ -629,7 +629,7 @@ func (s *clientSuite) testClientUnitResolved(c *gc.C, retry bool, expectedResolv err = u.SetAgentStatus(sInfo) c.Assert(err, jc.ErrorIsNil) // Code under test: - err = apiclient.NewClient(s.APIState).Resolved("wordpress/0", retry) + err = apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).Resolved("wordpress/0", retry) c.Assert(err, jc.ErrorIsNil) // Freshen the unit's state. err = u.Refresh() @@ -664,7 +664,7 @@ func (s *clientSuite) setupResolved(c *gc.C) *state.Unit { } func (s *clientSuite) assertResolved(c *gc.C, u *state.Unit) { - err := apiclient.NewClient(s.APIState).Resolved("wordpress/0", true) + err := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).Resolved("wordpress/0", true) c.Assert(err, jc.ErrorIsNil) // Freshen the unit's state. err = u.Refresh() @@ -676,7 +676,7 @@ func (s *clientSuite) assertResolved(c *gc.C, u *state.Unit) { } func (s *clientSuite) assertResolvedBlocked(c *gc.C, u *state.Unit, msg string) { - err := apiclient.NewClient(s.APIState).Resolved("wordpress/0", false) + err := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).Resolved("wordpress/0", false) s.AssertBlocked(c, err, msg) } @@ -774,7 +774,7 @@ func (s *clientSuite) TestClientWatchAllReadPermission(c *gc.C) { Password: "ro-password", }) c.Assert(err, jc.ErrorIsNil) - roClient := apiclient.NewClient(s.OpenAPIAs(c, user.UserTag(), "ro-password")) + roClient := apiclient.NewClient(s.OpenAPIAs(c, user.UserTag(), "ro-password"), coretesting.NoopLogger{}) defer roClient.Close() watcher, err := roClient.WatchAll() @@ -874,7 +874,7 @@ func (s *clientSuite) TestClientWatchAllAdminPermission(c *gc.C) { }) c.Assert(err, jc.ErrorIsNil) - watcher, err := apiclient.NewClient(s.APIState).WatchAll() + watcher, err := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}).WatchAll() c.Assert(err, jc.ErrorIsNil) defer func() { err := watcher.Stop() diff --git a/apiserver/facades/client/client/perm_test.go b/apiserver/facades/client/client/perm_test.go index fd044f5fc30..0b2f446cae0 100644 --- a/apiserver/facades/client/client/perm_test.go +++ b/apiserver/facades/client/client/perm_test.go @@ -25,6 +25,7 @@ import ( "github.com/juju/juju/rpc" "github.com/juju/juju/rpc/params" "github.com/juju/juju/state" + coretesting "github.com/juju/juju/testing" ) type permSuite struct { @@ -210,8 +211,8 @@ func opClientDestroyRelation(c *gc.C, st api.Connection, mst *state.State) (func return func() {}, err } -func opClientStatus(c *gc.C, st api.Connection, mst *state.State) (func(), error) { - status, err := apiclient.NewClient(st).Status(nil) +func opClientStatus(c *gc.C, st api.Connection, _ *state.State) (func(), error) { + status, err := apiclient.NewClient(st, coretesting.NoopLogger{}).Status(nil) if err != nil { c.Check(status, gc.IsNil) return func() {}, err @@ -272,7 +273,7 @@ func opClientServiceUnexpose(c *gc.C, st api.Connection, mst *state.State) (func } func opClientResolved(c *gc.C, st api.Connection, _ *state.State) (func(), error) { - err := apiclient.NewClient(st).Resolved("wordpress/1", false) + err := apiclient.NewClient(st, coretesting.NoopLogger{}).Resolved("wordpress/1", false) // There are several scenarios in which this test is called, one is // that the user is not authorized. In that case we want to exit now, // letting the error percolate out so the caller knows that the @@ -391,7 +392,7 @@ func opClientSetServiceConstraints(c *gc.C, st api.Connection, mst *state.State) func opClientSetEnvironmentConstraints(c *gc.C, st api.Connection, mst *state.State) (func(), error) { nullConstraints := constraints.Value{} - err := apiclient.NewClient(st).SetModelConstraints(nullConstraints) + err := apiclient.NewClient(st, coretesting.NoopLogger{}).SetModelConstraints(nullConstraints) if err != nil { return func() {}, err } @@ -424,7 +425,7 @@ func opClientSetModelAgentVersion(c *gc.C, st api.Connection, mst *state.State) return func() {}, err } ver := version.Number{Major: 2, Minor: 0, Patch: 0} - err = apiclient.NewClient(st).SetModelAgentVersion(ver, "released", false) + err = apiclient.NewClient(st, coretesting.NoopLogger{}).SetModelAgentVersion(ver, "released", false) if err != nil { return func() {}, err } @@ -433,13 +434,13 @@ func opClientSetModelAgentVersion(c *gc.C, st api.Connection, mst *state.State) oldAgentVersion, found := attrs["agent-version"] if found { versionString := oldAgentVersion.(string) - apiclient.NewClient(st).SetModelAgentVersion(version.MustParse(versionString), "released", false) + apiclient.NewClient(st, coretesting.NoopLogger{}).SetModelAgentVersion(version.MustParse(versionString), "released", false) } }, nil } func opClientWatchAll(c *gc.C, st api.Connection, mst *state.State) (func(), error) { - watcher, err := apiclient.NewClient(st).WatchAll() + watcher, err := apiclient.NewClient(st, coretesting.NoopLogger{}).WatchAll() if err == nil { watcher.Stop() } diff --git a/apiserver/facades/client/client/status_test.go b/apiserver/facades/client/client/status_test.go index 62b8b73a4ce..abcb0d361b5 100644 --- a/apiserver/facades/client/client/status_test.go +++ b/apiserver/facades/client/client/status_test.go @@ -58,7 +58,7 @@ func (s *statusSuite) TestFullStatus(c *gc.C) { machine := s.addMachine(c) c.Assert(s.State.SetSLA("essential", "test-user", []byte("")), jc.ErrorIsNil) c.Assert(s.State.SetModelMeterStatus("GREEN", "goo"), jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Check(status.Model.Name, gc.Equals, "controller") @@ -87,7 +87,7 @@ func (s *statusSuite) TestUnsupportedNoModelMeterStatus(c *gc.C) { s.addMachine(c) c.Assert(s.State.SetSLA("unsupported", "test-user", []byte("")), jc.ErrorIsNil) c.Assert(s.State.SetModelMeterStatus("RED", "nope"), jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Check(status.Model.SLA, gc.Equals, "unsupported") @@ -101,7 +101,7 @@ func (s *statusSuite) TestFullStatusUnitLeadership(c *gc.C) { c.Assert(err, jc.ErrorIsNil) err = claimer.Claim(u.ApplicationName(), u.Name(), time.Minute) c.Assert(err, jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) app, ok := status.Applications[u.ApplicationName()] @@ -118,7 +118,7 @@ func (s *statusSuite) TestFullStatusUnitScaling(c *gc.C) { }) tracker := s.State.TrackQueries("FullStatus") - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) _, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -153,7 +153,7 @@ func (s *statusSuite) TestFullStatusMachineScaling(c *gc.C) { s.Factory.MakeMachine(c, nil) tracker := s.State.TrackQueries("FullStatus") - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) _, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -182,7 +182,7 @@ func (s *statusSuite) TestFullStatusInterfaceScaling(c *gc.C) { s.createSpaceAndSubnetWithProviderID(c, "dmz", "10.30.0.0/24", "prov-abcd") tracker := s.State.TrackQueries("FullStatus") - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) _, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -265,7 +265,7 @@ func (s *statusUnitTestSuite) TestProcessMachinesWithOneMachineAndOneContainer(c host := s.Factory.MakeMachine(c, &factory.MachineParams{InstanceId: instance.Id("0")}) container := s.Factory.MakeMachineNested(c, host.Id(), nil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -284,7 +284,7 @@ func (s *statusUnitTestSuite) TestProcessMachinesWithEmbeddedContainers(c *gc.C) lxdHost := s.Factory.MakeMachineNested(c, host.Id(), nil) s.Factory.MakeMachineNested(c, lxdHost.Id(), nil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -322,7 +322,7 @@ func (s *statusUnitTestSuite) TestModelMeterStatus(c *gc.C) { c.Assert(s.State.SetSLA("advanced", "test-user", nil), jc.ErrorIsNil) c.Assert(s.State.SetModelMeterStatus("RED", "thing"), jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -349,7 +349,7 @@ func (s *statusUnitTestSuite) TestMeterStatus(c *gc.C) { } } - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -386,7 +386,7 @@ func (s *statusUnitTestSuite) TestNoMeterStatusWhenNotRequired(c *gc.C) { } } - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -414,7 +414,7 @@ func (s *statusUnitTestSuite) TestMeterStatusWithCredentials(c *gc.C) { } } - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -445,7 +445,7 @@ func (s *statusUnitTestSuite) TestApplicationWithExposedEndpoints(c *gc.C) { }) c.Assert(err, jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -468,7 +468,7 @@ func (s *statusUnitTestSuite) TestPrincipalUpgradingFrom(c *gc.C) { Application: app, SetCharmURL: true, }) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -520,7 +520,7 @@ func (s *statusUnitTestSuite) TestSubordinateUpgradingFrom(c *gc.C) { err = subordUnit.SetCharmURL(subordCharm.URL()) c.Assert(err, jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -556,7 +556,7 @@ func addUnitWithVersion(c *gc.C, application *state.Application, version string) func (s *statusUnitTestSuite) checkAppVersion(c *gc.C, application *state.Application, expectedVersion string) params.ApplicationStatus { - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) appStatus, found := status.Applications[application.Name()] @@ -635,7 +635,7 @@ func (s *statusUnitTestSuite) TestMigrationInProgress(c *gc.C) { conn, err := api.Open(apiInfo, api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) - client := apiclient.NewClient(conn) + client := apiclient.NewClient(conn, coretesting.NoopLogger{}) checkMigStatus := func(expected string) { status, err := client.Status(nil) @@ -718,7 +718,7 @@ func (s *statusUnitTestSuite) TestRelationFiltered(c *gc.C) { c.Assert(r13, gc.NotNil) // Test status filtering with application 1: should get both relations - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status([]string{a1.Name()}) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -767,7 +767,7 @@ func (s *statusUnitTestSuite) TestApplicationFilterIndependentOfAlphabeticUnitOr Machine: machine, }) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) for i := 0; i < 20; i++ { c.Logf("run %d", i) status, err := client.Status([]string{applicationA.Name()}) @@ -835,7 +835,7 @@ func (s *statusUnitTestSuite) TestFilterOutRelationsForRelatedApplicationsThatDo // Filtering status on application A should get: // * no relations; // * two applications. - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status([]string{applicationA.Name()}) c.Assert(err, jc.ErrorIsNil) c.Assert(status, gc.NotNil) @@ -848,7 +848,7 @@ func (s *statusUnitTestSuite) TestMachineWithNoDisplayNameHasItsEmptyDisplayName InstanceId: instance.Id("i-123"), }) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status.Machines, gc.HasLen, 1) @@ -861,7 +861,7 @@ func (s *statusUnitTestSuite) TestMachineWithDisplayNameHasItsDisplayNameSent(c DisplayName: "snowflake", }) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status.Machines, gc.HasLen, 1) @@ -932,7 +932,7 @@ func (s *statusUpgradeUnitSuite) TearDownTest(c *gc.C) { func (s *statusUpgradeUnitSuite) TestUpdateRevisionsCharmstore(c *gc.C) { s.AddMachine(c, "0", state.JobManageModel) s.SetupScenario(c) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, _ := client.Status(nil) appStatus, ok := status.Applications["mysql"] @@ -958,7 +958,7 @@ func (s *statusUpgradeUnitSuite) TestUpdateRevisionsCharmhub(c *gc.C) { s.AddApplication(c, "charmhubby", "charmhubby") s.AddUnit(c, "charmhubby", "1") - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, _ := client.Status(nil) appStatus, ok := status.Applications["charmhubby"] @@ -1028,7 +1028,7 @@ func (s *CAASStatusSuite) SetUpTest(c *gc.C) { } func (s *CAASStatusSuite) TestStatusOperatorNotReady(c *gc.C) { - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) @@ -1038,7 +1038,7 @@ func (s *CAASStatusSuite) TestStatusOperatorNotReady(c *gc.C) { } func (s *CAASStatusSuite) TestStatusPodSpecNotSet(c *gc.C) { - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) err := s.app.SetOperatorStatus(status.StatusInfo{Status: status.Active}) c.Assert(err, jc.ErrorIsNil) s.WaitForModelWatchersIdle(c, s.State.ModelUUID()) @@ -1051,7 +1051,7 @@ func (s *CAASStatusSuite) TestStatusPodSpecNotSet(c *gc.C) { } func (s *CAASStatusSuite) TestStatusPodSpecSet(c *gc.C) { - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) err := s.app.SetOperatorStatus(status.StatusInfo{Status: status.Active}) c.Assert(err, jc.ErrorIsNil) cm, err := s.Model.CAASModel() @@ -1075,7 +1075,7 @@ containers: func (s *CAASStatusSuite) TestStatusCloudContainerSet(c *gc.C) { loggo.GetLogger("juju.state.allwatcher").SetLogLevel(loggo.TRACE) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) err := s.app.SetOperatorStatus(status.StatusInfo{Status: status.Active}) c.Assert(err, jc.ErrorIsNil) @@ -1135,7 +1135,7 @@ func (s *CAASStatusSuite) assertUnitStatus(c *gc.C, appStatus params.Application func (s *CAASStatusSuite) TestStatusWorkloadVersionSetByCharm(c *gc.C) { loggo.GetLogger("juju.state.allwatcher").SetLogLevel(loggo.TRACE) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) err := s.app.SetOperatorStatus(status.StatusInfo{Status: status.Active}) c.Assert(err, jc.ErrorIsNil) err = s.app.SetScale(1, 1, true) diff --git a/cmd/juju/application/deploy.go b/cmd/juju/application/deploy.go index 097c4e2fb77..721e1d7081b 100644 --- a/cmd/juju/application/deploy.go +++ b/cmd/juju/application/deploy.go @@ -268,7 +268,7 @@ func newDeployCommand() *DeployCommand { } return &deployAPIAdapter{ Connection: apiRoot, - legacyClient: &apiClient{Client: apiclient.NewClient(apiRoot)}, + legacyClient: &apiClient{Client: apiclient.NewClient(apiRoot, logger)}, charmsClient: &charmsClient{Client: apicharms.NewClient(apiRoot)}, charmsAPIVersion: apiRoot.BestFacadeVersion("Charms"), applicationClient: &applicationClient{Client: application.NewClient(apiRoot)}, diff --git a/cmd/juju/application/deploy_test.go b/cmd/juju/application/deploy_test.go index a5bd80e2ef8..03cbc958119 100644 --- a/cmd/juju/application/deploy_test.go +++ b/cmd/juju/application/deploy_test.go @@ -2594,7 +2594,7 @@ func newDeployCommandForTest(fakeAPI *fakeDeployAPI) *DeployCommand { return &deployAPIAdapter{ Connection: apiRoot, - legacyClient: &apiClient{Client: apiclient.NewClient(apiRoot)}, + legacyClient: &apiClient{Client: apiclient.NewClient(apiRoot, coretesting.NoopLogger{})}, charmsClient: &charmsClient{Client: apicharms.NewClient(apiRoot)}, applicationClient: &applicationClient{Client: application.NewClient(apiRoot)}, modelConfigClient: &modelConfigClient{Client: modelconfig.NewClient(apiRoot)}, diff --git a/cmd/juju/application/diffbundle.go b/cmd/juju/application/diffbundle.go index 3f8f9654487..59c7df87dd7 100644 --- a/cmd/juju/application/diffbundle.go +++ b/cmd/juju/application/diffbundle.go @@ -114,7 +114,7 @@ func NewDiffBundleCommand() cmd.Command { if client.BestAPIVersion() > 2 { return client, nil } - return apiclient.NewClient(root), nil + return apiclient.NewClient(root, logger), nil } return modelcmd.Wrap(cmd) } diff --git a/cmd/juju/application/refresh.go b/cmd/juju/application/refresh.go index 12dee40f9a1..ebfa9f2568d 100644 --- a/cmd/juju/application/refresh.go +++ b/cmd/juju/application/refresh.go @@ -656,7 +656,7 @@ func newCharmAdder( conn api.Connection, ) store.CharmAdder { adder := &charmAdderShim{ - api: &apiClient{Client: apiclient.NewClient(conn)}, + api: &apiClient{Client: apiclient.NewClient(conn, logger)}, modelconfig: &modelConfigClient{Client: modelconfig.NewClient(conn)}, } adder.charmuploader = &charmsClient{Client: apicharms.NewClient(conn)} diff --git a/cmd/juju/commands/ssh_machine.go b/cmd/juju/commands/ssh_machine.go index bf363c25bf8..210472a4e1a 100644 --- a/cmd/juju/commands/ssh_machine.go +++ b/cmd/juju/commands/ssh_machine.go @@ -455,7 +455,7 @@ func (c *sshMachine) initAPIClient(mc ModelCommand) error { c.apiClient = sshclient.NewFacade(conn) c.apiAddr = conn.Addr() - c.statusClient = apiclient.NewClient(conn) + c.statusClient = apiclient.NewClient(conn, logger) return nil } diff --git a/cmd/juju/machine/add.go b/cmd/juju/machine/add.go index 0e75e15bf36..539a2acaad2 100644 --- a/cmd/juju/machine/add.go +++ b/cmd/juju/machine/add.go @@ -307,7 +307,7 @@ func (c *addCommand) Run(ctx *cmd.Context) error { if err != nil { return errors.Trace(err) } - manualClientAPI = &manualAPIAdaptor{apiclient.NewClient(root)} + manualClientAPI = &manualAPIAdaptor{apiclient.NewClient(root, logger)} } if len(c.Disks) > 0 && machineManager.BestAPIVersion() < 1 { diff --git a/cmd/juju/model/constraints.go b/cmd/juju/model/constraints.go index fccc4f08196..7419e3e02f3 100644 --- a/cmd/juju/model/constraints.go +++ b/cmd/juju/model/constraints.go @@ -112,7 +112,7 @@ func (c *modelGetConstraintsCommand) getAPI() (ConstraintsAPI, error) { if client.BestAPIVersion() > 2 { return client, nil } - return apiclient.NewClient(root), nil + return apiclient.NewClient(root, logger), nil } func formatConstraints(writer io.Writer, value interface{}) error { @@ -181,7 +181,7 @@ func (c *modelSetConstraintsCommand) getAPI() (ConstraintsAPI, error) { if client.BestAPIVersion() > 2 { return client, nil } - return apiclient.NewClient(root), nil + return apiclient.NewClient(root, logger), nil } func (c *modelSetConstraintsCommand) Run(_ *cmd.Context) (err error) { diff --git a/cmd/juju/model/retryprovisioning.go b/cmd/juju/model/retryprovisioning.go index d7705024049..ae83d20175c 100644 --- a/cmd/juju/model/retryprovisioning.go +++ b/cmd/juju/model/retryprovisioning.go @@ -88,7 +88,7 @@ func (c *retryProvisioningCommand) getAPI() (RetryProvisioningAPI, error) { if c.all { return nil, errors.New("this version of Juju does not support --all") } - return apiclient.NewClient(root), nil + return apiclient.NewClient(root, logger), nil } func (c *retryProvisioningCommand) Run(context *cmd.Context) error { diff --git a/cmd/juju/storage/filesystemlist_test.go b/cmd/juju/storage/filesystemlist_test.go index b1fc8248139..7dd7ef66b70 100644 --- a/cmd/juju/storage/filesystemlist_test.go +++ b/cmd/juju/storage/filesystemlist_test.go @@ -89,14 +89,13 @@ func (s *ListSuite) TestFilesystemListWithErrorResults(c *gc.C) { } var expectedFilesystemListTabular = ` -Machine Unit Storage ID ID Volume Provider ID Mountpoint Size State Message -0 abc/0 db-dir/1001 0/0 0/1 provider-supplied-filesystem-0-0 /mnt/fuji 512MiB attached -0 transcode/0 shared-fs/0 4 provider-supplied-filesystem-4 /mnt/doom 1.0GiB attached -0 1 provider-supplied-filesystem-1 2.0GiB attaching failed to attach, will retry -1 transcode/1 shared-fs/0 4 provider-supplied-filesystem-4 /mnt/huang 1.0GiB attached -1 2 provider-supplied-filesystem-2 /mnt/zion 3.0MiB attached -1 3 42MiB pending - +Machine Unit Storage ID ID Volume Provider ID Mountpoint Size State Message +0 abc/0 db-dir/1001 0/0 0/1 provider-supplied-filesystem-0-0 /mnt/fuji 512 MiB attached +0 transcode/0 shared-fs/0 4 provider-supplied-filesystem-4 /mnt/doom 1.0 GiB attached +0 1 provider-supplied-filesystem-1 2.0 GiB attaching failed to attach, will retry +1 transcode/1 shared-fs/0 4 provider-supplied-filesystem-4 /mnt/huang 1.0 GiB attached +1 2 provider-supplied-filesystem-2 /mnt/zion 3.0 MiB attached +1 3 42 MiB pending `[1:] func (s *ListSuite) TestFilesystemListTabular(c *gc.C) { @@ -116,9 +115,8 @@ func (s *ListSuite) TestFilesystemListTabular(c *gc.C) { } var expectedCAASFilesystemListTabular = ` -Unit Storage ID ID Provider ID Mountpoint Size State Message -mysql/0 db-dir/1001 0/0 provider-supplied-filesystem-0-0 /mnt/fuji 512MiB attached - +Unit Storage ID ID Provider ID Mountpoint Size State Message +mysql/0 db-dir/1001 0/0 provider-supplied-filesystem-0-0 /mnt/fuji 512 MiB attached `[1:] func (s *ListSuite) TestCAASFilesystemListTabular(c *gc.C) { diff --git a/cmd/juju/storage/list_test.go b/cmd/juju/storage/list_test.go index fd8ea9669d8..b6939a16b85 100644 --- a/cmd/juju/storage/list_test.go +++ b/cmd/juju/storage/list_test.go @@ -43,13 +43,12 @@ func (s *ListSuite) TestList(c *gc.C) { nil, // Default format is tabular ` -Unit Storage ID Type Pool Size Status Message - persistent/1 filesystem detached -postgresql/0 db-dir/1100 block 3.0MiB attached -transcode/0 db-dir/1000 block pending creating volume -transcode/0 shared-fs/0 filesystem radiance 1.0GiB attached -transcode/1 shared-fs/0 filesystem radiance 1.0GiB attached - +Unit Storage ID Type Pool Size Status Message + persistent/1 filesystem detached +postgresql/0 db-dir/1100 block 3.0 MiB attached +transcode/0 db-dir/1000 block pending creating volume +transcode/0 shared-fs/0 filesystem radiance 1.0 GiB attached +transcode/1 shared-fs/0 filesystem radiance 1.0 GiB attached `[1:]) } @@ -60,13 +59,12 @@ func (s *ListSuite) TestListNoPool(c *gc.C) { nil, // Default format is tabular ` -Unit Storage ID Type Size Status Message - persistent/1 filesystem detached -postgresql/0 db-dir/1100 block 3.0MiB attached -transcode/0 db-dir/1000 block pending creating volume -transcode/0 shared-fs/0 filesystem 1.0GiB attached -transcode/1 shared-fs/0 filesystem 1.0GiB attached - +Unit Storage ID Type Size Status Message + persistent/1 filesystem detached +postgresql/0 db-dir/1100 block 3.0 MiB attached +transcode/0 db-dir/1000 block pending creating volume +transcode/0 shared-fs/0 filesystem 1.0 GiB attached +transcode/1 shared-fs/0 filesystem 1.0 GiB attached `[1:]) } diff --git a/cmd/juju/storage/poollist_test.go b/cmd/juju/storage/poollist_test.go index e7be05f7a13..f64642b14b5 100644 --- a/cmd/juju/storage/poollist_test.go +++ b/cmd/juju/storage/poollist_test.go @@ -89,7 +89,6 @@ abc testType key=value one=1 two=2 testName0 a key=value one=1 two=2 testName1 b key=value one=1 two=2 xyz testType key=value one=1 two=2 - `[1:]) } @@ -106,7 +105,6 @@ Name Provider Attributes abc testType a=true b=maybe c=well myaw testType a=true b=maybe c=well xyz testType a=true b=maybe c=well - `[1:]) } diff --git a/cmd/juju/storage/volumelist_test.go b/cmd/juju/storage/volumelist_test.go index 5ec0243ca5a..d1e930285df 100644 --- a/cmd/juju/storage/volumelist_test.go +++ b/cmd/juju/storage/volumelist_test.go @@ -90,14 +90,13 @@ func (s *ListSuite) TestVolumeListWithErrorResults(c *gc.C) { } var expectedVolumeListTabular = ` -Machine Unit Storage ID Volume ID Provider ID Device Size State Message -0 abc/0 db-dir/1001 0/0 provider-supplied-volume-0-0 loop0 512MiB attached -0 transcode/0 shared-fs/0 4 provider-supplied-volume-4 xvdf2 1.0GiB attached -0 1 provider-supplied-volume-1 2.0GiB attaching failed to attach, will retry -1 transcode/1 shared-fs/0 4 provider-supplied-volume-4 xvdf3 1.0GiB attached -1 2 provider-supplied-volume-2 xvdf1 3.0MiB attached -1 3 42MiB pending - +Machine Unit Storage ID Volume ID Provider ID Device Size State Message +0 abc/0 db-dir/1001 0/0 provider-supplied-volume-0-0 loop0 512 MiB attached +0 transcode/0 shared-fs/0 4 provider-supplied-volume-4 xvdf2 1.0 GiB attached +0 1 provider-supplied-volume-1 2.0 GiB attaching failed to attach, will retry +1 transcode/1 shared-fs/0 4 provider-supplied-volume-4 xvdf3 1.0 GiB attached +1 2 provider-supplied-volume-2 xvdf1 3.0 MiB attached +1 3 42 MiB pending `[1:] func (s *ListSuite) TestVolumeListTabular(c *gc.C) { @@ -118,9 +117,8 @@ func (s *ListSuite) TestVolumeListTabular(c *gc.C) { } var expectedCAASVolumeListTabular = ` -Unit Storage ID Volume ID Provider ID Size State Message -mysql/0 db-dir/1001 0 provider-supplied-volume-0 512MiB attached - +Unit Storage ID Volume ID Provider ID Size State Message +mysql/0 db-dir/1001 0 provider-supplied-volume-0 512 MiB attached `[1:] func (s *ListSuite) TestCAASVolumeListTabular(c *gc.C) { diff --git a/cmd/juju/user/list.go b/cmd/juju/user/list.go index b0e65265c71..a3161206e13 100644 --- a/cmd/juju/user/list.go +++ b/cmd/juju/user/list.go @@ -87,7 +87,7 @@ func (c *listCommand) getModelUsersAPI() (modelUsersAPI, error) { if err != nil { return nil, errors.Trace(err) } - return apiclient.NewClient(conn), nil + return apiclient.NewClient(conn, logger), nil } // Info implements Command.Info. diff --git a/cmd/jujud/agent/machine_test.go b/cmd/jujud/agent/machine_test.go index 8112f4bbcf9..b736c5de207 100644 --- a/cmd/jujud/agent/machine_test.go +++ b/cmd/jujud/agent/machine_test.go @@ -659,7 +659,7 @@ func (s *MachineSuite) TestManageModelAuditsAPI(c *gc.C) { st, err := api.Open(apiInfo, fastDialOpts) c.Assert(err, jc.ErrorIsNil) defer st.Close() - doRequest(apiclient.NewClient(st)) + doRequest(apiclient.NewClient(st, coretesting.NoopLogger{})) } // Make requests in separate API connections so they're separate conversations. diff --git a/cmd/modelcmd/modelcommand.go b/cmd/modelcmd/modelcommand.go index e8e5a3d69d1..81d556da1f4 100644 --- a/cmd/modelcmd/modelcommand.go +++ b/cmd/modelcmd/modelcommand.go @@ -313,7 +313,7 @@ func (c *ModelCommandBase) NewAPIClient() (*apiclient.Client, error) { if err != nil { return nil, errors.Trace(err) } - return apiclient.NewClient(root), nil + return apiclient.NewClient(root, logger), nil } // ModelDetails returns details from the file store for the model indicated by diff --git a/container/kvm/sync_internal_test.go b/container/kvm/sync_internal_test.go index ca4ee00859e..886a448860a 100644 --- a/container/kvm/sync_internal_test.go +++ b/container/kvm/sync_internal_test.go @@ -305,7 +305,7 @@ func (s *progressWriterSuite) TestOnlyPercentChanges(c *gc.C) { for i := 1; i <= 100; i++ { // We tick every 1ms and add 50kiB each time, which is // 50*1024 *1000/ 1000/1000 = 51MB/s - expectedCB = append(expectedCB, fmt.Sprintf("copying http://host/path %d%% (51MB/s)", i)) + expectedCB = append(expectedCB, fmt.Sprintf("copying http://host/path %d%% (51 MB/s)", i)) } // There are 2048 calls to Write, but there should only be 100 calls to progress update c.Check(len(cbLog), gc.Equals, 100) diff --git a/container/lxd/certificate.go b/container/lxd/certificate.go index 6a56eb1d715..282d1058f8b 100644 --- a/container/lxd/certificate.go +++ b/container/lxd/certificate.go @@ -11,9 +11,9 @@ import ( "fmt" "io" + "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - "github.com/lxc/lxd/shared" - "github.com/lxc/lxd/shared/api" ) // Certificate holds the information for a single certificate that a client may diff --git a/container/lxd/connection.go b/container/lxd/connection.go index 2300aac6a1b..8cd779a90cf 100644 --- a/container/lxd/connection.go +++ b/container/lxd/connection.go @@ -11,9 +11,9 @@ import ( "path/filepath" "strings" + lxd "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared" "github.com/juju/errors" - lxd "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared" ) type Protocol string diff --git a/container/lxd/container.go b/container/lxd/container.go index 4c423874e55..10b9fcf3c44 100644 --- a/container/lxd/container.go +++ b/container/lxd/container.go @@ -10,13 +10,13 @@ import ( "strings" "time" + "github.com/canonical/lxd/shared/api" + "github.com/canonical/lxd/shared/units" + "github.com/canonical/lxd/shared/version" "github.com/juju/clock" "github.com/juju/errors" "github.com/juju/retry" "github.com/juju/utils/v3/arch" - "github.com/lxc/lxd/shared/api" - "github.com/lxc/lxd/shared/units" - "github.com/lxc/lxd/shared/version" "github.com/juju/juju/core/constraints" corenetwork "github.com/juju/juju/core/network" diff --git a/container/lxd/container_test.go b/container/lxd/container_test.go index 8a4ffd6b614..9c931b254d6 100644 --- a/container/lxd/container_test.go +++ b/container/lxd/container_test.go @@ -7,11 +7,11 @@ import ( "net/http" "time" + "github.com/canonical/lxd/shared/api" + "github.com/canonical/lxd/shared/osarch" "github.com/juju/errors" jc "github.com/juju/testing/checkers" "github.com/juju/utils/v3/arch" - "github.com/lxc/lxd/shared/api" - "github.com/lxc/lxd/shared/osarch" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/export_test.go b/container/lxd/export_test.go index 4ede26b9c0e..4fbdb38614c 100644 --- a/container/lxd/export_test.go +++ b/container/lxd/export_test.go @@ -6,8 +6,8 @@ package lxd import ( "errors" + lxdclient "github.com/canonical/lxd/client" "github.com/juju/clock" - lxdclient "github.com/lxc/lxd/client" "github.com/juju/juju/container" "github.com/juju/juju/core/network" diff --git a/container/lxd/image.go b/container/lxd/image.go index 3d8a5844430..3a0f254e4a4 100644 --- a/container/lxd/image.go +++ b/container/lxd/image.go @@ -7,10 +7,10 @@ import ( "fmt" "path" + lxd "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" jujuarch "github.com/juju/utils/v3/arch" - lxd "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared/api" jujuos "github.com/juju/juju/core/os" jujuseries "github.com/juju/juju/core/series" diff --git a/container/lxd/image_test.go b/container/lxd/image_test.go index 27e89e172e8..50b3431205c 100644 --- a/container/lxd/image_test.go +++ b/container/lxd/image_test.go @@ -6,9 +6,9 @@ package lxd_test import ( "errors" + lxdclient "github.com/canonical/lxd/client" + lxdapi "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" - lxdclient "github.com/lxc/lxd/client" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/initialisation_linux.go b/container/lxd/initialisation_linux.go index 14d50838904..ef8ec768058 100644 --- a/container/lxd/initialisation_linux.go +++ b/container/lxd/initialisation_linux.go @@ -15,12 +15,12 @@ import ( "syscall" "time" + "github.com/canonical/lxd/shared" "github.com/juju/collections/set" "github.com/juju/errors" "github.com/juju/os/v2/series" "github.com/juju/packaging/v2/manager" "github.com/juju/proxy" - "github.com/lxc/lxd/shared" "github.com/juju/juju/container" "github.com/juju/juju/packaging" diff --git a/container/lxd/initialisation_test.go b/container/lxd/initialisation_test.go index 71e59db14d6..a4df7a73685 100644 --- a/container/lxd/initialisation_test.go +++ b/container/lxd/initialisation_test.go @@ -14,13 +14,13 @@ import ( "os/exec" "runtime" + lxd "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared/api" "github.com/juju/packaging/v2/commands" "github.com/juju/packaging/v2/manager" "github.com/juju/proxy" "github.com/juju/testing" jc "github.com/juju/testing/checkers" - lxd "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/instance.go b/container/lxd/instance.go index d0a4b961c3f..768f9034166 100644 --- a/container/lxd/instance.go +++ b/container/lxd/instance.go @@ -6,9 +6,9 @@ package lxd import ( "fmt" + lxd "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - lxd "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared/api" "github.com/juju/juju/core/instance" corenetwork "github.com/juju/juju/core/network" diff --git a/container/lxd/logger.go b/container/lxd/logger.go index 61c784bcefd..3b968a0aedf 100644 --- a/container/lxd/logger.go +++ b/container/lxd/logger.go @@ -7,8 +7,8 @@ import ( "bytes" "fmt" + lxdLogger "github.com/canonical/lxd/shared/logger" "github.com/juju/loggo" - lxdLogger "github.com/lxc/lxd/shared/logger" ) // lxdLogProxy proxies LXD's log calls through the juju logger. diff --git a/container/lxd/manager.go b/container/lxd/manager.go index 07c6e39e967..6b856eed766 100644 --- a/container/lxd/manager.go +++ b/container/lxd/manager.go @@ -8,11 +8,11 @@ import ( "strings" "sync" + "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" "github.com/juju/loggo" jujuarch "github.com/juju/utils/v3/arch" - "github.com/lxc/lxd/shared" - "github.com/lxc/lxd/shared/api" "github.com/juju/juju/cloudconfig/cloudinit" "github.com/juju/juju/cloudconfig/containerinit" diff --git a/container/lxd/manager_test.go b/container/lxd/manager_test.go index 9f592c04899..c6d6a9b831e 100644 --- a/container/lxd/manager_test.go +++ b/container/lxd/manager_test.go @@ -7,12 +7,12 @@ import ( "errors" stdtesting "testing" + lxdclient "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared" + lxdapi "github.com/canonical/lxd/shared/api" "github.com/juju/names/v4" jc "github.com/juju/testing/checkers" "github.com/juju/version/v2" - lxdclient "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/network.go b/container/lxd/network.go index cca4042f547..a0760b828e6 100644 --- a/container/lxd/network.go +++ b/container/lxd/network.go @@ -11,8 +11,8 @@ import ( "strconv" "strings" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - "github.com/lxc/lxd/shared/api" corenetwork "github.com/juju/juju/core/network" "github.com/juju/juju/network" diff --git a/container/lxd/network_test.go b/container/lxd/network_test.go index e9ae61c1058..8dbd012538a 100644 --- a/container/lxd/network_test.go +++ b/container/lxd/network_test.go @@ -6,8 +6,8 @@ package lxd_test import ( "errors" + lxdapi "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/server.go b/container/lxd/server.go index 7544ec34245..86c77b6a365 100644 --- a/container/lxd/server.go +++ b/container/lxd/server.go @@ -7,12 +7,12 @@ import ( "net/http" "strings" + lxd "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" "github.com/juju/clock" "github.com/juju/errors" "github.com/juju/utils/v3/arch" - lxd "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared" - "github.com/lxc/lxd/shared/api" ) // Server extends the upstream LXD container server. diff --git a/container/lxd/server_test.go b/container/lxd/server_test.go index d5fc20bf643..f3832ee17c7 100644 --- a/container/lxd/server_test.go +++ b/container/lxd/server_test.go @@ -4,8 +4,8 @@ package lxd_test import ( + "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/storage.go b/container/lxd/storage.go index a4ab5369a9a..56f5ef5ea79 100644 --- a/container/lxd/storage.go +++ b/container/lxd/storage.go @@ -4,8 +4,8 @@ package lxd import ( + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - "github.com/lxc/lxd/shared/api" ) func (s *Server) StorageSupported() bool { diff --git a/container/lxd/storage_test.go b/container/lxd/storage_test.go index b4143ebacba..76b7574f347 100644 --- a/container/lxd/storage_test.go +++ b/container/lxd/storage_test.go @@ -4,8 +4,8 @@ package lxd_test import ( + lxdapi "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/container/lxd/testing/doc.go b/container/lxd/testing/doc.go index 159ea895132..1cf0f288e96 100644 --- a/container/lxd/testing/doc.go +++ b/container/lxd/testing/doc.go @@ -5,4 +5,4 @@ // Run 'go generate' to regenerate the mock interfaces. package testing -//go:generate go run go.uber.org/mock/mockgen -package testing -destination lxd_mock.go -write_package_comment=false github.com/lxc/lxd/client Operation,RemoteOperation,Server,ImageServer,InstanceServer +//go:generate go run go.uber.org/mock/mockgen -package testing -destination lxd_mock.go -write_package_comment=false github.com/canonical/lxd/client Operation,RemoteOperation,Server,ImageServer,InstanceServer diff --git a/container/lxd/testing/lxd_mock.go b/container/lxd/testing/lxd_mock.go index 6b480782198..37b893d3996 100644 --- a/container/lxd/testing/lxd_mock.go +++ b/container/lxd/testing/lxd_mock.go @@ -1,17 +1,18 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/lxc/lxd/client (interfaces: Operation,RemoteOperation,Server,ImageServer,InstanceServer) +// Source: github.com/canonical/lxd/client (interfaces: Operation,RemoteOperation,Server,ImageServer,InstanceServer) package testing import ( + context "context" io "io" net "net" http "net/http" reflect "reflect" + lxd "github.com/canonical/lxd/client" + api "github.com/canonical/lxd/shared/api" websocket "github.com/gorilla/websocket" - lxd "github.com/lxc/lxd/client" - api "github.com/lxc/lxd/shared/api" sftp "github.com/pkg/sftp" gomock "go.uber.org/mock/gomock" ) @@ -139,6 +140,20 @@ func (mr *MockOperationMockRecorder) Wait() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Wait", reflect.TypeOf((*MockOperation)(nil).Wait)) } +// WaitContext mocks base method. +func (m *MockOperation) WaitContext(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitContext", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitContext indicates an expected call of WaitContext. +func (mr *MockOperationMockRecorder) WaitContext(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitContext", reflect.TypeOf((*MockOperation)(nil).WaitContext), arg0) +} + // MockRemoteOperation is a mock of RemoteOperation interface. type MockRemoteOperation struct { ctrl *gomock.Controller @@ -1201,6 +1216,36 @@ func (mr *MockInstanceServerMockRecorder) CreateStoragePool(arg0 interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStoragePool", reflect.TypeOf((*MockInstanceServer)(nil).CreateStoragePool), arg0) } +// CreateStoragePoolBucket mocks base method. +func (m *MockInstanceServer) CreateStoragePoolBucket(arg0 string, arg1 api.StorageBucketsPost) (*api.StorageBucketKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStoragePoolBucket", arg0, arg1) + ret0, _ := ret[0].(*api.StorageBucketKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStoragePoolBucket indicates an expected call of CreateStoragePoolBucket. +func (mr *MockInstanceServerMockRecorder) CreateStoragePoolBucket(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStoragePoolBucket", reflect.TypeOf((*MockInstanceServer)(nil).CreateStoragePoolBucket), arg0, arg1) +} + +// CreateStoragePoolBucketKey mocks base method. +func (m *MockInstanceServer) CreateStoragePoolBucketKey(arg0, arg1 string, arg2 api.StorageBucketKeysPost) (*api.StorageBucketKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStoragePoolBucketKey", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.StorageBucketKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStoragePoolBucketKey indicates an expected call of CreateStoragePoolBucketKey. +func (mr *MockInstanceServerMockRecorder) CreateStoragePoolBucketKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStoragePoolBucketKey", reflect.TypeOf((*MockInstanceServer)(nil).CreateStoragePoolBucketKey), arg0, arg1, arg2) +} + // CreateStoragePoolVolume mocks base method. func (m *MockInstanceServer) CreateStoragePoolVolume(arg0 string, arg1 api.StorageVolumesPost) error { m.ctrl.T.Helper() @@ -1245,6 +1290,21 @@ func (mr *MockInstanceServerMockRecorder) CreateStoragePoolVolumeFromBackup(arg0 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStoragePoolVolumeFromBackup", reflect.TypeOf((*MockInstanceServer)(nil).CreateStoragePoolVolumeFromBackup), arg0, arg1) } +// CreateStoragePoolVolumeFromISO mocks base method. +func (m *MockInstanceServer) CreateStoragePoolVolumeFromISO(arg0 string, arg1 lxd.StoragePoolVolumeBackupArgs) (lxd.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStoragePoolVolumeFromISO", arg0, arg1) + ret0, _ := ret[0].(lxd.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStoragePoolVolumeFromISO indicates an expected call of CreateStoragePoolVolumeFromISO. +func (mr *MockInstanceServerMockRecorder) CreateStoragePoolVolumeFromISO(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStoragePoolVolumeFromISO", reflect.TypeOf((*MockInstanceServer)(nil).CreateStoragePoolVolumeFromISO), arg0, arg1) +} + // CreateStoragePoolVolumeSnapshot mocks base method. func (m *MockInstanceServer) CreateStoragePoolVolumeSnapshot(arg0, arg1, arg2 string, arg3 api.StorageVolumeSnapshotsPost) (lxd.Operation, error) { m.ctrl.T.Helper() @@ -1687,6 +1747,34 @@ func (mr *MockInstanceServerMockRecorder) DeleteStoragePool(arg0 interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStoragePool", reflect.TypeOf((*MockInstanceServer)(nil).DeleteStoragePool), arg0) } +// DeleteStoragePoolBucket mocks base method. +func (m *MockInstanceServer) DeleteStoragePoolBucket(arg0, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStoragePoolBucket", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteStoragePoolBucket indicates an expected call of DeleteStoragePoolBucket. +func (mr *MockInstanceServerMockRecorder) DeleteStoragePoolBucket(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStoragePoolBucket", reflect.TypeOf((*MockInstanceServer)(nil).DeleteStoragePoolBucket), arg0, arg1) +} + +// DeleteStoragePoolBucketKey mocks base method. +func (m *MockInstanceServer) DeleteStoragePoolBucketKey(arg0, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStoragePoolBucketKey", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteStoragePoolBucketKey indicates an expected call of DeleteStoragePoolBucketKey. +func (mr *MockInstanceServerMockRecorder) DeleteStoragePoolBucketKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStoragePoolBucketKey", reflect.TypeOf((*MockInstanceServer)(nil).DeleteStoragePoolBucketKey), arg0, arg1, arg2) +} + // DeleteStoragePoolVolume mocks base method. func (m *MockInstanceServer) DeleteStoragePoolVolume(arg0, arg1, arg2 string) error { m.ctrl.T.Helper() @@ -1956,6 +2044,22 @@ func (mr *MockInstanceServerMockRecorder) GetClusterMemberNames() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterMemberNames", reflect.TypeOf((*MockInstanceServer)(nil).GetClusterMemberNames)) } +// GetClusterMemberState mocks base method. +func (m *MockInstanceServer) GetClusterMemberState(arg0 string) (*api.ClusterMemberState, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetClusterMemberState", arg0) + ret0, _ := ret[0].(*api.ClusterMemberState) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetClusterMemberState indicates an expected call of GetClusterMemberState. +func (mr *MockInstanceServerMockRecorder) GetClusterMemberState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterMemberState", reflect.TypeOf((*MockInstanceServer)(nil).GetClusterMemberState), arg0) +} + // GetClusterMembers mocks base method. func (m *MockInstanceServer) GetClusterMembers() ([]api.ClusterMember, error) { m.ctrl.T.Helper() @@ -3592,6 +3696,98 @@ func (mr *MockInstanceServerMockRecorder) GetStoragePool(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePool", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePool), arg0) } +// GetStoragePoolBucket mocks base method. +func (m *MockInstanceServer) GetStoragePoolBucket(arg0, arg1 string) (*api.StorageBucket, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBucket", arg0, arg1) + ret0, _ := ret[0].(*api.StorageBucket) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetStoragePoolBucket indicates an expected call of GetStoragePoolBucket. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBucket(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBucket", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBucket), arg0, arg1) +} + +// GetStoragePoolBucketKey mocks base method. +func (m *MockInstanceServer) GetStoragePoolBucketKey(arg0, arg1, arg2 string) (*api.StorageBucketKey, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBucketKey", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.StorageBucketKey) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetStoragePoolBucketKey indicates an expected call of GetStoragePoolBucketKey. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBucketKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBucketKey", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBucketKey), arg0, arg1, arg2) +} + +// GetStoragePoolBucketKeyNames mocks base method. +func (m *MockInstanceServer) GetStoragePoolBucketKeyNames(arg0, arg1 string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBucketKeyNames", arg0, arg1) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStoragePoolBucketKeyNames indicates an expected call of GetStoragePoolBucketKeyNames. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBucketKeyNames(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBucketKeyNames", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBucketKeyNames), arg0, arg1) +} + +// GetStoragePoolBucketKeys mocks base method. +func (m *MockInstanceServer) GetStoragePoolBucketKeys(arg0, arg1 string) ([]api.StorageBucketKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBucketKeys", arg0, arg1) + ret0, _ := ret[0].([]api.StorageBucketKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStoragePoolBucketKeys indicates an expected call of GetStoragePoolBucketKeys. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBucketKeys(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBucketKeys", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBucketKeys), arg0, arg1) +} + +// GetStoragePoolBucketNames mocks base method. +func (m *MockInstanceServer) GetStoragePoolBucketNames(arg0 string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBucketNames", arg0) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStoragePoolBucketNames indicates an expected call of GetStoragePoolBucketNames. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBucketNames(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBucketNames", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBucketNames), arg0) +} + +// GetStoragePoolBuckets mocks base method. +func (m *MockInstanceServer) GetStoragePoolBuckets(arg0 string) ([]api.StorageBucket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStoragePoolBuckets", arg0) + ret0, _ := ret[0].([]api.StorageBucket) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStoragePoolBuckets indicates an expected call of GetStoragePoolBuckets. +func (mr *MockInstanceServerMockRecorder) GetStoragePoolBuckets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoragePoolBuckets", reflect.TypeOf((*MockInstanceServer)(nil).GetStoragePoolBuckets), arg0) +} + // GetStoragePoolNames mocks base method. func (m *MockInstanceServer) GetStoragePoolNames() ([]string, error) { m.ctrl.T.Helper() @@ -3715,10 +3911,10 @@ func (mr *MockInstanceServerMockRecorder) GetStoragePoolVolumeNames(arg0 interfa } // GetStoragePoolVolumeNamesAllProjects mocks base method. -func (m *MockInstanceServer) GetStoragePoolVolumeNamesAllProjects(arg0 string) ([]string, error) { +func (m *MockInstanceServer) GetStoragePoolVolumeNamesAllProjects(arg0 string) (map[string][]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStoragePoolVolumeNamesAllProjects", arg0) - ret0, _ := ret[0].([]string) + ret0, _ := ret[0].(map[string][]string) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -4076,6 +4272,36 @@ func (mr *MockInstanceServerMockRecorder) RawWebsocket(arg0 interface{}) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RawWebsocket", reflect.TypeOf((*MockInstanceServer)(nil).RawWebsocket), arg0) } +// RebuildInstance mocks base method. +func (m *MockInstanceServer) RebuildInstance(arg0 string, arg1 api.InstanceRebuildPost) (lxd.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RebuildInstance", arg0, arg1) + ret0, _ := ret[0].(lxd.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RebuildInstance indicates an expected call of RebuildInstance. +func (mr *MockInstanceServerMockRecorder) RebuildInstance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebuildInstance", reflect.TypeOf((*MockInstanceServer)(nil).RebuildInstance), arg0, arg1) +} + +// RebuildInstanceFromImage mocks base method. +func (m *MockInstanceServer) RebuildInstanceFromImage(arg0 lxd.ImageServer, arg1 api.Image, arg2 string, arg3 api.InstanceRebuildPost) (lxd.RemoteOperation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RebuildInstanceFromImage", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(lxd.RemoteOperation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RebuildInstanceFromImage indicates an expected call of RebuildInstanceFromImage. +func (mr *MockInstanceServerMockRecorder) RebuildInstanceFromImage(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebuildInstanceFromImage", reflect.TypeOf((*MockInstanceServer)(nil).RebuildInstanceFromImage), arg0, arg1, arg2, arg3) +} + // RefreshImage mocks base method. func (m *MockInstanceServer) RefreshImage(arg0 string) (lxd.Operation, error) { m.ctrl.T.Helper() @@ -4765,6 +4991,34 @@ func (mr *MockInstanceServerMockRecorder) UpdateStoragePool(arg0, arg1, arg2 int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStoragePool", reflect.TypeOf((*MockInstanceServer)(nil).UpdateStoragePool), arg0, arg1, arg2) } +// UpdateStoragePoolBucket mocks base method. +func (m *MockInstanceServer) UpdateStoragePoolBucket(arg0, arg1 string, arg2 api.StorageBucketPut, arg3 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStoragePoolBucket", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateStoragePoolBucket indicates an expected call of UpdateStoragePoolBucket. +func (mr *MockInstanceServerMockRecorder) UpdateStoragePoolBucket(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStoragePoolBucket", reflect.TypeOf((*MockInstanceServer)(nil).UpdateStoragePoolBucket), arg0, arg1, arg2, arg3) +} + +// UpdateStoragePoolBucketKey mocks base method. +func (m *MockInstanceServer) UpdateStoragePoolBucketKey(arg0, arg1, arg2 string, arg3 api.StorageBucketKeyPut, arg4 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStoragePoolBucketKey", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateStoragePoolBucketKey indicates an expected call of UpdateStoragePoolBucketKey. +func (mr *MockInstanceServerMockRecorder) UpdateStoragePoolBucketKey(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStoragePoolBucketKey", reflect.TypeOf((*MockInstanceServer)(nil).UpdateStoragePoolBucketKey), arg0, arg1, arg2, arg3, arg4) +} + // UpdateStoragePoolVolume mocks base method. func (m *MockInstanceServer) UpdateStoragePoolVolume(arg0, arg1, arg2 string, arg3 api.StorageVolumePut, arg4 string) error { m.ctrl.T.Helper() diff --git a/container/lxd/testing/suite.go b/container/lxd/testing/suite.go index 31145fc2497..bf4b1939c18 100644 --- a/container/lxd/testing/suite.go +++ b/container/lxd/testing/suite.go @@ -4,8 +4,8 @@ package testing import ( + lxdapi "github.com/canonical/lxd/shared/api" "github.com/juju/utils/v3/arch" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/core/lxdprofile/doc.go b/core/lxdprofile/doc.go index 5f726cba416..20da59e3d4f 100644 --- a/core/lxdprofile/doc.go +++ b/core/lxdprofile/doc.go @@ -7,7 +7,7 @@ // to a container. // // More information about a type of LXD configuration profile can found -// https://github.com/lxc/lxd/blob/master/doc/containers.md +// https://github.com/canonical/lxd/blob/master/doc/containers.md // // LXDProfile package defines core concepts that can be utilised from different // packages of the codebase, that want to work with a LXD profile. Not all diff --git a/environs/jujutest/livetests.go b/environs/jujutest/livetests.go index a863be3dd0b..eb5af9b60b2 100644 --- a/environs/jujutest/livetests.go +++ b/environs/jujutest/livetests.go @@ -683,7 +683,7 @@ func (t *LiveTests) TestBootstrapAndDeploy(c *gc.C) { c.Assert(err, jc.ErrorIsNil) // Check that the API connection is working. - status, err := apiclient.NewClient(apiState).Status(nil) + status, err := apiclient.NewClient(apiState, coretesting.NoopLogger{}).Status(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(status.Machines["0"].InstanceId, gc.Equals, string(instId0)) diff --git a/featuretests/dblog_test.go b/featuretests/dblog_test.go index 2bb082759b0..b5c1f9e7777 100644 --- a/featuretests/dblog_test.go +++ b/featuretests/dblog_test.go @@ -197,7 +197,7 @@ func (s *debugLogDbSuite1) TestLogsAPI(c *gc.C) { messages := make(chan common.LogMessage) go func(numMessages int) { - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) logMessages, err := client.WatchDebugLog(common.DebugLogParams{}) c.Assert(err, jc.ErrorIsNil) @@ -306,7 +306,7 @@ func (s *debugLogDbSuite2) TestLogsUsesStartTime(c *gc.C) { }}) c.Assert(err, jc.ErrorIsNil) - client := apiclient.NewClient(s.APIState) + client := apiclient.NewClient(s.APIState, coretesting.NoopLogger{}) logMessages, err := client.WatchDebugLog(common.DebugLogParams{ StartTime: t3, }) diff --git a/go.mod b/go.mod index 1a4c16ad660..9c083799447 100644 --- a/go.mod +++ b/go.mod @@ -24,11 +24,12 @@ require ( github.com/aws/aws-sdk-go-v2/service/iam v1.9.0 github.com/aws/smithy-go v1.8.0 github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac + github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0 github.com/canonical/pebble v0.0.0-20230307221844-5842ea68c9c7 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/coreos/go-systemd/v22 v22.3.2 github.com/docker/distribution v2.8.2+incompatible - github.com/dustin/go-humanize v1.0.0 + github.com/dustin/go-humanize v1.0.1 github.com/go-goose/goose/v5 v5.0.0-20220707165353-781664254fe4 github.com/go-logr/logr v1.2.4 github.com/go-macaroon-bakery/macaroon-bakery/v3 v3.0.1 @@ -37,7 +38,7 @@ require ( github.com/google/uuid v1.3.0 github.com/googleapis/gnostic v0.5.5 github.com/gorilla/handlers v1.3.0 - github.com/gorilla/schema v0.0.0-20160426231512-08023a0215e7 + github.com/gorilla/schema v1.2.0 github.com/gorilla/websocket v1.5.0 github.com/gosuri/uitable v0.0.1 github.com/hashicorp/go-hclog v0.9.1 @@ -50,8 +51,8 @@ require ( github.com/juju/charm/v8 v8.0.6 github.com/juju/charmrepo/v6 v6.0.3 github.com/juju/clock v1.0.3 - github.com/juju/cmd/v3 v3.0.0 - github.com/juju/collections v1.0.2 + github.com/juju/cmd/v3 v3.0.14 + github.com/juju/collections v1.0.4 github.com/juju/description/v3 v3.0.15 github.com/juju/errors v1.0.0 github.com/juju/featureflag v1.0.0 @@ -89,8 +90,7 @@ require ( github.com/juju/worker/v3 v3.4.0 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kr/pretty v0.3.1 - github.com/lxc/lxd v0.0.0-20220816180258-7e0418163fa9 - github.com/mattn/go-isatty v0.0.16 + github.com/mattn/go-isatty v0.0.19 github.com/microsoft/kiota-abstractions-go v1.2.0 github.com/microsoft/kiota-http-go v1.0.1 github.com/microsoftgraph/msgraph-sdk-go v1.14.0 @@ -114,8 +114,8 @@ require ( google.golang.org/api v0.126.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/httprequest.v1 v1.2.1 - gopkg.in/ini.v1 v1.66.6 - gopkg.in/juju/environschema.v1 v1.0.1-0.20201027142642-c89a4490670a + gopkg.in/ini.v1 v1.67.0 + gopkg.in/juju/environschema.v1 v1.0.1 gopkg.in/macaroon-bakery.v2 v2.3.0 gopkg.in/macaroon.v2 v2.1.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce @@ -127,8 +127,8 @@ require ( k8s.io/apiextensions-apiserver v0.21.10 k8s.io/apimachinery v0.23.4 k8s.io/client-go v0.23.4 - k8s.io/klog/v2 v2.40.1 - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 + k8s.io/klog/v2 v2.80.1 + k8s.io/utils v0.0.0-20230711102312-30195339c3c7 ) require ( @@ -165,6 +165,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.0 // indirect github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect @@ -198,7 +199,7 @@ require ( github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/microsoft/kiota-authentication-azure-go v1.0.0 // indirect github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect @@ -209,6 +210,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/muhlemmer/gu v0.3.1 // indirect github.com/onsi/ginkgo v1.14.2 // indirect github.com/onsi/gomega v1.10.4 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect @@ -216,22 +218,24 @@ require ( github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pkg/xattr v0.4.9 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/common v0.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect - github.com/rs/xid v1.4.0 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/rs/xid v1.5.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.4 // indirect - github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect + github.com/vishvananda/netns v0.0.4 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + github.com/zitadel/oidc/v2 v2.6.4 // indirect go.etcd.io/bbolt v1.3.5 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.16.0 // indirect @@ -242,13 +246,13 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/grpc v1.56.2 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/errgo.v1 v1.0.1 // indirect gopkg.in/gobwas/glob.v0 v0.2.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/macaroon-bakery.v3 v3.0.0 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect @@ -256,7 +260,7 @@ require ( sigs.k8s.io/yaml v1.2.0 // indirect ) -// This is copied from the go.mod file in github.com/lxc/lxd +// This is copied from the go.mod file in github.com/canonical/lxd // It is needed to avoid this error when running go list -m // go: google.golang.org/grpc/naming@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000 replace google.golang.org/grpc/naming => google.golang.org/grpc v1.29.1 diff --git a/go.sum b/go.sum index ffa07d325a0..b5798e8ec7c 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,8 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac h1:X5YRFJiteUM3rajABEYJSzw1KWgmp1ulPFKxpfLm0M4= github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0 h1:1JfA4hOWjPoF18ebpKFWafOWFplCh0jvHhAethmLQFo= +github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0/go.mod h1:BAaklWDYuotKE0eQnwO6NArKc6rEwnTheuOPrtlLBYA= github.com/canonical/pebble v0.0.0-20230307221844-5842ea68c9c7 h1:/L2OgTX7McauPmggZfYNWEu6D/QiPHcNDQ60grftM04= github.com/canonical/pebble v0.0.0-20230307221844-5842ea68c9c7/go.mod h1:j3uyWpPkuWf8u0kB2v7n/XGVpYIg4luGetpSngCvzac= github.com/canonical/x-go v0.0.0-20230113154138-0ccdb0b57a43 h1:bey1JgA3D2EBabr2a7kWKj+JlEPxX1akv8rcRromotA= @@ -203,9 +205,10 @@ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5O github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20141228071148-145fabdb1ab7 h1:n/ETHd/ASEuDgfz8mVStuNUN2iUqKg4mNhxowUFhNjw= github.com/dustin/go-humanize v0.0.0-20141228071148-145fabdb1ab7/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -235,8 +238,8 @@ github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebP github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -300,8 +303,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -382,8 +386,8 @@ github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6Ylu github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/schema v0.0.0-20160426231512-08023a0215e7 h1:mOUfGq/7wiwNfHY5Wyz+aRzEfqUCGdUhUcSPsfHVaPs= -github.com/gorilla/schema v0.0.0-20160426231512-08023a0215e7/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= +github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= @@ -457,6 +461,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJz github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= +github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= @@ -494,13 +500,13 @@ github.com/juju/clock v1.0.3 h1:yJHIsWXeU8j3QcBdiess09SzfiXRRrsjKPn2whnMeds= github.com/juju/clock v1.0.3/go.mod h1:HIBvJ8kiV/n7UHwKuCkdYL4l/MDECztHR2sAvWDxxf0= github.com/juju/cmd v0.0.0-20171107070456-e74f39857ca0/go.mod h1:yWJQHl73rdSX4DHVKGqkAip+huBslxRwS8m9CrOLq18= github.com/juju/cmd/v3 v3.0.0-20220202061353-b1cc80b193b0/go.mod h1:EoGJiEG+vbMwO9l+Es0SDTlaQPjH6nLcnnc4NfZB3cY= -github.com/juju/cmd/v3 v3.0.0 h1:5D/4C9Q5quc9F2OfGEVi+xgHue3D9HyY0/ad8ywgk+A= -github.com/juju/cmd/v3 v3.0.0/go.mod h1:OwsFyKpl9Hz4oHdlZyVN2QFXjiwm5vSu/lShppBbwhI= +github.com/juju/cmd/v3 v3.0.14 h1:KuuamArSH7vQ6SdQKEHYK2scEMkJTEZKLs8abrlW3XE= +github.com/juju/cmd/v3 v3.0.14/go.mod h1:lGtDvm2BG+FKnIS8yY/vrhxQNX9imnL6bPIYGSTchuI= github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271/go.mod h1:5XgO71dV1JClcOJE+4dzdn4HrI5LiyKd7PlVG6eZYhY= github.com/juju/collections v0.0.0-20220203020748-febd7cad8a7a/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo= github.com/juju/collections v1.0.0/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo= -github.com/juju/collections v1.0.2 h1:y9t99Nq/uUZksJgWehiWxIr2vB1UG3hUT7LBNy1xiH8= -github.com/juju/collections v1.0.2/go.mod h1:kYJowQZYtHDvYDfZOvgf3Mt7mjKYwm/k1nqnJoMYOUc= +github.com/juju/collections v1.0.4 h1:GjL+aN512m2rVDqhPII7P6qB0e+iYFubz8sqBhZaZtk= +github.com/juju/collections v1.0.4/go.mod h1:hVrdB0Zwq9wIU1Fl6ItD2+UETeNeOEs+nGvJufVe+0c= github.com/juju/description/v3 v3.0.15 h1:Mf61RoWOsNUw4aEx9KVLf2RCopmIH5FX3d48x0x5W84= github.com/juju/description/v3 v3.0.15/go.mod h1:VzqhM294IF39mV66NdIx2bTcNSkfhZTVEqrtB9ktLWk= github.com/juju/errors v0.0.0-20150916125642-1b5e39b83d18/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= @@ -549,7 +555,6 @@ github.com/juju/mgo/v2 v2.0.0-20220111072304-f200228f1090/go.mod h1:N614SE0a4e+i github.com/juju/mgo/v2 v2.0.2 h1:ufYtW2OFNjniTuxOngecP3Mk5sSclo8Zl1mnmyGWUWA= github.com/juju/mgo/v2 v2.0.2/go.mod h1:Z2QbXIrR9JuJcSyankQOw31tINNA5p3qevW73oDoHsM= github.com/juju/mgotest v1.0.1/go.mod h1:vTaDufYul+Ps8D7bgseHjq87X8eu0ivlKLp9mVc/Bfc= -github.com/juju/mgotest v1.0.2/go.mod h1:04v1Xi2RiTO3h77YWtaXB2LAaGRSSi+Vl4hOV1coD0k= github.com/juju/mgotest v1.0.3 h1:3UIS2cOSzE6qz/dtiLAaQew5AKYw/bRb++/lsB522HI= github.com/juju/mgotest v1.0.3/go.mod h1:Dnzi6seljG9GoZpqFdTqRV3ybB3UcIj+H8iQqy1so1A= github.com/juju/mutex v0.0.0-20171110020013-1fe2a4bf0a3a/go.mod h1:Y3oOzHH8CQ0Ppt0oCKJ2JFO81/EsWenH5AEqigLH+yY= @@ -677,8 +682,6 @@ github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/lxc/lxd v0.0.0-20220816180258-7e0418163fa9 h1:PUHgePCgYTL5ehDTp9k2dFu0EdqW23UUOQtyVRE4JIc= -github.com/lxc/lxd v0.0.0-20220816180258-7e0418163fa9/go.mod h1:Wi22FmJJIPu8lb8jWxxZ+JlTcvMimUut7v1OStGaB0M= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -703,11 +706,12 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -754,6 +758,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= +github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -802,8 +808,11 @@ github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= +github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -831,11 +840,13 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a h1:3QH7VyOaaiUHNrA9Se4YQIRkDTCw1EJls9xTUCaCeRM= @@ -846,8 +857,10 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -856,8 +869,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -900,8 +913,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= -github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vmware/govmomi v0.21.1-0.20191008161538-40aebf13ba45 h1:zpQBW+l4uPQTfTOxedN5GEcSONhabbCf3X+5+P/H4Jk= github.com/vmware/govmomi v0.21.1-0.20191008161538-40aebf13ba45/go.mod h1:zbnFoBQ9GIjs2RVETy8CNEpb+L+Lwkjs3XZUL0B3/m0= github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk= @@ -924,6 +937,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zitadel/oidc/v2 v2.6.4 h1:bruA+KOFHcGpxr++WgtvR82ZlH54kKituu5xE4wpF7o= +github.com/zitadel/oidc/v2 v2.6.4/go.mod h1:owrsdzRqGvIZjBCY9LY1ZUYJ0mRUbGkQpZ3OskXL4wM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -986,6 +1001,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1168,10 +1185,12 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1338,12 +1357,12 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1364,8 +1383,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1406,15 +1425,13 @@ gopkg.in/httprequest.v1 v1.2.1/go.mod h1:x2Otw96yda5+8+6ZeWwHIJTFkEHWP/qP8pJOzqE gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/juju/environschema.v1 v1.0.0/go.mod h1:WTgU3KXKCVoO9bMmG/4KHzoaRvLeoxfjArpgd1MGWFA= -gopkg.in/juju/environschema.v1 v1.0.1-0.20201027142642-c89a4490670a h1:tOwxh73E6us6t6MJHVe/erls2255hEwFKY8TJ40wcWY= -gopkg.in/juju/environschema.v1 v1.0.1-0.20201027142642-c89a4490670a/go.mod h1:WTgU3KXKCVoO9bMmG/4KHzoaRvLeoxfjArpgd1MGWFA= +gopkg.in/juju/environschema.v1 v1.0.1 h1:eXQQsfSJykpp1Kz79pVmKWE6G5yzKuiCqkR01LHFVS0= +gopkg.in/juju/environschema.v1 v1.0.1/go.mod h1:WTgU3KXKCVoO9bMmG/4KHzoaRvLeoxfjArpgd1MGWFA= gopkg.in/macaroon-bakery.v2 v2.3.0 h1:b40knPgPTke1QLTE8BSYeH7+R/hiIozB1A8CTLYN0Ic= gopkg.in/macaroon-bakery.v2 v2.3.0/go.mod h1:/8YhtPARXeRzbpEPLmRB66+gQE8/pzBBkWwg7Vz/guc= -gopkg.in/macaroon-bakery.v3 v3.0.0 h1:bgTztGVwcj62/Zms7DIHTMtBPNBajeCzJfiA8TBsK8w= -gopkg.in/macaroon-bakery.v3 v3.0.0/go.mod h1:jc4E407H0WJzjH84QSPeecCdts0XnHUmKhA1AP/w1k8= gopkg.in/macaroon.v2 v2.1.0 h1:HZcsjBCzq9t0eBPMKqTN/uSN6JOm78ZJ2INbqcBQOUI= gopkg.in/macaroon.v2 v2.1.0/go.mod h1:OUb+TQP/OP0WOerC2Jp/3CwhIKyIa9kQjuc7H24e6/o= gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= @@ -1429,6 +1446,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= @@ -1468,16 +1487,16 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.40.1 h1:P4RRucWk/lFOlDdkAr3mc7iWFkgKrZY9qZMAgek06S4= -k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/utils v0.0.0-20210521133846-da695404a2bc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= launchpad.net/xmlpath v0.0.0-20130614043138-000000000004/go.mod h1:vqyExLOM3qBx7mvYRkoxjSCF945s0mbe7YynlKYXtsA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/provider/lxd/credentials.go b/provider/lxd/credentials.go index ee0fb4d7fad..c2d8a0551e0 100644 --- a/provider/lxd/credentials.go +++ b/provider/lxd/credentials.go @@ -14,10 +14,10 @@ import ( "path/filepath" "runtime" + "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" "github.com/juju/utils/v3" - "github.com/lxc/lxd/shared" - "github.com/lxc/lxd/shared/api" "github.com/juju/juju/cloud" "github.com/juju/juju/container/lxd" diff --git a/provider/lxd/credentials_test.go b/provider/lxd/credentials_test.go index aa9a4845729..343729dfe6f 100644 --- a/provider/lxd/credentials_test.go +++ b/provider/lxd/credentials_test.go @@ -10,11 +10,11 @@ import ( "path" "path/filepath" + "github.com/canonical/lxd/shared/api" "github.com/juju/cmd/v3/cmdtesting" "github.com/juju/errors" jc "github.com/juju/testing/checkers" "github.com/juju/utils/v3" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/environ.go b/provider/lxd/environ.go index e0ee0282736..a806ac62ac1 100644 --- a/provider/lxd/environ.go +++ b/provider/lxd/environ.go @@ -8,8 +8,8 @@ import ( "strings" "sync" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - "github.com/lxc/lxd/shared/api" "github.com/juju/juju/core/instance" "github.com/juju/juju/core/lxdprofile" diff --git a/provider/lxd/environ_broker.go b/provider/lxd/environ_broker.go index 3a56cbe6d15..b0a7c92c9f8 100644 --- a/provider/lxd/environ_broker.go +++ b/provider/lxd/environ_broker.go @@ -156,7 +156,7 @@ func (env *environ) getImageSources() ([]lxd.ServerSpec, error) { // image-metadata-url is an "https://" URL, so that Users get a // "your configuration is wrong" error, rather than silently // changing it and having them get confused. - // https://github.com/lxc/lxd/issues/1763 + // https://github.com/canonical/lxd/issues/1763 remotes = append(remotes, lxd.MakeSimpleStreamsServerSpec(source.Description(), url)) } // Required for CentOS images. diff --git a/provider/lxd/environ_broker_test.go b/provider/lxd/environ_broker_test.go index 0ef41e8c2f6..b65a66c0081 100644 --- a/provider/lxd/environ_broker_test.go +++ b/provider/lxd/environ_broker_test.go @@ -7,9 +7,9 @@ import ( "fmt" "reflect" + "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" "github.com/juju/utils/v3/arch" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/environ_network.go b/provider/lxd/environ_network.go index 0e1289c069a..d6e776be4ca 100644 --- a/provider/lxd/environ_network.go +++ b/provider/lxd/environ_network.go @@ -9,10 +9,10 @@ import ( "sort" "strings" + lxdapi "github.com/canonical/lxd/shared/api" "github.com/juju/collections/set" "github.com/juju/errors" "github.com/juju/names/v4" - lxdapi "github.com/lxc/lxd/shared/api" "github.com/juju/juju/core/instance" "github.com/juju/juju/core/network" diff --git a/provider/lxd/environ_network_test.go b/provider/lxd/environ_network_test.go index dc450841cba..2d98d9653bd 100644 --- a/provider/lxd/environ_network_test.go +++ b/provider/lxd/environ_network_test.go @@ -4,9 +4,9 @@ package lxd_test import ( + lxdapi "github.com/canonical/lxd/shared/api" "github.com/juju/errors" jc "github.com/juju/testing/checkers" - lxdapi "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/environ_policy_test.go b/provider/lxd/environ_policy_test.go index 08913a25817..e0ab5eae37e 100644 --- a/provider/lxd/environ_policy_test.go +++ b/provider/lxd/environ_policy_test.go @@ -6,9 +6,9 @@ package lxd_test import ( "strings" + "github.com/canonical/lxd/shared/api" jc "github.com/juju/testing/checkers" "github.com/juju/utils/v3/arch" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/environ_test.go b/provider/lxd/environ_test.go index 98250dafbc6..0efa7d811e4 100644 --- a/provider/lxd/environ_test.go +++ b/provider/lxd/environ_test.go @@ -7,11 +7,11 @@ import ( "context" stdcontext "context" + "github.com/canonical/lxd/shared/api" "github.com/juju/cmd/v3/cmdtesting" "github.com/juju/errors" gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/instance.go b/provider/lxd/instance.go index ca369738191..70fa66760aa 100644 --- a/provider/lxd/instance.go +++ b/provider/lxd/instance.go @@ -4,8 +4,8 @@ package lxd import ( + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" - "github.com/lxc/lxd/shared/api" "github.com/juju/juju/container/lxd" "github.com/juju/juju/core/instance" diff --git a/provider/lxd/package_mock_test.go b/provider/lxd/package_mock_test.go index c8ded996a10..2231faaf5db 100644 --- a/provider/lxd/package_mock_test.go +++ b/provider/lxd/package_mock_test.go @@ -7,12 +7,12 @@ package lxd import ( reflect "reflect" - lxd "github.com/juju/juju/container/lxd" + lxd "github.com/canonical/lxd/client" + api "github.com/canonical/lxd/shared/api" + lxd0 "github.com/juju/juju/container/lxd" network "github.com/juju/juju/core/network" environs "github.com/juju/juju/environs" cloudspec "github.com/juju/juju/environs/cloudspec" - lxd1 "github.com/lxc/lxd/client" - api "github.com/lxc/lxd/shared/api" gomock "go.uber.org/mock/gomock" ) @@ -40,10 +40,10 @@ func (m *MockServer) EXPECT() *MockServerMockRecorder { } // AliveContainers mocks base method. -func (m *MockServer) AliveContainers(arg0 string) ([]lxd.Container, error) { +func (m *MockServer) AliveContainers(arg0 string) ([]lxd0.Container, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AliveContainers", arg0) - ret0, _ := ret[0].([]lxd.Container) + ret0, _ := ret[0].([]lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -84,7 +84,7 @@ func (mr *MockServerMockRecorder) CreateCertificate(arg0 interface{}) *gomock.Ca } // CreateClientCertificate mocks base method. -func (m *MockServer) CreateClientCertificate(arg0 *lxd.Certificate) error { +func (m *MockServer) CreateClientCertificate(arg0 *lxd0.Certificate) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateClientCertificate", arg0) ret0, _ := ret[0].(error) @@ -98,10 +98,10 @@ func (mr *MockServerMockRecorder) CreateClientCertificate(arg0 interface{}) *gom } // CreateContainerFromSpec mocks base method. -func (m *MockServer) CreateContainerFromSpec(arg0 lxd.ContainerSpec) (*lxd.Container, error) { +func (m *MockServer) CreateContainerFromSpec(arg0 lxd0.ContainerSpec) (*lxd0.Container, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateContainerFromSpec", arg0) - ret0, _ := ret[0].(*lxd.Container) + ret0, _ := ret[0].(*lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -239,14 +239,14 @@ func (mr *MockServerMockRecorder) EnsureDefaultStorage(arg0, arg1 interface{}) * } // FilterContainers mocks base method. -func (m *MockServer) FilterContainers(arg0 string, arg1 ...string) ([]lxd.Container, error) { +func (m *MockServer) FilterContainers(arg0 string, arg1 ...string) ([]lxd0.Container, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0} for _, a := range arg1 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "FilterContainers", varargs...) - ret0, _ := ret[0].([]lxd.Container) + ret0, _ := ret[0].([]lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -259,10 +259,10 @@ func (mr *MockServerMockRecorder) FilterContainers(arg0 interface{}, arg1 ...int } // FindImage mocks base method. -func (m *MockServer) FindImage(arg0, arg1 string, arg2 []lxd.ServerSpec, arg3 bool, arg4 environs.StatusCallbackFunc) (lxd.SourcedImage, error) { +func (m *MockServer) FindImage(arg0, arg1 string, arg2 []lxd0.ServerSpec, arg3 bool, arg4 environs.StatusCallbackFunc) (lxd0.SourcedImage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FindImage", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(lxd.SourcedImage) + ret0, _ := ret[0].(lxd0.SourcedImage) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -305,10 +305,10 @@ func (mr *MockServerMockRecorder) GetClusterMembers() *gomock.Call { } // GetConnectionInfo mocks base method. -func (m *MockServer) GetConnectionInfo() (*lxd1.ConnectionInfo, error) { +func (m *MockServer) GetConnectionInfo() (*lxd.ConnectionInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetConnectionInfo") - ret0, _ := ret[0].(*lxd1.ConnectionInfo) + ret0, _ := ret[0].(*lxd.ConnectionInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -757,10 +757,10 @@ func (mr *MockServerMockRecorder) UseProject(arg0 interface{}) *gomock.Call { } // UseTargetServer mocks base method. -func (m *MockServer) UseTargetServer(arg0 string) (*lxd.Server, error) { +func (m *MockServer) UseTargetServer(arg0 string) (*lxd0.Server, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UseTargetServer", arg0) - ret0, _ := ret[0].(*lxd.Server) + ret0, _ := ret[0].(*lxd0.Server) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -786,7 +786,7 @@ func (mr *MockServerMockRecorder) VerifyNetworkDevice(arg0, arg1 interface{}) *g } // WriteContainer mocks base method. -func (m *MockServer) WriteContainer(arg0 *lxd.Container) error { +func (m *MockServer) WriteContainer(arg0 *lxd0.Container) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteContainer", arg0) ret0, _ := ret[0].(error) diff --git a/provider/lxd/server.go b/provider/lxd/server.go index 2d4f44b17d4..28ecf91b139 100644 --- a/provider/lxd/server.go +++ b/provider/lxd/server.go @@ -15,13 +15,13 @@ import ( "syscall" "time" + lxdclient "github.com/canonical/lxd/client" + lxdapi "github.com/canonical/lxd/shared/api" "github.com/juju/clock" "github.com/juju/errors" "github.com/juju/retry" "github.com/juju/utils/v3" "github.com/juju/version/v2" - lxdclient "github.com/lxc/lxd/client" - lxdapi "github.com/lxc/lxd/shared/api" "github.com/juju/juju/container/lxd" "github.com/juju/juju/core/network" diff --git a/provider/lxd/server_integration_test.go b/provider/lxd/server_integration_test.go index 1c7a7a55bf7..e038f6da41b 100644 --- a/provider/lxd/server_integration_test.go +++ b/provider/lxd/server_integration_test.go @@ -9,10 +9,10 @@ import ( "os" "syscall" + client "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" "github.com/juju/testing" - client "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared/api" "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" diff --git a/provider/lxd/storage.go b/provider/lxd/storage.go index 22b5a76db61..637c4544bdb 100644 --- a/provider/lxd/storage.go +++ b/provider/lxd/storage.go @@ -7,12 +7,12 @@ import ( "fmt" "strings" + "github.com/canonical/lxd/shared/api" + "github.com/canonical/lxd/shared/units" "github.com/juju/collections/set" "github.com/juju/errors" "github.com/juju/names/v4" "github.com/juju/schema" - "github.com/lxc/lxd/shared/api" - "github.com/lxc/lxd/shared/units" "github.com/juju/juju/container/lxd" "github.com/juju/juju/core/instance" diff --git a/provider/lxd/storage_test.go b/provider/lxd/storage_test.go index baae0b30ade..36b307667d5 100644 --- a/provider/lxd/storage_test.go +++ b/provider/lxd/storage_test.go @@ -4,11 +4,11 @@ package lxd_test import ( + "github.com/canonical/lxd/shared/api" "github.com/juju/errors" "github.com/juju/names/v4" "github.com/juju/testing" jc "github.com/juju/testing/checkers" - "github.com/lxc/lxd/shared/api" gc "gopkg.in/check.v1" containerlxd "github.com/juju/juju/container/lxd" diff --git a/provider/lxd/testing_test.go b/provider/lxd/testing_test.go index b3b65569dd7..e0f18722ed8 100644 --- a/provider/lxd/testing_test.go +++ b/provider/lxd/testing_test.go @@ -9,14 +9,14 @@ import ( "strconv" "time" + lxdclient "github.com/canonical/lxd/client" + "github.com/canonical/lxd/shared/api" "github.com/juju/clock" "github.com/juju/errors" jujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/v3/arch" "github.com/juju/version/v2" - lxdclient "github.com/lxc/lxd/client" - "github.com/lxc/lxd/shared/api" gc "gopkg.in/check.v1" "github.com/juju/juju/cloud" diff --git a/state/charm.go b/state/charm.go index fa1f2bd44df..14c8bf86943 100644 --- a/state/charm.go +++ b/state/charm.go @@ -162,7 +162,7 @@ type charmDoc struct { LXDProfile *LXDProfile `bson:"lxd-profile"` } -// LXDProfile is the same as ProfilePut defined in github.com/lxc/lxd/shared/api/profile.go +// LXDProfile is the same as ProfilePut defined in github.com/canonical/lxd/shared/api/profile.go type LXDProfile struct { Config map[string]string `bson:"config"` Description string `bson:"description"` diff --git a/state/storage_test.go b/state/storage_test.go index 88fcee0f455..d40c8047be9 100644 --- a/state/storage_test.go +++ b/state/storage_test.go @@ -519,7 +519,7 @@ func (s *StorageStateSuite) TestAddApplicationStorageConstraintsValidation(c *gc } assertErr(storageCons, `cannot add application "storage-block2": charm "storage-block2" store "multi2up": 2 instances required, 1 specified`) storageCons["multi2up"] = makeStorageCons("loop-pool", 1024, 2) - assertErr(storageCons, `cannot add application "storage-block2": charm "storage-block2" store "multi2up": minimum storage size is 2.0GB, 1.0GB specified`) + assertErr(storageCons, `cannot add application "storage-block2": charm "storage-block2" store "multi2up": minimum storage size is 2.0 GB, 1.0 GB specified`) storageCons["multi2up"] = makeStorageCons("loop-pool", 2048, 2) storageCons["multi1to10"] = makeStorageCons("loop-pool", 1024, 11) assertErr(storageCons, `cannot add application "storage-block2": charm "storage-block2" store "multi1to10": at most 10 instances supported, 11 specified`) diff --git a/upgrades/upgradevalidation/mocks/lxd_mock.go b/upgrades/upgradevalidation/mocks/lxd_mock.go index 43ab184efd1..024a2820006 100644 --- a/upgrades/upgradevalidation/mocks/lxd_mock.go +++ b/upgrades/upgradevalidation/mocks/lxd_mock.go @@ -7,13 +7,13 @@ package mocks import ( reflect "reflect" - lxd "github.com/juju/juju/container/lxd" + lxd "github.com/canonical/lxd/client" + api "github.com/canonical/lxd/shared/api" + lxd0 "github.com/juju/juju/container/lxd" network "github.com/juju/juju/core/network" environs "github.com/juju/juju/environs" cloudspec "github.com/juju/juju/environs/cloudspec" - lxd0 "github.com/juju/juju/provider/lxd" - lxd1 "github.com/lxc/lxd/client" - api "github.com/lxc/lxd/shared/api" + lxd1 "github.com/juju/juju/provider/lxd" gomock "go.uber.org/mock/gomock" ) @@ -41,10 +41,10 @@ func (m *MockServerFactory) EXPECT() *MockServerFactoryMockRecorder { } // InsecureRemoteServer mocks base method. -func (m *MockServerFactory) InsecureRemoteServer(arg0 cloudspec.CloudSpec) (lxd0.Server, error) { +func (m *MockServerFactory) InsecureRemoteServer(arg0 cloudspec.CloudSpec) (lxd1.Server, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsecureRemoteServer", arg0) - ret0, _ := ret[0].(lxd0.Server) + ret0, _ := ret[0].(lxd1.Server) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -56,10 +56,10 @@ func (mr *MockServerFactoryMockRecorder) InsecureRemoteServer(arg0 interface{}) } // LocalServer mocks base method. -func (m *MockServerFactory) LocalServer() (lxd0.Server, error) { +func (m *MockServerFactory) LocalServer() (lxd1.Server, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LocalServer") - ret0, _ := ret[0].(lxd0.Server) + ret0, _ := ret[0].(lxd1.Server) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -86,10 +86,10 @@ func (mr *MockServerFactoryMockRecorder) LocalServerAddress() *gomock.Call { } // RemoteServer mocks base method. -func (m *MockServerFactory) RemoteServer(arg0 cloudspec.CloudSpec) (lxd0.Server, error) { +func (m *MockServerFactory) RemoteServer(arg0 cloudspec.CloudSpec) (lxd1.Server, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RemoteServer", arg0) - ret0, _ := ret[0].(lxd0.Server) + ret0, _ := ret[0].(lxd1.Server) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -124,10 +124,10 @@ func (m *MockServer) EXPECT() *MockServerMockRecorder { } // AliveContainers mocks base method. -func (m *MockServer) AliveContainers(arg0 string) ([]lxd.Container, error) { +func (m *MockServer) AliveContainers(arg0 string) ([]lxd0.Container, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AliveContainers", arg0) - ret0, _ := ret[0].([]lxd.Container) + ret0, _ := ret[0].([]lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -168,7 +168,7 @@ func (mr *MockServerMockRecorder) CreateCertificate(arg0 interface{}) *gomock.Ca } // CreateClientCertificate mocks base method. -func (m *MockServer) CreateClientCertificate(arg0 *lxd.Certificate) error { +func (m *MockServer) CreateClientCertificate(arg0 *lxd0.Certificate) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateClientCertificate", arg0) ret0, _ := ret[0].(error) @@ -182,10 +182,10 @@ func (mr *MockServerMockRecorder) CreateClientCertificate(arg0 interface{}) *gom } // CreateContainerFromSpec mocks base method. -func (m *MockServer) CreateContainerFromSpec(arg0 lxd.ContainerSpec) (*lxd.Container, error) { +func (m *MockServer) CreateContainerFromSpec(arg0 lxd0.ContainerSpec) (*lxd0.Container, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateContainerFromSpec", arg0) - ret0, _ := ret[0].(*lxd.Container) + ret0, _ := ret[0].(*lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -323,14 +323,14 @@ func (mr *MockServerMockRecorder) EnsureDefaultStorage(arg0, arg1 interface{}) * } // FilterContainers mocks base method. -func (m *MockServer) FilterContainers(arg0 string, arg1 ...string) ([]lxd.Container, error) { +func (m *MockServer) FilterContainers(arg0 string, arg1 ...string) ([]lxd0.Container, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0} for _, a := range arg1 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "FilterContainers", varargs...) - ret0, _ := ret[0].([]lxd.Container) + ret0, _ := ret[0].([]lxd0.Container) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -343,10 +343,10 @@ func (mr *MockServerMockRecorder) FilterContainers(arg0 interface{}, arg1 ...int } // FindImage mocks base method. -func (m *MockServer) FindImage(arg0, arg1 string, arg2 []lxd.ServerSpec, arg3 bool, arg4 environs.StatusCallbackFunc) (lxd.SourcedImage, error) { +func (m *MockServer) FindImage(arg0, arg1 string, arg2 []lxd0.ServerSpec, arg3 bool, arg4 environs.StatusCallbackFunc) (lxd0.SourcedImage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FindImage", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(lxd.SourcedImage) + ret0, _ := ret[0].(lxd0.SourcedImage) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -389,10 +389,10 @@ func (mr *MockServerMockRecorder) GetClusterMembers() *gomock.Call { } // GetConnectionInfo mocks base method. -func (m *MockServer) GetConnectionInfo() (*lxd1.ConnectionInfo, error) { +func (m *MockServer) GetConnectionInfo() (*lxd.ConnectionInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetConnectionInfo") - ret0, _ := ret[0].(*lxd1.ConnectionInfo) + ret0, _ := ret[0].(*lxd.ConnectionInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -841,10 +841,10 @@ func (mr *MockServerMockRecorder) UseProject(arg0 interface{}) *gomock.Call { } // UseTargetServer mocks base method. -func (m *MockServer) UseTargetServer(arg0 string) (*lxd.Server, error) { +func (m *MockServer) UseTargetServer(arg0 string) (*lxd0.Server, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UseTargetServer", arg0) - ret0, _ := ret[0].(*lxd.Server) + ret0, _ := ret[0].(*lxd0.Server) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -870,7 +870,7 @@ func (mr *MockServerMockRecorder) VerifyNetworkDevice(arg0, arg1 interface{}) *g } // WriteContainer mocks base method. -func (m *MockServer) WriteContainer(arg0 *lxd.Container) error { +func (m *MockServer) WriteContainer(arg0 *lxd0.Container) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteContainer", arg0) ret0, _ := ret[0].(error) From aba86096387c3a72be5bc0dd7614589f822a8e8a Mon Sep 17 00:00:00 2001 From: Harry Pidcock Date: Tue, 28 Nov 2023 13:10:53 +1000 Subject: [PATCH 35/50] Fix coslite test by testing readiness/health endpoint. --- tests/suites/coslite/cl.sh | 11 ++++++----- tests/suites/coslite/task.sh | 9 --------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/tests/suites/coslite/cl.sh b/tests/suites/coslite/cl.sh index 5cc38fec4da..20679fbbe27 100644 --- a/tests/suites/coslite/cl.sh +++ b/tests/suites/coslite/cl.sh @@ -8,6 +8,7 @@ run_deploy_coslite() { file="${TEST_DIR}/${model_name}.log" ensure "${model_name}" "${file}" + juju deploy ubuntu-lite # deploy ubuntu-lite for a container that can easily access cos-lite components on all k8s juju deploy cos-lite --trust --channel=stable juju config traefik external_hostname=test-coslite.com echo "Wait for all unit agents to be in idle condition" @@ -22,15 +23,15 @@ run_deploy_coslite() { echo "check if alertmanager is ready" alertmanager_ip=$(juju status --format=json | jq -r '.applications.alertmanager.units."alertmanager/0".address') - check_ready "http://$alertmanager_ip:9093" 200 + check_ready "http://$alertmanager_ip:9093/-/ready" 200 echo "check if grafana is ready" grafana_ip=$(juju status --format=json | jq -r '.applications.grafana.units."grafana/0".address') - check_ready "http://$grafana_ip:3000" 200 + check_ready "http://$grafana_ip:3000/api/health" 200 echo "check if prometheus is ready" prometheus_ip=$(juju status --format=json | jq -r '.applications.prometheus.units."prometheus/0".address') - check_ready "http://$prometheus_ip:9090" 200 + check_ready "http://$prometheus_ip:9090/-/ready" 200 echo "cos lite tests passed" } @@ -42,12 +43,12 @@ check_ready() { code=${2} attempt=1 while true; do - status_code=$(curl --write-out "%{http_code}" -L --silent --output /dev/null "${url}") + status_code=$(juju ssh ubuntu-lite/0 curl --write-out "%{http_code}" -L --silent --output /dev/null "${url}") if [[ $status_code -eq $code ]]; then echo "Ready to serve traffic" break fi - if [[ ${attempt} -ge 3 ]]; then + if [[ ${attempt} -ge 5 ]]; then echo "Failed to connect to ${url} after ${attempt} attempts with status code ${status_code}" exit 1 fi diff --git a/tests/suites/coslite/task.sh b/tests/suites/coslite/task.sh index 825fc74f25d..193d92af24a 100644 --- a/tests/suites/coslite/task.sh +++ b/tests/suites/coslite/task.sh @@ -15,20 +15,11 @@ test_coslite() { case "${BOOTSTRAP_PROVIDER:-}" in "k8s") - # disable metallb then enable it with a new set of out ipaddr - microk8s disable metallb - IPADDR=$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc') - microk8s enable metallb:"$IPADDR"-"$IPADDR" - microk8s kubectl rollout status deployments/hostpath-provisioner -n kube-system -w - microk8s kubectl rollout status deployments/coredns -n kube-system -w - microk8s kubectl rollout status daemonset.apps/speaker -n metallb-system -w - test_deploy_coslite ;; *) echo "==> TEST SKIPPED: test_deploy_coslite test runs on k8s only" ;; - esac # TODO(basebandit): remove KILL_CONTROLLER once model teardown has been fixed for k8s models. From b2c751be5ee502a23778e25345b47b213cd02e00 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Tue, 28 Nov 2023 10:33:38 +1000 Subject: [PATCH 36/50] Update Azure, AWS, and related upstream SDK dependiency versions --- .../client/application/application_test.go | 6 +- .../provider/exec/mocks/remotecommand_mock.go | 15 + .../admissionregistrationv1beta1_mock.go | 28 + .../provider/mocks/discovery_mock.go | 47 +- .../kubernetes/provider/mocks/dynamic_mock.go | 70 +++ .../provider/mocks/k8sclient_mock.go | 126 ++++- .../mocks/sharedindexinformer_mock.go | 56 +- .../provider/mocks/storagev1_mock.go | 14 + .../provider/specs/admissionregistration.go | 8 +- caas/kubernetes/provider/storage_test.go | 2 +- .../kubernetes/provider/watcher/k8swatcher.go | 11 +- caas/kubernetes/tunnel.go | 5 +- cmd/juju/status/status_test.go | 12 +- cmd/juju/storage/filesystemlist_test.go | 2 + cmd/juju/storage/list_test.go | 2 + cmd/juju/storage/poollist_test.go | 2 + cmd/juju/storage/volumelist_test.go | 2 + go.mod | 152 +++--- go.sum | 513 ++++++------------ .../azure/internal/azureauth/discovery.go | 4 +- .../azure/internal/errorutils/errors_test.go | 2 + provider/ec2/ebs_test.go | 2 +- provider/ec2/internal/testing/instances.go | 10 +- state/storage_dynamicadd_test.go | 2 +- worker/caasrbacmapper/mapper.go | 5 +- worker/caasrbacmapper/mapper_test.go | 12 +- 26 files changed, 626 insertions(+), 484 deletions(-) diff --git a/apiserver/facades/client/application/application_test.go b/apiserver/facades/client/application/application_test.go index 31079c6910b..3eda04aa973 100644 --- a/apiserver/facades/client/application/application_test.go +++ b/apiserver/facades/client/application/application_test.go @@ -846,7 +846,7 @@ func (s *applicationSuite) TestAddCharm(c *gc.C) { return &recordingStorage{Storage: storage, blobs: &blobs} }) - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, testing.NoopLogger{}) // First test the sanity checks. err := client.AddCharm(&charm.URL{Name: "nonsense"}, csparams.StableChannel, false) c.Assert(err, gc.ErrorMatches, `cannot parse charm or bundle URL: ":nonsense-0"`) @@ -896,7 +896,7 @@ func (s *applicationSuite) TestAddCharmConcurrently(c *gc.C) { return &recordingStorage{Storage: storage, blobs: &blobs, putBarrier: &putBarrier} }) - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, testing.NoopLogger{}) curl, _ := s.UploadCharm(c, "trusty/wordpress-3", "wordpress") // Try adding the same charm concurrently from multiple goroutines @@ -951,7 +951,7 @@ func (s *applicationSuite) assertUploaded(c *gc.C, storage statestorage.Storage, } func (s *applicationSuite) TestAddCharmOverwritesPlaceholders(c *gc.C) { - client := client.NewClient(s.APIState) + client := client.NewClient(s.APIState, testing.NoopLogger{}) curl, _ := s.UploadCharm(c, "cs:trusty/wordpress-42", "wordpress") // Add a placeholder with the same charm URL. diff --git a/caas/kubernetes/provider/exec/mocks/remotecommand_mock.go b/caas/kubernetes/provider/exec/mocks/remotecommand_mock.go index 9217e4c36ca..b0cb2d53bbc 100644 --- a/caas/kubernetes/provider/exec/mocks/remotecommand_mock.go +++ b/caas/kubernetes/provider/exec/mocks/remotecommand_mock.go @@ -5,6 +5,7 @@ package mocks import ( + context "context" reflect "reflect" gomock "go.uber.org/mock/gomock" @@ -47,3 +48,17 @@ func (mr *MockExecutorMockRecorder) Stream(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stream", reflect.TypeOf((*MockExecutor)(nil).Stream), arg0) } + +// StreamWithContext mocks base method. +func (m *MockExecutor) StreamWithContext(arg0 context.Context, arg1 remotecommand.StreamOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StreamWithContext", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// StreamWithContext indicates an expected call of StreamWithContext. +func (mr *MockExecutorMockRecorder) StreamWithContext(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamWithContext", reflect.TypeOf((*MockExecutor)(nil).StreamWithContext), arg0, arg1) +} diff --git a/caas/kubernetes/provider/mocks/admissionregistrationv1beta1_mock.go b/caas/kubernetes/provider/mocks/admissionregistrationv1beta1_mock.go index 4db0930abce..2dc1bfee511 100644 --- a/caas/kubernetes/provider/mocks/admissionregistrationv1beta1_mock.go +++ b/caas/kubernetes/provider/mocks/admissionregistrationv1beta1_mock.go @@ -69,6 +69,34 @@ func (mr *MockAdmissionregistrationV1beta1InterfaceMockRecorder) RESTClient() *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTClient", reflect.TypeOf((*MockAdmissionregistrationV1beta1Interface)(nil).RESTClient)) } +// ValidatingAdmissionPolicies mocks base method. +func (m *MockAdmissionregistrationV1beta1Interface) ValidatingAdmissionPolicies() v1beta11.ValidatingAdmissionPolicyInterface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidatingAdmissionPolicies") + ret0, _ := ret[0].(v1beta11.ValidatingAdmissionPolicyInterface) + return ret0 +} + +// ValidatingAdmissionPolicies indicates an expected call of ValidatingAdmissionPolicies. +func (mr *MockAdmissionregistrationV1beta1InterfaceMockRecorder) ValidatingAdmissionPolicies() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatingAdmissionPolicies", reflect.TypeOf((*MockAdmissionregistrationV1beta1Interface)(nil).ValidatingAdmissionPolicies)) +} + +// ValidatingAdmissionPolicyBindings mocks base method. +func (m *MockAdmissionregistrationV1beta1Interface) ValidatingAdmissionPolicyBindings() v1beta11.ValidatingAdmissionPolicyBindingInterface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidatingAdmissionPolicyBindings") + ret0, _ := ret[0].(v1beta11.ValidatingAdmissionPolicyBindingInterface) + return ret0 +} + +// ValidatingAdmissionPolicyBindings indicates an expected call of ValidatingAdmissionPolicyBindings. +func (mr *MockAdmissionregistrationV1beta1InterfaceMockRecorder) ValidatingAdmissionPolicyBindings() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatingAdmissionPolicyBindings", reflect.TypeOf((*MockAdmissionregistrationV1beta1Interface)(nil).ValidatingAdmissionPolicyBindings)) +} + // ValidatingWebhookConfigurations mocks base method. func (m *MockAdmissionregistrationV1beta1Interface) ValidatingWebhookConfigurations() v1beta11.ValidatingWebhookConfigurationInterface { m.ctrl.T.Helper() diff --git a/caas/kubernetes/provider/mocks/discovery_mock.go b/caas/kubernetes/provider/mocks/discovery_mock.go index 05ab6cd24e7..f524180b35c 100644 --- a/caas/kubernetes/provider/mocks/discovery_mock.go +++ b/caas/kubernetes/provider/mocks/discovery_mock.go @@ -7,10 +7,12 @@ package mocks import ( reflect "reflect" - openapi_v2 "github.com/googleapis/gnostic/openapiv2" + openapi_v2 "github.com/google/gnostic-models/openapiv2" gomock "go.uber.org/mock/gomock" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" version "k8s.io/apimachinery/pkg/version" + discovery "k8s.io/client-go/discovery" + openapi "k8s.io/client-go/openapi" rest "k8s.io/client-go/rest" ) @@ -52,6 +54,20 @@ func (mr *MockDiscoveryInterfaceMockRecorder) OpenAPISchema() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenAPISchema", reflect.TypeOf((*MockDiscoveryInterface)(nil).OpenAPISchema)) } +// OpenAPIV3 mocks base method. +func (m *MockDiscoveryInterface) OpenAPIV3() openapi.Client { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenAPIV3") + ret0, _ := ret[0].(openapi.Client) + return ret0 +} + +// OpenAPIV3 indicates an expected call of OpenAPIV3. +func (mr *MockDiscoveryInterfaceMockRecorder) OpenAPIV3() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenAPIV3", reflect.TypeOf((*MockDiscoveryInterface)(nil).OpenAPIV3)) +} + // RESTClient mocks base method. func (m *MockDiscoveryInterface) RESTClient() rest.Interface { m.ctrl.T.Helper() @@ -127,21 +143,6 @@ func (mr *MockDiscoveryInterfaceMockRecorder) ServerPreferredResources() *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerPreferredResources", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerPreferredResources)) } -// ServerResources mocks base method. -func (m *MockDiscoveryInterface) ServerResources() ([]*v1.APIResourceList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerResources") - ret0, _ := ret[0].([]*v1.APIResourceList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerResources indicates an expected call of ServerResources. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerResources() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerResources", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerResources)) -} - // ServerResourcesForGroupVersion mocks base method. func (m *MockDiscoveryInterface) ServerResourcesForGroupVersion(arg0 string) (*v1.APIResourceList, error) { m.ctrl.T.Helper() @@ -171,3 +172,17 @@ func (mr *MockDiscoveryInterfaceMockRecorder) ServerVersion() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerVersion", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerVersion)) } + +// WithLegacy mocks base method. +func (m *MockDiscoveryInterface) WithLegacy() discovery.DiscoveryInterface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WithLegacy") + ret0, _ := ret[0].(discovery.DiscoveryInterface) + return ret0 +} + +// WithLegacy indicates an expected call of WithLegacy. +func (mr *MockDiscoveryInterfaceMockRecorder) WithLegacy() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithLegacy", reflect.TypeOf((*MockDiscoveryInterface)(nil).WithLegacy)) +} diff --git a/caas/kubernetes/provider/mocks/dynamic_mock.go b/caas/kubernetes/provider/mocks/dynamic_mock.go index e668515a004..71b2c927275 100644 --- a/caas/kubernetes/provider/mocks/dynamic_mock.go +++ b/caas/kubernetes/provider/mocks/dynamic_mock.go @@ -77,6 +77,41 @@ func (m *MockResourceInterface) EXPECT() *MockResourceInterfaceMockRecorder { return m.recorder } +// Apply mocks base method. +func (m *MockResourceInterface) Apply(arg0 context.Context, arg1 string, arg2 *unstructured.Unstructured, arg3 v1.ApplyOptions, arg4 ...string) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Apply", varargs...) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Apply indicates an expected call of Apply. +func (mr *MockResourceInterfaceMockRecorder) Apply(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockResourceInterface)(nil).Apply), varargs...) +} + +// ApplyStatus mocks base method. +func (m *MockResourceInterface) ApplyStatus(arg0 context.Context, arg1 string, arg2 *unstructured.Unstructured, arg3 v1.ApplyOptions) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplyStatus", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ApplyStatus indicates an expected call of ApplyStatus. +func (mr *MockResourceInterfaceMockRecorder) ApplyStatus(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyStatus", reflect.TypeOf((*MockResourceInterface)(nil).ApplyStatus), arg0, arg1, arg2, arg3) +} + // Create mocks base method. func (m *MockResourceInterface) Create(arg0 context.Context, arg1 *unstructured.Unstructured, arg2 v1.CreateOptions, arg3 ...string) (*unstructured.Unstructured, error) { m.ctrl.T.Helper() @@ -258,6 +293,41 @@ func (m *MockNamespaceableResourceInterface) EXPECT() *MockNamespaceableResource return m.recorder } +// Apply mocks base method. +func (m *MockNamespaceableResourceInterface) Apply(arg0 context.Context, arg1 string, arg2 *unstructured.Unstructured, arg3 v1.ApplyOptions, arg4 ...string) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Apply", varargs...) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Apply indicates an expected call of Apply. +func (mr *MockNamespaceableResourceInterfaceMockRecorder) Apply(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockNamespaceableResourceInterface)(nil).Apply), varargs...) +} + +// ApplyStatus mocks base method. +func (m *MockNamespaceableResourceInterface) ApplyStatus(arg0 context.Context, arg1 string, arg2 *unstructured.Unstructured, arg3 v1.ApplyOptions) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplyStatus", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ApplyStatus indicates an expected call of ApplyStatus. +func (mr *MockNamespaceableResourceInterfaceMockRecorder) ApplyStatus(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyStatus", reflect.TypeOf((*MockNamespaceableResourceInterface)(nil).ApplyStatus), arg0, arg1, arg2, arg3) +} + // Create mocks base method. func (m *MockNamespaceableResourceInterface) Create(arg0 context.Context, arg1 *unstructured.Unstructured, arg2 v1.CreateOptions, arg3 ...string) (*unstructured.Unstructured, error) { m.ctrl.T.Helper() diff --git a/caas/kubernetes/provider/mocks/k8sclient_mock.go b/caas/kubernetes/provider/mocks/k8sclient_mock.go index 3890552e7af..93adfa53b60 100644 --- a/caas/kubernetes/provider/mocks/k8sclient_mock.go +++ b/caas/kubernetes/provider/mocks/k8sclient_mock.go @@ -10,12 +10,14 @@ import ( gomock "go.uber.org/mock/gomock" discovery "k8s.io/client-go/discovery" v1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" + v1alpha1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1" v1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1" - v1alpha1 "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1" + v1alpha10 "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1" v10 "k8s.io/client-go/kubernetes/typed/apps/v1" v1beta10 "k8s.io/client-go/kubernetes/typed/apps/v1beta1" v1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" v11 "k8s.io/client-go/kubernetes/typed/authentication/v1" + v1alpha11 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1" v1beta11 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1" v12 "k8s.io/client-go/kubernetes/typed/authorization/v1" v1beta12 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1" @@ -26,6 +28,7 @@ import ( v14 "k8s.io/client-go/kubernetes/typed/batch/v1" v1beta13 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" v15 "k8s.io/client-go/kubernetes/typed/certificates/v1" + v1alpha12 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" v1beta14 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" v16 "k8s.io/client-go/kubernetes/typed/coordination/v1" v1beta15 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" @@ -35,24 +38,27 @@ import ( v19 "k8s.io/client-go/kubernetes/typed/events/v1" v1beta17 "k8s.io/client-go/kubernetes/typed/events/v1beta1" v1beta18 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1" - v1alpha10 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1" + v1alpha13 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1" v1beta19 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1" v1beta20 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2" + v1beta3 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" v110 "k8s.io/client-go/kubernetes/typed/networking/v1" + v1alpha14 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1" v1beta110 "k8s.io/client-go/kubernetes/typed/networking/v1beta1" v111 "k8s.io/client-go/kubernetes/typed/node/v1" - v1alpha11 "k8s.io/client-go/kubernetes/typed/node/v1alpha1" + v1alpha15 "k8s.io/client-go/kubernetes/typed/node/v1alpha1" v1beta111 "k8s.io/client-go/kubernetes/typed/node/v1beta1" v112 "k8s.io/client-go/kubernetes/typed/policy/v1" v1beta112 "k8s.io/client-go/kubernetes/typed/policy/v1beta1" v113 "k8s.io/client-go/kubernetes/typed/rbac/v1" - v1alpha12 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" + v1alpha16 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" v1beta113 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" + v1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" v114 "k8s.io/client-go/kubernetes/typed/scheduling/v1" - v1alpha13 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" + v1alpha17 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" v1beta114 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" v115 "k8s.io/client-go/kubernetes/typed/storage/v1" - v1alpha14 "k8s.io/client-go/kubernetes/typed/storage/v1alpha1" + v1alpha18 "k8s.io/client-go/kubernetes/typed/storage/v1alpha1" v1beta115 "k8s.io/client-go/kubernetes/typed/storage/v1beta1" ) @@ -93,6 +99,20 @@ func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1)) } +// AdmissionregistrationV1alpha1 mocks base method. +func (m *MockInterface) AdmissionregistrationV1alpha1() v1alpha1.AdmissionregistrationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdmissionregistrationV1alpha1") + ret0, _ := ret[0].(v1alpha1.AdmissionregistrationV1alpha1Interface) + return ret0 +} + +// AdmissionregistrationV1alpha1 indicates an expected call of AdmissionregistrationV1alpha1. +func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1alpha1)) +} + // AdmissionregistrationV1beta1 mocks base method. func (m *MockInterface) AdmissionregistrationV1beta1() v1beta1.AdmissionregistrationV1beta1Interface { m.ctrl.T.Helper() @@ -163,6 +183,20 @@ func (mr *MockInterfaceMockRecorder) AuthenticationV1() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1)) } +// AuthenticationV1alpha1 mocks base method. +func (m *MockInterface) AuthenticationV1alpha1() v1alpha11.AuthenticationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthenticationV1alpha1") + ret0, _ := ret[0].(v1alpha11.AuthenticationV1alpha1Interface) + return ret0 +} + +// AuthenticationV1alpha1 indicates an expected call of AuthenticationV1alpha1. +func (mr *MockInterfaceMockRecorder) AuthenticationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1alpha1)) +} + // AuthenticationV1beta1 mocks base method. func (m *MockInterface) AuthenticationV1beta1() v1beta11.AuthenticationV1beta1Interface { m.ctrl.T.Helper() @@ -303,6 +337,20 @@ func (mr *MockInterfaceMockRecorder) CertificatesV1() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1)) } +// CertificatesV1alpha1 mocks base method. +func (m *MockInterface) CertificatesV1alpha1() v1alpha12.CertificatesV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CertificatesV1alpha1") + ret0, _ := ret[0].(v1alpha12.CertificatesV1alpha1Interface) + return ret0 +} + +// CertificatesV1alpha1 indicates an expected call of CertificatesV1alpha1. +func (mr *MockInterfaceMockRecorder) CertificatesV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1alpha1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1alpha1)) +} + // CertificatesV1beta1 mocks base method. func (m *MockInterface) CertificatesV1beta1() v1beta14.CertificatesV1beta1Interface { m.ctrl.T.Helper() @@ -444,10 +492,10 @@ func (mr *MockInterfaceMockRecorder) ExtensionsV1beta1() *gomock.Call { } // FlowcontrolV1alpha1 mocks base method. -func (m *MockInterface) FlowcontrolV1alpha1() v1alpha10.FlowcontrolV1alpha1Interface { +func (m *MockInterface) FlowcontrolV1alpha1() v1alpha13.FlowcontrolV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FlowcontrolV1alpha1") - ret0, _ := ret[0].(v1alpha10.FlowcontrolV1alpha1Interface) + ret0, _ := ret[0].(v1alpha13.FlowcontrolV1alpha1Interface) return ret0 } @@ -485,11 +533,25 @@ func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta2() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta2", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta2)) } +// FlowcontrolV1beta3 mocks base method. +func (m *MockInterface) FlowcontrolV1beta3() v1beta3.FlowcontrolV1beta3Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FlowcontrolV1beta3") + ret0, _ := ret[0].(v1beta3.FlowcontrolV1beta3Interface) + return ret0 +} + +// FlowcontrolV1beta3 indicates an expected call of FlowcontrolV1beta3. +func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta3() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta3", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta3)) +} + // InternalV1alpha1 mocks base method. -func (m *MockInterface) InternalV1alpha1() v1alpha1.InternalV1alpha1Interface { +func (m *MockInterface) InternalV1alpha1() v1alpha10.InternalV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InternalV1alpha1") - ret0, _ := ret[0].(v1alpha1.InternalV1alpha1Interface) + ret0, _ := ret[0].(v1alpha10.InternalV1alpha1Interface) return ret0 } @@ -513,6 +575,20 @@ func (mr *MockInterfaceMockRecorder) NetworkingV1() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1)) } +// NetworkingV1alpha1 mocks base method. +func (m *MockInterface) NetworkingV1alpha1() v1alpha14.NetworkingV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkingV1alpha1") + ret0, _ := ret[0].(v1alpha14.NetworkingV1alpha1Interface) + return ret0 +} + +// NetworkingV1alpha1 indicates an expected call of NetworkingV1alpha1. +func (mr *MockInterfaceMockRecorder) NetworkingV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1alpha1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1alpha1)) +} + // NetworkingV1beta1 mocks base method. func (m *MockInterface) NetworkingV1beta1() v1beta110.NetworkingV1beta1Interface { m.ctrl.T.Helper() @@ -542,10 +618,10 @@ func (mr *MockInterfaceMockRecorder) NodeV1() *gomock.Call { } // NodeV1alpha1 mocks base method. -func (m *MockInterface) NodeV1alpha1() v1alpha11.NodeV1alpha1Interface { +func (m *MockInterface) NodeV1alpha1() v1alpha15.NodeV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NodeV1alpha1") - ret0, _ := ret[0].(v1alpha11.NodeV1alpha1Interface) + ret0, _ := ret[0].(v1alpha15.NodeV1alpha1Interface) return ret0 } @@ -612,10 +688,10 @@ func (mr *MockInterfaceMockRecorder) RbacV1() *gomock.Call { } // RbacV1alpha1 mocks base method. -func (m *MockInterface) RbacV1alpha1() v1alpha12.RbacV1alpha1Interface { +func (m *MockInterface) RbacV1alpha1() v1alpha16.RbacV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RbacV1alpha1") - ret0, _ := ret[0].(v1alpha12.RbacV1alpha1Interface) + ret0, _ := ret[0].(v1alpha16.RbacV1alpha1Interface) return ret0 } @@ -639,6 +715,20 @@ func (mr *MockInterfaceMockRecorder) RbacV1beta1() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1beta1", reflect.TypeOf((*MockInterface)(nil).RbacV1beta1)) } +// ResourceV1alpha2 mocks base method. +func (m *MockInterface) ResourceV1alpha2() v1alpha2.ResourceV1alpha2Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResourceV1alpha2") + ret0, _ := ret[0].(v1alpha2.ResourceV1alpha2Interface) + return ret0 +} + +// ResourceV1alpha2 indicates an expected call of ResourceV1alpha2. +func (mr *MockInterfaceMockRecorder) ResourceV1alpha2() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResourceV1alpha2", reflect.TypeOf((*MockInterface)(nil).ResourceV1alpha2)) +} + // SchedulingV1 mocks base method. func (m *MockInterface) SchedulingV1() v114.SchedulingV1Interface { m.ctrl.T.Helper() @@ -654,10 +744,10 @@ func (mr *MockInterfaceMockRecorder) SchedulingV1() *gomock.Call { } // SchedulingV1alpha1 mocks base method. -func (m *MockInterface) SchedulingV1alpha1() v1alpha13.SchedulingV1alpha1Interface { +func (m *MockInterface) SchedulingV1alpha1() v1alpha17.SchedulingV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SchedulingV1alpha1") - ret0, _ := ret[0].(v1alpha13.SchedulingV1alpha1Interface) + ret0, _ := ret[0].(v1alpha17.SchedulingV1alpha1Interface) return ret0 } @@ -696,10 +786,10 @@ func (mr *MockInterfaceMockRecorder) StorageV1() *gomock.Call { } // StorageV1alpha1 mocks base method. -func (m *MockInterface) StorageV1alpha1() v1alpha14.StorageV1alpha1Interface { +func (m *MockInterface) StorageV1alpha1() v1alpha18.StorageV1alpha1Interface { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StorageV1alpha1") - ret0, _ := ret[0].(v1alpha14.StorageV1alpha1Interface) + ret0, _ := ret[0].(v1alpha18.StorageV1alpha1Interface) return ret0 } diff --git a/caas/kubernetes/provider/mocks/sharedindexinformer_mock.go b/caas/kubernetes/provider/mocks/sharedindexinformer_mock.go index 750d31c932b..f34343eed2c 100644 --- a/caas/kubernetes/provider/mocks/sharedindexinformer_mock.go +++ b/caas/kubernetes/provider/mocks/sharedindexinformer_mock.go @@ -36,9 +36,12 @@ func (m *MockSharedIndexInformer) EXPECT() *MockSharedIndexInformerMockRecorder } // AddEventHandler mocks base method. -func (m *MockSharedIndexInformer) AddEventHandler(arg0 cache.ResourceEventHandler) { +func (m *MockSharedIndexInformer) AddEventHandler(arg0 cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddEventHandler", arg0) + ret := m.ctrl.Call(m, "AddEventHandler", arg0) + ret0, _ := ret[0].(cache.ResourceEventHandlerRegistration) + ret1, _ := ret[1].(error) + return ret0, ret1 } // AddEventHandler indicates an expected call of AddEventHandler. @@ -48,9 +51,12 @@ func (mr *MockSharedIndexInformerMockRecorder) AddEventHandler(arg0 interface{}) } // AddEventHandlerWithResyncPeriod mocks base method. -func (m *MockSharedIndexInformer) AddEventHandlerWithResyncPeriod(arg0 cache.ResourceEventHandler, arg1 time.Duration) { +func (m *MockSharedIndexInformer) AddEventHandlerWithResyncPeriod(arg0 cache.ResourceEventHandler, arg1 time.Duration) (cache.ResourceEventHandlerRegistration, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddEventHandlerWithResyncPeriod", arg0, arg1) + ret := m.ctrl.Call(m, "AddEventHandlerWithResyncPeriod", arg0, arg1) + ret0, _ := ret[0].(cache.ResourceEventHandlerRegistration) + ret1, _ := ret[1].(error) + return ret0, ret1 } // AddEventHandlerWithResyncPeriod indicates an expected call of AddEventHandlerWithResyncPeriod. @@ -129,6 +135,20 @@ func (mr *MockSharedIndexInformerMockRecorder) HasSynced() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasSynced", reflect.TypeOf((*MockSharedIndexInformer)(nil).HasSynced)) } +// IsStopped mocks base method. +func (m *MockSharedIndexInformer) IsStopped() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsStopped") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsStopped indicates an expected call of IsStopped. +func (mr *MockSharedIndexInformerMockRecorder) IsStopped() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsStopped", reflect.TypeOf((*MockSharedIndexInformer)(nil).IsStopped)) +} + // LastSyncResourceVersion mocks base method. func (m *MockSharedIndexInformer) LastSyncResourceVersion() string { m.ctrl.T.Helper() @@ -143,6 +163,20 @@ func (mr *MockSharedIndexInformerMockRecorder) LastSyncResourceVersion() *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastSyncResourceVersion", reflect.TypeOf((*MockSharedIndexInformer)(nil).LastSyncResourceVersion)) } +// RemoveEventHandler mocks base method. +func (m *MockSharedIndexInformer) RemoveEventHandler(arg0 cache.ResourceEventHandlerRegistration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveEventHandler", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveEventHandler indicates an expected call of RemoveEventHandler. +func (mr *MockSharedIndexInformerMockRecorder) RemoveEventHandler(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveEventHandler", reflect.TypeOf((*MockSharedIndexInformer)(nil).RemoveEventHandler), arg0) +} + // Run mocks base method. func (m *MockSharedIndexInformer) Run(arg0 <-chan struct{}) { m.ctrl.T.Helper() @@ -155,6 +189,20 @@ func (mr *MockSharedIndexInformerMockRecorder) Run(arg0 interface{}) *gomock.Cal return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockSharedIndexInformer)(nil).Run), arg0) } +// SetTransform mocks base method. +func (m *MockSharedIndexInformer) SetTransform(arg0 cache.TransformFunc) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetTransform", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetTransform indicates an expected call of SetTransform. +func (mr *MockSharedIndexInformerMockRecorder) SetTransform(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTransform", reflect.TypeOf((*MockSharedIndexInformer)(nil).SetTransform), arg0) +} + // SetWatchErrorHandler mocks base method. func (m *MockSharedIndexInformer) SetWatchErrorHandler(arg0 cache.WatchErrorHandler) error { m.ctrl.T.Helper() diff --git a/caas/kubernetes/provider/mocks/storagev1_mock.go b/caas/kubernetes/provider/mocks/storagev1_mock.go index 697d91f7d01..e0add2ea075 100644 --- a/caas/kubernetes/provider/mocks/storagev1_mock.go +++ b/caas/kubernetes/provider/mocks/storagev1_mock.go @@ -69,6 +69,20 @@ func (mr *MockStorageV1InterfaceMockRecorder) CSINodes() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CSINodes", reflect.TypeOf((*MockStorageV1Interface)(nil).CSINodes)) } +// CSIStorageCapacities mocks base method. +func (m *MockStorageV1Interface) CSIStorageCapacities(arg0 string) v12.CSIStorageCapacityInterface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CSIStorageCapacities", arg0) + ret0, _ := ret[0].(v12.CSIStorageCapacityInterface) + return ret0 +} + +// CSIStorageCapacities indicates an expected call of CSIStorageCapacities. +func (mr *MockStorageV1InterfaceMockRecorder) CSIStorageCapacities(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CSIStorageCapacities", reflect.TypeOf((*MockStorageV1Interface)(nil).CSIStorageCapacities), arg0) +} + // RESTClient mocks base method. func (m *MockStorageV1Interface) RESTClient() rest.Interface { m.ctrl.T.Helper() diff --git a/caas/kubernetes/provider/specs/admissionregistration.go b/caas/kubernetes/provider/specs/admissionregistration.go index 73ae7534850..b67e4112ea3 100644 --- a/caas/kubernetes/provider/specs/admissionregistration.go +++ b/caas/kubernetes/provider/specs/admissionregistration.go @@ -91,11 +91,11 @@ func UpgradeK8sMutatingWebhookSpecV1Beta1(spec admissionregistrationv1beta1.Muta }, } if rule.Scope != nil { - scope := admissionregistrationv1.ScopeType(*rule.Scope) + scope := *rule.Scope newRule.Scope = &scope } for _, op := range rule.Operations { - newRule.Operations = append(newRule.Operations, admissionregistrationv1.OperationType(op)) + newRule.Operations = append(newRule.Operations, op) } hook.Rules = append(hook.Rules, newRule) } @@ -213,11 +213,11 @@ func UpgradeK8sValidatingWebhookSpecV1Beta1(spec admissionregistrationv1beta1.Va }, } if rule.Scope != nil { - scope := admissionregistrationv1.ScopeType(*rule.Scope) + scope := *rule.Scope newRule.Scope = &scope } for _, op := range rule.Operations { - newRule.Operations = append(newRule.Operations, admissionregistrationv1.OperationType(op)) + newRule.Operations = append(newRule.Operations, op) } hook.Rules = append(hook.Rules, newRule) } diff --git a/caas/kubernetes/provider/storage_test.go b/caas/kubernetes/provider/storage_test.go index 10b16df3e99..3419a28dff9 100644 --- a/caas/kubernetes/provider/storage_test.go +++ b/caas/kubernetes/provider/storage_test.go @@ -169,7 +169,7 @@ func (s *storageSuite) TestDescribeVolumes(c *gc.C) { result, err := vs.DescribeVolumes(&context.CloudCallContext{}, []string{"vol-id"}) c.Assert(err, jc.ErrorIsNil) c.Assert(result, jc.DeepEquals, []storage.DescribeVolumesResult{{ - VolumeInfo: &storage.VolumeInfo{VolumeId: "vol-id", Size: 68, Persistent: true}, + VolumeInfo: &storage.VolumeInfo{VolumeId: "vol-id", Size: 66, Persistent: true}, }}) } diff --git a/caas/kubernetes/provider/watcher/k8swatcher.go b/caas/kubernetes/provider/watcher/k8swatcher.go index e8fbb6f425a..0548d131bcf 100644 --- a/caas/kubernetes/provider/watcher/k8swatcher.go +++ b/caas/kubernetes/provider/watcher/k8swatcher.go @@ -7,6 +7,7 @@ import ( "time" jujuclock "github.com/juju/clock" + "github.com/juju/errors" "github.com/juju/loggo" "github.com/juju/worker/v3/catacomb" "k8s.io/apimachinery/pkg/api/meta" @@ -87,13 +88,16 @@ func (w *kubernetesNotifyWatcher) loop() error { } } - w.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + _, err := w.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: fireFn("add"), DeleteFunc: fireFn("delete"), UpdateFunc: func(_, obj interface{}) { fireFn("update")(obj) }, }) + if err != nil { + return errors.Trace(err) + } // Set out now so that initial event is sent. out := w.out @@ -207,13 +211,16 @@ func (w *kubernetesStringsWatcher) loop() error { } } - w.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + _, err := w.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: fireFn(WatchEventAdd), DeleteFunc: fireFn(WatchEventDelete), UpdateFunc: func(_, obj interface{}) { fireFn(WatchEventUpdate)(obj) }, }) + if err != nil { + return errors.Trace(err) + } // Set out now so that initial event is sent. var out chan []string diff --git a/caas/kubernetes/tunnel.go b/caas/kubernetes/tunnel.go index 29e9aeb886e..28375ef559f 100644 --- a/caas/kubernetes/tunnel.go +++ b/caas/kubernetes/tunnel.go @@ -245,7 +245,7 @@ func (t *Tunnel) waitForPodReady(ctx context.Context, podName string) error { defer close(stopChan) defer close(eventChan) - informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + _, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { objPod, valid := obj.(*corev1.Pod) if !valid { @@ -280,6 +280,9 @@ func (t *Tunnel) waitForPodReady(ctx context.Context, podName string) error { } }, }) + if err != nil { + return errors.Trace(err) + } go informer.Run(stopChan) diff --git a/cmd/juju/status/status_test.go b/cmd/juju/status/status_test.go index 0b2d3e7b088..dd0efa110e4 100644 --- a/cmd/juju/status/status_test.go +++ b/cmd/juju/status/status_test.go @@ -95,12 +95,12 @@ func (s *MinimalStatusSuite) TestGoodCallWithStorage(c *gc.C) { Model Controller Cloud/Region Version test test foo -Storage Unit Storage ID Type Pool Mountpoint Size Status Message - persistent/1 filesystem detached -postgresql/0 db-dir/1100 block 3.0MiB attached -transcode/0 db-dir/1000 block pending creating volume -transcode/0 shared-fs/0 filesystem radiance /mnt/doom 1.0GiB attached -transcode/1 shared-fs/0 filesystem radiance /mnt/huang 1.0GiB attached +Storage Unit Storage ID Type Pool Mountpoint Size Status Message + persistent/1 filesystem detached +postgresql/0 db-dir/1100 block 3.0 MiB attached +transcode/0 db-dir/1000 block pending creating volume +transcode/0 shared-fs/0 filesystem radiance /mnt/doom 1.0 GiB attached +transcode/1 shared-fs/0 filesystem radiance /mnt/huang 1.0 GiB attached `[1:]) } diff --git a/cmd/juju/storage/filesystemlist_test.go b/cmd/juju/storage/filesystemlist_test.go index 7dd7ef66b70..c485c681b24 100644 --- a/cmd/juju/storage/filesystemlist_test.go +++ b/cmd/juju/storage/filesystemlist_test.go @@ -96,6 +96,7 @@ Machine Unit Storage ID ID Volume Provider ID 1 transcode/1 shared-fs/0 4 provider-supplied-filesystem-4 /mnt/huang 1.0 GiB attached 1 2 provider-supplied-filesystem-2 /mnt/zion 3.0 MiB attached 1 3 42 MiB pending + `[1:] func (s *ListSuite) TestFilesystemListTabular(c *gc.C) { @@ -117,6 +118,7 @@ func (s *ListSuite) TestFilesystemListTabular(c *gc.C) { var expectedCAASFilesystemListTabular = ` Unit Storage ID ID Provider ID Mountpoint Size State Message mysql/0 db-dir/1001 0/0 provider-supplied-filesystem-0-0 /mnt/fuji 512 MiB attached + `[1:] func (s *ListSuite) TestCAASFilesystemListTabular(c *gc.C) { diff --git a/cmd/juju/storage/list_test.go b/cmd/juju/storage/list_test.go index b6939a16b85..60be9724583 100644 --- a/cmd/juju/storage/list_test.go +++ b/cmd/juju/storage/list_test.go @@ -49,6 +49,7 @@ postgresql/0 db-dir/1100 block 3.0 MiB attached transcode/0 db-dir/1000 block pending creating volume transcode/0 shared-fs/0 filesystem radiance 1.0 GiB attached transcode/1 shared-fs/0 filesystem radiance 1.0 GiB attached + `[1:]) } @@ -65,6 +66,7 @@ postgresql/0 db-dir/1100 block 3.0 MiB attached transcode/0 db-dir/1000 block pending creating volume transcode/0 shared-fs/0 filesystem 1.0 GiB attached transcode/1 shared-fs/0 filesystem 1.0 GiB attached + `[1:]) } diff --git a/cmd/juju/storage/poollist_test.go b/cmd/juju/storage/poollist_test.go index f64642b14b5..e7be05f7a13 100644 --- a/cmd/juju/storage/poollist_test.go +++ b/cmd/juju/storage/poollist_test.go @@ -89,6 +89,7 @@ abc testType key=value one=1 two=2 testName0 a key=value one=1 two=2 testName1 b key=value one=1 two=2 xyz testType key=value one=1 two=2 + `[1:]) } @@ -105,6 +106,7 @@ Name Provider Attributes abc testType a=true b=maybe c=well myaw testType a=true b=maybe c=well xyz testType a=true b=maybe c=well + `[1:]) } diff --git a/cmd/juju/storage/volumelist_test.go b/cmd/juju/storage/volumelist_test.go index d1e930285df..db92f025296 100644 --- a/cmd/juju/storage/volumelist_test.go +++ b/cmd/juju/storage/volumelist_test.go @@ -97,6 +97,7 @@ Machine Unit Storage ID Volume ID Provider ID Devi 1 transcode/1 shared-fs/0 4 provider-supplied-volume-4 xvdf3 1.0 GiB attached 1 2 provider-supplied-volume-2 xvdf1 3.0 MiB attached 1 3 42 MiB pending + `[1:] func (s *ListSuite) TestVolumeListTabular(c *gc.C) { @@ -119,6 +120,7 @@ func (s *ListSuite) TestVolumeListTabular(c *gc.C) { var expectedCAASVolumeListTabular = ` Unit Storage ID Volume ID Provider ID Size State Message mysql/0 db-dir/1001 0 provider-supplied-volume-0 512 MiB attached + `[1:] func (s *ListSuite) TestCAASVolumeListTabular(c *gc.C) { diff --git a/go.mod b/go.mod index 9c083799447..81c76075c1f 100644 --- a/go.mod +++ b/go.mod @@ -3,40 +3,40 @@ module github.com/juju/juju go 1.21 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.1 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0 - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 github.com/EvilSuperstars/go-cidrman v0.0.0-20170211231153-4e5a4a63d9b7 github.com/altoros/gosigma v0.0.0-20150408145232-31228935eec6 github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 - github.com/aws/aws-sdk-go-v2 v1.9.1 - github.com/aws/aws-sdk-go-v2/config v1.3.0 - github.com/aws/aws-sdk-go-v2/credentials v1.2.1 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.9.0 - github.com/aws/aws-sdk-go-v2/service/ecr v1.6.0 - github.com/aws/aws-sdk-go-v2/service/iam v1.9.0 - github.com/aws/smithy-go v1.8.0 + github.com/aws/aws-sdk-go-v2 v1.23.1 + github.com/aws/aws-sdk-go-v2/config v1.25.5 + github.com/aws/aws-sdk-go-v2/credentials v1.16.4 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 + github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 + github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 + github.com/aws/smithy-go v1.17.0 github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0 github.com/canonical/pebble v0.0.0-20230307221844-5842ea68c9c7 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/coreos/go-systemd/v22 v22.3.2 - github.com/docker/distribution v2.8.2+incompatible + github.com/docker/distribution v2.8.3+incompatible github.com/dustin/go-humanize v1.0.1 github.com/go-goose/goose/v5 v5.0.0-20220707165353-781664254fe4 - github.com/go-logr/logr v1.2.4 + github.com/go-logr/logr v1.3.0 github.com/go-macaroon-bakery/macaroon-bakery/v3 v3.0.1 github.com/gofrs/uuid v4.2.0+incompatible + github.com/google/gnostic-models v0.6.8 github.com/google/go-querystring v1.1.0 - github.com/google/uuid v1.3.0 - github.com/googleapis/gnostic v0.5.5 + github.com/google/uuid v1.4.0 github.com/gorilla/handlers v1.3.0 github.com/gorilla/schema v1.2.0 github.com/gorilla/websocket v1.5.0 @@ -51,7 +51,7 @@ require ( github.com/juju/charm/v8 v8.0.6 github.com/juju/charmrepo/v6 v6.0.3 github.com/juju/clock v1.0.3 - github.com/juju/cmd/v3 v3.0.14 + github.com/juju/cmd/v3 v3.0.0 github.com/juju/collections v1.0.4 github.com/juju/description/v3 v3.0.15 github.com/juju/errors v1.0.0 @@ -91,9 +91,9 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kr/pretty v0.3.1 github.com/mattn/go-isatty v0.0.19 - github.com/microsoft/kiota-abstractions-go v1.2.0 - github.com/microsoft/kiota-http-go v1.0.1 - github.com/microsoftgraph/msgraph-sdk-go v1.14.0 + github.com/microsoft/kiota-abstractions-go v1.5.3 + github.com/microsoft/kiota-http-go v1.1.1 + github.com/microsoftgraph/msgraph-sdk-go v1.25.0 github.com/mitchellh/go-linereader v0.0.0-20190213213312-1b945b3263eb github.com/mitchellh/mapstructure v1.5.0 github.com/moby/sys/mountinfo v0.6.2 @@ -105,13 +105,13 @@ require ( github.com/vishvananda/netlink v1.2.1-beta.2 github.com/vmware/govmomi v0.21.1-0.20191008161538-40aebf13ba45 go.uber.org/mock v0.2.0 - golang.org/x/crypto v0.14.0 - golang.org/x/net v0.17.0 - golang.org/x/oauth2 v0.13.0 - golang.org/x/sync v0.4.0 - golang.org/x/sys v0.13.0 - golang.org/x/tools v0.14.0 - google.golang.org/api v0.126.0 + golang.org/x/crypto v0.16.0 + golang.org/x/net v0.19.0 + golang.org/x/oauth2 v0.15.0 + golang.org/x/sync v0.5.0 + golang.org/x/sys v0.15.0 + golang.org/x/tools v0.16.0 + google.golang.org/api v0.152.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/httprequest.v1 v1.2.1 gopkg.in/ini.v1 v1.67.0 @@ -123,47 +123,56 @@ require ( gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.23.4 + k8s.io/api v0.28.4 k8s.io/apiextensions-apiserver v0.21.10 - k8s.io/apimachinery v0.23.4 - k8s.io/client-go v0.23.4 - k8s.io/klog/v2 v2.80.1 - k8s.io/utils v0.0.0-20230711102312-30195339c3c7 + k8s.io/apimachinery v0.28.4 + k8s.io/client-go v0.28.4 + k8s.io/klog/v2 v2.110.1 + k8s.io/utils v0.0.0-20231127182322-b307cd553661 ) require ( - cloud.google.com/go/compute v1.20.1 // indirect + cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.1.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.0.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.1.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.2.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.4.1 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/canonical/x-go v0.0.0-20230113154138-0ccdb0b57a43 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cjlapao/common-go v0.0.39 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-macaroon-bakery/macaroonpb v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.1.0 // indirect - github.com/google/s2a-go v0.1.4 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.11.0 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.0 // indirect @@ -178,6 +187,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juju/go4 v0.0.0-20160222163258-40d72ab9641a // indirect github.com/juju/gojsonpointer v0.0.0-20150204194629-afe8b77aa08f // indirect @@ -196,6 +206,7 @@ require ( github.com/lestrrat/go-pdebug v0.0.0-20160817063333-2e6eaaa5717f // indirect github.com/lestrrat/go-structinfo v0.0.0-20160308131105-f74c056fe41f // indirect github.com/lunixbochs/vtclean v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -204,6 +215,7 @@ require ( github.com/microsoft/kiota-authentication-azure-go v1.0.0 // indirect github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect github.com/microsoft/kiota-serialization-json-go v1.0.4 // indirect + github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0 // indirect github.com/moby/spdystream v0.2.0 // indirect @@ -211,8 +223,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/muhlemmer/gu v0.3.1 // indirect - github.com/onsi/ginkgo v1.14.2 // indirect - github.com/onsi/gomega v1.10.4 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect @@ -225,50 +236,43 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/fastuuid v1.2.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/std-uritemplate/std-uritemplate/go v0.0.47 // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/zitadel/oidc/v2 v2.6.4 // indirect go.etcd.io/bbolt v1.3.5 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.56.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/errgo.v1 v1.0.1 // indirect gopkg.in/gobwas/glob.v0 v0.2.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect - sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) -// This is copied from the go.mod file in github.com/canonical/lxd -// It is needed to avoid this error when running go list -m -// go: google.golang.org/grpc/naming@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000 -replace google.golang.org/grpc/naming => google.golang.org/grpc v1.29.1 - replace github.com/altoros/gosigma => github.com/juju/gosigma v1.0.0 replace gopkg.in/yaml.v2 => github.com/juju/yaml/v2 v2.0.0 -replace github.com/dustin/go-humanize v1.0.0 => github.com/dustin/go-humanize v0.0.0-20141228071148-145fabdb1ab7 - replace github.com/hashicorp/raft-boltdb => github.com/juju/raft-boltdb v0.0.0-20200518034108-40b112c917c5 diff --git a/go.sum b/go.sum index b5798e8ec7c..636894939be 100644 --- a/go.sum +++ b/go.sum @@ -9,23 +9,11 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -34,58 +22,54 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.1 h1:kRt6idL93W/nYRkUPbZ81yxJeLFevvrLYkyJEVzLpYM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.1/go.mod h1:nPsyC5G3IY+ljp+OHp8w/xa9UuLWe7ehFADNkqCSTaw= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 h1:d81/ng9rET2YqdVkVwkb6EXeRrLJIwyGnJcAlAWKwhs= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2 h1:qiir/pptnHqp6hV8QwV+IExYIf6cPsXBfUDUXQ27t2Y= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2/go.mod h1:jVRrRDLCOuif95HDYC23ADTMlvahB7tMdl519m9Iyjc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0 h1:/Di3vB4sNeQ+7A8efjUVENvyB945Wruvstucqp7ZArg= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0/go.mod h1:gM3K25LQlsET3QR+4V74zxCsFAy0r6xMNN9n80SZn+4= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0.0 h1:xxe4naFUPYEW1W6C8yWrfFNmyZLnEbO+CsbsSF83wDo= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v2 v2.0.0/go.mod h1:aLFjumYDvv63tH1qnqkcmdjdZ6Sn+/viPv7H3jft0oY= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2/go.mod h1:FbdwsQ2EzwvXxOPcMFYO8ogEc9uMMIj3YkmCdXdAFmk= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0 h1:8d4U82r7ItT1Es91x3eUcAQweih36KWvUha8AZ9X0Rs= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.2.0/go.mod h1:/1bkGperHinQbAHMWivoec/Ucu6//iXo6jn5mhmqCVU= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/17LUA5z1XTURo7LcVG2ICBPlyMHjIUrcFZNQ= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1:ceIuwmxDWptoW3eCqSXlnPsZFKh4X+R38dWPv7GS9Vs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 h1:HlZMUZW8S4P9oob1nCHxCCKrytxyLc+24nUJGssoEto= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0/go.mod h1:StGsLbuJh06Bd8IBfnAlIFV3fLb+gkczONWf15hpX2E= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1/go.mod h1:c/wcGeGx5FUPbM/JltUYHZcKmigwyVLJlDq+4HdtXaw= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0 h1:Pmy0+3ox1IC3sp6musv87BFPIdQbqyPFjn7I8I0o2Js= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0/go.mod h1:ThfyMjs6auYrWPnYJjI3H4H++oVPrz01pizpu8lfl3A= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0 h1:LcJtQjCXJUm1s7JpUHZvu+bpgURhCatxVNbGADXniX0= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0/go.mod h1:+OgGVo0Httq7N5oayfvaLQ/Jq+2gJdqfp++Hyyl7Tws= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 h1:wxQx2Bt4xzPIKvW59WQf1tJNx/ZZKPfN+EhPX3Z6CYY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0/go.mod h1:TpiwjwnW/khS0LKs4vW5UmmT9OWcxaveS8U7+tlknzo= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ= github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -105,40 +89,46 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go-v2 v1.6.0/go.mod h1:tI4KhsR5VkzlUa2DZAdwx7wCAYGwkZZ1H31PYrBFx1w= -github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2 v1.9.1 h1:ZbovGV/qo40nrOJ4q8G33AGICzaPI45FHQWJ9650pF4= -github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/config v1.3.0 h1:0JAnp0WcsgKilFLiZEScUTKIvTKa2LkicadZADza+u0= -github.com/aws/aws-sdk-go-v2/config v1.3.0/go.mod h1:lOxzHWDt/k7MMidA/K8DgXL4+ynnZYsDq65Qhs/l3dg= -github.com/aws/aws-sdk-go-v2/credentials v1.2.1 h1:AqQ8PzWll1wegNUOfIKcbp/JspTbJl54gNonrO6VUsY= -github.com/aws/aws-sdk-go-v2/credentials v1.2.1/go.mod h1:Rfvim1eZTC9W5s8YJyYYtl1KMk6e8fHv+wMRQGO4Ru0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.1.1 h1:w1ocBIhQkLgupEB3d0uOuBddqVYl0xpubz7HSTzWG8A= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.1.1/go.mod h1:GTXAhrxHQOj9N+J5tYVjwt+rpRyy/42qLjlgw9pz1a0= -github.com/aws/aws-sdk-go-v2/internal/ini v1.0.0 h1:k7I9E6tyVWBo7H9ffpnxDWudtjau6Qt9rnOYgV+ciEQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.0.0/go.mod h1:g3XMXuxvqSMUjnsXXp/960152w0wFS4CXVYgQaSVOHE= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.9.0 h1:SF0h/HR4zUDBbGv6Hf/fbbG6ywTVi9r2DmpIhfZMckI= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.9.0/go.mod h1:XzzkrryeCoPUd9jxcdDnI2/UmlfIp13nBSpjl2SDSCM= -github.com/aws/aws-sdk-go-v2/service/ecr v1.6.0 h1:ZtWi8hEr5zp8zmJZK4Wl9K6M2zzbv1E/qGJD6q9dZE0= -github.com/aws/aws-sdk-go-v2/service/ecr v1.6.0/go.mod h1:uFNN66CD8T+MPYoN5ku0atY9hMNtEZqOTgvX3WLQ0Hc= -github.com/aws/aws-sdk-go-v2/service/iam v1.9.0 h1:PkrJTTEtdXtx+SF74QTQ0tPcVS1Vu9hghYfWx0SmBCw= -github.com/aws/aws-sdk-go-v2/service/iam v1.9.0/go.mod h1:aDjZkXLwXAd6Rn1cbiWnkGYBKXUb9fXO8UED20HwCnw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.1.1 h1:l7pDLsmOGrnR8LT+3gIv8NlHpUhs7220E457KEC2UM0= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.1.1/go.mod h1:2+ehJPkdIdl46VCj67Emz/EH2hpebHZtaLdzqg+sWOI= -github.com/aws/aws-sdk-go-v2/service/sso v1.2.1 h1:alpXc5UG7al7QnttHe/9hfvUfitV8r3w0onPpPkGzi0= -github.com/aws/aws-sdk-go-v2/service/sso v1.2.1/go.mod h1:VimPFPltQ/920i1X0Sb0VJBROLIHkDg2MNP10D46OGs= -github.com/aws/aws-sdk-go-v2/service/sts v1.4.1 h1:9Z00tExoaLutWVDmY6LyvIAcKjHetkbdmpRt4JN/FN0= -github.com/aws/aws-sdk-go-v2/service/sts v1.4.1/go.mod h1:G9osDWA52WQ38BDcj65VY1cNmcAQXAXTsE8IWH8j81w= -github.com/aws/smithy-go v1.4.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/aws/aws-sdk-go-v2 v1.23.1 h1:qXaFsOOMA+HsZtX8WoCa+gJnbyW7qyFFBlPqvTSzbaI= +github.com/aws/aws-sdk-go-v2 v1.23.1/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA= +github.com/aws/aws-sdk-go-v2/config v1.25.5 h1:UGKm9hpQS2hoK8CEJ1BzAW8NbUpvwDJJ4lyqXSzu8bk= +github.com/aws/aws-sdk-go-v2/config v1.25.5/go.mod h1:Bf4gDvy4ZcFIK0rqDu1wp9wrubNba2DojiPB2rt6nvI= +github.com/aws/aws-sdk-go-v2/credentials v1.16.4 h1:i7UQYYDSJrtc30RSwJwfBKwLFNnBTiICqAJ0pPdum8E= +github.com/aws/aws-sdk-go-v2/credentials v1.16.4/go.mod h1:Kdh/okh+//vQ/AjEt81CjvkTo64+/zIE4OewP7RpfXk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 h1:KehRNiVzIfAcj6gw98zotVbb/K67taJE0fkfgM6vzqU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5/go.mod h1:VhnExhw6uXy9QzetvpXDolo1/hjhx4u9qukBGkuUwjs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 h1:LAm3Ycm9HJfbSCd5I+wqC2S9Ej7FPrgr5CQoOljJZcE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4/go.mod h1:xEhvbJcyUf/31yfGSQBe01fukXwXJ0gxDp7rLfymWE0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 h1:4GV0kKZzUxiWxSVpn/9gwR0g21NF1Jsyduzo9rHgC/Q= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4/go.mod h1:dYvTNAggxDZy6y1AF7YDwXsPuHFy/VNEpEI/2dWK9IU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 h1:J/N4ydefXQZIwKBDPtvrhxrIuP/vaaYKnAsy3bKVIvU= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1/go.mod h1:hrBzQzlQQRmiaeYRQPr0SdSx6fdqP+5YcGhb97LCt8M= +github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 h1:YbmdI0hfIhr/7oxjKLI23bYXlFerABZfHnfX3mQATsM= +github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1/go.mod h1:l9cQba3Vzc7ftueGCezlMb0bBwow7Va0ZMZfmk0qNYQ= +github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 h1:rHgJTYLKwLcZ9/k8CVWJuhdApnb3cdjoQeLvKa6bAcU= +github.com/aws/aws-sdk-go-v2/service/iam v1.27.3/go.mod h1:LklzfZoa7bL/NdhOzoaRtqSLGhu5j+GqE/9WoOQGFKY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 h1:rdovz3rEu0vZKbzoMYPTehp0E8veoE9AyfzqCr5Eeao= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4/go.mod h1:aYCGNjyUCUelhofxlZyj63srdxWUSsBSGg5l6MCuXuE= +github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 h1:CdsSOGlFF3Pn+koXOIpTtvX7st0IuGsZ8kJqcWMlX54= +github.com/aws/aws-sdk-go-v2/service/sso v1.17.3/go.mod h1:oA6VjNsLll2eVuUoF2D+CMyORgNzPEW/3PyUdq6WQjI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 h1:cbRqFTVnJV+KRpwFl76GJdIZJKKCdTPnjUZ7uWh3pIU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1/go.mod h1:hHL974p5auvXlZPIjJTblXJpbkfK4klBczlsEaMCGVY= +github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 h1:yEvZ4neOQ/KpUqyR+X0ycUTW/kVRNR4nDZ38wStHGAA= +github.com/aws/aws-sdk-go-v2/service/sts v1.25.4/go.mod h1:feTnm2Tk/pJxdX+eooEsxvlvTWBvDm6CasRZ+JOs2IY= +github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI= +github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -171,12 +161,6 @@ github.com/cjlapao/common-go v0.0.39 h1:bAAUrj2B9v0kMzbAOhzjSmiyDy+rd56r2sy7oEiQ github.com/cjlapao/common-go v0.0.39/go.mod h1:M3dzazLjTjEtZJbbxoA5ZDiGCiHmpwqW9l4UWaddwOA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -199,26 +183,26 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20141228071148-145fabdb1ab7/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -227,7 +211,6 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 h1:fmFk0Wt3bBxxwZnu48jqMdaOR/IZ4vdtJFuaFV8MpIE= github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3/go.mod h1:bJWSKrZyQvfTnb2OudyUjurSG4/edverV7n82+K3JiM= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.0.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k= github.com/frankban/quicktest v1.1.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= @@ -237,10 +220,6 @@ github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -256,10 +235,9 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-macaroon-bakery/macaroon-bakery/v3 v3.0.1 h1:uvQJoKTHrFFu8zxoaopNKedRzwdy3+8H72we4T/5cGs= @@ -268,14 +246,21 @@ github.com/go-macaroon-bakery/macaroonpb v1.0.0 h1:It9exBaRMZ9iix1iJ6gwzfwsDE6Ex github.com/go-macaroon-bakery/macaroonpb v1.0.0/go.mod h1:UzrGOcbiwTXISFP2XDLDPjfhMINZa+fX/7A2lMd31zc= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= @@ -286,8 +271,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -301,8 +286,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= @@ -311,7 +294,6 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -321,66 +303,55 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v0.0.0-20170306145142-6a5e28554805/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI= github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= @@ -404,7 +375,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -442,7 +412,6 @@ github.com/hashicorp/raft v1.3.2-0.20210825230038-1a621031eb2b/go.mod h1:4Ak7FSP github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/im7mortal/kmutex v1.0.1 h1:zAACzjwD+OEknDqnLdvRa/BhzFM872EBwKijviGLc9Q= github.com/im7mortal/kmutex v1.0.1/go.mod h1:f71c/Ugk/+58OHRAgvgzPP3QEiWGUjK13fd8ozfKWdo= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -471,6 +440,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -500,8 +471,8 @@ github.com/juju/clock v1.0.3 h1:yJHIsWXeU8j3QcBdiess09SzfiXRRrsjKPn2whnMeds= github.com/juju/clock v1.0.3/go.mod h1:HIBvJ8kiV/n7UHwKuCkdYL4l/MDECztHR2sAvWDxxf0= github.com/juju/cmd v0.0.0-20171107070456-e74f39857ca0/go.mod h1:yWJQHl73rdSX4DHVKGqkAip+huBslxRwS8m9CrOLq18= github.com/juju/cmd/v3 v3.0.0-20220202061353-b1cc80b193b0/go.mod h1:EoGJiEG+vbMwO9l+Es0SDTlaQPjH6nLcnnc4NfZB3cY= -github.com/juju/cmd/v3 v3.0.14 h1:KuuamArSH7vQ6SdQKEHYK2scEMkJTEZKLs8abrlW3XE= -github.com/juju/cmd/v3 v3.0.14/go.mod h1:lGtDvm2BG+FKnIS8yY/vrhxQNX9imnL6bPIYGSTchuI= +github.com/juju/cmd/v3 v3.0.0 h1:5D/4C9Q5quc9F2OfGEVi+xgHue3D9HyY0/ad8ywgk+A= +github.com/juju/cmd/v3 v3.0.0/go.mod h1:OwsFyKpl9Hz4oHdlZyVN2QFXjiwm5vSu/lShppBbwhI= github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271/go.mod h1:5XgO71dV1JClcOJE+4dzdn4HrI5LiyKd7PlVG6eZYhY= github.com/juju/collections v0.0.0-20220203020748-febd7cad8a7a/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo= github.com/juju/collections v1.0.0/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo= @@ -686,6 +657,8 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+incompatible/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE= github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg= @@ -715,20 +688,22 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/microsoft/kiota-abstractions-go v1.2.0 h1:lUriJgqdCY/QajwWQOgTCQE9Atywfe2NHhgoTCSXTRE= -github.com/microsoft/kiota-abstractions-go v1.2.0/go.mod h1:RkxyZ5x87Njik7iVeQY9M2wtrrL1MJZcXiI/BxD/82g= +github.com/microsoft/kiota-abstractions-go v1.5.3 h1:qUTwuXCbMi99EkHaTh5NGMK5MOKxJn7u/M2FbYcesLY= +github.com/microsoft/kiota-abstractions-go v1.5.3/go.mod h1:xyBzTVCYrp7QBW4/p+RFi44PHwp/IPn2dZepuV4nF80= github.com/microsoft/kiota-authentication-azure-go v1.0.0 h1:29FNZZ/4nnCOwFcGWlB/sxPvWz487HA2bXH8jR5k2Rk= github.com/microsoft/kiota-authentication-azure-go v1.0.0/go.mod h1:rnx3PRlkGdXDcA/0lZQTbBwyYGmc+3POt7HpE/e4jGw= -github.com/microsoft/kiota-http-go v1.0.1 h1:818u3aiLpxj35hZgfUSqphQ18IUTK3gVdTE4cQ5vjLw= -github.com/microsoft/kiota-http-go v1.0.1/go.mod h1:H0cg+ly+5ZSR8z4swj5ea9O/GB5ll2YuYeQ0/pJs7AY= +github.com/microsoft/kiota-http-go v1.1.1 h1:W4Olo7Z/MwNZCfkcvH/5eLhnn7koRBMMRhLEnf5MPKo= +github.com/microsoft/kiota-http-go v1.1.1/go.mod h1:QzhhfW5xkoUuT+/ohflpHJvumWeXIxa/Xl0GmQ2M6mY= github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= github.com/microsoft/kiota-serialization-json-go v1.0.4 h1:5TaISWwd2Me8clrK7SqNATo0tv9seOq59y4I5953egQ= github.com/microsoft/kiota-serialization-json-go v1.0.4/go.mod h1:rM4+FsAY+9AEpBsBzkFFis+b/LZLlNKKewuLwK9Q6Mg= +github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs= +github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so= github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA= github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M= -github.com/microsoftgraph/msgraph-sdk-go v1.14.0 h1:YdhMvzu8bXcfIQGRur6NkXnv4cPOsMBJ44XjfWLOt9Y= -github.com/microsoftgraph/msgraph-sdk-go v1.14.0/go.mod h1:ccLv84FJFtwdSzYWM/HlTes5FLzkzzBsYh9kg93/WS8= +github.com/microsoftgraph/msgraph-sdk-go v1.25.0 h1:AKHYi6TqyXrKrbgYnVq4RNbxM9FHs+0McoFTmy9VH28= +github.com/microsoftgraph/msgraph-sdk-go v1.25.0/go.mod h1:9atTwyb9mpNq5MgTBPs2KAlDzGcMcTszDVzE4GeXCeo= github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0 h1:7NWTfyXvOjoizW7PmxNp3+8wCKPgpODs/D1cUZ3fkAY= github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0/go.mod h1:tQb4q3YMIj2dWhhXhQSJ4ELpol931ANKzHSYK5kX1qE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -761,29 +736,25 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U= -github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/oracle/oci-go-sdk/v47 v47.1.0 h1:oXkuD18OpcE2bsl6AHMJWKcoPcQrsFq7TiNzCuDiRU8= @@ -855,8 +826,9 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= @@ -887,7 +859,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/std-uritemplate/std-uritemplate/go v0.0.47 h1:erzz/DR4sOzWr0ca2MgSTkMckpLEsDySaTZwVFQq9zw= +github.com/std-uritemplate/std-uritemplate/go v0.0.47/go.mod h1:Qov4Ay4U83j37XjgxMYevGJFLbnZ2o9cEOhGufBKgKY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -929,14 +902,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI= -github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= -github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/oidc/v2 v2.6.4 h1:bruA+KOFHcGpxr++WgtvR82ZlH54kKituu5xE4wpF7o= github.com/zitadel/oidc/v2 v2.6.4/go.mod h1:owrsdzRqGvIZjBCY9LY1ZUYJ0mRUbGkQpZ3OskXL4wM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -949,18 +916,14 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= @@ -985,12 +948,9 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1015,7 +975,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1025,12 +984,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20150829230318-ea47fc708ee3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1050,7 +1005,6 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1061,60 +1015,36 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1134,11 +1064,8 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1151,75 +1078,53 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1255,34 +1160,16 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1293,26 +1180,14 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY= +google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1332,37 +1207,15 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1371,20 +1224,9 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1397,7 +1239,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1453,7 +1294,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1465,49 +1305,46 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.21.10/go.mod h1:5kqv2pCXwcrOvV12WhVAtLZUKaM0kyrZ6nHObw8SojA= -k8s.io/api v0.23.4 h1:85gnfXQOWbJa1SiWGpE9EEtHs0UVvDyIsSMpEtl2D4E= -k8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI= +k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= +k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/apiextensions-apiserver v0.21.10 h1:61ymf3Yw6dadgfUbWCEVud5j6l9rme8ocy6jJbuFK04= k8s.io/apiextensions-apiserver v0.21.10/go.mod h1:Uu9eBo+d489/K5pauF1oLaVxQzgvdng6aIb2LRlT/w8= k8s.io/apimachinery v0.21.10/go.mod h1:USs+ifLG6ZUgHGA/9lGxjdHzCB3hUO3fG1VBOwi0IHo= -k8s.io/apimachinery v0.23.4 h1:fhnuMd/xUL3Cjfl64j5ULKZ1/J9n8NuQEgNL+WXWfdM= -k8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= +k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/apiserver v0.21.10/go.mod h1:dMEmFJ//OIDnnWmjcpVq+XkKQubRY1rAm5as7MwbIWQ= k8s.io/client-go v0.21.10/go.mod h1:nAGhVCjwhbDP2whk65n3STSCn24H/VGp1pKSk9UszU8= -k8s.io/client-go v0.23.4 h1:YVWvPeerA2gpUudLelvsolzH7c2sFoXXR5wM/sWqNFU= -k8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0= +k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= +k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/code-generator v0.21.10/go.mod h1:FbZCzn44pBTAjY3tIvLIQcF2514rGUzMP1liffRr5jQ= k8s.io/component-base v0.21.10/go.mod h1:zO/BjKH/RR6DoZEQAws7m+Q81pYZ+f5vDfujDqvWdlA= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/utils v0.0.0-20210521133846-da695404a2bc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= +k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= launchpad.net/xmlpath v0.0.0-20130614043138-000000000004/go.mod h1:vqyExLOM3qBx7mvYRkoxjSCF945s0mbe7YynlKYXtsA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27/go.mod h1:tq2nT0Kx7W+/f2JVE+zxYtUhdjuELJkVpNz+x/QN5R4= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/provider/azure/internal/azureauth/discovery.go b/provider/azure/internal/azureauth/discovery.go index 68cb776be9f..a9587913e08 100644 --- a/provider/azure/internal/azureauth/discovery.go +++ b/provider/azure/internal/azureauth/discovery.go @@ -29,9 +29,7 @@ type recordAuthHeaderPolicy struct { func (p *recordAuthHeaderPolicy) Do(req *policy.Request) (*http.Response, error) { resp, err := req.Next() - if err == nil { - p.authHeader = resp.Header.Get(authenticateHeaderKey) - } + p.authHeader = resp.Header.Get(authenticateHeaderKey) return resp, err } diff --git a/provider/azure/internal/errorutils/errors_test.go b/provider/azure/internal/errorutils/errors_test.go index b83bd53fb16..f7bd4a8c1a2 100644 --- a/provider/azure/internal/errorutils/errors_test.go +++ b/provider/azure/internal/errorutils/errors_test.go @@ -79,6 +79,8 @@ func (s *ErrorSuite) TestAuthRelatedStatusCodes(c *gc.C) { for t := range common.AuthorisationFailureStatusCodes { called = false s.azureError.StatusCode = t + s.azureError.ErrorCode = "some error code" + s.azureError.RawResponse = &http.Response{} errorutils.HandleCredentialError(s.azureError, ctx) c.Assert(called, jc.IsTrue) } diff --git a/provider/ec2/ebs_test.go b/provider/ec2/ebs_test.go index c3628edee0d..70fd775d266 100644 --- a/provider/ec2/ebs_test.go +++ b/provider/ec2/ebs_test.go @@ -658,7 +658,7 @@ func (s *ebsSuite) TestListVolumesIgnoresRootDisks(c *gc.C) { _, err := s.srv.ec2srv.CreateTags(s.cloudCallCtx, &awsec2.CreateTagsInput{ Resources: []string{"vol-0"}, Tags: []types.Tag{ - {aws.String(tags.JujuModel), aws.String(s.modelConfig.UUID())}, + {Key: aws.String(tags.JujuModel), Value: aws.String(s.modelConfig.UUID())}, }, }) c.Assert(err, jc.ErrorIsNil) diff --git a/provider/ec2/internal/testing/instances.go b/provider/ec2/internal/testing/instances.go index d5f35a8e828..93231cee32a 100644 --- a/provider/ec2/internal/testing/instances.go +++ b/provider/ec2/internal/testing/instances.go @@ -18,11 +18,11 @@ import ( // Recognized AWS instance states. var ( - Pending = types.InstanceState{aws.Int32(0), "pending"} - Running = types.InstanceState{aws.Int32(16), "running"} - ShuttingDown = types.InstanceState{aws.Int32(32), "shutting-down"} - Terminated = types.InstanceState{aws.Int32(16), "terminated"} - Stopped = types.InstanceState{aws.Int32(16), "stopped"} + Pending = types.InstanceState{Code: aws.Int32(0), Name: "pending"} + Running = types.InstanceState{Code: aws.Int32(16), Name: "running"} + ShuttingDown = types.InstanceState{Code: aws.Int32(32), Name: "shutting-down"} + Terminated = types.InstanceState{Code: aws.Int32(16), Name: "terminated"} + Stopped = types.InstanceState{Code: aws.Int32(16), Name: "stopped"} ) // Instance holds a fake ec2 instance diff --git a/state/storage_dynamicadd_test.go b/state/storage_dynamicadd_test.go index a70a91fbc1f..6fed874da81 100644 --- a/state/storage_dynamicadd_test.go +++ b/state/storage_dynamicadd_test.go @@ -304,7 +304,7 @@ func (s *storageAddSuite) TestAddStorageLessMinSize(c *gc.C) { s.assignUnit(c, u) _, err := s.storageBackend.AddStorageForUnit(s.unitTag, "multi2up", state.StorageConstraints{Size: 2, Count: 1}) - c.Assert(err, gc.ErrorMatches, `.*charm "storage-block2" store "multi2up": minimum storage size is 2.0GB, 2.0MB specified.*`) + c.Assert(err, gc.ErrorMatches, `.*charm "storage-block2" store "multi2up": minimum storage size is 2.0 GB, 2.0 MB specified.*`) s.assertStorageCount(c, s.originalStorageCount) s.assertVolumeCount(c, s.originalVolumeCount) s.assertFileSystemCount(c, s.originalFilesystemCount) diff --git a/worker/caasrbacmapper/mapper.go b/worker/caasrbacmapper/mapper.go index 3da7c388143..c04de5ff261 100644 --- a/worker/caasrbacmapper/mapper.go +++ b/worker/caasrbacmapper/mapper.go @@ -110,13 +110,16 @@ func NewMapper(logger Logger, informer core.ServiceAccountInformer) (*DefaultMap workQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), } - dm.saInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + _, err := dm.saInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: dm.enqueueServiceAccount, DeleteFunc: dm.enqueueServiceAccount, UpdateFunc: func(_, newObj interface{}) { dm.enqueueServiceAccount(newObj) }, }) + if err != nil { + return nil, errors.Trace(err) + } if err := catacomb.Invoke(catacomb.Plan{ Site: &dm.catacomb, diff --git a/worker/caasrbacmapper/mapper_test.go b/worker/caasrbacmapper/mapper_test.go index 444f912d755..098a2f5bae4 100644 --- a/worker/caasrbacmapper/mapper_test.go +++ b/worker/caasrbacmapper/mapper_test.go @@ -57,7 +57,7 @@ func (m *MapperSuite) TestMapperAdditionSync(c *gc.C) { DoAndReturn(func(h cache.ResourceEventHandlerFuncs) { eventHandlers = h waitGroup.Done() - }) + }).Return(m.mockSharedIndexInformer, nil) mapper, err := caasrbacmapper.NewMapper(loggo.Logger{}, m.mockSAInformer) c.Assert(err, jc.ErrorIsNil) @@ -85,7 +85,7 @@ func (m *MapperSuite) TestMapperAdditionSync(c *gc.C) { return sa, nil }) - eventHandlers.OnAdd(sa) + eventHandlers.OnAdd(sa, false) waitGroup.Wait() mapper.Kill() @@ -112,7 +112,7 @@ func (m *MapperSuite) TestRBACMapperUpdateSync(c *gc.C) { DoAndReturn(func(h cache.ResourceEventHandlerFuncs) { eventHandlers = h waitGroup.Done() - }) + }).Return(m.mockSharedIndexInformer, nil) mapper, err := caasrbacmapper.NewMapper(loggo.Logger{}, m.mockSAInformer) c.Assert(err, jc.ErrorIsNil) @@ -140,7 +140,7 @@ func (m *MapperSuite) TestRBACMapperUpdateSync(c *gc.C) { return sa, nil }) - eventHandlers.OnAdd(sa) + eventHandlers.OnAdd(sa, false) waitGroup.Wait() for a := coretesting.LongAttempt.Start(); a.Next(); { @@ -193,7 +193,7 @@ func (m *MapperSuite) TestRBACMapperDeleteSync(c *gc.C) { DoAndReturn(func(h cache.ResourceEventHandlerFuncs) { eventHandlers = h waitGroup.Done() - }) + }).Return(m.mockSharedIndexInformer, nil) mapper, err := caasrbacmapper.NewMapper(loggo.Logger{}, m.mockSAInformer) c.Assert(err, jc.ErrorIsNil) @@ -215,7 +215,7 @@ func (m *MapperSuite) TestRBACMapperDeleteSync(c *gc.C) { m.mockSALister.EXPECT().ServiceAccounts(gomock.Eq(namespace)). Return(m.mockSANamespaceLister).AnyTimes() m.mockSANamespaceLister.EXPECT().Get(gomock.Eq(name)).Return(sa, nil) - eventHandlers.OnAdd(sa) + eventHandlers.OnAdd(sa, false) for a := coretesting.LongAttempt.Start(); a.Next(); { rAppName, err := mapper.AppNameForServiceAccount(uid) From 28b873a0c549901f8d4e1e0259a017a3f46c9749 Mon Sep 17 00:00:00 2001 From: Harry Pidcock Date: Tue, 28 Nov 2023 13:55:55 +1000 Subject: [PATCH 37/50] Improve PULL_REQUEST_TEMPLATE.md --- PULL_REQUEST_TEMPLATE.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index a3896add50f..ea38f35d808 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,8 @@ -*Why this change is needed and what it does.* + ## Checklist -*If an item is not applicable, use `~strikethrough~`.* + - [ ] Code style: imports ordered, good names, simple structure, etc - [ ] Comments saying why design decisions were made @@ -12,20 +12,17 @@ ## QA steps -*Commands to run to verify that the change works.* - -```sh -QA steps here -``` + ## Documentation changes -*How it affects user workflow (CLI or API). Delete section if not applicable.* + ## Links -**Launchpad bug:** https://pad.lv/ + + +**Launchpad bug:** https://bugs.launchpad.net/juju/+bug/ -**Jira card:** JUJU-[XXXX] +**Jira card:** JUJU- -*Insert other relevant links here.* \ No newline at end of file From 7f910e8b68fe36aedfa89938fc6cab4fd481b153 Mon Sep 17 00:00:00 2001 From: Harry Pidcock Date: Tue, 28 Nov 2023 15:02:21 +1000 Subject: [PATCH 38/50] Backport change from 3.1 to fix model config test. --- tests/suites/model/config.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/suites/model/config.sh b/tests/suites/model/config.sh index e333eb062ed..786d7059d50 100644 --- a/tests/suites/model/config.sh +++ b/tests/suites/model/config.sh @@ -6,12 +6,12 @@ run_model_config() { file="${TEST_DIR}/test-model-config.log" ensure "model-config" "${file}" - juju model-config mode="[strict]" - juju model-config mode | grep "strict" - juju model-config mode="[]" - juju model-config mode | grep "\[\]" - juju model-config mode="[boom]" || echo "ERROR" | grep "ERROR" - juju model-config --reset mode + juju model-config provisioner-harvest-mode="none" + juju model-config provisioner-harvest-mode | grep "none" + juju model-config provisioner-harvest-mode="destroyed" + juju model-config provisioner-harvest-mode | grep "destroyed" + juju model-config provisioner-harvest-mode="invalid" || echo "ERROR" | grep "ERROR" + juju model-config --reset provisioner-harvest-mode destroy_model "model-config" } From 192b3dfb8a5cc8baed0d4c6127a9e78d042d7dac Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Tue, 28 Nov 2023 17:48:07 +1000 Subject: [PATCH 39/50] Quick fix for map odering issue causing TestMultipleSuggestion to fail --- core/charm/repository/charmhub_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/charm/repository/charmhub_test.go b/core/charm/repository/charmhub_test.go index 83c5df30edd..4095c99536c 100644 --- a/core/charm/repository/charmhub_test.go +++ b/core/charm/repository/charmhub_test.go @@ -1007,7 +1007,7 @@ func (s *composeSuggestionsSuite) TestMultipleSuggestion(c *gc.C) { Architecture: "c", }, }) - c.Assert(suggestions, gc.DeepEquals, []string{ + c.Assert(suggestions, jc.SameContents, []string{ `channel "latest/stable": available series are: focal, bionic`, `channel "2.0/stable": available series are: bionic`, }) From a799e87b44837e560cdb0c59acab7e704732d28b Mon Sep 17 00:00:00 2001 From: Vitaly Antonenko Date: Tue, 28 Nov 2023 13:34:00 +0300 Subject: [PATCH 40/50] Fixes deploy_aks CI test - add removing applications with `--force` to avoid scaling to 0 issues --- tests/suites/deploy_aks/deploy_aks.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/suites/deploy_aks/deploy_aks.sh b/tests/suites/deploy_aks/deploy_aks.sh index 226d99dc128..313d067490b 100644 --- a/tests/suites/deploy_aks/deploy_aks.sh +++ b/tests/suites/deploy_aks/deploy_aks.sh @@ -21,6 +21,11 @@ run_deploy_aks_charms() { echo "Destroy model" juju destroy-model "test-deploy-aks-charms" --destroy-storage -y + + # Because of issues with scaling `dummy-source` and `dummy-sink` we need to remove it with `--force` flag + echo "Remove applications with --force flag" + juju remove-application dummy-source --force --no-wait + juju remove-application dummy-sink --force --no-wait } test_deploy_aks_charms() { From 2528efa47adc51785b9916de322edd02874339c7 Mon Sep 17 00:00:00 2001 From: Vitaly Antonenko Date: Tue, 28 Nov 2023 14:04:49 +0300 Subject: [PATCH 41/50] Adds TODO message --- tests/suites/deploy_aks/deploy_aks.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/suites/deploy_aks/deploy_aks.sh b/tests/suites/deploy_aks/deploy_aks.sh index 313d067490b..fa4a8e452a3 100644 --- a/tests/suites/deploy_aks/deploy_aks.sh +++ b/tests/suites/deploy_aks/deploy_aks.sh @@ -22,7 +22,10 @@ run_deploy_aks_charms() { echo "Destroy model" juju destroy-model "test-deploy-aks-charms" --destroy-storage -y - # Because of issues with scaling `dummy-source` and `dummy-sink` we need to remove it with `--force` flag + # TODO(anvial - 2023.11.28): We need to drop this hack when possible. + # The problem is that on AKS (possibly on other K8s substrates) + # we have issues with scaling `dummy-source` and `dummy-sink` apps to zero. + # The current workaround is to remove these apps with `--force` flag echo "Remove applications with --force flag" juju remove-application dummy-source --force --no-wait juju remove-application dummy-sink --force --no-wait From c4d5a9b769f0cd0a0f3494ea5c6feff34f1c83c2 Mon Sep 17 00:00:00 2001 From: Kelvin Liu Date: Tue, 28 Nov 2023 22:48:14 +1100 Subject: [PATCH 42/50] Simplify vault setup for secret Iaas tests; --- tests/suites/secrets_iaas/vault.sh | 19 +++++++++++++------ tests/suites/secrets_k8s/k8s.sh | 11 +++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/tests/suites/secrets_iaas/vault.sh b/tests/suites/secrets_iaas/vault.sh index 17263d0756e..f64f416cd39 100644 --- a/tests/suites/secrets_iaas/vault.sh +++ b/tests/suites/secrets_iaas/vault.sh @@ -74,15 +74,11 @@ prepare_vault() { sudo snap install vault fi + # If no databases are related, vault will be auto configured to + # use its embedded raft storage backend for storage and HA. juju --show-log deploy vault - juju --show-log deploy -n 3 mysql-innodb-cluster - juju --show-log deploy mysql-router - juju --show-log integrate mysql-router:db-router mysql-innodb-cluster:db-router - juju --show-log integrate mysql-router:shared-db vault:shared-db juju --show-log expose vault - wait_for "active" '.applications["mysql-innodb-cluster"] | ."application-status".current' 1200 - wait_for "active" '.applications["mysql-router"] | ."application-status".current' 1200 wait_for "blocked" "$(workload_status vault 0).current" vault_public_addr=$(juju status --format json | jq -r '.applications.vault.units."vault/0"."public-address"') export VAULT_ADDR="http://${vault_public_addr}:8200" @@ -97,6 +93,17 @@ prepare_vault() { vault operator unseal "$unseal_key0" vault operator unseal "$unseal_key1" vault operator unseal "$unseal_key2" + + # wait for vault server to be ready. + attempt=0 + until [[ $(vault status -format yaml 2>/dev/null | yq .initialized | grep -i 'true') ]]; do + if [[ ${attempt} -ge 30 ]]; then + echo "Failed: vault server was not able to be ready." + exit 1 + fi + sleep 2 + attempt=$((attempt + 1)) + done } test_secret_drain() { diff --git a/tests/suites/secrets_k8s/k8s.sh b/tests/suites/secrets_k8s/k8s.sh index b499d0d0032..88f39874f46 100644 --- a/tests/suites/secrets_k8s/k8s.sh +++ b/tests/suites/secrets_k8s/k8s.sh @@ -169,6 +169,17 @@ prepare_vault() { export VAULT_ADDR="http://${ip}:8200" export VAULT_TOKEN="$root_token" + + # wait for vault server to be ready. + attempt=0 + until [[ $(vault status -format yaml 2>/dev/null | yq .initialized | grep -i 'true') ]]; do + if [[ ${attempt} -ge 30 ]]; then + echo "Failed: vault server was not able to be ready." + exit 1 + fi + sleep 2 + attempt=$((attempt + 1)) + done } test_secrets() { From 68507c6ba00a24e3d50c5040228a5938bcd35ef6 Mon Sep 17 00:00:00 2001 From: Vitaly Antonenko Date: Tue, 28 Nov 2023 16:56:23 +0300 Subject: [PATCH 43/50] Revert "Fixes deploy_aks CI test" --- tests/suites/deploy_aks/deploy_aks.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/suites/deploy_aks/deploy_aks.sh b/tests/suites/deploy_aks/deploy_aks.sh index fa4a8e452a3..226d99dc128 100644 --- a/tests/suites/deploy_aks/deploy_aks.sh +++ b/tests/suites/deploy_aks/deploy_aks.sh @@ -21,14 +21,6 @@ run_deploy_aks_charms() { echo "Destroy model" juju destroy-model "test-deploy-aks-charms" --destroy-storage -y - - # TODO(anvial - 2023.11.28): We need to drop this hack when possible. - # The problem is that on AKS (possibly on other K8s substrates) - # we have issues with scaling `dummy-source` and `dummy-sink` apps to zero. - # The current workaround is to remove these apps with `--force` flag - echo "Remove applications with --force flag" - juju remove-application dummy-source --force --no-wait - juju remove-application dummy-sink --force --no-wait } test_deploy_aks_charms() { From 6dacc089bcb2598bbc7586b185aa84371a7cdc14 Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Tue, 28 Nov 2023 16:43:46 +0000 Subject: [PATCH 44/50] Removes aws s3 dependency on api client Removes the dependency on the worker type, which then brings in the aws-sdk. By providing our own interface we can then remove that hardcoded dependency on the aws library. --- api/client/charms/downloader_s3.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/api/client/charms/downloader_s3.go b/api/client/charms/downloader_s3.go index 4e27bda92c4..6444e970a1c 100644 --- a/api/client/charms/downloader_s3.go +++ b/api/client/charms/downloader_s3.go @@ -12,15 +12,21 @@ import ( "github.com/juju/juju/api/base" "github.com/juju/juju/downloader" - "github.com/juju/juju/worker/s3caller" ) +// ObjectGetter defines a way to get objects from a bucket. +type ObjectGetter interface { + // GetObject returns an io.ReadCloser for the specified object within the + // specified bucket. + GetObject(ctx context.Context, bucketName, objectName string) (io.ReadCloser, error) +} + // NewS3CharmDownloader returns a new charm downloader that wraps a s3Caller // client for the provided endpoint. -func NewS3CharmDownloader(s3Session s3caller.Session, apiCaller base.APICaller) *downloader.Downloader { +func NewS3CharmDownloader(objectGetter ObjectGetter, apiCaller base.APICaller) *downloader.Downloader { dlr := &downloader.Downloader{ OpenBlob: func(req downloader.Request) (io.ReadCloser, error) { - streamer := NewS3CharmOpener(s3Session, apiCaller) + streamer := NewS3CharmOpener(objectGetter, apiCaller) reader, err := streamer.OpenCharm(req) if err != nil { return nil, errors.Trace(err) @@ -37,9 +43,9 @@ type S3CharmOpener interface { } type s3charmOpener struct { - ctx context.Context - s3Session s3caller.Session - apiCaller base.APICaller + ctx context.Context + objectGetter ObjectGetter + apiCaller base.APICaller } func (s *s3charmOpener) OpenCharm(req downloader.Request) (io.ReadCloser, error) { @@ -60,14 +66,14 @@ func (s *s3charmOpener) OpenCharm(req downloader.Request) (io.ReadCloser, error) bucket := "model-" + modelTag.Id() object := "charms/" + curl.Name + "-" + shortSha256 - return s.s3Session.GetObject(s.ctx, bucket, object) + return s.objectGetter.GetObject(s.ctx, bucket, object) } // NewS3CharmOpener returns a charm opener for the specified s3Caller. -func NewS3CharmOpener(s3Session s3caller.Session, apiCaller base.APICaller) S3CharmOpener { +func NewS3CharmOpener(objectGetter ObjectGetter, apiCaller base.APICaller) S3CharmOpener { return &s3charmOpener{ - ctx: context.Background(), - s3Session: s3Session, - apiCaller: apiCaller, + ctx: context.Background(), + objectGetter: objectGetter, + apiCaller: apiCaller, } } From 919f657e73b36123d099a4603840720314df7622 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Wed, 29 Nov 2023 12:42:51 +1000 Subject: [PATCH 45/50] Revert to older aws sdk since the new one breaks s3 --- go.mod | 30 +++++++++++----------- go.sum | 78 ++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index ff61c3cae34..9b633efaff2 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 github.com/EvilSuperstars/go-cidrman v0.0.0-20170211231153-4e5a4a63d9b7 - github.com/aws/aws-sdk-go-v2 v1.23.1 - github.com/aws/aws-sdk-go-v2/config v1.25.5 - github.com/aws/aws-sdk-go-v2/credentials v1.16.4 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 - github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 - github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 + github.com/aws/aws-sdk-go-v2 v1.21.0 + github.com/aws/aws-sdk-go-v2/config v1.18.35 + github.com/aws/aws-sdk-go-v2/credentials v1.13.35 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0 + github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2 + github.com/aws/aws-sdk-go-v2/service/iam v1.22.2 github.com/aws/aws-sdk-go-v2/service/s3 v1.30.3 github.com/aws/smithy-go v1.17.0 github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac @@ -143,18 +143,18 @@ require ( github.com/armon/go-metrics v0.4.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.20 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/canonical/go-flags v0.0.0-20230403090104-105d09a091b8 // indirect github.com/canonical/x-go v0.0.0-20230522092633-7947a7587f5b // indirect diff --git a/go.sum b/go.sum index 1e9ca3a82d4..b9063c8adc8 100644 --- a/go.sum +++ b/go.sum @@ -153,51 +153,69 @@ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2 v1.23.1 h1:qXaFsOOMA+HsZtX8WoCa+gJnbyW7qyFFBlPqvTSzbaI= -github.com/aws/aws-sdk-go-v2 v1.23.1/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA= +github.com/aws/aws-sdk-go-v2 v1.20.1/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac= +github.com/aws/aws-sdk-go-v2 v1.20.2/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac= +github.com/aws/aws-sdk-go-v2 v1.20.3/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= +github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= +github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= -github.com/aws/aws-sdk-go-v2/config v1.25.5 h1:UGKm9hpQS2hoK8CEJ1BzAW8NbUpvwDJJ4lyqXSzu8bk= -github.com/aws/aws-sdk-go-v2/config v1.25.5/go.mod h1:Bf4gDvy4ZcFIK0rqDu1wp9wrubNba2DojiPB2rt6nvI= -github.com/aws/aws-sdk-go-v2/credentials v1.16.4 h1:i7UQYYDSJrtc30RSwJwfBKwLFNnBTiICqAJ0pPdum8E= -github.com/aws/aws-sdk-go-v2/credentials v1.16.4/go.mod h1:Kdh/okh+//vQ/AjEt81CjvkTo64+/zIE4OewP7RpfXk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 h1:KehRNiVzIfAcj6gw98zotVbb/K67taJE0fkfgM6vzqU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5/go.mod h1:VhnExhw6uXy9QzetvpXDolo1/hjhx4u9qukBGkuUwjs= +github.com/aws/aws-sdk-go-v2/config v1.18.35 h1:uU9rgCzrW/pVRUUlRULiwKQe8RoEDst1NQu4Qo8kOtk= +github.com/aws/aws-sdk-go-v2/config v1.18.35/go.mod h1:7xF1yr9GBMfYRQI4PLHO8iceqKLM6DpGVEvXI38HB/A= +github.com/aws/aws-sdk-go-v2/credentials v1.13.34/go.mod h1:+wgdxCGNulHme6kTMZuDL9KOagLPloemoYkfjpQkSEU= +github.com/aws/aws-sdk-go-v2/credentials v1.13.35 h1:QpsNitYJu0GgvMBLUIYu9H4yryA5kMksjeIVQfgXrt8= +github.com/aws/aws-sdk-go-v2/credentials v1.13.35/go.mod h1:o7rCaLtvK0hUggAGclf76mNGGkaG5a9KWlp+d9IpcV8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.10/go.mod h1:wMsSLVM2hRpDVhd+3dtLUzqwm7/fjuhNN+b1aOLDt6g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 h1:LAm3Ycm9HJfbSCd5I+wqC2S9Ej7FPrgr5CQoOljJZcE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4/go.mod h1:xEhvbJcyUf/31yfGSQBe01fukXwXJ0gxDp7rLfymWE0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38/go.mod h1:qggunOChCMu9ZF/UkAfhTz25+U2rLVb3ya0Ua6TTfCA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.39/go.mod h1:OLmjwglQh90dCcFJDGD+T44G0ToLH+696kRwRhS1KOU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.40/go.mod h1:5kKmFhLeOVy6pwPDpDNA6/hK/d6URC98pqDDqHgdBx4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22/go.mod h1:EqK7gVrIGAHyZItrD1D8B0ilgwMD1GiWAmbU4u/JHNk= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 h1:4GV0kKZzUxiWxSVpn/9gwR0g21NF1Jsyduzo9rHgC/Q= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4/go.mod h1:dYvTNAggxDZy6y1AF7YDwXsPuHFy/VNEpEI/2dWK9IU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32/go.mod h1:0ZXSqrty4FtQ7p8TEuRde/SZm9X05KT18LAUlR40Ln0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.33/go.mod h1:S/zgOphghZAIvrbtvsVycoOncfqh1Hc4uGDIHqDLwTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.34/go.mod h1:RZP0scceAyhMIQ9JvFp7HvkpcgqjL4l/4C+7RAeGbuM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.41/go.mod h1:mKxUXW+TuwpCKKHVlmHGVVuBi9y9LKW8AiQodg23M5E= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 h1:GPUcE/Yq7Ur8YSUk6lVkoIMWnJNO0HT18GUzCWCgCI0= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.20 h1:YIvKIfPXQVp0EhXUV644kmQo6cQPPSRmC44A1HSoJeg= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.20/go.mod h1:8W88sW3PjamQpKFUQvHWWKay6ARsNvZnzU7+a4apubw= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 h1:J/N4ydefXQZIwKBDPtvrhxrIuP/vaaYKnAsy3bKVIvU= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1/go.mod h1:hrBzQzlQQRmiaeYRQPr0SdSx6fdqP+5YcGhb97LCt8M= -github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 h1:YbmdI0hfIhr/7oxjKLI23bYXlFerABZfHnfX3mQATsM= -github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1/go.mod h1:l9cQba3Vzc7ftueGCezlMb0bBwow7Va0ZMZfmk0qNYQ= -github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 h1:rHgJTYLKwLcZ9/k8CVWJuhdApnb3cdjoQeLvKa6bAcU= -github.com/aws/aws-sdk-go-v2/service/iam v1.27.3/go.mod h1:LklzfZoa7bL/NdhOzoaRtqSLGhu5j+GqE/9WoOQGFKY= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0 h1:r6pW/VOm8ea4GDEmwDwN2IkgYmu8JjcYzYvHJRs5sEw= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0/go.mod h1:UAWT8Tspir6mGp9WKvKWALaMkPgX1gnkSYZb5oo18XI= +github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2 h1:w0gKerNa4omzguFtH0bkX+lXjUvwoXNdBcmWvFwd7E4= +github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2/go.mod h1:jcU1u1nvnJhPCqNk9ZOJmFEkKJsbRw5oYEYHH4sfOAQ= +github.com/aws/aws-sdk-go-v2/service/iam v1.22.2 h1:DPFxx/6Zwes/MiadlDteVqDKov7yQ5v9vuwfhZuJm1s= +github.com/aws/aws-sdk-go-v2/service/iam v1.22.2/go.mod h1:cQTMNdo/Z5t1DDRsUnx0a2j6cPnytMBidUYZw2zks28= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23 h1:c5+bNdV8E4fIPteWx4HZSkqI07oY9exbfQ7JH7Yx4PI= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.23/go.mod h1:1jcUfF+FAOEwtIcNiHPaV4TSoZqkUIPzrohmD7fb95c= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22/go.mod h1:xt0Au8yPIwYXf/GYPy/vl4K3CgwhfQMYbrH7DlUUIws= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 h1:rdovz3rEu0vZKbzoMYPTehp0E8veoE9AyfzqCr5Eeao= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4/go.mod h1:aYCGNjyUCUelhofxlZyj63srdxWUSsBSGg5l6MCuXuE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.33/go.mod h1:kcNtzCcEoflp+6e2CDTmm2h3xQGZOBZqYA/8DhYx/S8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.34/go.mod h1:ytsF+t+FApY2lFnN51fJKPhH6ICKOPXKEcwwgmJEdWI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22 h1:ISLJ2BKXe4zzyZ7mp5ewKECiw0U7KpLgS3S6OxY9Cm0= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22/go.mod h1:QFVbqK54XArazLvn2wvWMRBi/jGrWii46qbr5DyPGjc= github.com/aws/aws-sdk-go-v2/service/s3 v1.30.3 h1:PVieHTwugdlHedlxLpYLQsOZAq736RScuEb/m4zhzc4= github.com/aws/aws-sdk-go-v2/service/s3 v1.30.3/go.mod h1:XN3YcdmnWYZ3Hrnojvo5p2mc/wfF973nkq3ClXPDMHk= -github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 h1:CdsSOGlFF3Pn+koXOIpTtvX7st0IuGsZ8kJqcWMlX54= -github.com/aws/aws-sdk-go-v2/service/sso v1.17.3/go.mod h1:oA6VjNsLll2eVuUoF2D+CMyORgNzPEW/3PyUdq6WQjI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 h1:cbRqFTVnJV+KRpwFl76GJdIZJKKCdTPnjUZ7uWh3pIU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1/go.mod h1:hHL974p5auvXlZPIjJTblXJpbkfK4klBczlsEaMCGVY= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 h1:yEvZ4neOQ/KpUqyR+X0ycUTW/kVRNR4nDZ38wStHGAA= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.4/go.mod h1:feTnm2Tk/pJxdX+eooEsxvlvTWBvDm6CasRZ+JOs2IY= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.4/go.mod h1:FP05hDXTLouXwAMQ1swqybHy7tHySblMkBMKSumaKg0= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 h1:oCvTFSDi67AX0pOX3PuPdGFewvLRU2zzFSrTsgURNo0= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.5/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.4/go.mod h1:4pdlNASc29u0j9bq2jIQcBghG5Lx2oQAIj91vo1u1t8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 h1:dnInJb4S0oy8aQuri1mV6ipLlnZPfnsDNB9BGO9PDNY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.4/go.mod h1:CQRMCzYvl5eeAQW3AWkRLS+zGGXCucBnsiQlrs+tCeo= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvTZW2S44Lt9Mk2aYQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI= github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= From 11430d0e42a01d07b803482a2f77e697bf5d732d Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Wed, 29 Nov 2023 12:50:00 +1000 Subject: [PATCH 46/50] Revert to using AWS SDK dependency versions from before last change --- go.mod | 29 +++++++++++----------- go.sum | 77 +++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index 81c76075c1f..440f8bee2ea 100644 --- a/go.mod +++ b/go.mod @@ -16,12 +16,12 @@ require ( github.com/EvilSuperstars/go-cidrman v0.0.0-20170211231153-4e5a4a63d9b7 github.com/altoros/gosigma v0.0.0-20150408145232-31228935eec6 github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 - github.com/aws/aws-sdk-go-v2 v1.23.1 - github.com/aws/aws-sdk-go-v2/config v1.25.5 - github.com/aws/aws-sdk-go-v2/credentials v1.16.4 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 - github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 - github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 + github.com/aws/aws-sdk-go-v2 v1.21.0 + github.com/aws/aws-sdk-go-v2/config v1.18.35 + github.com/aws/aws-sdk-go-v2/credentials v1.13.35 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0 + github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2 + github.com/aws/aws-sdk-go-v2/service/iam v1.22.2 github.com/aws/smithy-go v1.17.0 github.com/bmizerany/pat v0.0.0-20160217103242-c068ca2f0aac github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0 @@ -139,15 +139,14 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.41 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/canonical/x-go v0.0.0-20230113154138-0ccdb0b57a43 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/go.sum b/go.sum index 636894939be..70a05940c72 100644 --- a/go.sum +++ b/go.sum @@ -97,36 +97,52 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go-v2 v1.23.1 h1:qXaFsOOMA+HsZtX8WoCa+gJnbyW7qyFFBlPqvTSzbaI= -github.com/aws/aws-sdk-go-v2 v1.23.1/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA= -github.com/aws/aws-sdk-go-v2/config v1.25.5 h1:UGKm9hpQS2hoK8CEJ1BzAW8NbUpvwDJJ4lyqXSzu8bk= -github.com/aws/aws-sdk-go-v2/config v1.25.5/go.mod h1:Bf4gDvy4ZcFIK0rqDu1wp9wrubNba2DojiPB2rt6nvI= -github.com/aws/aws-sdk-go-v2/credentials v1.16.4 h1:i7UQYYDSJrtc30RSwJwfBKwLFNnBTiICqAJ0pPdum8E= -github.com/aws/aws-sdk-go-v2/credentials v1.16.4/go.mod h1:Kdh/okh+//vQ/AjEt81CjvkTo64+/zIE4OewP7RpfXk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 h1:KehRNiVzIfAcj6gw98zotVbb/K67taJE0fkfgM6vzqU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5/go.mod h1:VhnExhw6uXy9QzetvpXDolo1/hjhx4u9qukBGkuUwjs= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 h1:LAm3Ycm9HJfbSCd5I+wqC2S9Ej7FPrgr5CQoOljJZcE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4/go.mod h1:xEhvbJcyUf/31yfGSQBe01fukXwXJ0gxDp7rLfymWE0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 h1:4GV0kKZzUxiWxSVpn/9gwR0g21NF1Jsyduzo9rHgC/Q= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4/go.mod h1:dYvTNAggxDZy6y1AF7YDwXsPuHFy/VNEpEI/2dWK9IU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1 h1:J/N4ydefXQZIwKBDPtvrhxrIuP/vaaYKnAsy3bKVIvU= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.137.1/go.mod h1:hrBzQzlQQRmiaeYRQPr0SdSx6fdqP+5YcGhb97LCt8M= -github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1 h1:YbmdI0hfIhr/7oxjKLI23bYXlFerABZfHnfX3mQATsM= -github.com/aws/aws-sdk-go-v2/service/ecr v1.23.1/go.mod h1:l9cQba3Vzc7ftueGCezlMb0bBwow7Va0ZMZfmk0qNYQ= -github.com/aws/aws-sdk-go-v2/service/iam v1.27.3 h1:rHgJTYLKwLcZ9/k8CVWJuhdApnb3cdjoQeLvKa6bAcU= -github.com/aws/aws-sdk-go-v2/service/iam v1.27.3/go.mod h1:LklzfZoa7bL/NdhOzoaRtqSLGhu5j+GqE/9WoOQGFKY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 h1:rpkF4n0CyFcrJUG/rNNohoTmhtWlFTRI4BsZOh9PvLs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 h1:rdovz3rEu0vZKbzoMYPTehp0E8veoE9AyfzqCr5Eeao= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4/go.mod h1:aYCGNjyUCUelhofxlZyj63srdxWUSsBSGg5l6MCuXuE= -github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 h1:CdsSOGlFF3Pn+koXOIpTtvX7st0IuGsZ8kJqcWMlX54= -github.com/aws/aws-sdk-go-v2/service/sso v1.17.3/go.mod h1:oA6VjNsLll2eVuUoF2D+CMyORgNzPEW/3PyUdq6WQjI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 h1:cbRqFTVnJV+KRpwFl76GJdIZJKKCdTPnjUZ7uWh3pIU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1/go.mod h1:hHL974p5auvXlZPIjJTblXJpbkfK4klBczlsEaMCGVY= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 h1:yEvZ4neOQ/KpUqyR+X0ycUTW/kVRNR4nDZ38wStHGAA= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.4/go.mod h1:feTnm2Tk/pJxdX+eooEsxvlvTWBvDm6CasRZ+JOs2IY= +github.com/aws/aws-sdk-go-v2 v1.20.1/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac= +github.com/aws/aws-sdk-go-v2 v1.20.2/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac= +github.com/aws/aws-sdk-go-v2 v1.20.3/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= +github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= +github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= +github.com/aws/aws-sdk-go-v2/config v1.18.35 h1:uU9rgCzrW/pVRUUlRULiwKQe8RoEDst1NQu4Qo8kOtk= +github.com/aws/aws-sdk-go-v2/config v1.18.35/go.mod h1:7xF1yr9GBMfYRQI4PLHO8iceqKLM6DpGVEvXI38HB/A= +github.com/aws/aws-sdk-go-v2/credentials v1.13.34/go.mod h1:+wgdxCGNulHme6kTMZuDL9KOagLPloemoYkfjpQkSEU= +github.com/aws/aws-sdk-go-v2/credentials v1.13.35 h1:QpsNitYJu0GgvMBLUIYu9H4yryA5kMksjeIVQfgXrt8= +github.com/aws/aws-sdk-go-v2/credentials v1.13.35/go.mod h1:o7rCaLtvK0hUggAGclf76mNGGkaG5a9KWlp+d9IpcV8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.10/go.mod h1:wMsSLVM2hRpDVhd+3dtLUzqwm7/fjuhNN+b1aOLDt6g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38/go.mod h1:qggunOChCMu9ZF/UkAfhTz25+U2rLVb3ya0Ua6TTfCA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.39/go.mod h1:OLmjwglQh90dCcFJDGD+T44G0ToLH+696kRwRhS1KOU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.40/go.mod h1:5kKmFhLeOVy6pwPDpDNA6/hK/d6URC98pqDDqHgdBx4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32/go.mod h1:0ZXSqrty4FtQ7p8TEuRde/SZm9X05KT18LAUlR40Ln0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.33/go.mod h1:S/zgOphghZAIvrbtvsVycoOncfqh1Hc4uGDIHqDLwTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.34/go.mod h1:RZP0scceAyhMIQ9JvFp7HvkpcgqjL4l/4C+7RAeGbuM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.41 h1:EcSFdpLdkF3FWizimox0qYLuorn9e4PNMR27mvshGLs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.41/go.mod h1:mKxUXW+TuwpCKKHVlmHGVVuBi9y9LKW8AiQodg23M5E= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0 h1:r6pW/VOm8ea4GDEmwDwN2IkgYmu8JjcYzYvHJRs5sEw= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.113.0/go.mod h1:UAWT8Tspir6mGp9WKvKWALaMkPgX1gnkSYZb5oo18XI= +github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2 h1:w0gKerNa4omzguFtH0bkX+lXjUvwoXNdBcmWvFwd7E4= +github.com/aws/aws-sdk-go-v2/service/ecr v1.19.2/go.mod h1:jcU1u1nvnJhPCqNk9ZOJmFEkKJsbRw5oYEYHH4sfOAQ= +github.com/aws/aws-sdk-go-v2/service/iam v1.22.2 h1:DPFxx/6Zwes/MiadlDteVqDKov7yQ5v9vuwfhZuJm1s= +github.com/aws/aws-sdk-go-v2/service/iam v1.22.2/go.mod h1:cQTMNdo/Z5t1DDRsUnx0a2j6cPnytMBidUYZw2zks28= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.33/go.mod h1:kcNtzCcEoflp+6e2CDTmm2h3xQGZOBZqYA/8DhYx/S8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.34/go.mod h1:ytsF+t+FApY2lFnN51fJKPhH6ICKOPXKEcwwgmJEdWI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.4/go.mod h1:FP05hDXTLouXwAMQ1swqybHy7tHySblMkBMKSumaKg0= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.5 h1:oCvTFSDi67AX0pOX3PuPdGFewvLRU2zzFSrTsgURNo0= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.5/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.4/go.mod h1:4pdlNASc29u0j9bq2jIQcBghG5Lx2oQAIj91vo1u1t8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5 h1:dnInJb4S0oy8aQuri1mV6ipLlnZPfnsDNB9BGO9PDNY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.5/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.4/go.mod h1:CQRMCzYvl5eeAQW3AWkRLS+zGGXCucBnsiQlrs+tCeo= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvTZW2S44Lt9Mk2aYQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU= +github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI= github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -320,6 +336,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= From 6a8d967c43ca617b1a99b12a91294de0d60280ee Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Wed, 29 Nov 2023 08:52:01 +0000 Subject: [PATCH 47/50] Update go.sum to include latest OTEL libraries --- go.sum | 3 --- 1 file changed, 3 deletions(-) diff --git a/go.sum b/go.sum index a2cbb3a0af2..8670f052dd4 100644 --- a/go.sum +++ b/go.sum @@ -1424,15 +1424,12 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= From 0069467e1c9c01c42ba1fc752944865745946fec Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Wed, 29 Nov 2023 09:13:08 +0000 Subject: [PATCH 48/50] Upgrade to the latest OTEL Unfortunately OTEL decided to use an embedded interface with a lower case method to ensure that you only used their spans. This is silly. I've migrated from Jaeger to opentracing and now to OTEL. Each with a different set of interfaces. Instead we have our own managed span that abstracts this sillyness away. The solution was to just copy their span interface minus the embedded interface and return that from a shim type. --- worker/trace/client.go | 168 +++++++++++++++++++++++++++++++ worker/trace/package_test.go | 2 +- worker/trace/tracer.go | 86 +--------------- worker/trace/tracer_mock_test.go | 6 +- 4 files changed, 175 insertions(+), 87 deletions(-) create mode 100644 worker/trace/client.go diff --git a/worker/trace/client.go b/worker/trace/client.go new file mode 100644 index 00000000000..b7187b4a54e --- /dev/null +++ b/worker/trace/client.go @@ -0,0 +1,168 @@ +// Copyright 2023 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package trace + +import ( + "context" + + "github.com/juju/errors" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.20.0" + "go.opentelemetry.io/otel/trace" + + coretrace "github.com/juju/juju/core/trace" + "github.com/juju/juju/version" +) + +// This file solely exists so that we do not tie ourselves to OTEL directly +// into Juju. This allows us to swap out the tracing implementation in the +// future if we need to. I've retooled a codebase from Jaeger to opentracing +// and this lesson was learned the hard way. + +// Client manages connections to the collector, handles the +// transformation of data into wire format, and the transmission of that +// data to the collector. +type Client interface { + // Start should establish connection(s) to endpoint(s). It is + // called just once by the exporter, so the implementation + // does not need to worry about idempotence and locking. + Start(ctx context.Context) error + + // Stop should close the connections. The function is called + // only once by the exporter, so the implementation does not + // need to worry about idempotence, but it may be called + // concurrently with UploadTraces, so proper + // locking is required. The function serves as a + // synchronization point - after the function returns, the + // process of closing connections is assumed to be finished. + Stop(ctx context.Context) error +} + +// ClientSpan is directly equivalent to the opentelemetry Span interface, minus +// the embedded interface. +type ClientSpan interface { + // End completes the Span. The Span is considered complete and ready to be + // delivered through the rest of the telemetry pipeline after this method + // is called. Therefore, updates to the Span are not allowed after this + // method has been called. + End(options ...trace.SpanEndOption) + + // AddEvent adds an event with the provided name and options. + AddEvent(name string, options ...trace.EventOption) + + // IsRecording returns the recording state of the Span. It will return + // true if the Span is active and events can be recorded. + IsRecording() bool + + // RecordError will record err as an exception span event for this span. An + // additional call to SetStatus is required if the Status of the Span should + // be set to Error, as this method does not change the Span status. If this + // span is not being recorded or err is nil then this method does nothing. + RecordError(err error, options ...trace.EventOption) + + // SpanContext returns the SpanContext of the Span. The returned SpanContext + // is usable even after the End method has been called for the Span. + SpanContext() trace.SpanContext + + // SetStatus sets the status of the Span in the form of a code and a + // description, provided the status hasn't already been set to a higher + // value before (OK > Error > Unset). The description is only included in a + // status when the code is for an error. + SetStatus(code codes.Code, description string) + + // SetName sets the Span name. + SetName(name string) + + // SetAttributes sets kv as attributes of the Span. If a key from kv + // already exists for an attribute of the Span it will be overwritten with + // the value contained in kv. + SetAttributes(kv ...attribute.KeyValue) + + // TracerProvider returns a TracerProvider that can be used to generate + // additional Spans on the same telemetry pipeline as the current Span. + TracerProvider() trace.TracerProvider +} + +// Tracer is the creator of Spans. +type ClientTracer interface { + // Start creates a span and a context.Context containing the newly-created span. + // + // If the context.Context provided in `ctx` contains a Span then the newly-created + // Span will be a child of that span, otherwise it will be a root span. This behavior + // can be overridden by providing `WithNewRoot()` as a SpanOption, causing the + // newly-created Span to be a root span even if `ctx` contains a Span. + // + // When creating a Span it is recommended to provide all known span attributes using + // the `WithAttributes()` SpanOption as samplers will only have access to the + // attributes provided when a Span is created. + // + // Any Span that is created MUST also be ended. This is the responsibility of the user. + // Implementations of this API may leak memory or other resources if Spans are not ended. + Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption) (context.Context, ClientSpan) +} + +// ClientTracerProvider is the interface for a tracer provider. +type ClientTracerProvider interface { + ForceFlush(ctx context.Context) error + Shutdown(ctx context.Context) error +} + +// NewClient returns a new tracing client. +func NewClient(ctx context.Context, namespace coretrace.TaggedTracerNamespace, endpoint string, insecureSkipVerify bool, sampleRatio float64) (Client, ClientTracerProvider, ClientTracer, error) { + options := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(endpoint), + } + if insecureSkipVerify { + options = append(options, otlptracegrpc.WithInsecure()) + } + + client := otlptracegrpc.NewClient(options...) + exporter, err := otlptrace.New(ctx, client) + if err != nil { + return nil, nil, nil, errors.Trace(err) + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.TraceIDRatioBased(sampleRatio)), + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(newResource(namespace.ServiceName())), + ) + return client, tp, clientSpanShim{tp.Tracer(namespace.String())}, nil +} + +// clientSpanShim exists to mask out the embedded interface within the +// trace.Span +type clientSpanShim struct { + tracer trace.Tracer +} + +// Start creates a span and a context.Context containing the newly-created span. +// +// If the context.Context provided in `ctx` contains a Span then the newly-created +// Span will be a child of that span, otherwise it will be a root span. This behavior +// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the +// newly-created Span to be a root span even if `ctx` contains a Span. +// +// When creating a Span it is recommended to provide all known span attributes using +// the `WithAttributes()` SpanOption as samplers will only have access to the +// attributes provided when a Span is created. +// +// Any Span that is created MUST also be ended. This is the responsibility of the user. +// Implementations of this API may leak memory or other resources if Spans are not ended. +func (s clientSpanShim) Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption) (context.Context, ClientSpan) { + return s.tracer.Start(ctx, spanName, opts...) +} + +func newResource(serviceName string) *resource.Resource { + return resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName(serviceName), + semconv.ServiceVersion(version.Current.String()), + ) +} diff --git a/worker/trace/package_test.go b/worker/trace/package_test.go index 4e432f6cc4a..db9b786fc62 100644 --- a/worker/trace/package_test.go +++ b/worker/trace/package_test.go @@ -76,7 +76,7 @@ func (s *baseSuite) expectClient() { s.client.EXPECT().Start(gomock.Any()).AnyTimes() s.client.EXPECT().Stop(gomock.Any()).AnyTimes() - s.clientTracer.EXPECT().Start(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { + s.clientTracer.EXPECT().Start(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, ClientSpan) { return ctx, s.span }).AnyTimes() diff --git a/worker/trace/tracer.go b/worker/trace/tracer.go index cf278539558..12159192f5e 100644 --- a/worker/trace/tracer.go +++ b/worker/trace/tracer.go @@ -10,61 +10,12 @@ import ( "github.com/juju/errors" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.20.0" "go.opentelemetry.io/otel/trace" "gopkg.in/tomb.v2" coretrace "github.com/juju/juju/core/trace" - "github.com/juju/juju/version" ) -// Client manages connections to the collector, handles the -// transformation of data into wire format, and the transmission of that -// data to the collector. -type Client interface { - // Start should establish connection(s) to endpoint(s). It is - // called just once by the exporter, so the implementation - // does not need to worry about idempotence and locking. - Start(ctx context.Context) error - - // Stop should close the connections. The function is called - // only once by the exporter, so the implementation does not - // need to worry about idempotence, but it may be called - // concurrently with UploadTraces, so proper - // locking is required. The function serves as a - // synchronization point - after the function returns, the - // process of closing connections is assumed to be finished. - Stop(ctx context.Context) error -} - -// Tracer is the creator of Spans. -type ClientTracer interface { - // Start creates a span and a context.Context containing the newly-created span. - // - // If the context.Context provided in `ctx` contains a Span then the newly-created - // Span will be a child of that span, otherwise it will be a root span. This behavior - // can be overridden by providing `WithNewRoot()` as a SpanOption, causing the - // newly-created Span to be a root span even if `ctx` contains a Span. - // - // When creating a Span it is recommended to provide all known span attributes using - // the `WithAttributes()` SpanOption as samplers will only have access to the - // attributes provided when a Span is created. - // - // Any Span that is created MUST also be ended. This is the responsibility of the user. - // Implementations of this API may leak memory or other resources if Spans are not ended. - Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption) (context.Context, trace.Span) -} - -// ClientTracerProvider is the interface for a tracer provider. -type ClientTracerProvider interface { - ForceFlush(ctx context.Context) error - Shutdown(ctx context.Context) error -} - // NewClientFunc is the function signature for creating a new client. type NewClientFunc func(context.Context, coretrace.TaggedTracerNamespace, string, bool, float64) (Client, ClientTracerProvider, ClientTracer, error) @@ -131,7 +82,7 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...coretrace.Optio // they also die at the same time as the worker. var ( cancel context.CancelFunc - span trace.Span + span ClientSpan ) ctx = t.buildRequestContext(ctx) ctx, cancel = t.scopedContext(ctx) @@ -245,39 +196,8 @@ func (t *tracer) buildRequestContext(ctx context.Context) context.Context { return trace.ContextWithRemoteSpanContext(ctx, sc) } -// NewClient returns a new tracing client. -func NewClient(ctx context.Context, namespace coretrace.TaggedTracerNamespace, endpoint string, insecureSkipVerify bool, sampleRatio float64) (Client, ClientTracerProvider, ClientTracer, error) { - options := []otlptracegrpc.Option{ - otlptracegrpc.WithEndpoint(endpoint), - } - if insecureSkipVerify { - options = append(options, otlptracegrpc.WithInsecure()) - } - - client := otlptracegrpc.NewClient(options...) - exporter, err := otlptrace.New(ctx, client) - if err != nil { - return nil, nil, nil, errors.Trace(err) - } - - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.TraceIDRatioBased(sampleRatio)), - sdktrace.WithBatcher(exporter), - sdktrace.WithResource(newResource(namespace.ServiceName())), - ) - return client, tp, tp.Tracer(namespace.String()), nil -} - -func newResource(serviceName string) *resource.Resource { - return resource.NewWithAttributes( - semconv.SchemaURL, - semconv.ServiceName(serviceName), - semconv.ServiceVersion(version.Current.String()), - ) -} - type managedSpan struct { - span trace.Span + span ClientSpan cancel context.CancelFunc scope coretrace.Scope stackTracesEnabled bool @@ -324,7 +244,7 @@ func (s *managedSpan) End(attrs ...coretrace.Attribute) { } type managedScope struct { - span trace.Span + span ClientSpan } // TraceID returns the trace ID of the span. diff --git a/worker/trace/tracer_mock_test.go b/worker/trace/tracer_mock_test.go index e79c29e458a..118ca02433c 100644 --- a/worker/trace/tracer_mock_test.go +++ b/worker/trace/tracer_mock_test.go @@ -9,7 +9,7 @@ import ( reflect "reflect" trace "github.com/juju/juju/core/trace" - trace0 "go.opentelemetry.io/otel/trace" + trace1 "go.opentelemetry.io/otel/trace" gomock "go.uber.org/mock/gomock" ) @@ -171,7 +171,7 @@ func (m *MockClientTracer) EXPECT() *MockClientTracerMockRecorder { } // Start mocks base method. -func (m *MockClientTracer) Start(arg0 context.Context, arg1 string, arg2 ...trace0.SpanStartOption) (context.Context, trace0.Span) { +func (m *MockClientTracer) Start(arg0 context.Context, arg1 string, arg2 ...trace1.SpanStartOption) (context.Context, ClientSpan) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1} for _, a := range arg2 { @@ -179,7 +179,7 @@ func (m *MockClientTracer) Start(arg0 context.Context, arg1 string, arg2 ...trac } ret := m.ctrl.Call(m, "Start", varargs...) ret0, _ := ret[0].(context.Context) - ret1, _ := ret[1].(trace0.Span) + ret1, _ := ret[1].(ClientSpan) return ret0, ret1 } From 06b2faa2db5e5c71c31fb2423b43677c0f6900ee Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Wed, 29 Nov 2023 09:55:16 +0000 Subject: [PATCH 49/50] Fix the tests for migration target Ensure that we test the slice rather than the integer. This is ensures we can view it as a sliding window. --- api/package_test.go | 1 + .../migrationtarget/migrationtarget_test.go | 5 ++-- .../controller/migrationtarget/register.go | 3 ++- apiserver/facadeversions_test.go | 26 +++++++++---------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/api/package_test.go b/api/package_test.go index f13141ffa27..b84f687fb1a 100644 --- a/api/package_test.go +++ b/api/package_test.go @@ -28,6 +28,7 @@ func (*ImportSuite) TestImports(c *gc.C) { "api/base", "api/watcher", "core/arch", + "core/backups", "core/base", "core/constraints", "core/database", diff --git a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go index eb87fe2fb75..363eada43c7 100644 --- a/apiserver/facades/controller/migrationtarget/migrationtarget_test.go +++ b/apiserver/facades/controller/migrationtarget/migrationtarget_test.go @@ -81,8 +81,9 @@ func (s *Suite) TestFacadeRegistered(c *gc.C) { c.Assert(err, jc.ErrorIsNil) api, err := aFactory(&facadetest.Context{ - State_: s.State, - Auth_: s.authorizer, + State_: s.State, + Auth_: s.authorizer, + ServiceFactory_: servicefactorytesting.NewTestingServiceFactory(), }) c.Assert(err, jc.ErrorIsNil) c.Assert(api, gc.FitsTypeOf, new(migrationtarget.API)) diff --git a/apiserver/facades/controller/migrationtarget/register.go b/apiserver/facades/controller/migrationtarget/register.go index 835e7322a94..45d7cf6d6ff 100644 --- a/apiserver/facades/controller/migrationtarget/register.go +++ b/apiserver/facades/controller/migrationtarget/register.go @@ -110,5 +110,6 @@ func newFacade(ctx facade.Context, facadeVersions facades.FacadeVersions) (*API, credentialcommon.CredentialInvalidatorGetter(ctx), stateenvirons.GetNewEnvironFunc(environs.New), stateenvirons.GetNewCAASBrokerFunc(caas.New), - facadeVersions) + facadeVersions, + ) } diff --git a/apiserver/facadeversions_test.go b/apiserver/facadeversions_test.go index 159f63afd25..95d1a61f15d 100644 --- a/apiserver/facadeversions_test.go +++ b/apiserver/facadeversions_test.go @@ -10,6 +10,7 @@ import ( "github.com/juju/juju/api" "github.com/juju/juju/apiserver" + "github.com/juju/juju/core/facades" coretesting "github.com/juju/juju/testing" ) @@ -52,24 +53,24 @@ func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) { c.Check(apiFacadeVersions, jc.DeepEquals, serverFacadeBestVersions) } -// TestClient3xSupport checks that the client facade supports the 3.x for -// certain tasks. You must be very careful when removing support for facades +// TestClientSupport checks that the client facade supports the 3.x and 4.x +// for certain tasks. You must be very careful when removing support for facades // as it can break model migrations, upgrades, and state reports. -func (s *facadeVersionSuite) TestClient3xSupport(c *gc.C) { +func (s *facadeVersionSuite) TestClientSupport(c *gc.C) { tests := []struct { facadeName string summary string - apiClientVersion int + apiClientVersion facades.FacadeVersion }{ { facadeName: "Client", summary: "Ensure that the Client facade supports 3.x for status requests", - apiClientVersion: 6, + apiClientVersion: []int{6}, }, { facadeName: "ModelManager", summary: "Ensure that the ModelManager facade supports 3.x for model migration and status requests", - apiClientVersion: 9, + apiClientVersion: []int{9}, }, } for _, test := range tests { @@ -88,18 +89,17 @@ var Contains gc.Checker = &containsChecker{ } func (checker *containsChecker) Check(params []interface{}, names []string) (result bool, err string) { - expected, ok := params[1].(int) + expected, ok := params[1].(facades.FacadeVersion) if !ok { - return false, "expected must be a string" + return false, "expected must be a int" } - obtained, ok := params[0].([]int) + obtained, ok := params[0].(facades.FacadeVersion) if ok { - for _, v := range obtained { - if v == expected { - return true, "" - } + if set.NewInts(expected...).Intersection(set.NewInts(obtained...)).Size() > 0 { + return true, "" } + return false, "" } From c0efa4ee1243438ac32f22dbad9b255e5f8d4976 Mon Sep 17 00:00:00 2001 From: Ian Booth Date: Thu, 30 Nov 2023 07:13:08 +1000 Subject: [PATCH 50/50] Remove some secrets tests that were accidentally included --- worker/uniter/runner/context/context_test.go | 28 -------------------- 1 file changed, 28 deletions(-) diff --git a/worker/uniter/runner/context/context_test.go b/worker/uniter/runner/context/context_test.go index 3739b289743..ff4749a7694 100644 --- a/worker/uniter/runner/context/context_test.go +++ b/worker/uniter/runner/context/context_test.go @@ -1254,34 +1254,6 @@ func (s *HookContextSuite) TestSecretGet(c *gc.C) { }) } -func (s *HookContextSuite) TestSecretGetOwnedSecretFailedBothURIAndLabel(c *gc.C) { - defer s.setupMocks(c).Finish() - - uri := coresecrets.NewURI() - hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) - context.SetEnvironmentHookContextSecret(hookContext, uri.String(), - map[string]jujuc.SecretMetadata{ - uri.ID: {Label: "label", Owner: s.mockUnit.Tag()}, - }, nil, nil) - - _, err := hookContext.GetSecret(uri, "label", false, false) - c.Assert(err, gc.ErrorMatches, `either URI or label should be used for getting an owned secret but not both`) -} - -func (s *HookContextSuite) TestSecretGetOwnedSecretFailedWithUpdate(c *gc.C) { - defer s.setupMocks(c).Finish() - - uri := coresecrets.NewURI() - hookContext := context.NewMockUnitHookContext(s.mockUnit, model.IAAS, s.mockLeadership) - context.SetEnvironmentHookContextSecret(hookContext, uri.String(), - map[string]jujuc.SecretMetadata{ - uri.ID: {Label: "label", Owner: s.mockUnit.Tag()}, - }, nil, nil) - - _, err := hookContext.GetSecret(nil, "label", true, false) - c.Assert(err, gc.ErrorMatches, `secret owner cannot use --refresh`) -} - func (s *HookContextSuite) assertSecretGetOwnedSecretURILookup( c *gc.C, patchContext func(*context.HookContext, *coresecrets.URI, string, api.SecretsAccessor, secrets.BackendsClient), ) {