Bump helm.sh/helm/v3 from 3.10.3 to 3.11.1 (#5528)
This commit is contained in:
@@ -29,7 +29,7 @@ var (
|
||||
//
|
||||
// Increment major number for new feature additions and behavioral changes.
|
||||
// Increment minor number for bug fixes and performance enhancements.
|
||||
version = "v3.10"
|
||||
version = "v3.11"
|
||||
|
||||
// metadata is extra build time data
|
||||
metadata = ""
|
||||
|
||||
13
vendor/helm.sh/helm/v3/pkg/action/action.go
vendored
13
vendor/helm.sh/helm/v3/pkg/action/action.go
vendored
@@ -101,8 +101,9 @@ type Configuration struct {
|
||||
//
|
||||
// TODO: This function is badly in need of a refactor.
|
||||
// TODO: As part of the refactor the duplicate code in cmd/helm/template.go should be removed
|
||||
// This code has to do with writing files to disk.
|
||||
func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun bool) ([]*release.Hook, *bytes.Buffer, string, error) {
|
||||
//
|
||||
// This code has to do with writing files to disk.
|
||||
func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun, enableDNS bool) ([]*release.Hook, *bytes.Buffer, string, error) {
|
||||
hs := []*release.Hook{}
|
||||
b := bytes.NewBuffer(nil)
|
||||
|
||||
@@ -130,9 +131,13 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
|
||||
if err != nil {
|
||||
return hs, b, "", err
|
||||
}
|
||||
files, err2 = engine.RenderWithClient(ch, values, restConfig)
|
||||
e := engine.New(restConfig)
|
||||
e.EnableDNS = enableDNS
|
||||
files, err2 = e.Render(ch, values)
|
||||
} else {
|
||||
files, err2 = engine.Render(ch, values)
|
||||
var e engine.Engine
|
||||
e.EnableDNS = enableDNS
|
||||
files, err2 = e.Render(ch, values)
|
||||
}
|
||||
|
||||
if err2 != nil {
|
||||
|
||||
15
vendor/helm.sh/helm/v3/pkg/action/install.go
vendored
15
vendor/helm.sh/helm/v3/pkg/action/install.go
vendored
@@ -69,6 +69,7 @@ type Install struct {
|
||||
ChartPathOptions
|
||||
|
||||
ClientOnly bool
|
||||
Force bool
|
||||
CreateNamespace bool
|
||||
DryRun bool
|
||||
DisableHooks bool
|
||||
@@ -96,6 +97,8 @@ type Install struct {
|
||||
APIVersions chartutil.VersionSet
|
||||
// Used by helm template to render charts with .Release.IsUpgrade. Ignored if Dry-Run is false
|
||||
IsUpgrade bool
|
||||
// Enable DNS lookups when rendering templates
|
||||
EnableDNS bool
|
||||
// Used by helm template to add the release as part of OutputDir path
|
||||
// OutputDir/<ReleaseName>
|
||||
UseReleaseName bool
|
||||
@@ -256,7 +259,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
rel := i.createRelease(chrt, vals)
|
||||
|
||||
var manifestDoc *bytes.Buffer
|
||||
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun)
|
||||
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun, i.EnableDNS)
|
||||
// Even for errors, attach this if available
|
||||
if manifestDoc != nil {
|
||||
rel.Manifest = manifestDoc.String()
|
||||
@@ -372,7 +375,7 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
|
||||
return
|
||||
}
|
||||
} else if len(resources) > 0 {
|
||||
if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, false); err != nil {
|
||||
if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, i.Force); err != nil {
|
||||
i.reportToRun(c, rel, err)
|
||||
return
|
||||
}
|
||||
@@ -456,10 +459,10 @@ func (i *Install) failRelease(rel *release.Release, err error) (*release.Release
|
||||
//
|
||||
// Roughly, this will return an error if name is
|
||||
//
|
||||
// - empty
|
||||
// - too long
|
||||
// - already in use, and not deleted
|
||||
// - used by a deleted release, and i.Replace is false
|
||||
// - empty
|
||||
// - too long
|
||||
// - already in use, and not deleted
|
||||
// - used by a deleted release, and i.Replace is false
|
||||
func (i *Install) availableName() error {
|
||||
start := i.ReleaseName
|
||||
|
||||
|
||||
46
vendor/helm.sh/helm/v3/pkg/action/status.go
vendored
46
vendor/helm.sh/helm/v3/pkg/action/status.go
vendored
@@ -17,6 +17,10 @@ limitations under the License.
|
||||
package action
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
)
|
||||
|
||||
@@ -32,6 +36,14 @@ type Status struct {
|
||||
// only affect print type table.
|
||||
// TODO Helm 4: Remove this flag and output the description by default.
|
||||
ShowDescription bool
|
||||
|
||||
// ShowResources sets if the resources should be retrieved with the status.
|
||||
// TODO Helm 4: Remove this flag and output the resources by default.
|
||||
ShowResources bool
|
||||
|
||||
// ShowResourcesTable is used with ShowResources. When true this will cause
|
||||
// the resulting objects to be retrieved as a kind=table.
|
||||
ShowResourcesTable bool
|
||||
}
|
||||
|
||||
// NewStatus creates a new Status object with the given configuration.
|
||||
@@ -47,5 +59,37 @@ func (s *Status) Run(name string) (*release.Release, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.cfg.releaseContent(name, s.Version)
|
||||
if !s.ShowResources {
|
||||
return s.cfg.releaseContent(name, s.Version)
|
||||
}
|
||||
|
||||
rel, err := s.cfg.releaseContent(name, s.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if kubeClient, ok := s.cfg.KubeClient.(kube.InterfaceResources); ok {
|
||||
var resources kube.ResourceList
|
||||
if s.ShowResourcesTable {
|
||||
resources, err = kubeClient.BuildTable(bytes.NewBufferString(rel.Manifest), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
resources, err = s.cfg.KubeClient.Build(bytes.NewBufferString(rel.Manifest), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := kubeClient.Get(resources, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rel.Info.Resources = resp
|
||||
|
||||
return rel, nil
|
||||
}
|
||||
return nil, errors.New("unable to get kubeClient with interface InterfaceResources")
|
||||
}
|
||||
|
||||
4
vendor/helm.sh/helm/v3/pkg/action/upgrade.go
vendored
4
vendor/helm.sh/helm/v3/pkg/action/upgrade.go
vendored
@@ -103,6 +103,8 @@ type Upgrade struct {
|
||||
DependencyUpdate bool
|
||||
// Lock to control raceconditions when the process receives a SIGTERM
|
||||
Lock sync.Mutex
|
||||
// Enable DNS lookups when rendering templates
|
||||
EnableDNS bool
|
||||
}
|
||||
|
||||
type resultMessage struct {
|
||||
@@ -231,7 +233,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun)
|
||||
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun, u.EnableDNS)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ type Dependency struct {
|
||||
// loaded.
|
||||
func (d *Dependency) Validate() error {
|
||||
if d == nil {
|
||||
return ValidationError("dependency cannot be an empty list")
|
||||
return ValidationError("dependencies must not contain empty or null nodes")
|
||||
}
|
||||
d.Name = sanitizeString(d.Name)
|
||||
d.Version = sanitizeString(d.Version)
|
||||
|
||||
2
vendor/helm.sh/helm/v3/pkg/chart/metadata.go
vendored
2
vendor/helm.sh/helm/v3/pkg/chart/metadata.go
vendored
@@ -35,7 +35,7 @@ type Maintainer struct {
|
||||
// Validate checks valid data and sanitizes string characters.
|
||||
func (m *Maintainer) Validate() error {
|
||||
if m == nil {
|
||||
return ValidationError("maintainer cannot be an empty list")
|
||||
return ValidationError("maintainers must not contain empty or null nodes")
|
||||
}
|
||||
m.Name = sanitizeString(m.Name)
|
||||
m.Email = sanitizeString(m.Email)
|
||||
|
||||
@@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*Package cli describes the operating environment for the Helm CLI.
|
||||
/*
|
||||
Package cli describes the operating environment for the Helm CLI.
|
||||
|
||||
Helm's environment encapsulates all of the service dependencies Helm has.
|
||||
These dependencies are expressed as interfaces so that alternate implementations
|
||||
@@ -24,6 +25,7 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -32,6 +34,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"helm.sh/helm/v3/internal/version"
|
||||
"helm.sh/helm/v3/pkg/helmpath"
|
||||
)
|
||||
|
||||
@@ -116,6 +119,10 @@ func New() *EnvSettings {
|
||||
ImpersonateGroup: &env.KubeAsGroups,
|
||||
WrapConfigFn: func(config *rest.Config) *rest.Config {
|
||||
config.Burst = env.BurstLimit
|
||||
config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
|
||||
return &retryingRoundTripper{wrapped: rt}
|
||||
})
|
||||
config.UserAgent = version.GetUserAgent()
|
||||
return config
|
||||
},
|
||||
}
|
||||
|
||||
80
vendor/helm.sh/helm/v3/pkg/cli/roundtripper.go
vendored
Normal file
80
vendor/helm.sh/helm/v3/pkg/cli/roundtripper.go
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
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 cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type retryingRoundTripper struct {
|
||||
wrapped http.RoundTripper
|
||||
}
|
||||
|
||||
func (rt *retryingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return rt.roundTrip(req, 1, nil)
|
||||
}
|
||||
|
||||
func (rt *retryingRoundTripper) roundTrip(req *http.Request, retry int, prevResp *http.Response) (*http.Response, error) {
|
||||
if retry < 0 {
|
||||
return prevResp, nil
|
||||
}
|
||||
resp, rtErr := rt.wrapped.RoundTrip(req)
|
||||
if rtErr != nil {
|
||||
return resp, rtErr
|
||||
}
|
||||
if resp.StatusCode < 500 {
|
||||
return resp, rtErr
|
||||
}
|
||||
if resp.Header.Get("content-type") != "application/json" {
|
||||
return resp, rtErr
|
||||
}
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return resp, rtErr
|
||||
}
|
||||
|
||||
var ke kubernetesError
|
||||
r := bytes.NewReader(b)
|
||||
err = json.NewDecoder(r).Decode(&ke)
|
||||
r.Seek(0, io.SeekStart)
|
||||
resp.Body = io.NopCloser(r)
|
||||
if err != nil {
|
||||
return resp, rtErr
|
||||
}
|
||||
if ke.Code < 500 {
|
||||
return resp, rtErr
|
||||
}
|
||||
// Matches messages like "etcdserver: leader changed"
|
||||
if strings.HasSuffix(ke.Message, "etcdserver: leader changed") {
|
||||
return rt.roundTrip(req, retry-1, resp)
|
||||
}
|
||||
// Matches messages like "rpc error: code = Unknown desc = raft proposal dropped"
|
||||
if strings.HasSuffix(ke.Message, "raft proposal dropped") {
|
||||
return rt.roundTrip(req, retry-1, resp)
|
||||
}
|
||||
return resp, rtErr
|
||||
}
|
||||
|
||||
type kubernetesError struct {
|
||||
Message string `json:"message"`
|
||||
Code int `json:"code"`
|
||||
}
|
||||
@@ -294,32 +294,13 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, er
|
||||
}
|
||||
|
||||
// TODO: Seems that picking first URL is not fully correct
|
||||
u, err = url.Parse(cv.URLs[0])
|
||||
resolvedURL, err := repo.ResolveReferenceURL(rc.URL, cv.URLs[0])
|
||||
|
||||
if err != nil {
|
||||
return u, errors.Errorf("invalid chart URL format: %s", ref)
|
||||
}
|
||||
|
||||
// If the URL is relative (no scheme), prepend the chart repo's base URL
|
||||
if !u.IsAbs() {
|
||||
repoURL, err := url.Parse(rc.URL)
|
||||
if err != nil {
|
||||
return repoURL, err
|
||||
}
|
||||
q := repoURL.Query()
|
||||
// We need a trailing slash for ResolveReference to work, but make sure there isn't already one
|
||||
repoURL.RawPath = strings.TrimSuffix(repoURL.RawPath, "/") + "/"
|
||||
repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/"
|
||||
u = repoURL.ResolveReference(u)
|
||||
u.RawQuery = q.Encode()
|
||||
// TODO add user-agent
|
||||
if _, err := getter.NewHTTPGetter(getter.WithURL(rc.URL)); err != nil {
|
||||
return repoURL, err
|
||||
}
|
||||
return u, err
|
||||
}
|
||||
|
||||
// TODO add user-agent
|
||||
return u, nil
|
||||
return url.Parse(resolvedURL)
|
||||
}
|
||||
|
||||
// VerifyChart takes a path to a chart archive and a keyring, and verifies the chart.
|
||||
|
||||
17
vendor/helm.sh/helm/v3/pkg/engine/engine.go
vendored
17
vendor/helm.sh/helm/v3/pkg/engine/engine.go
vendored
@@ -42,6 +42,15 @@ type Engine struct {
|
||||
LintMode bool
|
||||
// the rest config to connect to the kubernetes api
|
||||
config *rest.Config
|
||||
// EnableDNS tells the engine to allow DNS lookups when rendering templates
|
||||
EnableDNS bool
|
||||
}
|
||||
|
||||
// New creates a new instance of Engine using the passed in rest config.
|
||||
func New(config *rest.Config) Engine {
|
||||
return Engine{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Render takes a chart, optional values, and value overrides, and attempts to render the Go templates.
|
||||
@@ -189,6 +198,14 @@ func (e Engine) initFunMap(t *template.Template, referenceTpls map[string]render
|
||||
funcMap["lookup"] = NewLookupFunction(e.config)
|
||||
}
|
||||
|
||||
// When DNS lookups are not enabled override the sprig function and return
|
||||
// an empty string.
|
||||
if !e.EnableDNS {
|
||||
funcMap["getHostByName"] = func(name string) string {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
t.Funcs(funcMap)
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,6 @@ func (g *HTTPGetter) httpClient() (*http.Client, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "can't create TLS config for client")
|
||||
}
|
||||
tlsConf.BuildNameToCertificate()
|
||||
|
||||
sni, err := urlutil.ExtractHostname(g.opts.url)
|
||||
if err != nil {
|
||||
|
||||
199
vendor/helm.sh/helm/v3/pkg/kube/client.go
vendored
199
vendor/helm.sh/helm/v3/pkg/kube/client.go
vendored
@@ -17,12 +17,14 @@ limitations under the License.
|
||||
package kube // import "helm.sh/helm/v3/pkg/kube"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -38,7 +40,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
@@ -47,6 +51,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
cachetools "k8s.io/client-go/tools/cache"
|
||||
watchtools "k8s.io/client-go/tools/watch"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
@@ -132,6 +137,141 @@ func (c *Client) Create(resources ResourceList) (*Result, error) {
|
||||
return &Result{Created: resources}, nil
|
||||
}
|
||||
|
||||
func transformRequests(req *rest.Request) {
|
||||
tableParam := strings.Join([]string{
|
||||
fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1.SchemeGroupVersion.Version, metav1.GroupName),
|
||||
fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName),
|
||||
"application/json",
|
||||
}, ",")
|
||||
req.SetHeader("Accept", tableParam)
|
||||
|
||||
// if sorting, ensure we receive the full object in order to introspect its fields via jsonpath
|
||||
req.Param("includeObject", "Object")
|
||||
}
|
||||
|
||||
// Get retrieves the resource objects supplied. If related is set to true the
|
||||
// related pods are fetched as well. If the passed in resources are a table kind
|
||||
// the related resources will also be fetched as kind=table.
|
||||
func (c *Client) Get(resources ResourceList, related bool) (map[string][]runtime.Object, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
objs := make(map[string][]runtime.Object)
|
||||
|
||||
podSelectors := []map[string]string{}
|
||||
err := resources.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gvk := info.ResourceMapping().GroupVersionKind
|
||||
vk := gvk.Version + "/" + gvk.Kind
|
||||
obj, err := getResource(info)
|
||||
if err != nil {
|
||||
fmt.Fprintf(buf, "Get resource %s failed, err:%v\n", info.Name, err)
|
||||
} else {
|
||||
objs[vk] = append(objs[vk], obj)
|
||||
|
||||
// Only fetch related pods if they are requested
|
||||
if related {
|
||||
// Discover if the existing object is a table. If it is, request
|
||||
// the pods as Tables. Otherwise request them normally.
|
||||
objGVK := obj.GetObjectKind().GroupVersionKind()
|
||||
var isTable bool
|
||||
if objGVK.Kind == "Table" {
|
||||
isTable = true
|
||||
}
|
||||
|
||||
objs, err = c.getSelectRelationPod(info, objs, isTable, &podSelectors)
|
||||
if err != nil {
|
||||
c.Log("Warning: get the relation pod is failed, err:%s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
func (c *Client) getSelectRelationPod(info *resource.Info, objs map[string][]runtime.Object, table bool, podSelectors *[]map[string]string) (map[string][]runtime.Object, error) {
|
||||
if info == nil {
|
||||
return objs, nil
|
||||
}
|
||||
c.Log("get relation pod of object: %s/%s/%s", info.Namespace, info.Mapping.GroupVersionKind.Kind, info.Name)
|
||||
selector, ok, _ := getSelectorFromObject(info.Object)
|
||||
if !ok {
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
for index := range *podSelectors {
|
||||
if reflect.DeepEqual((*podSelectors)[index], selector) {
|
||||
// check if pods for selectors are already added. This avoids duplicate printing of pods
|
||||
return objs, nil
|
||||
}
|
||||
}
|
||||
|
||||
*podSelectors = append(*podSelectors, selector)
|
||||
|
||||
var infos []*resource.Info
|
||||
var err error
|
||||
if table {
|
||||
infos, err = c.Factory.NewBuilder().
|
||||
Unstructured().
|
||||
ContinueOnError().
|
||||
NamespaceParam(info.Namespace).
|
||||
DefaultNamespace().
|
||||
ResourceTypes("pods").
|
||||
LabelSelector(labels.Set(selector).AsSelector().String()).
|
||||
TransformRequests(transformRequests).
|
||||
Do().Infos()
|
||||
if err != nil {
|
||||
return objs, err
|
||||
}
|
||||
} else {
|
||||
infos, err = c.Factory.NewBuilder().
|
||||
Unstructured().
|
||||
ContinueOnError().
|
||||
NamespaceParam(info.Namespace).
|
||||
DefaultNamespace().
|
||||
ResourceTypes("pods").
|
||||
LabelSelector(labels.Set(selector).AsSelector().String()).
|
||||
Do().Infos()
|
||||
if err != nil {
|
||||
return objs, err
|
||||
}
|
||||
}
|
||||
vk := "v1/Pod(related)"
|
||||
|
||||
for _, info := range infos {
|
||||
objs[vk] = append(objs[vk], info.Object)
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
func getSelectorFromObject(obj runtime.Object) (map[string]string, bool, error) {
|
||||
typed := obj.(*unstructured.Unstructured)
|
||||
kind := typed.Object["kind"]
|
||||
switch kind {
|
||||
case "ReplicaSet", "Deployment", "StatefulSet", "DaemonSet", "Job":
|
||||
return unstructured.NestedStringMap(typed.Object, "spec", "selector", "matchLabels")
|
||||
case "ReplicationController":
|
||||
return unstructured.NestedStringMap(typed.Object, "spec", "selector")
|
||||
default:
|
||||
return nil, false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getResource(info *resource.Info) (runtime.Object, error) {
|
||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// Wait waits up to the given timeout for the specified resources to be ready.
|
||||
func (c *Client) Wait(resources ResourceList, timeout time.Duration) error {
|
||||
cs, err := c.getKubeClient()
|
||||
@@ -215,6 +355,33 @@ func (c *Client) Build(reader io.Reader, validate bool) (ResourceList, error) {
|
||||
return result, scrubValidationError(err)
|
||||
}
|
||||
|
||||
// BuildTable validates for Kubernetes objects and returns unstructured infos.
|
||||
// The returned kind is a Table.
|
||||
func (c *Client) BuildTable(reader io.Reader, validate bool) (ResourceList, error) {
|
||||
validationDirective := metav1.FieldValidationIgnore
|
||||
if validate {
|
||||
validationDirective = metav1.FieldValidationStrict
|
||||
}
|
||||
|
||||
dynamicClient, err := c.Factory.DynamicClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier := resource.NewQueryParamVerifier(dynamicClient, c.Factory.OpenAPIGetter(), resource.QueryParamFieldValidation)
|
||||
schema, err := c.Factory.Validator(validationDirective, verifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := c.newBuilder().
|
||||
Unstructured().
|
||||
Schema(schema).
|
||||
Stream(reader, "").
|
||||
TransformRequests(transformRequests).
|
||||
Do().Infos()
|
||||
return result, scrubValidationError(err)
|
||||
}
|
||||
|
||||
// Update takes the current list of objects and target list of objects and
|
||||
// creates resources that don't already exist, updates resources that have been
|
||||
// modified in the target configuration, and deletes resources from the current
|
||||
@@ -308,16 +475,20 @@ func (c *Client) Delete(resources ResourceList) (*Result, []error) {
|
||||
mtx := sync.Mutex{}
|
||||
err := perform(resources, func(info *resource.Info) error {
|
||||
c.Log("Starting delete for %q %s", info.Name, info.Mapping.GroupVersionKind.Kind)
|
||||
if err := c.skipIfNotFound(deleteResource(info)); err != nil {
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
// Collect the error and continue on
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
err := deleteResource(info)
|
||||
if err == nil || apierrors.IsNotFound(err) {
|
||||
if err != nil {
|
||||
c.Log("Ignoring delete failure for %q %s: %v", info.Name, info.Mapping.GroupVersionKind, err)
|
||||
}
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
res.Deleted = append(res.Deleted, info)
|
||||
return nil
|
||||
}
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
// Collect the error and continue on
|
||||
errs = append(errs, err)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -334,14 +505,6 @@ func (c *Client) Delete(resources ResourceList) (*Result, []error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) skipIfNotFound(err error) error {
|
||||
if apierrors.IsNotFound(err) {
|
||||
c.Log("%v", err)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) watchTimeout(t time.Duration) func(*resource.Info) error {
|
||||
return func(info *resource.Info) error {
|
||||
return c.watchUntilReady(t, info)
|
||||
@@ -356,10 +519,10 @@ func (c *Client) watchTimeout(t time.Duration) func(*resource.Info) error {
|
||||
// For most kinds, it checks to see if the resource is marked as Added or Modified
|
||||
// by the Kubernetes event stream. For some kinds, it does more:
|
||||
//
|
||||
// - Jobs: A job is marked "Ready" when it has successfully completed. This is
|
||||
// ascertained by watching the Status fields in a job's output.
|
||||
// - Pods: A pod is marked "Ready" when it has successfully completed. This is
|
||||
// ascertained by watching the status.phase field in a pod's output.
|
||||
// - Jobs: A job is marked "Ready" when it has successfully completed. This is
|
||||
// ascertained by watching the Status fields in a job's output.
|
||||
// - Pods: A pod is marked "Ready" when it has successfully completed. This is
|
||||
// ascertained by watching the status.phase field in a pod's output.
|
||||
//
|
||||
// Handling for other kinds will be added as necessary.
|
||||
func (c *Client) WatchUntilReady(resources ResourceList, timeout time.Duration) error {
|
||||
|
||||
19
vendor/helm.sh/helm/v3/pkg/kube/fake/fake.go
vendored
19
vendor/helm.sh/helm/v3/pkg/kube/fake/fake.go
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
@@ -33,11 +34,13 @@ import (
|
||||
type FailingKubeClient struct {
|
||||
PrintingKubeClient
|
||||
CreateError error
|
||||
GetError error
|
||||
WaitError error
|
||||
DeleteError error
|
||||
WatchUntilReadyError error
|
||||
UpdateError error
|
||||
BuildError error
|
||||
BuildTableError error
|
||||
BuildUnstructuredError error
|
||||
WaitAndGetCompletedPodPhaseError error
|
||||
WaitDuration time.Duration
|
||||
@@ -51,6 +54,14 @@ func (f *FailingKubeClient) Create(resources kube.ResourceList) (*kube.Result, e
|
||||
return f.PrintingKubeClient.Create(resources)
|
||||
}
|
||||
|
||||
// Get returns the configured error if set or prints
|
||||
func (f *FailingKubeClient) Get(resources kube.ResourceList, related bool) (map[string][]runtime.Object, error) {
|
||||
if f.GetError != nil {
|
||||
return nil, f.GetError
|
||||
}
|
||||
return f.PrintingKubeClient.Get(resources, related)
|
||||
}
|
||||
|
||||
// Waits the amount of time defined on f.WaitDuration, then returns the configured error if set or prints.
|
||||
func (f *FailingKubeClient) Wait(resources kube.ResourceList, d time.Duration) error {
|
||||
time.Sleep(f.WaitDuration)
|
||||
@@ -108,6 +119,14 @@ func (f *FailingKubeClient) Build(r io.Reader, _ bool) (kube.ResourceList, error
|
||||
return f.PrintingKubeClient.Build(r, false)
|
||||
}
|
||||
|
||||
// BuildTable returns the configured error if set or prints
|
||||
func (f *FailingKubeClient) BuildTable(r io.Reader, _ bool) (kube.ResourceList, error) {
|
||||
if f.BuildTableError != nil {
|
||||
return []*resource.Info{}, f.BuildTableError
|
||||
}
|
||||
return f.PrintingKubeClient.BuildTable(r, false)
|
||||
}
|
||||
|
||||
// WaitAndGetCompletedPodPhase returns the configured error if set or prints
|
||||
func (f *FailingKubeClient) WaitAndGetCompletedPodPhase(s string, d time.Duration) (v1.PodPhase, error) {
|
||||
if f.WaitAndGetCompletedPodPhaseError != nil {
|
||||
|
||||
14
vendor/helm.sh/helm/v3/pkg/kube/fake/printer.go
vendored
14
vendor/helm.sh/helm/v3/pkg/kube/fake/printer.go
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
@@ -47,6 +48,14 @@ func (p *PrintingKubeClient) Create(resources kube.ResourceList) (*kube.Result,
|
||||
return &kube.Result{Created: resources}, nil
|
||||
}
|
||||
|
||||
func (p *PrintingKubeClient) Get(resources kube.ResourceList, related bool) (map[string][]runtime.Object, error) {
|
||||
_, err := io.Copy(p.Out, bufferize(resources))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return make(map[string][]runtime.Object), nil
|
||||
}
|
||||
|
||||
func (p *PrintingKubeClient) Wait(resources kube.ResourceList, _ time.Duration) error {
|
||||
_, err := io.Copy(p.Out, bufferize(resources))
|
||||
return err
|
||||
@@ -96,6 +105,11 @@ func (p *PrintingKubeClient) Build(_ io.Reader, _ bool) (kube.ResourceList, erro
|
||||
return []*resource.Info{}, nil
|
||||
}
|
||||
|
||||
// BuildTable implements KubeClient BuildTable.
|
||||
func (p *PrintingKubeClient) BuildTable(_ io.Reader, _ bool) (kube.ResourceList, error) {
|
||||
return []*resource.Info{}, nil
|
||||
}
|
||||
|
||||
// WaitAndGetCompletedPodPhase implements KubeClient WaitAndGetCompletedPodPhase.
|
||||
func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(_ string, _ time.Duration) (v1.PodPhase, error) {
|
||||
return v1.PodSucceeded, nil
|
||||
|
||||
24
vendor/helm.sh/helm/v3/pkg/kube/interface.go
vendored
24
vendor/helm.sh/helm/v3/pkg/kube/interface.go
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// Interface represents a client capable of communicating with the Kubernetes API.
|
||||
@@ -78,5 +79,28 @@ type InterfaceExt interface {
|
||||
WaitForDelete(resources ResourceList, timeout time.Duration) error
|
||||
}
|
||||
|
||||
// InterfaceResources is introduced to avoid breaking backwards compatibility for Interface implementers.
|
||||
//
|
||||
// TODO Helm 4: Remove InterfaceResources and integrate its method(s) into the Interface.
|
||||
type InterfaceResources interface {
|
||||
// Get details of deployed resources.
|
||||
// The first argument is a list of resources to get. The second argument
|
||||
// specifies if related pods should be fetched. For example, the pods being
|
||||
// managed by a deployment.
|
||||
Get(resources ResourceList, related bool) (map[string][]runtime.Object, error)
|
||||
|
||||
// BuildTable creates a resource list from a Reader. This differs from
|
||||
// Interface.Build() in that a table kind is returned. A table is useful
|
||||
// if you want to use a printer to display the information.
|
||||
//
|
||||
// Reader must contain a YAML stream (one or more YAML documents separated
|
||||
// by "\n---\n")
|
||||
//
|
||||
// Validates against OpenAPI schema if validate is true.
|
||||
// TODO Helm 4: Integrate into Build with an argument
|
||||
BuildTable(reader io.Reader, validate bool) (ResourceList, error)
|
||||
}
|
||||
|
||||
var _ Interface = (*Client)(nil)
|
||||
var _ InterfaceExt = (*Client)(nil)
|
||||
var _ InterfaceResources = (*Client)(nil)
|
||||
|
||||
2
vendor/helm.sh/helm/v3/pkg/kube/ready.go
vendored
2
vendor/helm.sh/helm/v3/pkg/kube/ready.go
vendored
@@ -291,7 +291,7 @@ func (c *ReadyChecker) daemonSetReady(ds *appsv1.DaemonSet) bool {
|
||||
c.log("DaemonSet is not ready: %s/%s. %d out of %d expected pods have been scheduled", ds.Namespace, ds.Name, ds.Status.UpdatedNumberScheduled, ds.Status.DesiredNumberScheduled)
|
||||
return false
|
||||
}
|
||||
maxUnavailable, err := intstr.GetValueFromIntOrPercent(ds.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable, int(ds.Status.DesiredNumberScheduled), true)
|
||||
maxUnavailable, err := intstr.GetScaledValueFromIntOrPercent(ds.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable, int(ds.Status.DesiredNumberScheduled), true)
|
||||
if err != nil {
|
||||
// If for some reason the value is invalid, set max unavailable to the
|
||||
// number of desired replicas. This is the same behavior as the
|
||||
|
||||
26
vendor/helm.sh/helm/v3/pkg/kube/wait.go
vendored
26
vendor/helm.sh/helm/v3/pkg/kube/wait.go
vendored
@@ -22,9 +22,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"google.golang.org/grpc/codes"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
@@ -35,6 +32,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
@@ -44,22 +42,6 @@ type waiter struct {
|
||||
log func(string, ...interface{})
|
||||
}
|
||||
|
||||
// isServiceUnavailable helps figure out if the error is caused by etcd not being available
|
||||
// see https://pkg.go.dev/go.etcd.io/etcd/api/v3/v3rpc/rpctypes for `codes.Unavailable`
|
||||
// we use this to check if the etcdserver is not available we should retry in case
|
||||
// this is a temporary situation
|
||||
func isServiceUnavailable(err error) bool {
|
||||
if err != nil {
|
||||
err = rpctypes.Error(err)
|
||||
if ev, ok := err.(rpctypes.EtcdError); ok {
|
||||
if ev.Code() == codes.Unavailable {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// waitForResources polls to get the current status of all pods, PVCs, Services and
|
||||
// Jobs(optional) until all are ready or a timeout is reached
|
||||
func (w *waiter) waitForResources(created ResourceList) error {
|
||||
@@ -72,9 +54,6 @@ func (w *waiter) waitForResources(created ResourceList) error {
|
||||
for _, v := range created {
|
||||
ready, err := w.c.IsReady(ctx, v)
|
||||
if !ready || err != nil {
|
||||
if isServiceUnavailable(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@@ -93,9 +72,6 @@ func (w *waiter) waitForDeletedResources(deleted ResourceList) error {
|
||||
for _, v := range deleted {
|
||||
err := v.Get()
|
||||
if err == nil || !apierrors.IsNotFound(err) {
|
||||
if isServiceUnavailable(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/helm.sh/helm/v3/pkg/release/info.go
vendored
4
vendor/helm.sh/helm/v3/pkg/release/info.go
vendored
@@ -16,6 +16,8 @@ limitations under the License.
|
||||
package release
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"helm.sh/helm/v3/pkg/time"
|
||||
)
|
||||
|
||||
@@ -33,4 +35,6 @@ type Info struct {
|
||||
Status Status `json:"status,omitempty"`
|
||||
// Contains the rendered templates/NOTES.txt if available
|
||||
Notes string `json:"notes,omitempty"`
|
||||
// Contains the deployed resources information
|
||||
Resources map[string][]runtime.Object `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
32
vendor/helm.sh/helm/v3/pkg/repo/chartrepo.go
vendored
32
vendor/helm.sh/helm/v3/pkg/repo/chartrepo.go
vendored
@@ -25,7 +25,6 @@ import (
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -116,15 +115,11 @@ func (r *ChartRepository) Load() error {
|
||||
|
||||
// DownloadIndexFile fetches the index from a repository.
|
||||
func (r *ChartRepository) DownloadIndexFile() (string, error) {
|
||||
parsedURL, err := url.Parse(r.Config.URL)
|
||||
indexURL, err := ResolveReferenceURL(r.Config.URL, "index.yaml")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parsedURL.RawPath = path.Join(parsedURL.RawPath, "index.yaml")
|
||||
parsedURL.Path = path.Join(parsedURL.Path, "index.yaml")
|
||||
|
||||
indexURL := parsedURL.String()
|
||||
// TODO add user-agent
|
||||
resp, err := r.Client.Get(indexURL,
|
||||
getter.WithURL(r.Config.URL),
|
||||
getter.WithInsecureSkipVerifyTLS(r.Config.InsecureSkipTLSverify),
|
||||
@@ -219,7 +214,7 @@ func FindChartInAuthRepoURL(repoURL, username, password, chartName, chartVersion
|
||||
// but it also receives credentials and TLS verify flag for the chart repository.
|
||||
// TODO Helm 4, FindChartInAuthAndTLSRepoURL should be integrated into FindChartInAuthRepoURL.
|
||||
func FindChartInAuthAndTLSRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile string, insecureSkipTLSverify bool, getters getter.Providers) (string, error) {
|
||||
return FindChartInAuthAndTLSAndPassRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile, false, false, getters)
|
||||
return FindChartInAuthAndTLSAndPassRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile, insecureSkipTLSverify, false, getters)
|
||||
}
|
||||
|
||||
// FindChartInAuthAndTLSAndPassRepoURL finds chart in chart repository pointed by repoURL
|
||||
@@ -290,18 +285,27 @@ func FindChartInAuthAndTLSAndPassRepoURL(repoURL, username, password, chartName,
|
||||
// ResolveReferenceURL resolves refURL relative to baseURL.
|
||||
// If refURL is absolute, it simply returns refURL.
|
||||
func ResolveReferenceURL(baseURL, refURL string) (string, error) {
|
||||
// We need a trailing slash for ResolveReference to work, but make sure there isn't already one
|
||||
parsedBaseURL, err := url.Parse(strings.TrimSuffix(baseURL, "/") + "/")
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse %s as URL", baseURL)
|
||||
}
|
||||
|
||||
parsedRefURL, err := url.Parse(refURL)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse %s as URL", refURL)
|
||||
}
|
||||
|
||||
return parsedBaseURL.ResolveReference(parsedRefURL).String(), nil
|
||||
if parsedRefURL.IsAbs() {
|
||||
return refURL, nil
|
||||
}
|
||||
|
||||
parsedBaseURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse %s as URL", baseURL)
|
||||
}
|
||||
|
||||
// We need a trailing slash for ResolveReference to work, but make sure there isn't already one
|
||||
parsedBaseURL.RawPath = strings.TrimSuffix(parsedBaseURL.RawPath, "/") + "/"
|
||||
parsedBaseURL.Path = strings.TrimSuffix(parsedBaseURL.Path, "/") + "/"
|
||||
|
||||
resolvedURL := parsedBaseURL.ResolveReference(parsedRefURL)
|
||||
resolvedURL.RawQuery = parsedBaseURL.RawQuery
|
||||
return resolvedURL.String(), nil
|
||||
}
|
||||
|
||||
func (e *Entry) String() string {
|
||||
|
||||
Reference in New Issue
Block a user