Skip to content

Commit

Permalink
Merge branch 'feature-oidc' into tweak-test-behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
kian99 authored Mar 18, 2024
2 parents 0708fee + 0c679a6 commit 1474c70
Show file tree
Hide file tree
Showing 167 changed files with 2,373 additions and 4,248 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
run: |
touch ./local/vault/approle.json
touch ./local/vault/roleid.txt
- name: Create test certs
run: make certs
- name: Start test environment
run: docker compose up -d --wait
- name: Build and Test
Expand All @@ -65,12 +67,6 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
- name: Pull candid repo for test environment
run: |
git clone https://github.com/canonical/candid.git ./tmp/candid
cd ./tmp/candid
make image
docker image ls candid
- name: Add volume files
run: |
touch ./local/vault/approle.json
Expand Down
16 changes: 6 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ clean:
-$(RM) -r jimm-release/
-$(RM) jimm-*.tar.xz

test-env: sysdeps
certs:
@cd local/traefik/certs; ./certs.sh; cd -

test-env: sysdeps certs
@touch ./local/vault/approle.json && touch ./local/vault/roleid.txt
@docker compose up --force-recreate
@docker compose up --force-recreate -d --wait

test-env-cleanup:
@docker compose down -v --remove-orphans

dev-env-setup: sysdeps pull/candid
@cd local/traefik/certs; ./certs.sh; cd -
dev-env-setup: sysdeps certs
@touch ./local/vault/approle.json && touch ./local/vault/roleid.txt
@make version/commit.txt && make version/version.txt
@go mod vendor
Expand Down Expand Up @@ -97,11 +99,6 @@ push-microk8s: jimm-image
docker tag jimm:latest localhost:32000/jimm:latest
docker push localhost:32000/jimm:latest

pull/candid:
-git clone https://github.com/canonical/candid.git ./tmp/candid
(cd ./tmp/candid && make image)
docker image ls candid

get-local-auth:
@go run ./local/authy

Expand Down Expand Up @@ -138,7 +135,6 @@ help:
@echo 'make sysdeps - Install the development environment system packages.'
@echo 'make format - Format the source files.'
@echo 'make simplify - Format and simplify the source files.'
@echo 'make pull/candid - Pull candid for local development environment.'
@echo 'make get-local-auth - Get local auth to the API WSS endpoint locally.'

.PHONY: build check install release clean format server simplify sysdeps help FORCE
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ See [here](./local/README.md) on how to get started.

## Testing

## TLDR
Run:
```
$ make test-env
$ go test ./...
```
### Pre-requisite
To check if your system has all the prequisites installed simply run `make sysdeps`.
This will check for all test prequisites and inform you how to install them if not installed.
Expand All @@ -56,6 +62,11 @@ This can be installed via: `sudo snap install juju-db`.
The latest JIMM has an upgraded dependency on Juju which requires in turn requires juju-db from channel `4.4/stable`,
this can be installed with `sudo snap install juju-db --channel=4.4/stable`

Tests inside of `cmd/` create a JIMM server and test the jimmctl and jaas CLI packages. The Juju CLI requires that it connects to
an HTTPS server, but these tests also start a Juju controller which expects to be able to fetch a JWKS and macaroon publickey
from JIMM (which is running as an HTTPS server). This would normally result in a TLS certificate error, however JIMM will
attempt to use a custom self-signed cert from the certificate generated in `local/traefik/certs`. The make command `make certs` will generate these certs and place the CA in your system's cert pool which will be picked up by the Go HTTP client.

The rest of the suite relies on PostgreSQL, OpenFGA and Hashicorp Vault which are dockerised
and as such you may simple run `make test-env` to be integration test ready.
The above command won't start a dockerised instance of JIMM as tests are normally run locally. Instead, to start a
Expand Down
2 changes: 1 addition & 1 deletion charms/bundles/controller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This bundle needs to be deployed on top of an already existing controller
model.

To bootstrap an appropriate model run commands like the following:
juju bootstrap --bootstrap-constraints="cores=8 mem=8G root-disk=50G" --config identity-url=<candid URL> --config allow-model-access=true --config public-dns-address=<DNS of the controller>:443 <cloud>/<region> <name>
juju bootstrap --bootstrap-constraints="cores=8 mem=8G root-disk=50G" --config allow-model-access=true --config public-dns-address=<DNS of the controller>:443 <cloud>/<region> <name>
juju enable-ha -n 3
juju switch controller

Expand Down
12 changes: 2 additions & 10 deletions charms/how-to-deploy-jimm-k8s.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,9 @@ juju switch jimm
make push-microk8s
//Switch to jimm-k8s charm directory
charmcraft pack
juju deploy ./juju-jimm-k8s_ubuntu-20.04-amd64.charm --resource jimm-image="localhost:32000/jimm:latest" --config uuid=ff77dbd0-ab87-444e-b9c7-768c675bf59d --config dns-name=juju-jimm-k8s-0.juju-jimm-k8s-endpoints.jimm.svc.cluster.local --config candid-url="https://api.staging.jujucharms.com/identity" --config vault-access-address="<IP>"
// The following commands can be skipped but will prevent
// JIMM from communicating with Candid.
juju config juju-jimm-k8s private-key=<removed>
juju config juju-jimm-k8s public-key=<removed>
juju config juju-jimm-k8s candid-public-key=<removed>
juju config juju-jimm-k8s candid-agent-username=<removed>
juju config juju-jimm-k8s candid-agent-public-key=<removed>
juju config juju-jimm-k8s candid-agent-private-key=<removed>
juju deploy ./juju-jimm-k8s_ubuntu-20.04-amd64.charm --resource jimm-image="localhost:32000/jimm:latest" --config uuid=ff77dbd0-ab87-444e-b9c7-768c675bf59d --config dns-name=juju-jimm-k8s-0.juju-jimm-k8s-endpoints.jimm.svc.cluster.local --config vault-access-address="<IP>"
```
Deploy OPNEFGA, make relations and run setup actions
Deploy OPENFGA, make relations and run setup actions
```
juju deploy openfga-k8s --series=jammy --channel=latest/edge --revision=5
juju relate juju-jimm-k8s openfga-k8s
Expand Down
9 changes: 5 additions & 4 deletions cmd/jaas/cmd/addserviceaccount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"context"

"github.com/juju/cmd/v3/cmdtesting"
"github.com/juju/names/v4"
"github.com/juju/names/v5"
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jaas/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/jimmtest"
"github.com/canonical/jimm/internal/openfga"
ofganames "github.com/canonical/jimm/internal/openfga/names"
jimmnames "github.com/canonical/jimm/pkg/names"
Expand All @@ -25,11 +26,11 @@ var _ = gc.Suite(&addServiceAccountSuite{})
func (s *addServiceAccountSuite) TestAddServiceAccount(c *gc.C) {
clientID := "abda51b2-d735-4794-a8bd-49c506baa4af"
// alice is superuser
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")
_, err := cmdtesting.RunCommand(c, cmd.NewAddServiceAccountCommandForTesting(s.ClientStore(), bClient), clientID)
c.Assert(err, gc.IsNil)
tuple := openfga.Tuple{
Object: ofganames.ConvertTag(names.NewUserTag("alice@external")),
Object: ofganames.ConvertTag(names.NewUserTag("alice@canonical.com")),
Relation: ofganames.AdministratorRelation,
Target: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(clientID)),
}
Expand All @@ -41,7 +42,7 @@ func (s *addServiceAccountSuite) TestAddServiceAccount(c *gc.C) {
_, err = cmdtesting.RunCommand(c, cmd.NewAddServiceAccountCommandForTesting(s.ClientStore(), bClient), clientID)
c.Assert(err, gc.IsNil)
// Check that re-running the command for a different user returns an error.
bClientBob := s.UserBakeryClient("bob")
bClientBob := jimmtest.NewUserSessionLogin("bob")
_, err = cmdtesting.RunCommand(c, cmd.NewAddServiceAccountCommandForTesting(s.ClientStore(), bClientBob), clientID)
c.Assert(err, gc.ErrorMatches, "service account already owned")
}
17 changes: 8 additions & 9 deletions cmd/jaas/cmd/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,54 @@
package cmd

import (
"github.com/go-macaroon-bakery/macaroon-bakery/v3/httpbakery"
"github.com/juju/cmd/v3"
jujuapi "github.com/juju/juju/api"
"github.com/juju/juju/cmd/modelcmd"
"github.com/juju/juju/jujuclient"
)

func NewAddServiceAccountCommandForTesting(store jujuclient.ClientStore, bClient *httpbakery.Client) cmd.Command {
func NewAddServiceAccountCommandForTesting(store jujuclient.ClientStore, lp jujuapi.LoginProvider) cmd.Command {
cmd := &addServiceAccountCommand{
store: store,
dialOpts: &jujuapi.DialOpts{
InsecureSkipVerify: true,
BakeryClient: bClient,
LoginProvider: lp,
},
}

return modelcmd.WrapBase(cmd)
}

func NewListServiceAccountCredentialsCommandForTesting(store jujuclient.ClientStore, bClient *httpbakery.Client) cmd.Command {
func NewListServiceAccountCredentialsCommandForTesting(store jujuclient.ClientStore, lp jujuapi.LoginProvider) cmd.Command {
cmd := &listServiceAccountCredentialsCommand{
store: store,
dialOpts: &jujuapi.DialOpts{
InsecureSkipVerify: true,
BakeryClient: bClient,
LoginProvider: lp,
},
}

return modelcmd.WrapBase(cmd)
}

func NewUpdateCredentialsCommandForTesting(store jujuclient.ClientStore, bClient *httpbakery.Client) cmd.Command {
func NewUpdateCredentialsCommandForTesting(store jujuclient.ClientStore, lp jujuapi.LoginProvider) cmd.Command {
cmd := &updateCredentialsCommand{
store: store,
dialOpts: &jujuapi.DialOpts{
InsecureSkipVerify: true,
BakeryClient: bClient,
LoginProvider: lp,
},
}

return modelcmd.WrapBase(cmd)
}

func NewGrantCommandForTesting(store jujuclient.ClientStore, bClient *httpbakery.Client) cmd.Command {
func NewGrantCommandForTesting(store jujuclient.ClientStore, lp jujuapi.LoginProvider) cmd.Command {
cmd := &grantCommand{
store: store,
dialOpts: &jujuapi.DialOpts{
InsecureSkipVerify: true,
BakeryClient: bClient,
LoginProvider: lp,
},
}

Expand Down
9 changes: 5 additions & 4 deletions cmd/jaas/cmd/grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (
"context"

"github.com/juju/cmd/v3/cmdtesting"
"github.com/juju/names/v4"
"github.com/juju/names/v5"
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jaas/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
"github.com/canonical/jimm/internal/jimmtest"
"github.com/canonical/jimm/internal/openfga"
ofganames "github.com/canonical/jimm/internal/openfga/names"
jimmnames "github.com/canonical/jimm/pkg/names"
Expand All @@ -29,7 +30,7 @@ func (s *grantSuite) TestGrant(c *gc.C) {
clientID := "abda51b2-d735-4794-a8bd-49c506baa4af"

// alice is superuser
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")

sa := dbmodel.Identity{
Name: clientID,
Expand All @@ -39,7 +40,7 @@ func (s *grantSuite) TestGrant(c *gc.C) {

// Make alice admin of the service account
tuple := openfga.Tuple{
Object: ofganames.ConvertTag(names.NewUserTag("alice@external")),
Object: ofganames.ConvertTag(names.NewUserTag("alice@canonical.com")),
Relation: ofganames.AdministratorRelation,
Target: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(clientID)),
}
Expand Down Expand Up @@ -85,7 +86,7 @@ func (s *grantSuite) TestMissingArgs(c *gc.C) {
expectedError: "user/group not specified",
}}

bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")
clientStore := s.ClientStore()
for _, t := range tests {
_, err := cmdtesting.RunCommand(c, cmd.NewGrantCommandForTesting(clientStore, bClient), t.args...)
Expand Down
7 changes: 4 additions & 3 deletions cmd/jaas/cmd/listserviceaccountcredentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (
jujucmd "github.com/juju/cmd/v3"
"github.com/juju/cmd/v3/cmdtesting"
"github.com/juju/juju/rpc/params"
"github.com/juju/names/v4"
"github.com/juju/names/v5"
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jaas/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
"github.com/canonical/jimm/internal/jimm"
"github.com/canonical/jimm/internal/jimmtest"
"github.com/canonical/jimm/internal/openfga"
)

Expand All @@ -36,7 +37,7 @@ func (s *listServiceAccountCredentialsSuite) TestListServiceAccountCredentials(c
clientID := "abda51b2-d735-4794-a8bd-49c506baa4af"
// alice is superuser
ctx := context.Background()
user := dbmodel.Identity{Name: "alice@external"}
user := dbmodel.Identity{Name: "alice@canonical.com"}
u := openfga.NewUser(&user, s.OFGAClient)
err = s.JIMM.AddServiceAccount(ctx, u, clientID)
c.Assert(err, gc.IsNil)
Expand Down Expand Up @@ -98,7 +99,7 @@ aws foo
}
for _, test := range testCases {
c.Log(test.about)
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")
var result *jujucmd.Context
if test.showSecrets {
result, err = cmdtesting.RunCommand(c, cmd.NewListServiceAccountCredentialsCommandForTesting(s.ClientStore(), bClient), clientID, "--format", test.format, "--show-secrets")
Expand Down
2 changes: 1 addition & 1 deletion cmd/jaas/cmd/updatecredentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
jujucmd "github.com/juju/juju/cmd"
"github.com/juju/juju/cmd/modelcmd"
"github.com/juju/juju/jujuclient"
"github.com/juju/names/v4"
"github.com/juju/names/v5"

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

Expand Down
17 changes: 9 additions & 8 deletions cmd/jaas/cmd/updatecredentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (
"context"

"github.com/juju/cmd/v3/cmdtesting"
"github.com/juju/names/v4"
"github.com/juju/names/v5"
gc "gopkg.in/check.v1"

"github.com/canonical/jimm/cmd/jaas/cmd"
"github.com/canonical/jimm/internal/cmdtest"
"github.com/canonical/jimm/internal/dbmodel"
"github.com/canonical/jimm/internal/jimmtest"
"github.com/canonical/jimm/internal/openfga"
ofganames "github.com/canonical/jimm/internal/openfga/names"
jimmnames "github.com/canonical/jimm/pkg/names"
Expand All @@ -30,7 +31,7 @@ func (s *updateCredentialsSuite) TestUpdateCredentialsWithNewCredentials(c *gc.C
clientID := "abda51b2-d735-4794-a8bd-49c506baa4af"

// alice is superuser
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")

sa := dbmodel.Identity{
Name: clientID,
Expand All @@ -40,7 +41,7 @@ func (s *updateCredentialsSuite) TestUpdateCredentialsWithNewCredentials(c *gc.C

// Make alice admin of the service account
tuple := openfga.Tuple{
Object: ofganames.ConvertTag(names.NewUserTag("alice@external")),
Object: ofganames.ConvertTag(names.NewUserTag("alice@canonical.com")),
Relation: ofganames.AdministratorRelation,
Target: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(clientID)),
}
Expand Down Expand Up @@ -91,7 +92,7 @@ func (s *updateCredentialsSuite) TestUpdateCredentialsWithExistingCredentials(c
clientID := "abda51b2-d735-4794-a8bd-49c506baa4af"

// alice is superuser
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")

sa := dbmodel.Identity{
Name: clientID,
Expand All @@ -101,7 +102,7 @@ func (s *updateCredentialsSuite) TestUpdateCredentialsWithExistingCredentials(c

// Make alice admin of the service account
tuple := openfga.Tuple{
Object: ofganames.ConvertTag(names.NewUserTag("alice@external")),
Object: ofganames.ConvertTag(names.NewUserTag("alice@canonical.com")),
Relation: ofganames.AdministratorRelation,
Target: ofganames.ConvertTag(jimmnames.NewServiceAccountTag(clientID)),
}
Expand Down Expand Up @@ -156,7 +157,7 @@ func (s *updateCredentialsSuite) TestUpdateCredentialsWithExistingCredentials(c
}

func (s *updateCredentialsSuite) TestCloudNotInLocalStore(c *gc.C) {
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")
_, err := cmdtesting.RunCommand(c, cmd.NewUpdateCredentialsCommandForTesting(s.ClientStore(), bClient),
"00000000-0000-0000-0000-000000000000",
"non-existing-cloud",
Expand All @@ -166,7 +167,7 @@ func (s *updateCredentialsSuite) TestCloudNotInLocalStore(c *gc.C) {
}

func (s *updateCredentialsSuite) TestCredentialNotInLocalStore(c *gc.C) {
bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")

clientStore := s.ClientStore()
err := clientStore.UpdateCredential("some-cloud", jujucloud.CloudCredential{
Expand Down Expand Up @@ -207,7 +208,7 @@ func (s *updateCredentialsSuite) TestMissingArgs(c *gc.C) {
expectedError: "too many args",
}}

bClient := s.UserBakeryClient("alice")
bClient := jimmtest.NewUserSessionLogin("alice")
clientStore := s.ClientStore()
for _, t := range tests {
_, err := cmdtesting.RunCommand(c, cmd.NewUpdateCredentialsCommandForTesting(clientStore, bClient), t.args...)
Expand Down
2 changes: 1 addition & 1 deletion cmd/jimmctl/cmd/addcloudtocontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/juju/juju/cmd/modelcmd"
"github.com/juju/juju/jujuclient"
"github.com/juju/juju/rpc/params"
"github.com/juju/names/v4"
"github.com/juju/names/v5"

"github.com/canonical/jimm/api"
apiparams "github.com/canonical/jimm/api/params"
Expand Down
Loading

0 comments on commit 1474c70

Please sign in to comment.