github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/command/stack/kubernetes/stack.go (about)

     1  package kubernetes
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  	"sort"
     7  
     8  	"github.com/docker/cli/kubernetes/compose/v1beta2"
     9  	"github.com/docker/cli/kubernetes/labels"
    10  	apiv1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
    13  )
    14  
    15  // Stack is the main type used by stack commands so they remain independent from kubernetes compose component version.
    16  type Stack struct {
    17  	Name        string
    18  	Namespace   string
    19  	ComposeFile string
    20  	Spec        *v1beta2.StackSpec
    21  }
    22  
    23  // getServices returns all the stack service names, sorted lexicographically
    24  func (s *Stack) getServices() []string {
    25  	services := make([]string, len(s.Spec.Services))
    26  	for i, service := range s.Spec.Services {
    27  		services[i] = service.Name
    28  	}
    29  	sort.Strings(services)
    30  	return services
    31  }
    32  
    33  // createFileBasedConfigMaps creates a Kubernetes ConfigMap for each Compose global file-based config.
    34  func (s *Stack) createFileBasedConfigMaps(configMaps corev1.ConfigMapInterface) error {
    35  	for name, config := range s.Spec.Configs {
    36  		if config.File == "" {
    37  			continue
    38  		}
    39  
    40  		fileName := filepath.Base(config.File)
    41  		content, err := ioutil.ReadFile(config.File)
    42  		if err != nil {
    43  			return err
    44  		}
    45  
    46  		if _, err := configMaps.Create(toConfigMap(s.Name, name, fileName, content)); err != nil {
    47  			return err
    48  		}
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  // toConfigMap converts a Compose Config to a Kube ConfigMap.
    55  func toConfigMap(stackName, name, key string, content []byte) *apiv1.ConfigMap {
    56  	return &apiv1.ConfigMap{
    57  		TypeMeta: metav1.TypeMeta{
    58  			Kind:       "ConfigMap",
    59  			APIVersion: "v1",
    60  		},
    61  		ObjectMeta: metav1.ObjectMeta{
    62  			Name: name,
    63  			Labels: map[string]string{
    64  				labels.ForStackName: stackName,
    65  			},
    66  		},
    67  		Data: map[string]string{
    68  			key: string(content),
    69  		},
    70  	}
    71  }
    72  
    73  // createFileBasedSecrets creates a Kubernetes Secret for each Compose global file-based secret.
    74  func (s *Stack) createFileBasedSecrets(secrets corev1.SecretInterface) error {
    75  	for name, secret := range s.Spec.Secrets {
    76  		if secret.File == "" {
    77  			continue
    78  		}
    79  
    80  		fileName := filepath.Base(secret.File)
    81  		content, err := ioutil.ReadFile(secret.File)
    82  		if err != nil {
    83  			return err
    84  		}
    85  
    86  		if _, err := secrets.Create(toSecret(s.Name, name, fileName, content)); err != nil {
    87  			return err
    88  		}
    89  	}
    90  
    91  	return nil
    92  }
    93  
    94  // toSecret converts a Compose Secret to a Kube Secret.
    95  func toSecret(stackName, name, key string, content []byte) *apiv1.Secret {
    96  	return &apiv1.Secret{
    97  		ObjectMeta: metav1.ObjectMeta{
    98  			Name: name,
    99  			Labels: map[string]string{
   100  				labels.ForStackName: stackName,
   101  			},
   102  		},
   103  		Data: map[string][]byte{
   104  			key: content,
   105  		},
   106  	}
   107  }