portainer/pkg/libkompose/convert.go

112 lines
3.6 KiB
Go

package libkompose
import (
"errors"
"fmt"
"github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/apimachinery/pkg/runtime"
)
var (
validProviders = map[string]bool{"kubernetes": true, "openshift": true}
validControllers = map[string]bool{"": true, "deployment": true, "daemonSet": true, "replicationController": true, "deploymentConfig": true}
validVolumes = map[string]bool{"persistentVolumeClaim": true, "emptyDir": true, "hostPath": true, "configMap": true}
)
// ConvertComposeFiles converts one or more Docker Compose files to Kubernetes manifests or Helm charts.
// It uses sensible defaults for all options and returns the generated Kubernetes objects.
func ConvertComposeFiles(composeFiles []string, opts *ConvertOptions) ([]runtime.Object, error) {
if len(composeFiles) == 0 {
return nil, errors.New("at least one compose file is required")
}
convertOpts, err := getDefaultConvertOptions(opts)
if err != nil {
return nil, fmt.Errorf("failed to get default convert options: %w", err)
}
convertOpts.InputFiles = composeFiles
if err := app.ValidateComposeFile(convertOpts); err != nil {
return nil, fmt.Errorf("failed to validate compose file: %w", err)
}
objects, err := app.Convert(*convertOpts)
if err != nil {
return nil, fmt.Errorf("failed to convert compose files: %w", err)
}
return objects, nil
}
func getDefaultConvertOptions(opts *ConvertOptions) (*kobject.ConvertOptions, error) {
if opts == nil {
opts = &ConvertOptions{}
}
provider := opts.Provider
if provider == "" {
provider = "kubernetes"
} else if !validProviders[provider] {
return nil, fmt.Errorf("invalid provider %q: must be one of: kubernetes, openshift", provider)
}
replicas := opts.Replicas
if replicas == 0 {
replicas = 1
} else if replicas < 0 {
return nil, fmt.Errorf("invalid replicas %d: must be a positive integer", replicas)
}
volumes := opts.Volumes
if volumes == "" {
volumes = "persistentVolumeClaim"
} else if !validVolumes[volumes] {
return nil, fmt.Errorf("invalid volumes %q: must be one of: persistentVolumeClaim, emptyDir, hostPath, configMap", volumes)
}
yamlIndent := opts.YAMLIndent
if yamlIndent == 0 {
yamlIndent = 2
} else if yamlIndent < 0 {
return nil, fmt.Errorf("invalid yamlIndent %d: must be a positive integer", yamlIndent)
}
if !validControllers[opts.Controller] {
return nil, fmt.Errorf("invalid controller %q: must be one of: deployment, daemonSet, replicationController, deploymentConfig", opts.Controller)
}
if opts.ToStdout && opts.CreateChart {
return nil, errors.New("cannot use ToStdout with CreateChart")
}
if opts.ToStdout && opts.OutFile != "" {
return nil, errors.New("cannot use ToStdout with OutFile")
}
return &kobject.ConvertOptions{
OutFile: opts.OutFile,
CreateChart: opts.CreateChart,
GenerateYaml: true,
GenerateJSON: false,
ToStdout: opts.ToStdout,
Namespace: opts.Namespace,
Provider: provider,
Controller: opts.Controller,
Replicas: replicas,
Volumes: volumes,
PVCRequestSize: opts.PVCRequestSize,
GenerateNetworkPolicies: opts.GenerateNetworkPolicies,
YAMLIndent: yamlIndent,
Build: "none",
WithKomposeAnnotation: false,
NoInterpolate: false,
EmptyVols: false,
InsecureRepository: false,
PushImage: false,
MultipleContainerMode: false,
SecretsAsFiles: false,
StoreManifest: false,
}, nil
}