diff --git a/docs/chart_template_guide/builtin_objects.md b/docs/chart_template_guide/builtin_objects.md index f7b2857bc..77d95f5f3 100644 --- a/docs/chart_template_guide/builtin_objects.md +++ b/docs/chart_template_guide/builtin_objects.md @@ -22,7 +22,7 @@ In the previous section, we use `{{.Release.Name}}` to insert the name of a rele - `Files.GetBytes` is a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images. - `Capabilities`: This provides information about what capabilities the Kubernetes cluster supports. - `Capabilities.APIVersions` is a set of versions. - - `Capabilities.APIVersions.Has $version` indicates whether a version (`batch/v1`) is enabled on the cluster. + - `Capabilities.APIVersions.Has $version` indicates whether a version (e.g., `batch/v1`) or resource (e.g., `apps/v1/Deployment`) is available on the cluster. Note, resources were not available before Helm v2.15. - `Capabilities.KubeVersion` provides a way to look up the Kubernetes version. It has the following values: `Major`, `Minor`, `GitVersion`, `GitCommit`, `GitTreeState`, `BuildDate`, `GoVersion`, `Compiler`, and `Platform`. - `Capabilities.TillerVersion` provides a way to look up the Tiller version. It has the following values: `SemVer`, `GitCommit`, and `GitTreeState`. - `Template`: Contains information about the current template that is being executed diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index c5638d20d..291135706 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -251,7 +251,7 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e if err != nil { return nil, err } - vs, err := GetVersionSet(disc) + vs, err := GetAllVersionSet(disc) if err != nil { return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err) } @@ -262,6 +262,59 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e }, nil } +// GetAllVersionSet retrieves a set of available k8s API versions and objects +// +// This is a different function from GetVersionSet because the signature changed. +// To keep compatibility through the public functions this needed to be a new +// function.GetAllVersionSet +// TODO(mattfarina): In Helm v3 merge with GetVersionSet +func GetAllVersionSet(client discovery.ServerResourcesInterface) (chartutil.VersionSet, error) { + groups, resources, err := client.ServerGroupsAndResources() + if err != nil { + return chartutil.DefaultVersionSet, err + } + + // FIXME: The Kubernetes test fixture for cli appears to always return nil + // for calls to Discovery().ServerGroupsAndResources(). So in this case, we + // return the default API list. This is also a safe value to return in any + // other odd-ball case. + if len(groups) == 0 && len(resources) == 0 { + return chartutil.DefaultVersionSet, nil + } + + versionMap := make(map[string]interface{}) + versions := []string{} + + // Extract the groups + for _, g := range groups { + for _, gv := range g.Versions { + versionMap[gv.GroupVersion] = struct{}{} + } + } + + // Extract the resources + var id string + var ok bool + for _, r := range resources { + for _, rl := range r.APIResources { + + // A Kind at a GroupVersion can show up more than once. We only want + // it displayed once in the final output. + id = path.Join(r.GroupVersion, rl.Kind) + if _, ok = versionMap[id]; !ok { + versionMap[id] = struct{}{} + } + } + } + + // Convert to a form that NewVersionSet can use + for k := range versionMap { + versions = append(versions, k) + } + + return chartutil.NewVersionSet(versions...), nil +} + // GetVersionSet retrieves a set of available k8s API versions func GetVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) { groups, err := client.ServerGroups() diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index d70221ed1..6fc1d48f6 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -338,6 +338,20 @@ func TestValidName(t *testing.T) { } } +func TestGetAllVersionSet(t *testing.T) { + rs := rsFixture() + vs, err := GetAllVersionSet(rs.clientset.Discovery()) + if err != nil { + t.Error(err) + } + if !vs.Has("v1") { + t.Errorf("Expected supported versions to at least include v1.") + } + if vs.Has("nosuchversion/v1") { + t.Error("Non-existent version is reported found.") + } +} + func TestGetVersionSet(t *testing.T) { rs := rsFixture() vs, err := GetVersionSet(rs.clientset.Discovery())