Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vault tests #749

Merged
merged 19 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint_and_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Unit test
run: |
PATH=$PATH:$(go env GOPATH)/bin make build
PATH=$PATH:$(go env GOPATH)/bin make test
PATH=$PATH:$(go env GOPATH)/bin make test-all

lint:
name: Lint
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ bin/
go.mod.bak
dist/
.cache_ggshield
.DS_Store
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,14 @@ force-test:

.PHONY: test
test:
@echo "> Test"
@echo "> Run Unit Tests"
@go test ./examples/lib/... $(REPO_ROOT)/cmds/ocm/... $(REPO_ROOT)/cmds/demoplugin/... $(REPO_ROOT)/pkg/...

.PHONY: test-all
test-all: install-requirements
@echo "> Run All Tests"
@go test --tags=integration ./examples/lib/... $(REPO_ROOT)/cmds/ocm/... $(REPO_ROOT)/cmds/demoplugin/... $(REPO_ROOT)/pkg/...

.PHONY: generate
generate:
@$(REPO_ROOT)/hack/generate.sh $(REPO_ROOT)/pkg... $(REPO_ROOT)/cmds/ocm/... $(REPO_ROOT)/cmds/helminstaller/... $(REPO_ROOT)/examples/...
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ocm_controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ ocm controller [<options>] <sub command> ...
##### Sub Commands

* [ocm controller <b>install</b>](ocm_controller_install.md) &mdash; Install either a specific or latest version of the ocm-controller. Optionally install prerequisites required by the controller.
* [ocm controller <b>uninstall</b>](ocm_controller_uninstall.md) &mdash; Uninstalls the ocm-controller and all of its dependencies

32 changes: 32 additions & 0 deletions docs/reference/ocm_controller_uninstall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## ocm controller uninstall &mdash; Uninstalls The Ocm-Controller And All Of Its Dependencies

### Synopsis

```
ocm controller uninstall controller
```

### Options

```
-u, --base-url string the base url to the ocm-controller's release page (default "https://github.com/open-component-model/ocm-controller/releases")
--cert-manager-base-url string the base url to the cert-manager's release page (default "https://github.com/cert-manager/cert-manager/releases")
--cert-manager-release-api-url string the base url to the cert-manager's API release page (default "https://api.github.com/repos/cert-manager/cert-manager/releases")
--cert-manager-version string version for cert-manager (default "v1.13.2")
-c, --controller-name string name of the controller that's used for status check (default "ocm-controller")
-d, --dry-run if enabled, prints the downloaded manifest file
-h, --help help for uninstall
-n, --namespace string the namespace into which the controller is installed (default "ocm-system")
-a, --release-api-url string the base url to the ocm-controller's API release page (default "https://api.github.com/repos/open-component-model/ocm-controller/releases")
-t, --timeout duration maximum time to wait for deployment to be ready (default 1m0s)
-p, --uninstall-prerequisites uninstall prerequisites required by ocm-controller
-v, --version string the version of the controller to install (default "latest")
```

### SEE ALSO

##### Parents

* [ocm controller](ocm_controller.md) &mdash; Commands acting on the ocm-controller
* [ocm](ocm.md) &mdash; Open Component Model command line client

8 changes: 3 additions & 5 deletions docs/reference/ocm_credential-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ The following credential consumer types are used/supported:
- <code>scheme</code>: (optional) URL scheme
- <code>port</code>: (optional) server port
- <code>namespace</code>: vault namespace
- <code>secretEngine</code>: secret engine
- <code>mountPath</code>: mount path
- <code>pathprefix</code>: path prefix for secret


Expand All @@ -138,7 +138,6 @@ The following credential consumer types are used/supported:
- <code>token</code>: vault token
- <code>roleid</code>: applrole role id
- <code>secretid</code>: applrole secret id
- <code>secretid</code>: applrole secret id

The only supported auth methods, so far, are <code>token</code> and <code>approle</code>.

Expand Down Expand Up @@ -315,7 +314,7 @@ The following types are currently available:
- <code>scheme</code>: (optional) URL scheme
- <code>port</code>: (optional) server port
- <code>namespace</code>: vault namespace
- <code>secretEngine</code>: secret engine
- <code>mountPath</code>: mount path
- <code>pathprefix</code>: path prefix for secret


Expand All @@ -325,7 +324,6 @@ The following types are currently available:
- <code>token</code>: vault token
- <code>roleid</code>: applrole role id
- <code>secretid</code>: applrole secret id
- <code>secretid</code>: applrole secret id

The only supported auth methods, so far, are <code>token</code> and <code>approle</code>.

Expand All @@ -335,7 +333,7 @@ The following types are currently available:
The repository specification supports the following fields:
- <code>serverURL</code>: *string* (required): the URL of the vault instance
- <code>namespace</code>: *string* (optional): the namespace used to evaluate secrets
- <code>secretsEngine</code>: *string* (optional): the secrets engine to use (default: secrets)
- <code>mountPath</code>: *string* (optional): the mount path to use (default: secrets)
- <code>path</code>: *string* (optional): the path prefix used to lookup secrets
- <code>secrets</code>: *[]string* (optional): list of secrets
- <code>propagateConsumerIdentity</code>: *bool*(optional): evaluate metadata for consumer id propagation
Expand Down
3 changes: 1 addition & 2 deletions docs/reference/ocm_get_credentials.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Matchers exist for the following usage contexts or consumer types:
- <code>scheme</code>: (optional) URL scheme
- <code>port</code>: (optional) server port
- <code>namespace</code>: vault namespace
- <code>secretEngine</code>: secret engine
- <code>mountPath</code>: mount path
- <code>pathprefix</code>: path prefix for secret


Expand All @@ -64,7 +64,6 @@ Matchers exist for the following usage contexts or consumer types:
- <code>token</code>: vault token
- <code>roleid</code>: applrole role id
- <code>secretid</code>: applrole secret id
- <code>secretid</code>: applrole secret id

The only supported auth methods, so far, are <code>token</code> and <code>approle</code>.

Expand Down
2 changes: 1 addition & 1 deletion examples/lib/tour/doc.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//go:generate mdref --headings --list docsrc .
//go:generate mdref --headings docsrc .

package tour
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/open-component-model/ocm

go 1.22.1
go 1.22.2

replace github.com/spf13/cobra => github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9

Expand Down Expand Up @@ -222,6 +222,7 @@ require (
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/hashicorp/vault/api v1.13.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/in-toto/in-toto-golang v0.9.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExRKHSUg3ljWc=
github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY=
github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE=
github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE=
github.com/hashicorp/vault/api v1.13.0 h1:RTCGpE2Rgkn9jyPcFlc7YmNocomda44k5ck8FKMH41Y=
github.com/hashicorp/vault/api v1.13.0/go.mod h1:0cb/uZUv1w2cVu9DIvuW1SMlXXC6qtATJt+LXJRx+kg=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM=
Expand Down
30 changes: 29 additions & 1 deletion hack/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
GOPATH := $(shell go env GOPATH)
LOCALBIN := $(shell pwd)/../bin
OS := $(shell go env GOOS 2>/dev/null || sh -c 'uname -o' | sed 's/.*/\L&/' )
ARCH := $(shell go env GOARCH 2>/dev/null || sh -c 'uname -m' | sed 's/.*/\L&/' )
OS_ARCH := $(OS)_$(ARCH)

ifeq ($(OS),Windows_NT)
detected_OS := Windows
Expand Down Expand Up @@ -39,6 +43,16 @@ GO_BINDATA := $(shell (go-bindata -version 2>/dev/null || echo 0.0.0) | head -n
ifneq ("v$(GO_BINDATA)",$(GO_BINDATA_VERSION))
deps += go-bindata
endif
VAULT_VERSION := 1.16.2
VAULT := $(shell ($(LOCALBIN)/vault --version 2>/dev/null || echo 0.0) | sed 's/.*Vault v\([0-9\.]*\).*/\1/')
ifeq ($(VAULT), $(VAULT_VERSION))
deps += vault
endif
OCI_REGISTRY_VERSION := 3.0.0-alpha.1
OCI_REGISTRY := $(shell (registry --version 2>/dev/null || echo 0.0) | sed 's/.* v\([0-9a-z\.\-]*\).*/\1/')
ifeq ($(OCI_REGISTRY), $(OCI_REGISTRY_VERSION))
deps += oci-registry
endif

.PHONY: install-requirements
install-requirements: $(deps) $(GOPATH)/bin/goimports mdref
Expand All @@ -58,14 +72,28 @@ golangci-lint-version:
go-bindata:
go install -v github.com/go-bindata/go-bindata/v3/...@$(GO_BINDATA_VERSION)

.PHONY: vault
vault:
@if [ "$(VAULT)" != "$(VAULT_VERSION)" ]; then \
curl -o $(LOCALBIN)/vault.zip https://releases.hashicorp.com/vault/$(VAULT_VERSION)/vault_$(VAULT_VERSION)_$(OS_ARCH).zip; \
unzip -o $(LOCALBIN)/vault.zip -d $(LOCALBIN); \
rm $(LOCALBIN)/vault.zip; \
chmod a+x $(LOCALBIN)/vault;\
fi

.PHONY: oci-registry
oci-registry:
@if [ "$(OCI_REGISTRY)" != "$(OCI_REGISTRY_VERSION)" ]; then \
go install -v github.com/distribution/distribution/v3/cmd/[email protected]; \
fi

$(GOPATH)/bin/goimports:
go install -v golang.org/x/tools/cmd/goimports@latest

.PHONY: mdref
mdref:
go install -v github.com/mandelsoft/mdref@master


Linux_jq:
$(info -> jq is missing)
$(info - sudo apt-get install jq / sudo dnf install jq / sudo zypper install jq / sudo pacman -S jq)
Expand Down
13 changes: 13 additions & 0 deletions pkg/contexts/credentials/cpi/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type (
GenericRepositorySpec = internal.GenericRepositorySpec
GenericCredentialsSpec = internal.GenericCredentialsSpec
DirectCredentials = internal.DirectCredentials
EvaluationContext = internal.EvaluationContext
)

type (
Expand Down Expand Up @@ -102,6 +103,18 @@ func RequiredCredentialsForConsumer(ctx ContextProvider, id ConsumerIdentity, ma
return internal.CredentialsForConsumer(ctx, id, true, matchers...)
}

func GetCredentialsForConsumer(ctx Context, ectx EvaluationContext, identity ConsumerIdentity, matchers ...IdentityMatcher) (CredentialsSource, error) {
return internal.GetCredentialsForConsumer(ctx, ectx, identity, matchers...)
}

func GetEvaluationContextFor[T any](ectx EvaluationContext) T {
return internal.GetEvaluationContextFor[T](ectx)
}

func SetEvaluationContextFor(ectx EvaluationContext, e any) {
internal.SetEvaluationContextFor(ectx, e)
}

var (
CompleteMatch = internal.CompleteMatch
NoMatch = internal.NoMatch
Expand Down
88 changes: 81 additions & 7 deletions pkg/contexts/credentials/internal/consumers.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
package internal

import (
"fmt"
"slices"
"sort"
"sync"

"github.com/mandelsoft/goutils/exception"
"github.com/mandelsoft/goutils/general"
"github.com/mandelsoft/goutils/maputils"
"github.com/mandelsoft/goutils/sliceutils"
"github.com/mandelsoft/goutils/stringutils"
)

// UsageContext descibes a dediacetd type specific
type CredentialRecursion []ConsumerIdentity

func (c CredentialRecursion) String() string {
return stringutils.Join(c)
}

func (c CredentialRecursion) Contains(identity ConsumerIdentity) bool {
return slices.ContainsFunc(c, general.ContainsFuncFor(identity))
}

func (c CredentialRecursion) Append(identity ConsumerIdentity) CredentialRecursion {
return sliceutils.CopyAppendUniqueFunc(c, general.EqualsFuncFor[ConsumerIdentity](), identity)
}

// UsageContext describes a dedicated type specific
// sub usage kinds for an object requiring credentials.
// For example, for an object providing a hierarchical
// namespace this might be a namespace prefix for
Expand Down Expand Up @@ -73,7 +93,7 @@ func (c *_consumers) Get(id ConsumerIdentity) (CredentialsSource, bool) {

// Match matches a given request (pattern) against configured
// identities.
func (c *_consumers) Match(pattern ConsumerIdentity, cur ConsumerIdentity, m IdentityMatcher) (CredentialsSource, ConsumerIdentity) {
func (c *_consumers) Match(ectx EvaluationContext, pattern ConsumerIdentity, cur ConsumerIdentity, m IdentityMatcher) (CredentialsSource, ConsumerIdentity) {
var found *_consumer
for _, s := range c.data {
if m(pattern, cur, s.identity) {
Expand Down Expand Up @@ -195,18 +215,72 @@ func (p *consumerProviderRegistry) Get(id ConsumerIdentity) (CredentialsSource,
return nil, false
}

func (p *consumerProviderRegistry) Match(pattern ConsumerIdentity, cur ConsumerIdentity, m IdentityMatcher) (CredentialsSource, ConsumerIdentity) {
p.lock.Lock()
defer p.lock.Unlock()
func (p *consumerProviderRegistry) checkHandleProvider(ectx EvaluationContext, prov ConsumerProvider, pattern ConsumerIdentity) (rctx EvaluationContext, useprov bool, usestack bool) {
if pr, ok := prov.(ConsumerIdentityProvider); ok {
r := GetEvaluationContextFor[CredentialRecursion](ectx)
if r == nil {
r = CredentialRecursion{}
}
if r.Contains(pr.GetConsumerId()) {
return ectx, false, true
}
r = r.Append(pr.GetConsumerId())
ectx = SetEvaluationContextFor(ectx, r)
}
return ectx, true, true
}

credsrc, cur := p.explicit.Match(pattern, cur, m)
type UnwindStack struct {
error
}

func (u *UnwindStack) Unwrap() error {
return u.error
}

func (p *consumerProviderRegistry) catchedMatch(ectx EvaluationContext, sub ConsumerProvider, pattern ConsumerIdentity, cur ConsumerIdentity, m IdentityMatcher) (cs CredentialsSource, ci ConsumerIdentity) {
defer exception.CatchError(func(err error) {
log.Trace("caught unwind stack error: {{error}}", "error", err)
cs = nil
ci = cur
}, exception.ByPrototypes(&UnwindStack{}))
log.Trace("pattern: {{pattern}}\ncontext: {{context}}\nprovider: {{provider}}",
"pattern", pattern, "context", ectx, "provider", sub)
ectx, useprov, _ := p.checkHandleProvider(ectx, sub, pattern)
if !useprov {
return nil, cur
}
log.Trace("attempt match with provider: {{provider}}", "provider", sub)
return sub.Match(ectx, pattern, cur, m)
}

func (p *consumerProviderRegistry) Match(ectx EvaluationContext, pattern ConsumerIdentity, cur ConsumerIdentity, m IdentityMatcher) (CredentialsSource, ConsumerIdentity) {
p.lock.RLock()
defer p.lock.RUnlock()

credsrc, cur := p.explicit.Match(ectx, pattern, cur, m)
for _, sub := range p.providers {
var f CredentialsSource
f, cur = sub.Match(pattern, cur, m)
f, cur = p.catchedMatch(ectx, sub, pattern, cur, m)
if f != nil {
credsrc = f
}
}
// If this is the case, we are in a situation where we have excluded all providers (since they are all in the stack).
// If we would simply return with no credentials, the follow-up coding would assume, that it should query the
// credential repository without any credentials, since none have been found.
// INSTEAD, we have to step down to the previous recursion level and check the other potentially available providers
// for credentials.
// BUT in case we have explicit credentials, then we should use those.
if credsrc == nil {
r := GetEvaluationContextFor[CredentialRecursion](ectx)
// unwind the stack only makes sense when we are in a recursive call, thus we have at least one provider on the
// credential recursion stack
if len(r) > 0 && len(r) == len(p.providers) {
exception.Throw(&UnwindStack{fmt.Errorf("impossible credential recursion detected - unwind stack")})
}
}
log.Trace("return credential source")
return credsrc, cur
}

Expand Down
Loading
Loading