-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Helm provider interface and a spirehelm unit test
- Loading branch information
1 parent
67c65dc
commit 7e24760
Showing
5 changed files
with
205 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// Copyright 2024 Cofide Limited. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package spirehelm | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
attestation_policy_proto "github.com/cofide/cofide-api-sdk/gen/go/proto/attestation_policy/v1alpha1" | ||
provisionpb "github.com/cofide/cofide-api-sdk/gen/go/proto/provision_plugin/v1alpha1" | ||
trust_zone_proto "github.com/cofide/cofide-api-sdk/gen/go/proto/trust_zone/v1alpha1" | ||
"github.com/cofide/cofidectl/internal/pkg/config" | ||
"github.com/cofide/cofidectl/internal/pkg/test/fixtures" | ||
"github.com/cofide/cofidectl/pkg/plugin" | ||
"github.com/cofide/cofidectl/pkg/plugin/local" | ||
"github.com/cofide/cofidectl/pkg/plugin/provision" | ||
"github.com/cofide/cofidectl/pkg/provider/helm" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestSpireHelm_Deploy(t *testing.T) { | ||
providerFactory := newFakeHelmSPIREProviderFactory() | ||
spireHelm := NewSpireHelm(providerFactory) | ||
ds := newFakeDataSource(t, defaultConfig()) | ||
|
||
statusCh, err := spireHelm.Deploy(context.Background(), ds, "fake-kube.cfg") | ||
require.NoError(t, err, err) | ||
|
||
statuses := collectStatuses(statusCh) | ||
want := []*provisionpb.Status{ | ||
provision.StatusOk("Preparing", "Adding SPIRE Helm repo"), | ||
provision.StatusDone("Prepared", "Added SPIRE Helm repo"), | ||
provision.StatusOk("Installing", "Installing SPIRE CRDs for local1 in tz1"), | ||
provision.StatusOk("Installing", "Installing SPIRE chart for local1 in tz1"), | ||
provision.StatusDone("Installed", "Installation completed for local1 in tz1"), | ||
provision.StatusOk("Installing", "Installing SPIRE CRDs for local2 in tz2"), | ||
provision.StatusOk("Installing", "Installing SPIRE chart for local2 in tz2"), | ||
provision.StatusDone("Installed", "Installation completed for local2 in tz2"), | ||
provision.StatusOk("Waiting", "Waiting for SPIRE server pod and service for local1 in tz1"), | ||
// FIXME: This attempts to create a real Kubernetes client and fails. | ||
provision.StatusError( | ||
"Waiting", | ||
"Failed waiting for SPIRE server pod and service for local1 in tz1", | ||
errors.New("load from file: open fake-kube.cfg: no such file or directory"), | ||
), | ||
} | ||
assert.EqualExportedValues(t, want, statuses) | ||
} | ||
|
||
func TestSpireHelm_TearDown(t *testing.T) { | ||
providerFactory := newFakeHelmSPIREProviderFactory() | ||
spireHelm := NewSpireHelm(providerFactory) | ||
ds := newFakeDataSource(t, defaultConfig()) | ||
|
||
statusCh, err := spireHelm.TearDown(context.Background(), ds) | ||
require.NoError(t, err, err) | ||
|
||
statuses := collectStatuses(statusCh) | ||
want := []*provisionpb.Status{ | ||
provision.StatusOk("Uninstalling", "Uninstalling SPIRE chart for local1 in tz1"), | ||
provision.StatusDone("Uninstalled", "Uninstallation completed for local1 in tz1"), | ||
provision.StatusOk("Uninstalling", "Uninstalling SPIRE chart for local2 in tz2"), | ||
provision.StatusDone("Uninstalled", "Uninstallation completed for local2 in tz2"), | ||
} | ||
assert.EqualExportedValues(t, want, statuses) | ||
} | ||
|
||
func collectStatuses(statusCh <-chan *provisionpb.Status) []*provisionpb.Status { | ||
statuses := []*provisionpb.Status{} | ||
for status := range statusCh { | ||
statuses = append(statuses, status) | ||
} | ||
return statuses | ||
} | ||
|
||
type fakeHelmSPIREProviderFactory struct{} | ||
|
||
func newFakeHelmSPIREProviderFactory() *fakeHelmSPIREProviderFactory { | ||
return &fakeHelmSPIREProviderFactory{} | ||
} | ||
|
||
func (f *fakeHelmSPIREProviderFactory) Build(ctx context.Context, ds plugin.DataSource, trustZone *trust_zone_proto.TrustZone, genValues bool) (helm.Provider, error) { | ||
return newFakeHelmSPIREProvider(trustZone), nil | ||
} | ||
|
||
// fakeHelmSPIREProvider implements a fake helm.Provider that can be used in testing. | ||
type fakeHelmSPIREProvider struct { | ||
trustZone *trust_zone_proto.TrustZone | ||
} | ||
|
||
func newFakeHelmSPIREProvider(trustZone *trust_zone_proto.TrustZone) helm.Provider { | ||
return &fakeHelmSPIREProvider{trustZone: trustZone} | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) AddRepository(statusCh chan<- *provisionpb.Status) error { | ||
statusCh <- provision.StatusOk("Preparing", "Adding SPIRE Helm repo") | ||
statusCh <- provision.StatusDone("Prepared", "Added SPIRE Helm repo") | ||
return nil | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) Execute(statusCh chan<- *provisionpb.Status) error { | ||
sb := provision.NewStatusBuilder(p.trustZone.Name, p.trustZone.GetKubernetesCluster()) | ||
statusCh <- sb.Ok("Installing", "Installing SPIRE CRDs") | ||
statusCh <- sb.Ok("Installing", "Installing SPIRE chart") | ||
statusCh <- sb.Done("Installed", "Installation completed") | ||
return nil | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) ExecutePostInstallUpgrade(statusCh chan<- *provisionpb.Status) error { | ||
return nil | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) ExecuteUpgrade(statusCh chan<- *provisionpb.Status) error { | ||
return nil | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) ExecuteUninstall(statusCh chan<- *provisionpb.Status) error { | ||
sb := provision.NewStatusBuilder(p.trustZone.Name, p.trustZone.GetKubernetesCluster()) | ||
statusCh <- sb.Ok("Uninstalling", "Uninstalling SPIRE chart") | ||
statusCh <- sb.Done("Uninstalled", "Uninstallation completed") | ||
return nil | ||
} | ||
|
||
func (p *fakeHelmSPIREProvider) CheckIfAlreadyInstalled() (bool, error) { | ||
return false, nil | ||
} | ||
|
||
func newFakeDataSource(t *testing.T, cfg *config.Config) plugin.DataSource { | ||
configLoader, err := config.NewMemoryLoader(cfg) | ||
require.Nil(t, err) | ||
lds, err := local.NewLocalDataSource(configLoader) | ||
require.Nil(t, err) | ||
return lds | ||
} | ||
|
||
func defaultConfig() *config.Config { | ||
return &config.Config{ | ||
TrustZones: []*trust_zone_proto.TrustZone{ | ||
fixtures.TrustZone("tz1"), | ||
fixtures.TrustZone("tz2"), | ||
}, | ||
AttestationPolicies: []*attestation_policy_proto.AttestationPolicy{ | ||
fixtures.AttestationPolicy("ap1"), | ||
fixtures.AttestationPolicy("ap2"), | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2024 Cofide Limited. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package helm | ||
|
||
import ( | ||
provisionpb "github.com/cofide/cofide-api-sdk/gen/go/proto/provision_plugin/v1alpha1" | ||
) | ||
|
||
// Provider is an interface that abstracts a Helm-based workload identity provider. | ||
type Provider interface { | ||
// AddRepository adds the SPIRE Helm repository to the local repositories.yaml. | ||
// The action is performed synchronously and status is streamed through the provided status channel. | ||
// This function should be called once, not per-trust zone. | ||
// The SPIRE Helm repository is added to the local repositories.yaml, locking the repositories.lock | ||
// file while making changes. | ||
AddRepository(statusCh chan<- *provisionpb.Status) error | ||
|
||
// Execute installs the SPIRE Helm stack to the selected Kubernetes context. | ||
// The action is performed synchronously and status is streamed through the provided status channel. | ||
Execute(statusCh chan<- *provisionpb.Status) error | ||
|
||
// ExecutePostInstallUpgrade upgrades the SPIRE stack to the selected Kubernetes context. | ||
// The action is performed synchronously and status is streamed through the provided status channel. | ||
ExecutePostInstallUpgrade(statusCh chan<- *provisionpb.Status) error | ||
|
||
// ExecuteUpgrade upgrades the SPIRE stack to the selected Kubernetes context. | ||
// The action is performed synchronously and status is streamed through the provided status channel. | ||
ExecuteUpgrade(statusCh chan<- *provisionpb.Status) error | ||
|
||
// ExecuteUninstall uninstalls the SPIRE stack from the selected Kubernetes context. | ||
// The action is performed synchronously and status is streamed through the provided status channel. | ||
ExecuteUninstall(statusCh chan<- *provisionpb.Status) error | ||
|
||
// CheckIfAlreadyInstalled returns true if the SPIRE chart has previously been installed. | ||
CheckIfAlreadyInstalled() (bool, error) | ||
} |