DockerCLI/cli/command/stack/kubernetes/stack.go

108 lines
2.6 KiB
Go

package kubernetes
import (
"io/ioutil"
"path/filepath"
"sort"
"github.com/docker/cli/kubernetes/compose/v1beta2"
"github.com/docker/cli/kubernetes/labels"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
)
// Stack is the main type used by stack commands so they remain independent from kubernetes compose component version.
type Stack struct {
Name string
Namespace string
ComposeFile string
Spec *v1beta2.StackSpec
}
// getServices returns all the stack service names, sorted lexicographically
func (s *Stack) getServices() []string {
services := make([]string, len(s.Spec.Services))
for i, service := range s.Spec.Services {
services[i] = service.Name
}
sort.Strings(services)
return services
}
// createFileBasedConfigMaps creates a Kubernetes ConfigMap for each Compose global file-based config.
func (s *Stack) createFileBasedConfigMaps(configMaps corev1.ConfigMapInterface) error {
for name, config := range s.Spec.Configs {
if config.File == "" {
continue
}
fileName := filepath.Base(config.File)
content, err := ioutil.ReadFile(config.File)
if err != nil {
return err
}
if _, err := configMaps.Create(toConfigMap(s.Name, name, fileName, content)); err != nil {
return err
}
}
return nil
}
// toConfigMap converts a Compose Config to a Kube ConfigMap.
func toConfigMap(stackName, name, key string, content []byte) *apiv1.ConfigMap {
return &apiv1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
labels.ForStackName: stackName,
},
},
Data: map[string]string{
key: string(content),
},
}
}
// createFileBasedSecrets creates a Kubernetes Secret for each Compose global file-based secret.
func (s *Stack) createFileBasedSecrets(secrets corev1.SecretInterface) error {
for name, secret := range s.Spec.Secrets {
if secret.File == "" {
continue
}
fileName := filepath.Base(secret.File)
content, err := ioutil.ReadFile(secret.File)
if err != nil {
return err
}
if _, err := secrets.Create(toSecret(s.Name, name, fileName, content)); err != nil {
return err
}
}
return nil
}
// toSecret converts a Compose Secret to a Kube Secret.
func toSecret(stackName, name, key string, content []byte) *apiv1.Secret {
return &apiv1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
labels.ForStackName: stackName,
},
},
Data: map[string][]byte{
key: content,
},
}
}