portainer/pkg/libhelm/binary/test/mock.go

161 lines
4.8 KiB
Go

package test
import (
"encoding/json"
"strings"
"github.com/pkg/errors"
"github.com/portainer/portainer/pkg/libhelm"
"github.com/portainer/portainer/pkg/libhelm/options"
"github.com/portainer/portainer/pkg/libhelm/release"
"gopkg.in/yaml.v3"
)
const (
MockDataIndex = "mock-index"
MockDataChart = "mock-chart"
MockDataReadme = "mock-readme"
MockDataValues = "mock-values"
)
const (
MockReleaseHooks = "mock-release-hooks"
MockReleaseManifest = "mock-release-manifest"
MockReleaseNotes = "mock-release-notes"
MockReleaseValues = "mock-release-values"
)
// helmMockPackageManager is a test package for helm related http handler testing
// Note: this package currently uses a slice in a way that is not thread safe.
// Do not use this package for concurrent tests.
type helmMockPackageManager struct{}
// NewMockHelmBinaryPackageManager initializes a new HelmPackageManager service (a mock instance)
func NewMockHelmBinaryPackageManager(binaryPath string) libhelm.HelmPackageManager {
return &helmMockPackageManager{}
}
var mockCharts = []release.ReleaseElement{}
func newMockReleaseElement(installOpts options.InstallOptions) *release.ReleaseElement {
return &release.ReleaseElement{
Name: installOpts.Name,
Namespace: installOpts.Namespace,
Updated: "date/time",
Status: "deployed",
Chart: installOpts.Chart,
AppVersion: "1.2.3",
}
}
func newMockRelease(re *release.ReleaseElement) *release.Release {
return &release.Release{
Name: re.Name,
Namespace: re.Namespace,
}
}
// Install a helm chart (not thread safe)
func (hpm *helmMockPackageManager) Install(installOpts options.InstallOptions) (*release.Release, error) {
releaseElement := newMockReleaseElement(installOpts)
// Enforce only one chart with the same name per namespace
for i, rel := range mockCharts {
if rel.Name == installOpts.Name && rel.Namespace == installOpts.Namespace {
mockCharts[i] = *releaseElement
return newMockRelease(releaseElement), nil
}
}
mockCharts = append(mockCharts, *releaseElement)
return newMockRelease(releaseElement), nil
}
// Show values/readme/chart etc
func (hpm *helmMockPackageManager) Show(showOpts options.ShowOptions) ([]byte, error) {
switch showOpts.OutputFormat {
case options.ShowChart:
return []byte(MockDataChart), nil
case options.ShowReadme:
return []byte(MockDataReadme), nil
case options.ShowValues:
return []byte(MockDataValues), nil
}
return nil, nil
}
// Get release details - all, hooks, manifest, notes and values
func (hpm *helmMockPackageManager) Get(getOpts options.GetOptions) ([]byte, error) {
switch getOpts.ReleaseResource {
case options.GetAll:
return []byte(strings.Join([]string{MockReleaseHooks, MockReleaseManifest, MockReleaseNotes, MockReleaseValues}, "---\n")), nil
case options.GetHooks:
return []byte(MockReleaseHooks), nil
case options.GetManifest:
return []byte(MockReleaseManifest), nil
case options.GetNotes:
return []byte(MockReleaseNotes), nil
case options.GetValues:
return []byte(MockReleaseValues), nil
default:
return nil, errors.New("invalid release resource")
}
}
// Uninstall a helm chart (not thread safe)
func (hpm *helmMockPackageManager) Uninstall(uninstallOpts options.UninstallOptions) error {
for i, rel := range mockCharts {
if rel.Name == uninstallOpts.Name && rel.Namespace == uninstallOpts.Namespace {
mockCharts = append(mockCharts[:i], mockCharts[i+1:]...)
}
}
return nil
}
// List a helm chart (not thread safe)
func (hpm *helmMockPackageManager) List(listOpts options.ListOptions) ([]release.ReleaseElement, error) {
return mockCharts, nil
}
const mockPortainerIndex = `apiVersion: v1
entries:
portainer:
- apiVersion: v2
appVersion: 2.0.0
created: "2020-12-01T21:51:37.367634957Z"
description: Helm chart used to deploy the Portainer for Kubernetes
digest: f0e13dd3e7a05d17cb35c7879ffa623fd43b2c10ca968203e302b7a6c2764ddb
home: https://www.portainer.io
icon: https://github.com/portainer/portainer/raw/develop/app/assets/ico/apple-touch-icon.png
maintainers:
- email: davidy@funkypenguin.co.nz
name: funkypenguin
url: https://www.funkypenguin.co.nz
name: portainer
sources:
- https://github.com/portainer/k8s
type: application
urls:
- https://github.com/portainer/k8s/releases/download/portainer-1.0.6/portainer-1.0.6.tgz
version: 1.0.6
generated: "2020-08-19T00:00:46.754739363Z"`
func (hbpm *helmMockPackageManager) SearchRepo(searchRepoOpts options.SearchRepoOptions) ([]byte, error) {
// Always return the same repo data no matter what
reader := strings.NewReader(mockPortainerIndex)
var file release.File
err := yaml.NewDecoder(reader).Decode(&file)
if err != nil {
return nil, errors.Wrap(err, "failed to decode index file")
}
result, err := json.Marshal(file)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal index file")
}
return result, nil
}