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

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     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  	"k8s.io/kubernetes/pkg/api"
    30  	"k8s.io/kubernetes/pkg/kubectl/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  // TillerNamespaceEnvVar is the environment variable name for the tiller
    41  // namespace in the kubernetes cluster.
    42  const TillerNamespaceEnvVar = "TILLER_NAMESPACE"
    43  
    44  // DefaultTillerNamespace is the default namespace for tiller.
    45  const DefaultTillerNamespace = "kube-system"
    46  
    47  // GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
    48  const GoTplEngine = "gotpl"
    49  
    50  // DefaultEngine points to the engine that the EngineYard should treat as the
    51  // default. A chart that does not specify an engine may be run through the
    52  // default engine.
    53  var DefaultEngine = GoTplEngine
    54  
    55  // EngineYard maps engine names to engine implementations.
    56  type EngineYard map[string]Engine
    57  
    58  // Get retrieves a template engine by name.
    59  //
    60  // If no matching template engine is found, the second return value will
    61  // be false.
    62  func (y EngineYard) Get(k string) (Engine, bool) {
    63  	e, ok := y[k]
    64  	return e, ok
    65  }
    66  
    67  // Default returns the default template engine.
    68  //
    69  // The default is specified by DefaultEngine.
    70  //
    71  // If the default template engine cannot be found, this panics.
    72  func (y EngineYard) Default() Engine {
    73  	d, ok := y[DefaultEngine]
    74  	if !ok {
    75  		// This is a developer error!
    76  		panic("Default template engine does not exist")
    77  	}
    78  	return d
    79  }
    80  
    81  // Engine represents a template engine that can render templates.
    82  //
    83  // For some engines, "rendering" includes both compiling and executing. (Other
    84  // engines do not distinguish between phases.)
    85  //
    86  // The engine returns a map where the key is the named output entity (usually
    87  // a file name) and the value is the rendered content of the template.
    88  //
    89  // An Engine must be capable of executing multiple concurrent requests, but
    90  // without tainting one request's environment with data from another request.
    91  type Engine interface {
    92  	// Render renders a chart.
    93  	//
    94  	// It receives a chart, a config, and a map of overrides to the config.
    95  	// Overrides are assumed to be passed from the system, not the user.
    96  	Render(*chart.Chart, chartutil.Values) (map[string]string, error)
    97  }
    98  
    99  // KubeClient represents a client capable of communicating with the Kubernetes API.
   100  //
   101  // A KubeClient must be concurrency safe.
   102  type KubeClient interface {
   103  	// Create creates one or more resources.
   104  	//
   105  	// namespace must contain a valid existing namespace.
   106  	//
   107  	// reader must contain a YAML stream (one or more YAML documents separated
   108  	// by "\n---\n").
   109  	Create(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
   110  
   111  	// Get gets one or more resources. Returned string hsa the format like kubectl
   112  	// provides with the column headers separating the resource types.
   113  	//
   114  	// namespace must contain a valid existing namespace.
   115  	//
   116  	// reader must contain a YAML stream (one or more YAML documents separated
   117  	// by "\n---\n").
   118  	Get(namespace string, reader io.Reader) (string, error)
   119  
   120  	// Delete destroys one or more resources.
   121  	//
   122  	// namespace must contain a valid existing namespace.
   123  	//
   124  	// reader must contain a YAML stream (one or more YAML documents separated
   125  	// by "\n---\n").
   126  	Delete(namespace string, reader io.Reader) error
   127  
   128  	// Watch the resource in reader until it is "ready".
   129  	//
   130  	// For Jobs, "ready" means the job ran to completion (excited without error).
   131  	// For all other kinds, it means the kind was created or modified without
   132  	// error.
   133  	WatchUntilReady(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
   134  
   135  	// Update updates one or more resources or creates the resource
   136  	// if it doesn't exist
   137  	//
   138  	// namespace must contain a valid existing namespace
   139  	//
   140  	// reader must contain a YAML stream (one or more YAML documents separated
   141  	// by "\n---\n").
   142  	Update(namespace string, originalReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error
   143  
   144  	Build(namespace string, reader io.Reader) (kube.Result, error)
   145  	BuildUnstructured(namespace string, reader io.Reader) (kube.Result, error)
   146  
   147  	// WaitAndGetCompletedPodPhase waits up to a timeout until a pod enters a completed phase
   148  	// and returns said phase (PodSucceeded or PodFailed qualify)
   149  	WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (api.PodPhase, error)
   150  }
   151  
   152  // PrintingKubeClient implements KubeClient, but simply prints the reader to
   153  // the given output.
   154  type PrintingKubeClient struct {
   155  	Out io.Writer
   156  }
   157  
   158  // Create prints the values of what would be created with a real KubeClient.
   159  func (p *PrintingKubeClient) Create(ns string, r io.Reader, timeout int64, shouldWait bool) error {
   160  	_, err := io.Copy(p.Out, r)
   161  	return err
   162  }
   163  
   164  // Get prints the values of what would be created with a real KubeClient.
   165  func (p *PrintingKubeClient) Get(ns string, r io.Reader) (string, error) {
   166  	_, err := io.Copy(p.Out, r)
   167  	return "", err
   168  }
   169  
   170  // Delete implements KubeClient delete.
   171  //
   172  // It only prints out the content to be deleted.
   173  func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error {
   174  	_, err := io.Copy(p.Out, r)
   175  	return err
   176  }
   177  
   178  // WatchUntilReady implements KubeClient WatchUntilReady.
   179  func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int64, shouldWait bool) error {
   180  	_, err := io.Copy(p.Out, r)
   181  	return err
   182  }
   183  
   184  // Update implements KubeClient Update.
   185  func (p *PrintingKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error {
   186  	_, err := io.Copy(p.Out, modifiedReader)
   187  	return err
   188  }
   189  
   190  // Build implements KubeClient Build.
   191  func (p *PrintingKubeClient) Build(ns string, reader io.Reader) (kube.Result, error) {
   192  	return []*resource.Info{}, nil
   193  }
   194  
   195  // BuildUnstructured implements KubeClient BuildUnstructured.
   196  func (p *PrintingKubeClient) BuildUnstructured(ns string, reader io.Reader) (kube.Result, error) {
   197  	return []*resource.Info{}, nil
   198  }
   199  
   200  // WaitAndGetCompletedPodPhase implements KubeClient WaitAndGetCompletedPodPhase
   201  func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (api.PodPhase, error) {
   202  	_, err := io.Copy(p.Out, reader)
   203  	return api.PodUnknown, err
   204  }
   205  
   206  // Environment provides the context for executing a client request.
   207  //
   208  // All services in a context are concurrency safe.
   209  type Environment struct {
   210  	// EngineYard provides access to the known template engines.
   211  	EngineYard EngineYard
   212  	// Releases stores records of releases.
   213  	Releases *storage.Storage
   214  	// KubeClient is a Kubernetes API client.
   215  	KubeClient KubeClient
   216  }
   217  
   218  // New returns an environment initialized with the defaults.
   219  func New() *Environment {
   220  	e := engine.New()
   221  	var ey EngineYard = map[string]Engine{
   222  		// Currently, the only template engine we support is the GoTpl one. But
   223  		// we can easily add some here.
   224  		GoTplEngine: e,
   225  	}
   226  
   227  	return &Environment{
   228  		EngineYard: ey,
   229  		Releases:   storage.Init(driver.NewMemory()),
   230  	}
   231  }