Skip to content

Commit

Permalink
Adds a new caas model operator to Juju
Browse files Browse the repository at this point in the history
- Introduces a new command juju model that will be triggered as a k8s
  deployment by juju for each model created.
- Moves the cass admission logic to this new command
- Adds passwords for the operator to the model doc state
- New http server worker for simple agents
  • Loading branch information
tlm committed May 18, 2020
1 parent 64aef75 commit 8ab52a9
Show file tree
Hide file tree
Showing 52 changed files with 1,999 additions and 113 deletions.
10 changes: 7 additions & 3 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,10 +444,14 @@ func NewAgentConfig(configParams AgentConfigParams) (ConfigSetterWriter, error)
return nil, errors.Trace(requiredError("entity tag"))
}
switch configParams.Tag.(type) {
case names.MachineTag, names.UnitTag, names.ApplicationTag, names.ControllerAgentTag:
// These are the only three type of tags that can represent an agent
case names.MachineTag,
names.ModelTag,
names.UnitTag,
names.ApplicationTag,
names.ControllerAgentTag:
// These are the only five type of tags that can represent an agent
// IAAS - machine and unit
// CAAS - application, controller agent
// CAAS - application, controller agent, model
default:
return nil, errors.Errorf("entity tag must be MachineTag, UnitTag, ApplicationTag or ControllerAgentTag, got %T", configParams.Tag)
}
Expand Down
15 changes: 15 additions & 0 deletions agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,21 @@ var agentConfigTests = []struct {
inspectConfig: func(c *gc.C, cfg agent.Config) {
c.Check(cfg.Dir(), gc.Equals, "/data/dir/agents/application-ubuntu")
},
}, {
about: "agentConfig accepts an Model tag",
params: agent.AgentConfigParams{
Paths: agent.Paths{DataDir: "/data/dir"},
Tag: testing.ModelTag,
Password: "sekrit",
UpgradedToVersion: jujuversion.Current,
Controller: testing.ControllerTag,
Model: testing.ModelTag,
CACert: "ca cert",
APIAddresses: []string{"localhost:1235"},
},
inspectConfig: func(c *gc.C, cfg agent.Config) {
c.Check(cfg.Dir(), gc.Equals, "/data/dir/agents/model-deadbeef-0bad-400d-8000-4b1d0d06f00d")
},
}}

func (*suite) TestNewAgentConfig(c *gc.C) {
Expand Down
69 changes: 69 additions & 0 deletions api/caasmodeloperator/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package caasmodeloperator

import (
"github.com/juju/errors"
"github.com/juju/version"

"github.com/juju/juju/api/base"
"github.com/juju/juju/apiserver/params"
)

// Client is a caas model operator facade client
type Client struct {
facade base.FacadeCaller
}

// NewClient returns a client used to access the CAAS Operator Provisioner API.
func NewClient(caller base.APICaller) *Client {
facadeCaller := base.NewFacadeCaller(caller, "CAASModelOperator")
return &Client{
facade: facadeCaller,
}
}

// ModelOperatorProvisioningInfo represents return api information for
// provisioning a caas model operator
type ModelOperatorProvisioningInfo struct {
APIAddresses []string
ImagePath string
Version version.Number
}

// ModelOperatorProvisioningInfo returns the information needed for a given model
// when provisioning into a caas env
func (c *Client) ModelOperatorProvisioningInfo() (ModelOperatorProvisioningInfo, error) {
var result params.ModelOperatorInfo
if err := c.facade.FacadeCall("ModelOperatorProvisioningInfo", nil, &result); err != nil {
return ModelOperatorProvisioningInfo{}, err
}

return ModelOperatorProvisioningInfo{
APIAddresses: result.APIAddresses,
ImagePath: result.ImagePath,
Version: result.Version,
}, nil
}

// SetPasswords sets the supplied passwords on their corresponding models
func (c *Client) SetPassword(password string) error {
var result params.ErrorResults
modelTag, modelCon := c.facade.RawAPICaller().ModelTag()
if !modelCon {
return errors.New("not a model connection")
}

args := params.EntityPasswords{
Changes: []params.EntityPassword{{
Tag: modelTag.String(),
Password: password,
}},
}
err := c.facade.FacadeCall("SetPasswords", args, &result)
if err != nil {
return errors.Trace(err)
}
return result.OneError()
}
1 change: 1 addition & 0 deletions api/facadeversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var facadeVersions = map[string]int{
"CAASAgent": 1,
"CAASAdmission": 1,
"CAASFirewaller": 1,
"CAASModelOperator": 1,
"CAASOperator": 1,
"CAASOperatorProvisioner": 1,
"CAASOperatorUpgrader": 1,
Expand Down
2 changes: 2 additions & 0 deletions apiserver/allfacades.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import (
"github.com/juju/juju/apiserver/facades/controller/agenttools"
"github.com/juju/juju/apiserver/facades/controller/applicationscaler"
"github.com/juju/juju/apiserver/facades/controller/caasfirewaller"
"github.com/juju/juju/apiserver/facades/controller/caasmodeloperator"
"github.com/juju/juju/apiserver/facades/controller/caasoperatorprovisioner"
"github.com/juju/juju/apiserver/facades/controller/caasoperatorupgrader"
"github.com/juju/juju/apiserver/facades/controller/caasunitprovisioner"
Expand Down Expand Up @@ -183,6 +184,7 @@ func AllFacades() *facade.Registry {
reg("CAASOperator", 1, caasoperator.NewStateFacade)
reg("CAASAdmission", 1, caasadmission.NewStateFacade)
reg("CAASAgent", 1, caasagent.NewStateFacade)
reg("CAASModelOperator", 1, caasmodeloperator.NewAPIFromContext)
reg("CAASOperatorProvisioner", 1, caasoperatorprovisioner.NewStateCAASOperatorProvisionerAPI)
reg("CAASOperatorUpgrader", 1, caasoperatorupgrader.NewStateCAASOperatorUpgraderAPI)
reg("CAASUnitProvisioner", 1, caasunitprovisioner.NewStateFacade)
Expand Down
3 changes: 3 additions & 0 deletions apiserver/facade/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ type Authorizer interface {
// AuthApplicationAgent returns true if the entity is an application operator.
AuthApplicationAgent() bool

// AuthModelAgent returns true if the entity is a model operator.
AuthModelAgent() bool

// AuthUnitAgent returns true if the entity is a unit agent.
AuthUnitAgent() bool

Expand Down
55 changes: 47 additions & 8 deletions apiserver/facade/mocks/facade_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apiserver/facades/agent/caasagent/caasagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Facade struct {
// NewStateFacade provides the signature required for facade registration.
func NewStateFacade(ctx facade.Context) (*Facade, error) {
authorizer := ctx.Auth()
if !authorizer.AuthMachineAgent() {
if !authorizer.AuthMachineAgent() && !authorizer.AuthModelAgent() {
return nil, common.ErrPerm
}

Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/agent/proxyupdater/proxyupdater.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type Backend interface {

// NewAPIBase creates a new server-side API facade with the given Backing.
func NewAPIBase(backend Backend, resources facade.Resources, authorizer facade.Authorizer) (*APIBase, error) {
if !(authorizer.AuthMachineAgent() || authorizer.AuthUnitAgent() || authorizer.AuthApplicationAgent()) {
if !(authorizer.AuthMachineAgent() || authorizer.AuthUnitAgent() || authorizer.AuthApplicationAgent() || authorizer.AuthModelAgent()) {
return nil, common.ErrPerm
}
return &APIBase{
Expand Down
Loading

0 comments on commit 8ab52a9

Please sign in to comment.