Skip to content

Commit

Permalink
Merge pull request juju#13192 from ycliuhw/fix/lp-1935953
Browse files Browse the repository at this point in the history
juju#13192

This PR introduces non-dockerhub/private OCI registry support for:

- controller pods;
- model operators;
- application operators;
- charm container's base image in sidecar pods;

This PR currently enabled `basic` auth and `auth token` support.
The [v2 bear token](https://docs.docker.com/registry/spec/auth/token/) is still a `TODO` and will be added in the following PRs.

Note: this feature is currently hidden under featureflag: `private-registry`, but it's not testable without some hack because [this bug(it will be fixed soon)](https://bugs.launchpad.net/juju/+bug/1941055).

## Checklist

 - [ ] ~Requires a [pylibjuju](https://github.com/juju/python-libjuju) change~
 - [ ] ~Added [integration tests](https://github.com/juju/juju/tree/develop/tests) for the PR~
 - [ ] ~Added or updated [doc.go](https://discourse.jujucharms.com/t/readme-in-packages/451) related to packages changed~
 - [x] Comments answer the question of why design decisions were made

## QA steps

### private repo on non dockerhub
```console
$ cat tttt.json
{
 "serveraddress": "quay.io",
 "auth": "xxxxxx==",
 // "username": "a",
 // "password": "pwd",
 "repository": "quay.io/ycliuhw"
}

$ JUJU_DEV_FEATURE_FLAGS=private-registry juju bootstrap microk8s k1 --config "features=[private-registry]" --config caas-image-repo="'$(cat tttt.json)'"

$ mkubectl get all,pv,pvc,ing -o wide -ncontroller-k1
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/modeloperator-687cb75dd8-c5p8c 1/1 Running 0 2m51s 10.1.97.208 kelvinliu-m15-ryzen <none> <none>
pod/controller-0 2/2 Running 2 3m48s 10.1.97.207 kelvinliu-m15-ryzen <none> <none>

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/controller-service ClusterIP 10.152.183.22 <none> 17070/TCP 3m51s app.kubernetes.io/name=controller
service/modeloperator ClusterIP 10.152.183.161 <none> 17071/TCP 2m51s operator.juju.is/name=modeloperator,operator.juju.is/target=model

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/modeloperator 1/1 1 1 2m51s juju-operator quay.io/ycliuhw/jujud-operator:2.9.10.1 operator.juju.is/name=modeloperator,operator.juju.is/target=model

NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/modeloperator-687cb75dd8 1 1 1 2m51s juju-operator quay.io/ycliuhw/jujud-operator:2.9.10.1 operator.juju.is/name=modeloperator,operator.juju.is/target=model,pod-template-hash=687cb75dd8

NAME READY AGE CONTAINERS IMAGES
statefulset.apps/controller 1/1 3m48s mongodb,api-server quay.io/ycliuhw/juju-db:4.0,quay.io/ycliuhw/jujud-operator:2.9.10.1

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/pvc-30c9754b-9b51-4182-bb14-0ebca15a49f5 20Gi RWO Delete Bound controller-k1/storage-controller-0 microk8s-hostpath 3m48s Filesystem

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
persistentvolumeclaim/storage-controller-0 Bound pvc-30c9754b-9b51-4182-bb14-0ebca15a49f5 20Gi RWO microk8s-hostpath 3m48s Filesystem

$ juju add-model t1

$ juju deploy snappass-test

$ juju deploy cs:~juju/mariadb-k8s-3

$ mkubectl -ncontroller-k1 get pod/controller-0 -o json | jq .spec.imagePullSecrets
[
 {
 "name": "juju-image-pull-secret"
 }
]

$ mkubectl -ncontroller-k1 get secret/juju-image-pull-secret -o json | jq -r '.data[".dockerconfigjson"]' | base64 --decode | jq
{
 "auths": {
 "quay.io": {
 "auth": "xxxxxx==",
 "serveraddress": "quay.io"
 }
 }
}

$ mkubectl -nt1 get pods snappass-test-0 mariadb-k8s-operator-0 modeloperator-56b469cd6-n8dxp -o json |
 jq '.items[].spec.imagePullSecrets'
[
 {
 "name": "juju-image-pull-secret"
 }
]
[
 {
 "name": "juju-image-pull-secret"
 }
]
[
 {
 "name": "juju-image-pull-secret"
 }
]

$ mkubectl -nt1 get secret/juju-image-pull-secret -o json | jq -r '.data[".dockerconfigjson"]' | base64 --decode | jq
{
 "auths": {
 "quay.io": {
 "auth": "xxxxxx==",
 "serveraddress": "quay.io"
 }
 }
}

$ mkubectl -nt1 get pod/snappass-test-0 -o json | jq '.spec.containers[].image'
"quay.io/ycliuhw/charm-base:ubuntu-20.04"
"registry.hub.docker.com/library/redis@sha256:27bea08330830c6e5efc456075d66eb1fb4b76e5518947e8c87556adf1df3e51"
"registry.hub.docker.com/benhoyt/snappass-test@sha256:32506b5ac7bde75b7a76bee003cf8c77f30fc936f446c8c52d457b8fe6fce96f"

$ mkubectl -nt1 get pod/mariadb-k8s-operator-0 -o json | jq '.spec.containers[].image'
"quay.io/ycliuhw/jujud-operator:2.9.10"

$ mkubectl -nt1 get pod/modeloperator-56b469cd6-n8dxp -o json | jq '.spec.containers[].image'
"quay.io/ycliuhw/jujud-operator:2.9.10"

$ mkubectl -ncontroller-k1 get pod/controller-0 -o json | jq '.spec.containers[].image'
"quay.io/ycliuhw/juju-db:4.0"
"quay.io/ycliuhw/jujud-operator:2.9.10"

$ JUJU_DEV_FEATURE_FLAGS=private-registry juju upgrade-controller --agent-stream=develop


```

### public repo on dockerhub
```console
$ juju bootstrap microk8s k1 --config caas-image-repo=ycliuhw && juju add-model t1

$ mkubectl -ncontroller-k1 get pod/controller-0 -o json | jq .spec.imagePullSecrets
null

$ mkubectl -ncontroller-k1 get secret/juju-image-pull-secret
Error from server (NotFound): secrets "juju-image-pull-secret" not found

$ mkubectl -nt1 get pods snappass-test-0 mariadb-k8s-operator-0 modeloperator-84c9b5c68-9259k -o json |
 jq '.items[].spec.imagePullSecrets'
null
null
null

$ mkubectl -nt1 get secret/juju-image-pull-secret
Error from server (NotFound): secrets "juju-image-pull-secret" not found

$ mkubectl -nt1 get pod/snappass-test-0 -o json | jq '.spec.containers[].image'

"ycliuhw/charm-base:ubuntu-20.04"
"registry.hub.docker.com/library/redis@sha256:27bea08330830c6e5efc456075d66eb1fb4b76e5518947e8c87556adf1df3e51"
"registry.hub.docker.com/benhoyt/snappass-test@sha256:32506b5ac7bde75b7a76bee003cf8c77f30fc936f446c8c52d457b8fe6fce96f"

$ mkubectl -nt1 get pod/mariadb-k8s-operator-0 -o json | jq '.spec.containers[].image'
"ycliuhw/jujud-operator:2.9.10"

$ mkubectl -nt1 get pod/modeloperator-56b469cd6-n8dxp -o json | jq '.spec.containers[].image'
Error from server (NotFound): pods "modeloperator-56b469cd6-n8dxp" not found

$ mkubectl -nt1 get pod/modeloperator-84c9b5c68-9259k -o json | jq '.spec.containers[].image'
"ycliuhw/jujud-operator:2.9.10"

$ mkubectl -ncontroller-k1 get pod/controller-0 -o json | jq '.spec.containers[].image'

"ycliuhw/juju-db:4.0"
"ycliuhw/jujud-operator:2.9.10"

```


## Documentation changes

Yes

## Bug reference

https://bugs.launchpad.net/juju/+bug/1935953
https://bugs.launchpad.net/juju/+bug/1935830
  • Loading branch information
jujubot authored Aug 25, 2021
2 parents 4bae7a1 + 039f193 commit 57d78e4
Show file tree
Hide file tree
Showing 97 changed files with 4,261 additions and 922 deletions.
35 changes: 28 additions & 7 deletions api/caasapplicationprovisioner/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/juju/juju/core/resources"
"github.com/juju/juju/core/status"
"github.com/juju/juju/core/watcher"
"github.com/juju/juju/docker"
"github.com/juju/juju/storage"
)

Expand Down Expand Up @@ -119,16 +120,18 @@ type ProvisioningInfo struct {
Filesystems []storage.KubernetesFilesystemParams
Devices []devices.KubernetesDeviceParams
Series string
ImageRepo string
ImageRepo docker.ImageRepoDetails
CharmModifiedVersion int
CharmURL *charm.URL
}

// ProvisioningInfo returns the info needed to provision an operator for an application.
func (c *Client) ProvisioningInfo(applicationName string) (ProvisioningInfo, error) {
args := params.Entities{[]params.Entity{
{Tag: names.NewApplicationTag(applicationName).String()},
}}
args := params.Entities{
Entities: []params.Entity{
{Tag: names.NewApplicationTag(applicationName).String()},
},
}
var result params.CAASApplicationProvisioningInfoResults
if err := c.facade.FacadeCall("ProvisioningInfo", args, &result); err != nil {
return ProvisioningInfo{}, err
Expand All @@ -141,6 +144,20 @@ func (c *Client) ProvisioningInfo(applicationName string) (ProvisioningInfo, err
return ProvisioningInfo{}, errors.Trace(maybeNotFound(err))
}

imageRepo := docker.ImageRepoDetails{
Repository: r.ImageRepo.Repository,
ServerAddress: r.ImageRepo.ServerAddress,
BasicAuthConfig: docker.BasicAuthConfig{
Username: r.ImageRepo.Username,
Password: r.ImageRepo.Password,
Auth: r.ImageRepo.Auth,
},
TokenAuthConfig: docker.TokenAuthConfig{
IdentityToken: r.ImageRepo.IdentityToken,
RegistryToken: r.ImageRepo.RegistryToken,
Email: r.ImageRepo.Email,
},
}
info := ProvisioningInfo{
ImagePath: r.ImagePath,
Version: r.Version,
Expand All @@ -149,7 +166,7 @@ func (c *Client) ProvisioningInfo(applicationName string) (ProvisioningInfo, err
Tags: r.Tags,
Constraints: r.Constraints,
Series: r.Series,
ImageRepo: r.ImageRepo,
ImageRepo: imageRepo,
CharmModifiedVersion: r.CharmModifiedVersion,
}

Expand Down Expand Up @@ -303,8 +320,12 @@ func (c *Client) ApplicationOCIResources(appName string) (map[string]resources.D
for k, v := range res.Result.Images {
images[k] = resources.DockerImageDetails{
RegistryPath: v.RegistryPath,
Username: v.Username,
Password: v.Password,
ImageRepoDetails: docker.ImageRepoDetails{
BasicAuthConfig: docker.BasicAuthConfig{
Username: v.Username,
Password: v.Password,
},
},
}
}
return images, nil
Expand Down
13 changes: 9 additions & 4 deletions api/caasapplicationprovisioner/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/juju/juju/core/life"
"github.com/juju/juju/core/resources"
"github.com/juju/juju/core/status"
"github.com/juju/juju/docker"
)

type provisionerSuite struct {
Expand Down Expand Up @@ -151,7 +152,7 @@ func (s *provisionerSuite) TestProvisioningInfo(c *gc.C) {
APIAddresses: []string{"10.0.0.1:1"},
Tags: map[string]string{"foo": "bar"},
Series: "bionic",
ImageRepo: "jujuqa",
ImageRepo: params.DockerImageInfo{Repository: "jujuqa"},
CharmModifiedVersion: 1,
CharmURL: "cs:~test/charm-1",
}}}
Expand All @@ -165,7 +166,7 @@ func (s *provisionerSuite) TestProvisioningInfo(c *gc.C) {
APIAddresses: []string{"10.0.0.1:1"},
Tags: map[string]string{"foo": "bar"},
Series: "bionic",
ImageRepo: "jujuqa",
ImageRepo: docker.ImageRepoDetails{Repository: "jujuqa"},
CharmModifiedVersion: 1,
CharmURL: &charm.URL{Schema: "cs", User: "test", Name: "charm", Revision: 1},
})
Expand Down Expand Up @@ -199,8 +200,12 @@ func (s *provisionerSuite) TestApplicationOCIResources(c *gc.C) {
c.Assert(imageResources, jc.DeepEquals, map[string]resources.DockerImageDetails{
"cockroachdb-image": {
RegistryPath: "cockroachdb/cockroach:v20.1.4",
Username: "jujuqa",
Password: "pwd",
ImageRepoDetails: docker.ImageRepoDetails{
BasicAuthConfig: docker.BasicAuthConfig{
Username: "jujuqa",
Password: "pwd",
},
},
},
})
}
Expand Down
30 changes: 30 additions & 0 deletions api/caasmodelconfigmanager/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2021 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package caasmodelconfigmanager

import (
"github.com/juju/errors"

"github.com/juju/juju/api/base"
"github.com/juju/juju/api/common"
)

// Client allows access to the CAAS model config manager API endpoint.
type Client struct {
facade base.FacadeCaller
*common.ControllerConfigAPI
}

// NewClient returns a client used to access the CAAS Application Provisioner API.
func NewClient(caller base.APICaller) (*Client, error) {
_, isModel := caller.ModelTag()
if !isModel {
return nil, errors.New("expected model specific API connection")
}
facadeCaller := base.NewFacadeCaller(caller, "CAASModelConfigManager")
return &Client{
facade: facadeCaller,
ControllerConfigAPI: common.NewControllerConfig(facadeCaller),
}, nil
}
60 changes: 60 additions & 0 deletions api/caasmodelconfigmanager/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2021 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package caasmodelconfigmanager_test

import (
"github.com/juju/testing"
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"

basetesting "github.com/juju/juju/api/base/testing"
"github.com/juju/juju/api/caasmodelconfigmanager"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/controller"
)

type caasmodelconfigmanagerSuite struct {
testing.IsolationSuite
}

var _ = gc.Suite(&caasmodelconfigmanagerSuite{})

func newClient(f basetesting.APICallerFunc) (*caasmodelconfigmanager.Client, error) {
return caasmodelconfigmanager.NewClient(basetesting.BestVersionCaller{APICallerFunc: f, BestVersion: 1})
}

func (s *caasmodelconfigmanagerSuite) TestControllerConfig(c *gc.C) {
client, err := newClient(func(objType string, version int, id, request string, arg, result interface{}) error {
c.Check(objType, gc.Equals, "CAASModelConfigManager")
c.Check(id, gc.Equals, "")
c.Check(request, gc.Equals, "ControllerConfig")
c.Assert(arg, gc.IsNil)
c.Assert(result, gc.FitsTypeOf, &params.ControllerConfigResult{})
*(result.(*params.ControllerConfigResult)) = params.ControllerConfigResult{
Config: params.ControllerConfig{
"caas-image-repo": `
{
"serveraddress": "quay.io",
"auth": "xxxxx==",
"repository": "test-account"
}
`[1:],
},
}
return nil
})
c.Assert(err, jc.ErrorIsNil)

cfg, err := client.ControllerConfig()
c.Assert(err, jc.ErrorIsNil)
c.Assert(cfg, jc.DeepEquals, controller.Config{
"caas-image-repo": `
{
"serveraddress": "quay.io",
"auth": "xxxxx==",
"repository": "test-account"
}
`[1:],
})
}
14 changes: 14 additions & 0 deletions api/caasmodelconfigmanager/package_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2021 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package caasmodelconfigmanager

import (
"testing"

gc "gopkg.in/check.v1"
)

func TestAll(t *testing.T) {
gc.TestingT(t)
}
24 changes: 22 additions & 2 deletions api/caasmodeloperator/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (

"github.com/juju/juju/api/base"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/core/resources"
"github.com/juju/juju/docker"
)

// Client is a caas model operator facade client
Expand All @@ -28,7 +30,7 @@ func NewClient(caller base.APICaller) *Client {
// provisioning a caas model operator
type ModelOperatorProvisioningInfo struct {
APIAddresses []string
ImagePath string
ImageDetails resources.DockerImageDetails
Version version.Number
}

Expand All @@ -39,10 +41,28 @@ func (c *Client) ModelOperatorProvisioningInfo() (ModelOperatorProvisioningInfo,
if err := c.facade.FacadeCall("ModelOperatorProvisioningInfo", nil, &result); err != nil {
return ModelOperatorProvisioningInfo{}, err
}
d := result.ImageDetails
imageRepo := resources.DockerImageDetails{
RegistryPath: d.RegistryPath,
ImageRepoDetails: docker.ImageRepoDetails{
Repository: d.Repository,
ServerAddress: d.ServerAddress,
BasicAuthConfig: docker.BasicAuthConfig{
Username: d.Username,
Password: d.Password,
Auth: d.Auth,
},
TokenAuthConfig: docker.TokenAuthConfig{
IdentityToken: d.IdentityToken,
RegistryToken: d.RegistryToken,
Email: d.Email,
},
},
}

return ModelOperatorProvisioningInfo{
APIAddresses: result.APIAddresses,
ImagePath: result.ImagePath,
ImageDetails: imageRepo,
Version: result.Version,
}, nil
}
Expand Down
5 changes: 3 additions & 2 deletions api/caasmodeloperator/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
basetesting "github.com/juju/juju/api/base/testing"
"github.com/juju/juju/api/caasmodeloperator"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/core/resources"
)

type ModelOperatorSuite struct {
Expand All @@ -37,7 +38,7 @@ func (m *ModelOperatorSuite) TestProvisioningInfo(c *gc.C) {

*(result.(*params.ModelOperatorInfo)) = params.ModelOperatorInfo{
APIAddresses: apiAddresses,
ImagePath: imagePath,
ImageDetails: params.DockerImageInfo{RegistryPath: imagePath},
Version: ver,
}
return nil
Expand All @@ -48,7 +49,7 @@ func (m *ModelOperatorSuite) TestProvisioningInfo(c *gc.C) {
c.Assert(err, jc.ErrorIsNil)

c.Assert(result.APIAddresses, jc.DeepEquals, apiAddresses)
c.Assert(result.ImagePath, jc.DeepEquals, imagePath)
c.Assert(result.ImageDetails, jc.DeepEquals, resources.DockerImageDetails{RegistryPath: imagePath})
c.Assert(result.Version, jc.DeepEquals, ver)
}

Expand Down
23 changes: 21 additions & 2 deletions api/caasoperatorprovisioner/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (
apiwatcher "github.com/juju/juju/api/watcher"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/core/life"
"github.com/juju/juju/core/resources"
"github.com/juju/juju/core/watcher"
"github.com/juju/juju/docker"
"github.com/juju/juju/storage"
)

Expand Down Expand Up @@ -110,7 +112,7 @@ func (c *Client) Life(appName string) (life.Value, error) {

// OperatorProvisioningInfo holds the info needed to provision an operator.
type OperatorProvisioningInfo struct {
ImagePath string
ImageDetails resources.DockerImageDetails
Version version.Number
APIAddresses []string
Tags map[string]string
Expand All @@ -133,8 +135,25 @@ func (c *Client) OperatorProvisioningInfo(applicationName string) (OperatorProvi
if err := info.Error; err != nil {
return OperatorProvisioningInfo{}, errors.Trace(err)
}
imageRepo := resources.DockerImageDetails{
RegistryPath: info.ImageDetails.RegistryPath,
ImageRepoDetails: docker.ImageRepoDetails{
Repository: info.ImageDetails.Repository,
ServerAddress: info.ImageDetails.ServerAddress,
BasicAuthConfig: docker.BasicAuthConfig{
Username: info.ImageDetails.Username,
Password: info.ImageDetails.Password,
Auth: info.ImageDetails.Auth,
},
TokenAuthConfig: docker.TokenAuthConfig{
IdentityToken: info.ImageDetails.IdentityToken,
RegistryToken: info.ImageDetails.RegistryToken,
Email: info.ImageDetails.Email,
},
},
}
return OperatorProvisioningInfo{
ImagePath: info.ImagePath,
ImageDetails: imageRepo,
Version: info.Version,
APIAddresses: info.APIAddresses,
Tags: info.Tags,
Expand Down
5 changes: 3 additions & 2 deletions api/caasoperatorprovisioner/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/juju/juju/api/caasoperatorprovisioner"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/core/life"
"github.com/juju/juju/core/resources"
"github.com/juju/juju/storage"
)

Expand Down Expand Up @@ -165,7 +166,7 @@ func (s *provisionerSuite) TestOperatorProvisioningInfo(c *gc.C) {
c.Assert(result, gc.FitsTypeOf, &params.OperatorProvisioningInfoResults{})
*(result.(*params.OperatorProvisioningInfoResults)) = params.OperatorProvisioningInfoResults{
Results: []params.OperatorProvisioningInfo{{
ImagePath: "juju-operator-image",
ImageDetails: params.DockerImageInfo{RegistryPath: "juju-operator-image"},
Version: vers,
APIAddresses: []string{"10.0.0.1:1"},
Tags: map[string]string{"foo": "bar"},
Expand All @@ -182,7 +183,7 @@ func (s *provisionerSuite) TestOperatorProvisioningInfo(c *gc.C) {
info, err := client.OperatorProvisioningInfo("gitlab")
c.Assert(err, jc.ErrorIsNil)
c.Assert(info, jc.DeepEquals, caasoperatorprovisioner.OperatorProvisioningInfo{
ImagePath: "juju-operator-image",
ImageDetails: resources.DockerImageDetails{RegistryPath: "juju-operator-image"},
Version: vers,
APIAddresses: []string{"10.0.0.1:1"},
Tags: map[string]string{"foo": "bar"},
Expand Down
1 change: 1 addition & 0 deletions api/facadeversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var facadeVersions = map[string]int{
"CAASAdmission": 1,
"CAASApplication": 1,
"CAASApplicationProvisioner": 1,
"CAASModelConfigManager": 1,
"CAASFirewaller": 1,
"CAASFirewallerEmbedded": 1, // TODO(juju3): rename to CAASFirewallerSidecar
"CAASModelOperator": 1,
Expand Down
2 changes: 2 additions & 0 deletions apiserver/allfacades.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import (
"github.com/juju/juju/apiserver/facades/controller/applicationscaler"
"github.com/juju/juju/apiserver/facades/controller/caasapplicationprovisioner"
"github.com/juju/juju/apiserver/facades/controller/caasfirewaller"
"github.com/juju/juju/apiserver/facades/controller/caasmodelconfigmanager"
"github.com/juju/juju/apiserver/facades/controller/caasmodeloperator"
"github.com/juju/juju/apiserver/facades/controller/caasoperatorprovisioner"
"github.com/juju/juju/apiserver/facades/controller/caasoperatorupgrader"
Expand Down Expand Up @@ -206,6 +207,7 @@ func AllFacades() *facade.Registry {
reg("CAASUnitProvisioner", 2, caasunitprovisioner.NewStateFacade)
reg("CAASApplication", 1, caasapplication.NewStateFacade)
reg("CAASApplicationProvisioner", 1, caasapplicationprovisioner.NewStateCAASApplicationProvisionerAPI)
reg("CAASModelConfigManager", 1, caasmodelconfigmanager.NewFacade)

reg("Controller", 3, controller.NewControllerAPIv3)
reg("Controller", 4, controller.NewControllerAPIv4)
Expand Down
Loading

0 comments on commit 57d78e4

Please sign in to comment.