Skip to content

Commit

Permalink
Merge pull request juju#18652 from ycliuhw/implement-model-constraint…
Browse files Browse the repository at this point in the history
…s-service

juju#18652

This PR adds two more domain model service methods for getting and setting model constraints.
In the state layer in the next PR, we will ensure that the space you are setting is an existing space, and of course, the model has to exist as well.
The constraint logic follows the existing logic from Juju3; it overwrites everything in the database record for each update request(no partial update - merge).

This PR proposes the set of functions needed to as part of the model domain to both retrieve and set a model's constraints. This work is very straight forward for the most part following the same logic that we had in Juju 3.x with one exception. Juju has never performed any real validation on the values the user supplies for model constraints opting to save the values verbatim to the database. Now that we have RI in the database there exists cases where validation errors will now pop up around networking spaces not being found and also for container types that are not supported.

In addition to this the service will always set a default container type of None when save constraints to the database if the user has not previously set one. This is so that we may have strong RI in the database and avoid double meaning for no container. @wallyworld asked for this change as part of the work.

We have made an attempt in this PR as well to start introducing mocks into the service layer for model's. This work will be fully completed and cut over to mocks in an upcoming roadmap task.

## Checklist

- [x] Code style: imports ordered, good names, simple structure, etc
- [x] Comments saying why design decisions were made
- [x] Go unit tests, with comments saying what you're testing
- [ ] ~[Integration tests](https://github.com/juju/juju/tree/main/tests), with comments saying what you're testing~
- [ ] ~[doc.go](https://discourse.charmhub.io/t/readme-in-packages/451) added or updated in changed packages~

## QA steps

Unit tests.

## Documentation changes

No

## Links

**Jira card:** [JUJU-7260](https://warthogs.atlassian.net/browse/JUJU-7260)

[JUJU-7260]: https://warthogs.atlassian.net/browse/JUJU-7260?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
jujubot authored Jan 29, 2025
2 parents 6b404c3 + fecde32 commit cc58361
Show file tree
Hide file tree
Showing 7 changed files with 777 additions and 12 deletions.
8 changes: 7 additions & 1 deletion domain/machine/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package errors

import (
"github.com/juju/errors"
"github.com/juju/juju/internal/errors"
)

const (
Expand All @@ -24,6 +24,12 @@ const (
// or a cloud instance is not set yet.
StatusNotSet = errors.ConstError("status not set")

// InvalidContainerType describes an error that can occur when a container
// type has been used that isn't understood by the Juju controller.
// Container types can currently be found in
// [github.com/juju/juju/core/instance.ContainerType]
InvalidContainerType = errors.ConstError("invalid container type")

// InvalidStatus describes a status that is not valid
InvalidStatus = errors.ConstError("invalid status")

Expand Down
4 changes: 4 additions & 0 deletions domain/model/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const (
// to activate a model that has already been activated.
AlreadyActivated = errors.ConstError("model already activated")

// ConstraintsNotFound describes an error that occurs when no model
// constraints have been set for the model but they are requested.
ConstraintsNotFound = errors.ConstError("model constraints not found")

// ModelNamespaceNotFound describes an error that occurs when no database
// namespace for a model exists.
ModelNamespaceNotFound = errors.ConstError("model namespace not found")
Expand Down
48 changes: 48 additions & 0 deletions domain/model/service/modelservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (

"github.com/juju/clock"

"github.com/juju/juju/core/constraints"
coremodel "github.com/juju/juju/core/model"
corestatus "github.com/juju/juju/core/status"
"github.com/juju/juju/domain/model"
modelerrors "github.com/juju/juju/domain/model/errors"
"github.com/juju/juju/internal/errors"
"github.com/juju/juju/internal/uuid"
)
Expand All @@ -33,6 +35,23 @@ type ModelState interface {

// GetModelCloudType returns the model cloud type set in the database.
GetModelCloudType(context.Context) (string, error)

// GetModelConstraints returns the currently set constraints for the model.
// The following error types can be expected:
// - [modelerrors.NotFound]: when no model exists to set constraints for.
// - [modelerrors.ConstraintsNotFound]: when no model constraints have been
// set for the model.
GetModelConstraints(context.Context) (constraints.Value, error)

// SetModelConstraints sets the model constraints to the new values removing
// any previously set values.
// The following error types can be expected:
// - [networkerrors.SpaceNotFound]: when a space constraint is set but the
// space does not exist.
// - [machineerrors.InvalidContainerType]: when the container type set on
// the constraints is invalid.
// - [modelerrors.NotFound]: when no model exists to set constraints for.
SetModelConstraints(ctx context.Context, cons constraints.Value) error
}

// ControllerState is the controller state required by this service. This is the
Expand Down Expand Up @@ -72,6 +91,35 @@ func NewModelService(
}
}

// GetModelConstraints returns the current model constraints.
// It returns an error satisfying [modelerrors.NotFound] if the model does not
// exist.
// It returns an empty Value if the model does not have any constraints
// configured.
func (s *ModelService) GetModelConstraints(ctx context.Context) (constraints.Value, error) {
cons, err := s.modelSt.GetModelConstraints(ctx)
// If no constraints have been set for the model we return a zero value of
// constraints. This is done so the state layer isn't making decisions on
// what the caller of this service requires.
if errors.Is(err, modelerrors.ConstraintsNotFound) {
return constraints.Value{}, nil
}
return cons, err
}

// SetModelConstraints sets the model constraints to the new values removing
// any previously set constraints.
//
// The following error types can be expected:
// - [modelerrors.NotFound]: when the model does not exist
// - [github.com/juju/juju/domain/network/errors.SpaceNotFound]: when the space
// being set in the model constraint doesn't exist.
// - [github.com/juju/juju/domain/machine/errors.InvalidContainerType]: when
// the container type being set in the model constraint isn't valid.
func (s *ModelService) SetModelConstraints(ctx context.Context, cons constraints.Value) error {
return s.modelSt.SetModelConstraints(ctx, cons)
}

// GetModelInfo returns the readonly model information for the model in
// question.
func (s *ModelService) GetModelInfo(ctx context.Context) (coremodel.ModelInfo, error) {
Expand Down
Loading

0 comments on commit cc58361

Please sign in to comment.