Skip to content

Commit

Permalink
Merge branch 'v3' into tweak-cmd-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kian99 authored Aug 28, 2024
2 parents c974260 + d809f13 commit fe65b70
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 163 deletions.
11 changes: 9 additions & 2 deletions .github/actions/test-server/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ runs:
run: echo "name=$CONTROLLER_NAME" >> $GITHUB_OUTPUT
shell: bash

- name: Install jimmctl and yq
run: sudo snap install jimmctl --channel=3/stable && sudo snap install yq
- name: Install jimmctl, jaas plugin and yq
run: |
sudo snap install jimmctl --channel=3/stable && \
sudo snap install jaas --channel=3/stable &&
sudo snap install yq
shell: bash

- name: Authenticate Juju CLI
Expand All @@ -97,3 +100,7 @@ runs:
env:
JIMM_CONTROLLER_NAME: "jimm"
CONTROLLER_NAME: ${{ steps.lxd-controller.outputs.name }}

- name: Provide service account with cloud-credentials
run: ./local/jimm/setup-service-account.sh
shell: bash
2 changes: 1 addition & 1 deletion compose-common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ services:
JIMM_OAUTH_CLIENT_SECRET: "SwjDofnbDzJDm9iyfUhEp67FfUFMY8L4"
JIMM_OAUTH_SCOPES: "openid profile email" # Space separated list of scopes
JIMM_DASHBOARD_FINAL_REDIRECT_URL: "https://jaas.ai" # Example URL
JIMM_ACCESS_TOKEN_EXPIRY_DURATION: 1h
JIMM_ACCESS_TOKEN_EXPIRY_DURATION: 100h
JIMM_SECURE_SESSION_COOKIES: false
JIMM_SESSION_COOKIE_MAX_AGE: 86400
JIMM_SESSION_SECRET_KEY: Xz2RkR9g87M75xfoumhEs5OmGziIX8D88Rk5YW8FSvkBPSgeK9t5AS9IvPDJ3NnB
Expand Down
6 changes: 3 additions & 3 deletions internal/jimm/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (d *cacheDialer) Dial(ctx context.Context, ctl *dbmodel.Controller, mt name
return d.dialer.Dial(ctx, ctl, mt, requiredPermissions)
}
rc := d.sfg.DoChan(ctl.Name, func() (interface{}, error) {
return d.dial(ctx, ctl)
return d.dial(ctx, ctl, requiredPermissions)
})
select {
case r := <-rc:
Expand All @@ -57,7 +57,7 @@ func (d *cacheDialer) Dial(ctx context.Context, ctl *dbmodel.Controller, mt name
}
}

func (d *cacheDialer) dial(ctx context.Context, ctl *dbmodel.Controller) (interface{}, error) {
func (d *cacheDialer) dial(ctx context.Context, ctl *dbmodel.Controller, requiredPermissions map[string]string) (interface{}, error) {
d.mu.Lock()
capi, ok := d.conns[ctl.Name]
if ok {
Expand All @@ -73,7 +73,7 @@ func (d *cacheDialer) dial(ctx context.Context, ctl *dbmodel.Controller) (interf
d.mu.Unlock()

// We don't have a working connection to the controller, so dial one.
api, err := d.dialer.Dial(ctx, ctl, names.ModelTag{}, nil)
api, err := d.dialer.Dial(ctx, ctl, names.ModelTag{}, requiredPermissions)
if err != nil {
return nil, err
}
Expand Down
144 changes: 10 additions & 134 deletions internal/jimmtest/jimm_mock.go

Large diffs are not rendered by default.

167 changes: 167 additions & 0 deletions internal/jimmtest/mocks/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// Copyright 2024 Canonical.
package mocks

import (
"context"
"time"

jujuparams "github.com/juju/juju/rpc/params"
"github.com/juju/names/v5"

"github.com/canonical/jimm/v3/internal/dbmodel"
"github.com/canonical/jimm/v3/internal/errors"
"github.com/canonical/jimm/v3/internal/jimm"
"github.com/canonical/jimm/v3/internal/openfga"
"github.com/canonical/jimm/v3/pkg/api/params"
)

// ModelManager defines the mock struct used to implement the ModelManger interface.
type ModelManager struct {
AddModel_ func(ctx context.Context, u *openfga.User, args *jimm.ModelCreateArgs) (*jujuparams.ModelInfo, error)
ChangeModelCredential_ func(ctx context.Context, user *openfga.User, modelTag names.ModelTag, cloudCredentialTag names.CloudCredentialTag) error
DestroyModel_ func(ctx context.Context, u *openfga.User, mt names.ModelTag, destroyStorage *bool, force *bool, maxWait *time.Duration, timeout *time.Duration) error
DumpModel_ func(ctx context.Context, u *openfga.User, mt names.ModelTag, simplified bool) (string, error)
DumpModelDB_ func(ctx context.Context, u *openfga.User, mt names.ModelTag) (map[string]interface{}, error)
ForEachModel_ func(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error
ForEachUserModel_ func(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error
FullModelStatus_ func(ctx context.Context, user *openfga.User, modelTag names.ModelTag, patterns []string) (*jujuparams.FullStatus, error)
ImportModel_ func(ctx context.Context, user *openfga.User, controllerName string, modelTag names.ModelTag, newOwner string) error
IdentityModelDefaults_ func(ctx context.Context, user *dbmodel.Identity) (map[string]interface{}, error)
ModelDefaultsForCloud_ func(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag) (jujuparams.ModelDefaultsResult, error)
ModelInfo_ func(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelInfo, error)
ModelStatus_ func(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelStatus, error)
QueryModelsJq_ func(ctx context.Context, models []dbmodel.Model, jqQuery string) (params.CrossModelQueryResponse, error)
SetModelDefaults_ func(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, configs map[string]interface{}) error
UnsetModelDefaults_ func(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, keys []string) error
UpdateMigratedModel_ func(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetControllerName string) error
ValidateModelUpgrade_ func(ctx context.Context, u *openfga.User, mt names.ModelTag, force bool) error
WatchAllModelSummaries_ func(ctx context.Context, controller *dbmodel.Controller) (_ func() error, err error)
}

func (j *ModelManager) AddModel(ctx context.Context, u *openfga.User, args *jimm.ModelCreateArgs) (_ *jujuparams.ModelInfo, err error) {
if j.AddModel_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.AddModel_(ctx, u, args)
}

func (j *ModelManager) ChangeModelCredential(ctx context.Context, user *openfga.User, modelTag names.ModelTag, cloudCredentialTag names.CloudCredentialTag) error {
if j.ChangeModelCredential_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.ChangeModelCredential_(ctx, user, modelTag, cloudCredentialTag)
}

func (j *ModelManager) DestroyModel(ctx context.Context, u *openfga.User, mt names.ModelTag, destroyStorage *bool, force *bool, maxWait *time.Duration, timeout *time.Duration) error {
if j.DestroyModel_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.DestroyModel_(ctx, u, mt, destroyStorage, force, maxWait, timeout)
}

func (j *ModelManager) DumpModel(ctx context.Context, u *openfga.User, mt names.ModelTag, simplified bool) (string, error) {
if j.DumpModel_ == nil {
return "", errors.E(errors.CodeNotImplemented)
}
return j.DumpModel_(ctx, u, mt, simplified)
}
func (j *ModelManager) DumpModelDB(ctx context.Context, u *openfga.User, mt names.ModelTag) (map[string]interface{}, error) {
if j.DumpModelDB_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.DumpModelDB_(ctx, u, mt)
}

func (j *ModelManager) ForEachModel(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error {
if j.ForEachModel_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.ForEachModel_(ctx, u, f)
}

func (j *ModelManager) ForEachUserModel(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error {
if j.ForEachUserModel_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.ForEachUserModel_(ctx, u, f)
}

func (j *ModelManager) FullModelStatus(ctx context.Context, user *openfga.User, modelTag names.ModelTag, patterns []string) (*jujuparams.FullStatus, error) {
if j.FullModelStatus_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.FullModelStatus_(ctx, user, modelTag, patterns)
}

func (j *ModelManager) ImportModel(ctx context.Context, user *openfga.User, controllerName string, modelTag names.ModelTag, newOwner string) error {
if j.ImportModel_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.ImportModel_(ctx, user, controllerName, modelTag, newOwner)
}

func (j *ModelManager) ModelDefaultsForCloud(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag) (jujuparams.ModelDefaultsResult, error) {
if j.ModelDefaultsForCloud_ == nil {
return jujuparams.ModelDefaultsResult{}, errors.E(errors.CodeNotImplemented)
}
return j.ModelDefaultsForCloud_(ctx, user, cloudTag)
}

func (j *ModelManager) ModelInfo(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelInfo, error) {
if j.ModelInfo_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.ModelInfo_(ctx, u, mt)
}
func (j *ModelManager) ModelStatus(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelStatus, error) {
if j.ModelStatus_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.ModelStatus_(ctx, u, mt)
}

func (j *ModelManager) QueryModelsJq(ctx context.Context, models []dbmodel.Model, jqQuery string) (params.CrossModelQueryResponse, error) {
if j.QueryModelsJq_ == nil {
return params.CrossModelQueryResponse{}, errors.E(errors.CodeNotImplemented)
}
return j.QueryModelsJq_(ctx, models, jqQuery)
}

func (j *ModelManager) SetModelDefaults(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, configs map[string]interface{}) error {
if j.SetModelDefaults_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.SetModelDefaults_(ctx, user, cloudTag, region, configs)
}

func (j *ModelManager) UnsetModelDefaults(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, keys []string) error {
if j.UnsetModelDefaults_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.UnsetModelDefaults_(ctx, user, cloudTag, region, keys)
}

func (j *ModelManager) UpdateMigratedModel(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetControllerName string) error {
if j.UpdateMigratedModel_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.UpdateMigratedModel_(ctx, user, modelTag, targetControllerName)
}
func (j *ModelManager) IdentityModelDefaults(ctx context.Context, user *dbmodel.Identity) (map[string]interface{}, error) {
if j.IdentityModelDefaults_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.IdentityModelDefaults_(ctx, user)
}
func (j *ModelManager) ValidateModelUpgrade(ctx context.Context, u *openfga.User, mt names.ModelTag, force bool) error {
if j.ValidateModelUpgrade_ == nil {
return errors.E(errors.CodeNotImplemented)
}
return j.ValidateModelUpgrade_(ctx, u, mt, force)
}
func (j *ModelManager) WatchAllModelSummaries(ctx context.Context, controller *dbmodel.Controller) (_ func() error, err error) {
if j.WatchAllModelSummaries_ == nil {
return nil, errors.E(errors.CodeNotImplemented)
}
return j.WatchAllModelSummaries_(ctx, controller)
}
21 changes: 1 addition & 20 deletions internal/jujuapi/controllerroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,28 @@ import (
"github.com/canonical/jimm/v3/internal/openfga"
ofganames "github.com/canonical/jimm/v3/internal/openfga/names"
"github.com/canonical/jimm/v3/internal/pubsub"
"github.com/canonical/jimm/v3/pkg/api/params"
jimmnames "github.com/canonical/jimm/v3/pkg/names"
)

type JIMM interface {
LoginService
ModelManager
AddAuditLogEntry(ale *dbmodel.AuditLogEntry)
AddCloudToController(ctx context.Context, user *openfga.User, controllerName string, tag names.CloudTag, cloud jujuparams.Cloud, force bool) error
AddController(ctx context.Context, u *openfga.User, ctl *dbmodel.Controller) error
AddHostedCloud(ctx context.Context, user *openfga.User, tag names.CloudTag, cloud jujuparams.Cloud, force bool) error
AddGroup(ctx context.Context, user *openfga.User, name string) (*dbmodel.GroupEntry, error)
AddModel(ctx context.Context, u *openfga.User, args *jimm.ModelCreateArgs) (_ *jujuparams.ModelInfo, err error)
AddServiceAccount(ctx context.Context, u *openfga.User, clientId string) error
AuthorizationClient() *openfga.OFGAClient
ChangeModelCredential(ctx context.Context, user *openfga.User, modelTag names.ModelTag, cloudCredentialTag names.CloudCredentialTag) error
CopyServiceAccountCredential(ctx context.Context, u *openfga.User, svcAcc *openfga.User, cloudCredentialTag names.CloudCredentialTag) (names.CloudCredentialTag, []jujuparams.UpdateCredentialModelResult, error)
DB() *db.Database
DestroyModel(ctx context.Context, u *openfga.User, mt names.ModelTag, destroyStorage *bool, force *bool, maxWait *time.Duration, timeout *time.Duration) error
DestroyOffer(ctx context.Context, user *openfga.User, offerURL string, force bool) error
DumpModel(ctx context.Context, u *openfga.User, mt names.ModelTag, simplified bool) (string, error)
DumpModelDB(ctx context.Context, u *openfga.User, mt names.ModelTag) (map[string]interface{}, error)
EarliestControllerVersion(ctx context.Context) (version.Number, error)
FindApplicationOffers(ctx context.Context, user *openfga.User, filters ...jujuparams.OfferFilter) ([]jujuparams.ApplicationOfferAdminDetailsV5, error)
FindAuditEvents(ctx context.Context, user *openfga.User, filter db.AuditLogFilter) ([]dbmodel.AuditLogEntry, error)
ForEachCloud(ctx context.Context, user *openfga.User, f func(*dbmodel.Cloud) error) error
ForEachModel(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error
ForEachUserCloud(ctx context.Context, user *openfga.User, f func(*dbmodel.Cloud) error) error
ForEachUserCloudCredential(ctx context.Context, u *dbmodel.Identity, ct names.CloudTag, f func(cred *dbmodel.CloudCredential) error) error
ForEachUserModel(ctx context.Context, u *openfga.User, f func(*dbmodel.Model, jujuparams.UserAccessPermission) error) error
FullModelStatus(ctx context.Context, user *openfga.User, modelTag names.ModelTag, patterns []string) (*jujuparams.FullStatus, error)
GetApplicationOffer(ctx context.Context, user *openfga.User, offerURL string) (*jujuparams.ApplicationOfferAdminDetailsV5, error)
GetApplicationOfferConsumeDetails(ctx context.Context, user *openfga.User, details *jujuparams.ConsumeOfferDetails, v bakery.Version) error
GetCloud(ctx context.Context, u *openfga.User, tag names.CloudTag) (dbmodel.Cloud, error)
Expand All @@ -70,20 +62,14 @@ type JIMM interface {
GrantModelAccess(ctx context.Context, user *openfga.User, mt names.ModelTag, ut names.UserTag, access jujuparams.UserAccessPermission) error
GrantOfferAccess(ctx context.Context, u *openfga.User, offerURL string, ut names.UserTag, access jujuparams.OfferAccessPermission) error
GrantServiceAccountAccess(ctx context.Context, u *openfga.User, svcAccTag jimmnames.ServiceAccountTag, tags []string) error
IdentityModelDefaults(ctx context.Context, user *dbmodel.Identity) (map[string]interface{}, error)
ImportModel(ctx context.Context, user *openfga.User, controllerName string, modelTag names.ModelTag, newOwner string) error
InitiateInternalMigration(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetController string) (jujuparams.InitiateMigrationResult, error)
InitiateMigration(ctx context.Context, user *openfga.User, spec jujuparams.MigrationSpec) (jujuparams.InitiateMigrationResult, error)
ListApplicationOffers(ctx context.Context, user *openfga.User, filters ...jujuparams.OfferFilter) ([]jujuparams.ApplicationOfferAdminDetailsV5, error)
ListGroups(ctx context.Context, user *openfga.User) ([]dbmodel.GroupEntry, error)
ModelDefaultsForCloud(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag) (jujuparams.ModelDefaultsResult, error)
ModelInfo(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelInfo, error)
ModelStatus(ctx context.Context, u *openfga.User, mt names.ModelTag) (*jujuparams.ModelStatus, error)
Offer(ctx context.Context, user *openfga.User, offer jimm.AddApplicationOfferParams) error
ParseTag(ctx context.Context, key string) (*ofganames.Tag, error)
PubSubHub() *pubsub.Hub
PurgeLogs(ctx context.Context, user *openfga.User, before time.Time) (int64, error)
QueryModelsJq(ctx context.Context, models []dbmodel.Model, jqQuery string) (params.CrossModelQueryResponse, error)
RenameGroup(ctx context.Context, user *openfga.User, oldName, newName string) error
RemoveCloud(ctx context.Context, u *openfga.User, ct names.CloudTag) error
RemoveCloudFromController(ctx context.Context, u *openfga.User, controllerName string, ct names.CloudTag) error
Expand All @@ -97,16 +83,11 @@ type JIMM interface {
RevokeOfferAccess(ctx context.Context, user *openfga.User, offerURL string, ut names.UserTag, access jujuparams.OfferAccessPermission) (err error)
SetControllerConfig(ctx context.Context, u *openfga.User, args jujuparams.ControllerConfigSet) error
SetControllerDeprecated(ctx context.Context, user *openfga.User, controllerName string, deprecated bool) error
SetModelDefaults(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, configs map[string]interface{}) error
ToJAASTag(ctx context.Context, tag *ofganames.Tag, resolveUUIDs bool) (string, error)
UnsetModelDefaults(ctx context.Context, user *dbmodel.Identity, cloudTag names.CloudTag, region string, keys []string) error
UpdateApplicationOffer(ctx context.Context, controller *dbmodel.Controller, offerUUID string, removed bool) error
UpdateCloud(ctx context.Context, u *openfga.User, ct names.CloudTag, cloud jujuparams.Cloud) error
UpdateCloudCredential(ctx context.Context, u *openfga.User, args jimm.UpdateCloudCredentialArgs) ([]jujuparams.UpdateCredentialModelResult, error)
UpdateMigratedModel(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetControllerName string) error
UserLogin(ctx context.Context, identityName string) (*openfga.User, error)
ValidateModelUpgrade(ctx context.Context, u *openfga.User, mt names.ModelTag, force bool) error
WatchAllModelSummaries(ctx context.Context, controller *dbmodel.Controller) (_ func() error, err error)
}

// controllerRoot is the root for endpoints served on controller connections.
Expand Down
Loading

0 comments on commit fe65b70

Please sign in to comment.