Skip to content

Commit

Permalink
Adds bootstrap support for cloud defaults.
Browse files Browse the repository at this point in the history
With this change we are adding bootstrap methods for setting cloud
defaults. Specifically this applies to the controllers cloud during
bootstrap.
  • Loading branch information
tlm committed Dec 1, 2023
1 parent 843d4ae commit ad7bb75
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
28 changes: 28 additions & 0 deletions domain/cloud/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ package bootstrap
import (
"context"
"database/sql"
"fmt"

"github.com/juju/errors"
"github.com/juju/utils/v3"

"github.com/juju/juju/cloud"
"github.com/juju/juju/core/database"
"github.com/juju/juju/domain/cloud/state"
modelconfigservice "github.com/juju/juju/domain/modelconfig/service"
)

// InsertCloud inserts the initial cloud during bootstrap.
Expand All @@ -30,3 +32,29 @@ func InsertCloud(cloud cloud.Cloud) func(context.Context, database.TxnRunner) er
}))
}
}

// SetCloudDefaults is responsible for setting a previously inserted cloud's
// default config values that will be used as part of the default values
// supplied to a models config. If no cloud exists for the specified name an
// error satisfying [github.com/juju/juju/domain/cloud/errors.NotFound] will be
// returned.
func SetCloudDefaults(
cloudName string,
defaults map[string]any,
) func(context.Context, database.TxnRunner) error {
return func(ctx context.Context, db database.TxnRunner) error {
strDefaults, err := modelconfigservice.CoerceConfigForStorage(defaults)
if err != nil {
return fmt.Errorf("coercing cloud %q default values for storage: %w", cloudName, err)
}

err = db.StdTxn(ctx, func(ctx context.Context, tx *sql.Tx) error {
return state.SetCloudDefaults(ctx, tx, cloudName, strDefaults)
})

if err != nil {
return fmt.Errorf("setting cloud %q bootstrap defaults: %w", cloudName, err)
}
return nil
}
}
86 changes: 86 additions & 0 deletions domain/cloud/bootstrap/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
gc "gopkg.in/check.v1"

"github.com/juju/juju/cloud"
clouderrors "github.com/juju/juju/domain/cloud/errors"
"github.com/juju/juju/domain/cloud/state"
schematesting "github.com/juju/juju/domain/schema/testing"
)

Expand All @@ -29,3 +31,87 @@ func (s *bootstrapSuite) TestInsertCloud(c *gc.C) {
c.Assert(row.Scan(&name), jc.ErrorIsNil)
c.Assert(name, gc.Equals, "cirrus")
}

// TestSetCloudDefaultsNoExist is check that if we try and set cloud defaults
// for a cloud that doesn't exist we get a [clouderrors.NotFound] error back
func (s *bootstrapSuite) TestSetCloudDefaultsNoExist(c *gc.C) {
set := SetCloudDefaults("noexist", map[string]any{
"HTTP_PROXY": "[2001:0DB8::1]:80",
})

err := set(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIs, clouderrors.NotFound)

var count int
row := s.DB().QueryRow("SELECT count(*) FROM cloud_defaults")
err = row.Scan(&count)
c.Check(err, jc.ErrorIsNil)
c.Check(count, gc.Equals, 0)
}

// TestSetCloudDefaults is testing the happy path for setting cloud defaults.
func (s *bootstrapSuite) TestSetCloudDefaults(c *gc.C) {
cld := cloud.Cloud{
Name: "cirrus",
Type: "ec2",
AuthTypes: cloud.AuthTypes{cloud.UserPassAuthType},
}
err := InsertCloud(cld)(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIsNil)

set := SetCloudDefaults("cirrus", map[string]any{
"HTTP_PROXY": "[2001:0DB8::1]:80",
})

err = set(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIsNil)

st := state.NewState(s.TxnRunnerFactory())
defaults, err := st.CloudDefaults(context.Background(), "cirrus")
c.Check(err, jc.ErrorIsNil)
c.Check(defaults, jc.DeepEquals, map[string]string{
"HTTP_PROXY": "[2001:0DB8::1]:80",
})
}

// TestSetCloudDefaultsOverrides is testing that repeated calls to
// [SetCloudDefaults] overrides existing cloud defaults that have been set.
func (s *bootstrapSuite) TestSetCloudDefaultsOverides(c *gc.C) {
cld := cloud.Cloud{
Name: "cirrus",
Type: "ec2",
AuthTypes: cloud.AuthTypes{cloud.UserPassAuthType},
}
err := InsertCloud(cld)(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIsNil)

set := SetCloudDefaults("cirrus", map[string]any{
"HTTP_PROXY": "[2001:0DB8::1]:80",
})

err = set(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIsNil)

st := state.NewState(s.TxnRunnerFactory())
defaults, err := st.CloudDefaults(context.Background(), "cirrus")
c.Check(err, jc.ErrorIsNil)
c.Check(defaults, jc.DeepEquals, map[string]string{
"HTTP_PROXY": "[2001:0DB8::1]:80",
})

// Second time around

set = SetCloudDefaults("cirrus", map[string]any{
"foo": "bar",
})

err = set(context.Background(), s.TxnRunner())
c.Check(err, jc.ErrorIsNil)

st = state.NewState(s.TxnRunnerFactory())
defaults, err = st.CloudDefaults(context.Background(), "cirrus")
c.Check(err, jc.ErrorIsNil)
c.Check(defaults, jc.DeepEquals, map[string]string{
"foo": "bar",
})
}

0 comments on commit ad7bb75

Please sign in to comment.