mirror of https://github.com/helm/helm
While we removed Tiller, we left the internal client/server architecture mostly intact. This replaces that architecture with the `pkg/action` package. This implements the action package for list, but nothing else. Signed-off-by: Matt Butcher <matt.butcher@microsoft.com>pull/5077/head
parent
d07b95d0ae
commit
2016109616
@ -1,115 +0,0 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/helm/pkg/hapi/release"
|
||||
"k8s.io/helm/pkg/helm"
|
||||
)
|
||||
|
||||
func TestListCmd(t *testing.T) {
|
||||
tests := []cmdTestCase{{
|
||||
name: "with a release",
|
||||
cmd: "list",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
|
||||
},
|
||||
golden: "output/list-with-release.txt",
|
||||
}, {
|
||||
name: "list",
|
||||
cmd: "list",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}),
|
||||
},
|
||||
golden: "output/list.txt",
|
||||
}, {
|
||||
name: "list, one deployed, one failed",
|
||||
cmd: "list -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusFailed}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
golden: "output/list-with-failed.txt",
|
||||
}, {
|
||||
name: "with a release, multiple flags",
|
||||
cmd: "list --uninstalled --deployed --failed -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusUninstalled}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
// Note: We're really only testing that the flags parsed correctly. Which results are returned
|
||||
// depends on the backend. And until pkg/helm is done, we can't mock this.
|
||||
golden: "output/list-with-mulitple-flags.txt",
|
||||
}, {
|
||||
name: "with a release, multiple flags",
|
||||
cmd: "list --all -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusUninstalled}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
// See note on previous test.
|
||||
golden: "output/list-with-mulitple-flags2.txt",
|
||||
}, {
|
||||
name: "with a release, multiple flags, deleting",
|
||||
cmd: "list --all -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusUninstalling}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
// See note on previous test.
|
||||
golden: "output/list-with-mulitple-flags-deleting.txt",
|
||||
}, {
|
||||
name: "namespace defined, multiple flags",
|
||||
cmd: "list --all -q --namespace test123",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}),
|
||||
},
|
||||
// See note on previous test.
|
||||
golden: "output/list-with-mulitple-flags-namespaced.txt",
|
||||
}, {
|
||||
name: "with a pending release, multiple flags",
|
||||
cmd: "list --all -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusPendingInstall}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
golden: "output/list-with-mulitple-flags-pending.txt",
|
||||
}, {
|
||||
name: "with a pending release, pending flag",
|
||||
cmd: "list --pending -q",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusPendingInstall}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", Status: release.StatusPendingUpgrade}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", Status: release.StatusPendingRollback}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Status: release.StatusDeployed}),
|
||||
},
|
||||
golden: "output/list-with-pending.txt",
|
||||
}, {
|
||||
name: "with old releases",
|
||||
cmd: "list",
|
||||
rels: []*release.Release{
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
|
||||
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Status: release.StatusFailed}),
|
||||
},
|
||||
golden: "output/list-with-old-releases.txt",
|
||||
}}
|
||||
|
||||
runTestCmd(t, tests)
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,2 +1,2 @@
|
||||
thomas-guide
|
||||
atlas-guide
|
||||
thomas-guide
|
||||
|
@ -1,3 +1,3 @@
|
||||
NAME REVISION UPDATED STATUS CHART NAMESPACE
|
||||
thomas-guide 1 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 default
|
||||
thomas-guide 1 1977-09-02 22:04:05 +0000 UTC failed foo-0.1.0-beta.1 default
|
||||
thomas-guide 2 1977-09-02 22:04:05 +0000 UTC failed foo-0.1.0-beta.1 default
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package action
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestListStates(t *testing.T) {
|
||||
for input, expect := range map[string]ListStates{
|
||||
"deployed": ListDeployed,
|
||||
"uninstalled": ListUninstalled,
|
||||
"uninstalling": ListUninstalling,
|
||||
"superseded": ListSuperseded,
|
||||
"failed": ListFailed,
|
||||
"pending-install": ListPendingInstall,
|
||||
"pending-rollback": ListPendingRollback,
|
||||
"pending-upgrade": ListPendingUpgrade,
|
||||
"unknown": ListUnknown,
|
||||
"totally made up key": ListUnknown,
|
||||
} {
|
||||
if expect != expect.FromName(input) {
|
||||
t.Errorf("Expected %d for %s", expect, input)
|
||||
}
|
||||
// This is a cheap way to verify that ListAll actually allows everything but Unknown
|
||||
if got := expect.FromName(input); got != ListUnknown && got&ListAll == 0 {
|
||||
t.Errorf("Expected %s to match the ListAll filter", input)
|
||||
}
|
||||
}
|
||||
|
||||
filter := ListDeployed | ListPendingRollback
|
||||
if status := filter.FromName("deployed"); filter&status == 0 {
|
||||
t.Errorf("Expected %d to match mask %d", status, filter)
|
||||
}
|
||||
if status := filter.FromName("failed"); filter&status != 0 {
|
||||
t.Errorf("Expected %d to fail to match mask %d", status, filter)
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tiller
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"k8s.io/helm/pkg/hapi"
|
||||
"k8s.io/helm/pkg/hapi/release"
|
||||
relutil "k8s.io/helm/pkg/releaseutil"
|
||||
)
|
||||
|
||||
// ListReleases lists the releases found by the server.
|
||||
func (s *ReleaseServer) ListReleases(req *hapi.ListReleasesRequest) ([]*release.Release, error) {
|
||||
if len(req.StatusCodes) == 0 {
|
||||
req.StatusCodes = []release.ReleaseStatus{release.StatusDeployed}
|
||||
}
|
||||
|
||||
rels, err := s.Releases.ListFilterAll(func(r *release.Release) bool {
|
||||
for _, sc := range req.StatusCodes {
|
||||
if sc == r.Info.Status {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Filter) != 0 {
|
||||
rels, err = filterReleases(req.Filter, rels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
switch req.SortBy {
|
||||
case hapi.SortByName:
|
||||
relutil.SortByName(rels)
|
||||
case hapi.SortByLastReleased:
|
||||
relutil.SortByDate(rels)
|
||||
}
|
||||
|
||||
if req.SortOrder == hapi.SortDesc {
|
||||
ll := len(rels)
|
||||
rr := make([]*release.Release, ll)
|
||||
for i, item := range rels {
|
||||
rr[ll-i-1] = item
|
||||
}
|
||||
rels = rr
|
||||
}
|
||||
|
||||
return rels, nil
|
||||
}
|
||||
|
||||
func filterReleases(filter string, rels []*release.Release) ([]*release.Release, error) {
|
||||
preg, err := regexp.Compile(filter)
|
||||
if err != nil {
|
||||
return rels, err
|
||||
}
|
||||
matches := []*release.Release{}
|
||||
for _, r := range rels {
|
||||
if preg.MatchString(r.Name) {
|
||||
matches = append(matches, r)
|
||||
}
|
||||
}
|
||||
return matches, nil
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tiller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"k8s.io/helm/pkg/hapi"
|
||||
"k8s.io/helm/pkg/hapi/release"
|
||||
)
|
||||
|
||||
func TestListReleases(t *testing.T) {
|
||||
rs := rsFixture(t)
|
||||
num := 7
|
||||
for i := 0; i < num; i++ {
|
||||
rel := releaseStub()
|
||||
rel.Name = fmt.Sprintf("rel-%d", i)
|
||||
if err := rs.Releases.Create(rel); err != nil {
|
||||
t.Fatalf("Could not store mock release: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
rels, err := rs.ListReleases(&hapi.ListReleasesRequest{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed listing: %s", err)
|
||||
}
|
||||
|
||||
if len(rels) != num {
|
||||
t.Errorf("Expected %d releases, got %d", num, len(rels))
|
||||
}
|
||||
}
|
||||
|
||||
func TestListReleasesByStatus(t *testing.T) {
|
||||
rs := rsFixture(t)
|
||||
stubs := []*release.Release{
|
||||
namedReleaseStub("kamal", release.StatusDeployed),
|
||||
namedReleaseStub("astrolabe", release.StatusUninstalled),
|
||||
namedReleaseStub("octant", release.StatusFailed),
|
||||
namedReleaseStub("sextant", release.StatusUnknown),
|
||||
}
|
||||
for _, stub := range stubs {
|
||||
if err := rs.Releases.Create(stub); err != nil {
|
||||
t.Fatalf("Could not create stub: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
statusCodes []release.ReleaseStatus
|
||||
names []string
|
||||
}{
|
||||
{
|
||||
names: []string{"kamal"},
|
||||
statusCodes: []release.ReleaseStatus{release.StatusDeployed},
|
||||
},
|
||||
{
|
||||
names: []string{"astrolabe"},
|
||||
statusCodes: []release.ReleaseStatus{release.StatusUninstalled},
|
||||
},
|
||||
{
|
||||
names: []string{"kamal", "octant"},
|
||||
statusCodes: []release.ReleaseStatus{release.StatusDeployed, release.StatusFailed},
|
||||
},
|
||||
{
|
||||
names: []string{"kamal", "astrolabe", "octant", "sextant"},
|
||||
statusCodes: []release.ReleaseStatus{
|
||||
release.StatusDeployed,
|
||||
release.StatusUninstalled,
|
||||
release.StatusFailed,
|
||||
release.StatusUnknown,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
rels, err := rs.ListReleases(&hapi.ListReleasesRequest{StatusCodes: tt.statusCodes, Offset: "", Limit: 64})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed listing %d: %s", i, err)
|
||||
}
|
||||
|
||||
if len(tt.names) != len(rels) {
|
||||
t.Fatalf("Expected %d releases, got %d", len(tt.names), len(rels))
|
||||
}
|
||||
|
||||
for _, name := range tt.names {
|
||||
found := false
|
||||
for _, rel := range rels {
|
||||
if rel.Name == name {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("%d: Did not find name %q", i, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListReleasesSort(t *testing.T) {
|
||||
rs := rsFixture(t)
|
||||
|
||||
// Put them in by reverse order so that the mock doesn't "accidentally"
|
||||
// sort.
|
||||
num := 7
|
||||
for i := num; i > 0; i-- {
|
||||
rel := releaseStub()
|
||||
rel.Name = fmt.Sprintf("rel-%d", i)
|
||||
if err := rs.Releases.Create(rel); err != nil {
|
||||
t.Fatalf("Could not store mock release: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
limit := 6
|
||||
req := &hapi.ListReleasesRequest{
|
||||
Offset: "",
|
||||
Limit: int64(limit),
|
||||
SortBy: hapi.SortByName,
|
||||
}
|
||||
rels, err := rs.ListReleases(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed listing: %s", err)
|
||||
}
|
||||
|
||||
// if len(rels) != limit {
|
||||
// t.Errorf("Expected %d releases, got %d", limit, len(rels))
|
||||
// }
|
||||
|
||||
for i := 0; i < limit; i++ {
|
||||
n := fmt.Sprintf("rel-%d", i+1)
|
||||
if rels[i].Name != n {
|
||||
t.Errorf("Expected %q, got %q", n, rels[i].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListReleasesFilter(t *testing.T) {
|
||||
rs := rsFixture(t)
|
||||
names := []string{
|
||||
"axon",
|
||||
"dendrite",
|
||||
"neuron",
|
||||
"neuroglia",
|
||||
"synapse",
|
||||
"nucleus",
|
||||
"organelles",
|
||||
}
|
||||
num := 7
|
||||
for i := 0; i < num; i++ {
|
||||
rel := releaseStub()
|
||||
rel.Name = names[i]
|
||||
if err := rs.Releases.Create(rel); err != nil {
|
||||
t.Fatalf("Could not store mock release: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
req := &hapi.ListReleasesRequest{
|
||||
Offset: "",
|
||||
Limit: 64,
|
||||
Filter: "neuro[a-z]+",
|
||||
SortBy: hapi.SortByName,
|
||||
}
|
||||
rels, err := rs.ListReleases(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed listing: %s", err)
|
||||
}
|
||||
|
||||
if len(rels) != 2 {
|
||||
t.Errorf("Expected 2 releases, got %d", len(rels))
|
||||
}
|
||||
|
||||
if rels[0].Name != "neuroglia" {
|
||||
t.Errorf("Unexpected sort order: %v.", rels)
|
||||
}
|
||||
if rels[1].Name != "neuron" {
|
||||
t.Errorf("Unexpected sort order: %v.", rels)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue