github.com/koderover/helm@v2.17.0+incompatible/pkg/tiller/environment/environment.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  /*Package environment describes the operating environment for Tiller.
    18  
    19  Tiller's environment encapsulates all of the service dependencies Tiller has.
    20  These dependencies are expressed as interfaces so that alternate implementations
    21  (mocks, etc.) can be easily generated.
    22  */
    23  package environment
    24  
    25  import (
    26  	"io"
    27  	"time"
    28  
    29  	v1 "k8s.io/api/core/v1"
    30  	"k8s.io/cli-runtime/pkg/resource"
    31  
    32  	"k8s.io/helm/pkg/chartutil"
    33  	"k8s.io/helm/pkg/engine"
    34  	"k8s.io/helm/pkg/kube"
    35  	"k8s.io/helm/pkg/proto/hapi/chart"
    36  	"k8s.io/helm/pkg/storage"
    37  	"k8s.io/helm/pkg/storage/driver"
    38  )
    39  
    40  const (
    41  	// DefaultTillerNamespace is the default namespace for Tiller.
    42  	DefaultTillerNamespace = "kube-system"
    43  
    44  	// DefaultTillerPort defines the default port tiller listen on for client traffic
    45  	DefaultTillerPort = 44134
    46  
    47  	// DefaultTillerProbePort defines the default port to listen on for probes
    48  	DefaultTillerProbePort = 44135
    49  
    50  	// GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
    51  	GoTplEngine = "gotpl"
    52  )
    53  
    54  // DefaultEngine points to the engine that the EngineYard should treat as the
    55  // default. A chart that does not specify an engine may be run through the
    56  // default engine.
    57  var DefaultEngine = GoTplEngine
    58  
    59  // EngineYard maps engine names to engine implementations.
    60  type EngineYard map[string]Engine
    61  
    62  // Get retrieves a template engine by name.
    63  //
    64  // If no matching template engine is found, the second return value will
    65  // be false.
    66  func (y EngineYard) Get(k string) (Engine, bool) {
    67  	e, ok := y[k]
    68  	return e, ok
    69  }
    70  
    71  // Default returns the default template engine.
    72  //
    73  // The default is specified by DefaultEngine.
    74  //
    75  // If the default template engine cannot be found, this panics.
    76  func (y EngineYard) Default() Engine {
    77  	d, ok := y[DefaultEngine]
    78  	if !ok {
    79  		// This is a developer error!
    80  		panic("Default template engine does not exist")
    81  	}
    82  	return d
    83  }
    84  
    85  // Engine represents a template engine that can render templates.
    86  //
    87  // For some engines, "rendering" includes both compiling and executing. (Other
    88  // engines do not distinguish between phases.)
    89  //
    90  // The engine returns a map where the key is the named output entity (usually
    91  // a file name) and the value is the rendered content of the template.
    92  //
    93  // An Engine must be capable of executing multiple concurrent requests, but
    94  // without tainting one request's environment with data from another request.
    95  type Engine interface {
    96  	// Render renders a chart.
    97  	//
    98  	// It receives a chart, a config, and a map of overrides to the config.
    99  	// Overrides are assumed to be passed from the system, not the user.
   100  	Render(*chart.Chart, chartutil.Values) (map[string]string, error)
   101  }
   102  
   103  // KubeClient represents a client capable of communicating with the Kubernetes API.
   104  //
   105  // A KubeClient must be concurrency safe.
   106  type KubeClient interface {
   107  	// Create creates one or more resources.
   108  	//
   109  	// reader must contain a YAML stream (one or more YAML documents separated
   110  	// by "\n---\n").
   111  	Create(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
   112  
   113  	// Get gets one or more resources. Returned string hsa the format like kubectl
   114  	// provides with the column headers separating the resource types.
   115  	//
   116  	// namespace must contain a valid existing namespace.
   117  	//
   118  	// reader must contain a YAML stream (one or more YAML documents separated
   119  	// by "\n---\n").
   120  	Get(namespace string, reader io.Reader) (string, error)
   121  
   122  	// Delete destroys one or more resources.
   123  	//
   124  	// namespace must contain a valid existing namespace.
   125  	//
   126  	// reader must contain a YAML stream (one or more YAML documents separated
   127  	// by "\n---\n").
   128  	Delete(namespace string, reader io.Reader) error
   129  
   130  	// DeleteWithTimeout destroys one or more resources. If shouldWait is true, the function
   131  	// will not return until all the resources have been fully deleted or the provided
   132  	// timeout has expired.
   133  	//
   134  	// namespace must contain a valid existing namespace.
   135  	//
   136  	// reader must contain a YAML stream (one or more YAML documents separated
   137  	// by "\n---\n").
   138  	DeleteWithTimeout(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
   139  
   140  	// WatchUntilReady watch the resource in reader until it is "ready".
   141  	//
   142  	// For Jobs, "ready" means the job ran to completion (excited without error).
   143  	// For all other kinds, it means the kind was created or modified without
   144  	// error.
   145  	WatchUntilReady(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
   146  
   147  	// Deprecated; use UpdateWithOptions instead
   148  	Update(namespace string, originalReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error
   149  
   150  	// UpdateWithOptions updates one or more resources or creates the resource
   151  	// if it doesn't exist.
   152  	//
   153  	// namespace must contain a valid existing namespace.
   154  	//
   155  	// reader must contain a YAML stream (one or more YAML documents separated
   156  	// by "\n---\n").
   157  	UpdateWithOptions(namespace string, originalReader, modifiedReader io.Reader, opts kube.UpdateOptions) error
   158  
   159  	Build(namespace string, reader io.Reader) (kube.Result, error)
   160  
   161  	// BuildUnstructured reads a stream of manifests from a reader and turns them into
   162  	// info objects. Manifests are not validated against the schema, but it will fail if
   163  	// any resources types are not known by the apiserver.
   164  	//
   165  	// reader must contain a YAML stream (one or more YAML documents separated by "\n---\n").
   166  	BuildUnstructured(namespace string, reader io.Reader) (kube.Result, error)
   167  
   168  	// Validate reads a stream of manifests from a reader and validates them against
   169  	// the schema from the apiserver. It returns an error if any of the manifests does not validate.
   170  	//
   171  	// reader must contain a YAML stream (one or more YAML documents separated by "\n---\n").
   172  	Validate(namespace string, reader io.Reader) error
   173  
   174  	// WaitAndGetCompletedPodPhase waits up to a timeout until a pod enters a completed phase
   175  	// and returns said phase (PodSucceeded or PodFailed qualify).
   176  	WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error)
   177  
   178  	GetPodLogs(name, namespace string) (io.ReadCloser, error)
   179  
   180  	WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error
   181  }
   182  
   183  // PrintingKubeClient implements KubeClient, but simply prints the reader to
   184  // the given output.
   185  type PrintingKubeClient struct {
   186  	Out io.Writer
   187  }
   188  
   189  // Create prints the values of what would be created with a real KubeClient.
   190  func (p *PrintingKubeClient) Create(ns string, r io.Reader, timeout int64, shouldWait bool) error {
   191  	_, err := io.Copy(p.Out, r)
   192  	return err
   193  }
   194  
   195  // Get prints the values of what would be created with a real KubeClient.
   196  func (p *PrintingKubeClient) Get(ns string, r io.Reader) (string, error) {
   197  	_, err := io.Copy(p.Out, r)
   198  	return "", err
   199  }
   200  
   201  // Delete implements KubeClient delete.
   202  //
   203  // It only prints out the content to be deleted.
   204  func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error {
   205  	_, err := io.Copy(p.Out, r)
   206  	return err
   207  }
   208  
   209  // DeleteWithTimeout implements KubeClient DeleteWithTimeout.
   210  //
   211  // It only prints out the content to be deleted.
   212  func (p *PrintingKubeClient) DeleteWithTimeout(ns string, r io.Reader, timeout int64, shouldWait bool) error {
   213  	_, err := io.Copy(p.Out, r)
   214  	return err
   215  }
   216  
   217  // WatchUntilReady implements KubeClient WatchUntilReady.
   218  func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int64, shouldWait bool) error {
   219  	_, err := io.Copy(p.Out, r)
   220  	return err
   221  }
   222  
   223  // Update implements KubeClient Update.
   224  func (p *PrintingKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
   225  	return p.UpdateWithOptions(ns, currentReader, modifiedReader, kube.UpdateOptions{
   226  		Force:      force,
   227  		Recreate:   recreate,
   228  		Timeout:    timeout,
   229  		ShouldWait: shouldWait,
   230  	})
   231  }
   232  
   233  // UpdateWithOptions implements KubeClient UpdateWithOptions.
   234  func (p *PrintingKubeClient) UpdateWithOptions(ns string, currentReader, modifiedReader io.Reader, opts kube.UpdateOptions) error {
   235  	_, err := io.Copy(p.Out, modifiedReader)
   236  	return err
   237  }
   238  
   239  // Build implements KubeClient Build.
   240  func (p *PrintingKubeClient) Build(ns string, reader io.Reader) (kube.Result, error) {
   241  	return []*resource.Info{}, nil
   242  }
   243  
   244  // BuildUnstructured implements KubeClient BuildUnstructured.
   245  func (p *PrintingKubeClient) BuildUnstructured(ns string, reader io.Reader) (kube.Result, error) {
   246  	return []*resource.Info{}, nil
   247  }
   248  
   249  // Validate implements KubeClient Validate
   250  func (p *PrintingKubeClient) Validate(ns string, reader io.Reader) error {
   251  	return nil
   252  }
   253  
   254  // WaitAndGetCompletedPodPhase implements KubeClient WaitAndGetCompletedPodPhase.
   255  func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error) {
   256  	_, err := io.Copy(p.Out, reader)
   257  	return v1.PodUnknown, err
   258  }
   259  
   260  // GetPodLogs implements KubeClient GetPodLogs.
   261  func (p *PrintingKubeClient) GetPodLogs(name, ns string) (io.ReadCloser, error) {
   262  	return nil, nil
   263  }
   264  
   265  // WaitUntilCRDEstablished implements KubeClient WaitUntilCRDEstablished.
   266  func (p *PrintingKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error {
   267  	_, err := io.Copy(p.Out, reader)
   268  	return err
   269  }
   270  
   271  // Environment provides the context for executing a client request.
   272  //
   273  // All services in a context are concurrency safe.
   274  type Environment struct {
   275  	// EngineYard provides access to the known template engines.
   276  	EngineYard EngineYard
   277  	// Releases stores records of releases.
   278  	Releases *storage.Storage
   279  	// KubeClient is a Kubernetes API client.
   280  	KubeClient KubeClient
   281  }
   282  
   283  // New returns an environment initialized with the defaults.
   284  func New() *Environment {
   285  	e := engine.New()
   286  	var ey EngineYard = map[string]Engine{
   287  		// Currently, the only template engine we support is the GoTpl one. But
   288  		// we can easily add some here.
   289  		GoTplEngine: e,
   290  	}
   291  
   292  	return &Environment{
   293  		EngineYard: ey,
   294  		Releases:   storage.Init(driver.NewMemory()),
   295  	}
   296  }