Big refactorization
- reduce complexity - use better tools to format the code - add more tests - and too many things to list here We are rewriting for V3, so these commits are sometimes big and not fully detailed. Of course, further work will be more documented.
This commit is contained in:
@@ -9,11 +9,11 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"katenary/generator"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"katenary/generator"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
const longHelp = `Katenary is a tool to convert compose files to Helm Charts.
|
||||
|
@@ -1,12 +0,0 @@
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# katenary
|
||||
|
||||
```go
|
||||
import "katenary/cmd/katenary"
|
||||
```
|
||||
|
||||
Katenary CLI, main package.
|
||||
|
||||
This package is not intended to be imported. It contains the main function that build the command line with \`cobra\` package.
|
||||
|
@@ -35,7 +35,7 @@ var Version = "master" // changed at compile time
|
||||
```
|
||||
|
||||
<a name="Convert"></a>
|
||||
## func [Convert](<https://github.com/metal3d/katenary/blob/develop/generator/converter.go#L38>)
|
||||
## func [Convert](<https://github.com/metal3d/katenary/blob/develop/generator/converter.go#L37>)
|
||||
|
||||
```go
|
||||
func Convert(config ConvertOptions, dockerComposeFile ...string)
|
||||
@@ -116,16 +116,14 @@ func Prefix() string
|
||||
|
||||
|
||||
<a name="ChartTemplate"></a>
|
||||
## type [ChartTemplate](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L9-L12>)
|
||||
## type [ChartTemplate](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L25-L28>)
|
||||
|
||||
ChartTemplate is a template of a chart. It contains the content of the template and the name of the service. This is used internally to generate the templates.
|
||||
|
||||
TODO: maybe we can set it private.
|
||||
|
||||
```go
|
||||
type ChartTemplate struct {
|
||||
Content []byte
|
||||
Servicename string
|
||||
Content []byte
|
||||
}
|
||||
```
|
||||
|
||||
@@ -151,25 +149,25 @@ func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap
|
||||
NewConfigMap creates a new ConfigMap from a compose service. The appName is the name of the application taken from the project name. The ConfigMap is filled by environment variables and labels "map\-env".
|
||||
|
||||
<a name="NewConfigMapFromDirectory"></a>
|
||||
### func [NewConfigMapFromDirectory](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L130>)
|
||||
### func [NewConfigMapFromDirectory](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L128>)
|
||||
|
||||
```go
|
||||
func NewConfigMapFromDirectory(service types.ServiceConfig, appName string, path string) *ConfigMap
|
||||
func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap
|
||||
```
|
||||
|
||||
NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps.
|
||||
|
||||
<a name="ConfigMap.AddData"></a>
|
||||
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L166>)
|
||||
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L164>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) AddData(key string, value string)
|
||||
func (c *ConfigMap) AddData(key, value string)
|
||||
```
|
||||
|
||||
AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
|
||||
|
||||
<a name="ConfigMap.AppendDir"></a>
|
||||
### func \(\*ConfigMap\) [AppendDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L172>)
|
||||
### func \(\*ConfigMap\) [AppendDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L170>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) AppendDir(path string)
|
||||
@@ -178,7 +176,7 @@ func (c *ConfigMap) AppendDir(path string)
|
||||
AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, you need to call this function for each subdirectory.
|
||||
|
||||
<a name="ConfigMap.AppendFile"></a>
|
||||
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L208>)
|
||||
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L206>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) AppendFile(path string)
|
||||
@@ -187,7 +185,7 @@ func (c *ConfigMap) AppendFile(path string)
|
||||
|
||||
|
||||
<a name="ConfigMap.Filename"></a>
|
||||
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L226>)
|
||||
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L224>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) Filename() string
|
||||
@@ -196,7 +194,7 @@ func (c *ConfigMap) Filename() string
|
||||
Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
|
||||
|
||||
<a name="ConfigMap.SetData"></a>
|
||||
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L161>)
|
||||
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L159>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) SetData(data map[string]string)
|
||||
@@ -205,7 +203,7 @@ func (c *ConfigMap) SetData(data map[string]string)
|
||||
SetData sets the data of the configmap. It replaces the entire data.
|
||||
|
||||
<a name="ConfigMap.Yaml"></a>
|
||||
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L236>)
|
||||
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L234>)
|
||||
|
||||
```go
|
||||
func (c *ConfigMap) Yaml() ([]byte, error)
|
||||
@@ -225,18 +223,18 @@ type ConfigMapMount struct {
|
||||
```
|
||||
|
||||
<a name="ConvertOptions"></a>
|
||||
## type [ConvertOptions](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L46-L53>)
|
||||
## type [ConvertOptions](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L14-L21>)
|
||||
|
||||
ConvertOptions are the options to convert a compose project to a helm chart.
|
||||
|
||||
```go
|
||||
type ConvertOptions struct {
|
||||
Force bool // Force the chart directory deletion if it already exists.
|
||||
OutputDir string // The output directory of the chart.
|
||||
Profiles []string // Profile to use for the conversion.
|
||||
HelmUpdate bool // If true, the "helm dep update" command will be run after the chart generation.
|
||||
AppVersion *string // Set the chart "appVersion" field. If nil, the version will be set to 0.1.0.
|
||||
ChartVersion string // Set the chart "version" field.
|
||||
AppVersion *string
|
||||
OutputDir string
|
||||
ChartVersion string
|
||||
Profiles []string
|
||||
Force bool
|
||||
HelmUpdate bool
|
||||
}
|
||||
```
|
||||
|
||||
@@ -275,7 +273,7 @@ Yaml returns the yaml representation of the cronjob.
|
||||
Implements the Yaml interface.
|
||||
|
||||
<a name="CronJobValue"></a>
|
||||
## type [CronJobValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L50-L55>)
|
||||
## type [CronJobValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L47-L52>)
|
||||
|
||||
CronJobValue is a cronjob configuration that will be saved in values.yaml.
|
||||
|
||||
@@ -304,7 +302,7 @@ type DataMap interface {
|
||||
### func [NewFileMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L26>)
|
||||
|
||||
```go
|
||||
func NewFileMap(service types.ServiceConfig, appName string, kind string) DataMap
|
||||
func NewFileMap(service types.ServiceConfig, appName, kind string) DataMap
|
||||
```
|
||||
|
||||
NewFileMap creates a new DataMap from a compose service. The appName is the name of the application taken from the project name.
|
||||
@@ -340,7 +338,7 @@ func (d *Deployment) AddContainer(service types.ServiceConfig)
|
||||
AddContainer adds a container to the deployment.
|
||||
|
||||
<a name="Deployment.AddHealthCheck"></a>
|
||||
### func \(\*Deployment\) [AddHealthCheck](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L440>)
|
||||
### func \(\*Deployment\) [AddHealthCheck](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L450>)
|
||||
|
||||
```go
|
||||
func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container)
|
||||
@@ -367,7 +365,7 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string)
|
||||
AddVolumes adds a volume to the deployment. It does not create the PVC, it only adds the volumes to the deployment. If the volume is a bind volume it will warn the user that it is not supported yet.
|
||||
|
||||
<a name="Deployment.BindFrom"></a>
|
||||
### func \(\*Deployment\) [BindFrom](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L320>)
|
||||
### func \(\*Deployment\) [BindFrom](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L330>)
|
||||
|
||||
```go
|
||||
func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment)
|
||||
@@ -385,7 +383,7 @@ func (d *Deployment) DependsOn(to *Deployment, servicename string) error
|
||||
DependsOn adds a initContainer to the deployment that will wait for the service to be up.
|
||||
|
||||
<a name="Deployment.Filename"></a>
|
||||
### func \(\*Deployment\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L618>)
|
||||
### func \(\*Deployment\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L628>)
|
||||
|
||||
```go
|
||||
func (d *Deployment) Filename() string
|
||||
@@ -394,7 +392,7 @@ func (d *Deployment) Filename() string
|
||||
Filename returns the filename of the deployment.
|
||||
|
||||
<a name="Deployment.SetEnvFrom"></a>
|
||||
### func \(\*Deployment\) [SetEnvFrom](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L348>)
|
||||
### func \(\*Deployment\) [SetEnvFrom](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L358>)
|
||||
|
||||
```go
|
||||
func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string)
|
||||
@@ -403,7 +401,7 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string)
|
||||
SetEnvFrom sets the environment variables to a configmap. The configmap is created.
|
||||
|
||||
<a name="Deployment.Yaml"></a>
|
||||
### func \(\*Deployment\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L469>)
|
||||
### func \(\*Deployment\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/deployment.go#L479>)
|
||||
|
||||
```go
|
||||
func (d *Deployment) Yaml() ([]byte, error)
|
||||
@@ -430,28 +428,29 @@ const (
|
||||
```
|
||||
|
||||
<a name="HelmChart"></a>
|
||||
## type [HelmChart](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L16-L28>)
|
||||
## type [HelmChart](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L32-L44>)
|
||||
|
||||
HelmChart is a Helm Chart representation. It contains all the tempaltes, values, versions, helpers...
|
||||
|
||||
```go
|
||||
type HelmChart struct {
|
||||
Templates map[string]*ChartTemplate `yaml:"-"`
|
||||
Values map[string]any `yaml:"-"`
|
||||
VolumeMounts map[string]any `yaml:"-"`
|
||||
|
||||
Name string `yaml:"name"`
|
||||
ApiVersion string `yaml:"apiVersion"`
|
||||
Version string `yaml:"version"`
|
||||
AppVersion string `yaml:"appVersion"`
|
||||
Description string `yaml:"description"`
|
||||
Helper string `yaml:"-"`
|
||||
Dependencies []labelStructs.Dependency `yaml:"dependencies,omitempty"`
|
||||
Templates map[string]*ChartTemplate `yaml:"-"` // do not export to yaml
|
||||
Helper string `yaml:"-"` // do not export to yaml
|
||||
Values map[string]any `yaml:"-"` // do not export to yaml
|
||||
VolumeMounts map[string]any `yaml:"-"` // do not export to yaml
|
||||
// contains filtered or unexported fields
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Generate"></a>
|
||||
### func [Generate](<https://github.com/metal3d/katenary/blob/develop/generator/generator.go#L33>)
|
||||
### func [Generate](<https://github.com/metal3d/katenary/blob/develop/generator/generator.go#L31>)
|
||||
|
||||
```go
|
||||
func Generate(project *types.Project) (*HelmChart, error)
|
||||
@@ -471,7 +470,7 @@ The Generate function will create the HelmChart object this way:
|
||||
- Merge the same\-pod services.
|
||||
|
||||
<a name="NewChart"></a>
|
||||
### func [NewChart](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L31>)
|
||||
### func [NewChart](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L47>)
|
||||
|
||||
```go
|
||||
func NewChart(name string) *HelmChart
|
||||
@@ -479,6 +478,15 @@ func NewChart(name string) *HelmChart
|
||||
|
||||
NewChart creates a new empty chart with the given name.
|
||||
|
||||
<a name="HelmChart.SaveTemplates"></a>
|
||||
### func \(\*HelmChart\) [SaveTemplates](<https://github.com/metal3d/katenary/blob/develop/generator/chart.go#L62>)
|
||||
|
||||
```go
|
||||
func (chart *HelmChart) SaveTemplates(templateDir string)
|
||||
```
|
||||
|
||||
SaveTemplates the templates of the chart to the given directory.
|
||||
|
||||
<a name="Help"></a>
|
||||
## type [Help](<https://github.com/metal3d/katenary/blob/develop/generator/katenaryLabels.go#L32-L37>)
|
||||
|
||||
@@ -533,17 +541,17 @@ func (ingress *Ingress) Yaml() ([]byte, error)
|
||||
|
||||
|
||||
<a name="IngressValue"></a>
|
||||
## type [IngressValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L27-L33>)
|
||||
## type [IngressValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L24-L30>)
|
||||
|
||||
IngressValue is a ingress configuration that will be saved in values.yaml.
|
||||
|
||||
```go
|
||||
type IngressValue struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Annotations map[string]string `yaml:"annotations"`
|
||||
Host string `yaml:"host"`
|
||||
Path string `yaml:"path"`
|
||||
Class string `yaml:"class"`
|
||||
Annotations map[string]string `yaml:"annotations"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
```
|
||||
|
||||
@@ -578,16 +586,16 @@ const (
|
||||
```
|
||||
|
||||
<a name="PersistenceValue"></a>
|
||||
## type [PersistenceValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L19-L24>)
|
||||
## type [PersistenceValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L16-L21>)
|
||||
|
||||
PersistenceValue is a persistence configuration that will be saved in values.yaml.
|
||||
|
||||
```go
|
||||
type PersistenceValue struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
StorageClass string `yaml:"storageClass"`
|
||||
Size string `yaml:"size"`
|
||||
AccessMode []string `yaml:"accessMode"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
```
|
||||
|
||||
@@ -614,7 +622,7 @@ func NewRBAC(service types.ServiceConfig, appName string) *RBAC
|
||||
NewRBAC creates a new RBAC from a compose service. The appName is the name of the application taken from the project name.
|
||||
|
||||
<a name="RepositoryValue"></a>
|
||||
## type [RepositoryValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L13-L16>)
|
||||
## type [RepositoryValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L10-L13>)
|
||||
|
||||
RepositoryValue is a docker repository image and tag that will be saved in values.yaml.
|
||||
|
||||
@@ -712,7 +720,7 @@ NewSecret creates a new Secret from a compose service
|
||||
### func \(\*Secret\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/secret.go#L87>)
|
||||
|
||||
```go
|
||||
func (s *Secret) AddData(key string, value string)
|
||||
func (s *Secret) AddData(key, value string)
|
||||
```
|
||||
|
||||
AddData adds a key value pair to the secret.
|
||||
@@ -823,7 +831,7 @@ func (r *ServiceAccount) Yaml() ([]byte, error)
|
||||
|
||||
|
||||
<a name="Value"></a>
|
||||
## type [Value](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L36-L47>)
|
||||
## type [Value](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L33-L44>)
|
||||
|
||||
Value will be saved in values.yaml. It contains configuraiton for all deployment and services.
|
||||
|
||||
@@ -832,18 +840,18 @@ type Value struct {
|
||||
Repository *RepositoryValue `yaml:"repository,omitempty"`
|
||||
Persistence map[string]*PersistenceValue `yaml:"persistence,omitempty"`
|
||||
Ingress *IngressValue `yaml:"ingress,omitempty"`
|
||||
ImagePullPolicy string `yaml:"imagePullPolicy,omitempty"`
|
||||
Environment map[string]any `yaml:"environment,omitempty"`
|
||||
Replicas *uint32 `yaml:"replicas,omitempty"`
|
||||
CronJob *CronJobValue `yaml:"cronjob,omitempty"`
|
||||
NodeSelector map[string]string `yaml:"nodeSelector"`
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
Resources map[string]any `yaml:"resources"`
|
||||
ImagePullPolicy string `yaml:"imagePullPolicy,omitempty"`
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="NewValue"></a>
|
||||
### func [NewValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L62>)
|
||||
### func [NewValue](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L59>)
|
||||
|
||||
```go
|
||||
func NewValue(service types.ServiceConfig, main ...bool) *Value
|
||||
@@ -854,7 +862,7 @@ NewValue creates a new Value from a compose service. The value contains the nece
|
||||
If \`main\` is true, the tag will be empty because it will be set in the helm chart appVersion.
|
||||
|
||||
<a name="Value.AddIngress"></a>
|
||||
### func \(\*Value\) [AddIngress](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L101>)
|
||||
### func \(\*Value\) [AddIngress](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L98>)
|
||||
|
||||
```go
|
||||
func (v *Value) AddIngress(host, path string)
|
||||
@@ -863,7 +871,7 @@ func (v *Value) AddIngress(host, path string)
|
||||
|
||||
|
||||
<a name="Value.AddPersistence"></a>
|
||||
### func \(\*Value\) [AddPersistence](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L89>)
|
||||
### func \(\*Value\) [AddPersistence](<https://github.com/metal3d/katenary/blob/develop/generator/values.go#L86>)
|
||||
|
||||
```go
|
||||
func (v *Value) AddPersistence(volumeName string)
|
||||
@@ -872,7 +880,7 @@ func (v *Value) AddPersistence(volumeName string)
|
||||
AddPersistence adds persistence configuration to the Value.
|
||||
|
||||
<a name="VolumeClaim"></a>
|
||||
## type [VolumeClaim](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L18-L23>)
|
||||
## type [VolumeClaim](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L20-L25>)
|
||||
|
||||
VolumeClaim is a kubernetes VolumeClaim. This is a PersistentVolumeClaim.
|
||||
|
||||
@@ -884,7 +892,7 @@ type VolumeClaim struct {
|
||||
```
|
||||
|
||||
<a name="NewVolumeClaim"></a>
|
||||
### func [NewVolumeClaim](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L26>)
|
||||
### func [NewVolumeClaim](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L28>)
|
||||
|
||||
```go
|
||||
func NewVolumeClaim(service types.ServiceConfig, volumeName, appName string) *VolumeClaim
|
||||
@@ -893,7 +901,7 @@ func NewVolumeClaim(service types.ServiceConfig, volumeName, appName string) *Vo
|
||||
NewVolumeClaim creates a new VolumeClaim from a compose service.
|
||||
|
||||
<a name="VolumeClaim.Filename"></a>
|
||||
### func \(\*VolumeClaim\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L117>)
|
||||
### func \(\*VolumeClaim\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L127>)
|
||||
|
||||
```go
|
||||
func (v *VolumeClaim) Filename() string
|
||||
@@ -902,7 +910,7 @@ func (v *VolumeClaim) Filename() string
|
||||
Filename returns the suggested filename for a VolumeClaim.
|
||||
|
||||
<a name="VolumeClaim.Yaml"></a>
|
||||
### func \(\*VolumeClaim\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L56>)
|
||||
### func \(\*VolumeClaim\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/volume.go#L63>)
|
||||
|
||||
```go
|
||||
func (v *VolumeClaim) Yaml() ([]byte, error)
|
||||
|
@@ -17,7 +17,7 @@ func NotesFile(services []string) string
|
||||
NotesFile returns the content of the note.txt file.
|
||||
|
||||
<a name="ReadMeFile"></a>
|
||||
## func [ReadMeFile](<https://github.com/metal3d/katenary/blob/develop/generator/extrafiles/readme.go#L25>)
|
||||
## func [ReadMeFile](<https://github.com/metal3d/katenary/blob/develop/generator/extrafiles/readme.go#L24>)
|
||||
|
||||
```go
|
||||
func ReadMeFile(charname, description string, values map[string]any) string
|
||||
|
@@ -158,7 +158,7 @@ func PortsFrom(data string) (Ports, error)
|
||||
PortsFrom returns a Ports from the given string.
|
||||
|
||||
<a name="Probe"></a>
|
||||
## type [Probe](<https://github.com/metal3d/katenary/blob/develop/generator/labelStructs/probes.go#L8-L11>)
|
||||
## type [Probe](<https://github.com/metal3d/katenary/blob/develop/generator/labelStructs/probes.go#L11-L14>)
|
||||
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ type Probe struct {
|
||||
```
|
||||
|
||||
<a name="ProbeFrom"></a>
|
||||
### func [ProbeFrom](<https://github.com/metal3d/katenary/blob/develop/generator/labelStructs/probes.go#L13>)
|
||||
### func [ProbeFrom](<https://github.com/metal3d/katenary/blob/develop/generator/labelStructs/probes.go#L16>)
|
||||
|
||||
```go
|
||||
func ProbeFrom(data string) (*Probe, error)
|
||||
|
@@ -8,7 +8,16 @@ import "katenary/utils"
|
||||
|
||||
Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project.
|
||||
|
||||
## func [CountStartingSpaces](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L31>)
|
||||
## func [Confirm](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L167>)
|
||||
|
||||
```go
|
||||
func Confirm(question string, icon ...Icon) bool
|
||||
```
|
||||
|
||||
Confirm asks a question and returns true if the answer is y.
|
||||
|
||||
<a name="CountStartingSpaces"></a>
|
||||
## func [CountStartingSpaces](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L33>)
|
||||
|
||||
```go
|
||||
func CountStartingSpaces(line string) int
|
||||
@@ -16,8 +25,17 @@ func CountStartingSpaces(line string) int
|
||||
|
||||
CountStartingSpaces counts the number of spaces at the beginning of a string.
|
||||
|
||||
<a name="EncodeBasicYaml"></a>
|
||||
## func [EncodeBasicYaml](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L179>)
|
||||
|
||||
```go
|
||||
func EncodeBasicYaml(data any) ([]byte, error)
|
||||
```
|
||||
|
||||
EncodeBasicYaml encodes a basic yaml from an interface.
|
||||
|
||||
<a name="GetContainerByName"></a>
|
||||
## func [GetContainerByName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L82>)
|
||||
## func [GetContainerByName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L84>)
|
||||
|
||||
```go
|
||||
func GetContainerByName(name string, containers []corev1.Container) (*corev1.Container, int)
|
||||
@@ -26,7 +44,7 @@ func GetContainerByName(name string, containers []corev1.Container) (*corev1.Con
|
||||
GetContainerByName returns a container by name and its index in the array. It returns nil, \-1 if not found.
|
||||
|
||||
<a name="GetKind"></a>
|
||||
## func [GetKind](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L44>)
|
||||
## func [GetKind](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L46>)
|
||||
|
||||
```go
|
||||
func GetKind(path string) (kind string)
|
||||
@@ -35,7 +53,7 @@ func GetKind(path string) (kind string)
|
||||
GetKind returns the kind of the resource from the file path.
|
||||
|
||||
<a name="GetServiceNameByPort"></a>
|
||||
## func [GetServiceNameByPort](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L72>)
|
||||
## func [GetServiceNameByPort](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L74>)
|
||||
|
||||
```go
|
||||
func GetServiceNameByPort(port int) string
|
||||
@@ -44,7 +62,7 @@ func GetServiceNameByPort(port int) string
|
||||
GetServiceNameByPort returns the service name for a port. It the service name is not found, it returns an empty string.
|
||||
|
||||
<a name="GetValuesFromLabel"></a>
|
||||
## func [GetValuesFromLabel](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L122>)
|
||||
## func [GetValuesFromLabel](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L124>)
|
||||
|
||||
```go
|
||||
func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[string]*EnvConfig
|
||||
@@ -62,7 +80,7 @@ func HashComposefiles(files []string) (string, error)
|
||||
HashComposefiles returns a hash of the compose files.
|
||||
|
||||
<a name="Int32Ptr"></a>
|
||||
## func [Int32Ptr](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L25>)
|
||||
## func [Int32Ptr](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L27>)
|
||||
|
||||
```go
|
||||
func Int32Ptr(i int32) *int32
|
||||
@@ -71,7 +89,7 @@ func Int32Ptr(i int32) *int32
|
||||
Int32Ptr returns a pointer to an int32.
|
||||
|
||||
<a name="MapKeys"></a>
|
||||
## func [MapKeys](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L156>)
|
||||
## func [MapKeys](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L158>)
|
||||
|
||||
```go
|
||||
func MapKeys(m map[string]interface{}) []string
|
||||
@@ -80,7 +98,7 @@ func MapKeys(m map[string]interface{}) []string
|
||||
|
||||
|
||||
<a name="PathToName"></a>
|
||||
## func [PathToName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L101>)
|
||||
## func [PathToName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L103>)
|
||||
|
||||
```go
|
||||
func PathToName(path string) string
|
||||
@@ -89,7 +107,7 @@ func PathToName(path string) string
|
||||
PathToName converts a path to a kubernetes complient name.
|
||||
|
||||
<a name="StrPtr"></a>
|
||||
## func [StrPtr](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L28>)
|
||||
## func [StrPtr](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L30>)
|
||||
|
||||
```go
|
||||
func StrPtr(s string) *string
|
||||
@@ -98,7 +116,7 @@ func StrPtr(s string) *string
|
||||
StrPtr returns a pointer to a string.
|
||||
|
||||
<a name="TplName"></a>
|
||||
## func [TplName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L17>)
|
||||
## func [TplName](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L19>)
|
||||
|
||||
```go
|
||||
func TplName(serviceName, appname string, suffix ...string) string
|
||||
@@ -107,7 +125,7 @@ func TplName(serviceName, appname string, suffix ...string) string
|
||||
TplName returns the name of the kubernetes resource as a template string. It is used in the templates and defined in \_helper.tpl file.
|
||||
|
||||
<a name="TplValue"></a>
|
||||
## func [TplValue](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L92>)
|
||||
## func [TplValue](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L94>)
|
||||
|
||||
```go
|
||||
func TplValue(serviceName, variable string, pipes ...string) string
|
||||
@@ -125,7 +143,7 @@ func Warn(msg ...interface{})
|
||||
Warn prints a warning message
|
||||
|
||||
<a name="WordWrap"></a>
|
||||
## func [WordWrap](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L152>)
|
||||
## func [WordWrap](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L154>)
|
||||
|
||||
```go
|
||||
func WordWrap(text string, lineWidth int) string
|
||||
@@ -134,7 +152,7 @@ func WordWrap(text string, lineWidth int) string
|
||||
WordWrap wraps a string to a given line width. Warning: it may break the string. You need to check the result.
|
||||
|
||||
<a name="Wrap"></a>
|
||||
## func [Wrap](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L61>)
|
||||
## func [Wrap](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L63>)
|
||||
|
||||
```go
|
||||
func Wrap(src, above, below string) string
|
||||
@@ -143,7 +161,7 @@ func Wrap(src, above, below string) string
|
||||
Wrap wraps a string with a string above and below. It will respect the indentation of the src string.
|
||||
|
||||
<a name="WrapBytes"></a>
|
||||
## func [WrapBytes](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L67>)
|
||||
## func [WrapBytes](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L69>)
|
||||
|
||||
```go
|
||||
func WrapBytes(src, above, below []byte) []byte
|
||||
@@ -152,14 +170,14 @@ func WrapBytes(src, above, below []byte) []byte
|
||||
WrapBytes wraps a byte array with a byte array above and below. It will respect the indentation of the src string.
|
||||
|
||||
<a name="EnvConfig"></a>
|
||||
## type [EnvConfig](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L116-L119>)
|
||||
## type [EnvConfig](<https://github.com/metal3d/katenary/blob/develop/utils/utils.go#L118-L121>)
|
||||
|
||||
EnvConfig is a struct to hold the description of an environment variable.
|
||||
|
||||
```go
|
||||
type EnvConfig struct {
|
||||
Description string
|
||||
Service types.ServiceConfig
|
||||
Description string
|
||||
}
|
||||
```
|
||||
|
||||
|
@@ -77,11 +77,6 @@ h3[id*="katenaryio"] {
|
||||
}
|
||||
|
||||
/*Zoomable images*/
|
||||
|
||||
/*[data-md-color-scheme="slate"] #logo {
|
||||
background-image: url("logo-bright.svg");
|
||||
}*/
|
||||
|
||||
.zoomable svg {
|
||||
background-color: var(--md-default-bg-color);
|
||||
padding: 1rem;
|
||||
|
@@ -1,30 +1,46 @@
|
||||
package generator
|
||||
|
||||
import "katenary/generator/labelStructs"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
// ConvertOptions are the options to convert a compose project to a helm chart.
|
||||
type ConvertOptions struct {
|
||||
AppVersion *string
|
||||
OutputDir string
|
||||
ChartVersion string
|
||||
Profiles []string
|
||||
Force bool
|
||||
HelmUpdate bool
|
||||
}
|
||||
|
||||
// ChartTemplate is a template of a chart. It contains the content of the template and the name of the service.
|
||||
// This is used internally to generate the templates.
|
||||
//
|
||||
// TODO: maybe we can set it private.
|
||||
type ChartTemplate struct {
|
||||
Content []byte
|
||||
Servicename string
|
||||
Content []byte
|
||||
}
|
||||
|
||||
// HelmChart is a Helm Chart representation. It contains all the
|
||||
// tempaltes, values, versions, helpers...
|
||||
type HelmChart struct {
|
||||
Templates map[string]*ChartTemplate `yaml:"-"`
|
||||
Values map[string]any `yaml:"-"`
|
||||
VolumeMounts map[string]any `yaml:"-"`
|
||||
composeHash *string `yaml:"-"`
|
||||
Name string `yaml:"name"`
|
||||
ApiVersion string `yaml:"apiVersion"`
|
||||
Version string `yaml:"version"`
|
||||
AppVersion string `yaml:"appVersion"`
|
||||
Description string `yaml:"description"`
|
||||
Helper string `yaml:"-"`
|
||||
Dependencies []labelStructs.Dependency `yaml:"dependencies,omitempty"`
|
||||
Templates map[string]*ChartTemplate `yaml:"-"` // do not export to yaml
|
||||
Helper string `yaml:"-"` // do not export to yaml
|
||||
Values map[string]any `yaml:"-"` // do not export to yaml
|
||||
VolumeMounts map[string]any `yaml:"-"` // do not export to yaml
|
||||
composeHash *string `yaml:"-"` // do not export to yaml
|
||||
}
|
||||
|
||||
// NewChart creates a new empty chart with the given name.
|
||||
@@ -42,12 +58,59 @@ func NewChart(name string) *HelmChart {
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertOptions are the options to convert a compose project to a helm chart.
|
||||
type ConvertOptions struct {
|
||||
Force bool // Force the chart directory deletion if it already exists.
|
||||
OutputDir string // The output directory of the chart.
|
||||
Profiles []string // Profile to use for the conversion.
|
||||
HelmUpdate bool // If true, the "helm dep update" command will be run after the chart generation.
|
||||
AppVersion *string // Set the chart "appVersion" field. If nil, the version will be set to 0.1.0.
|
||||
ChartVersion string // Set the chart "version" field.
|
||||
// SaveTemplates the templates of the chart to the given directory.
|
||||
func (chart *HelmChart) SaveTemplates(templateDir string) {
|
||||
for name, template := range chart.Templates {
|
||||
t := template.Content
|
||||
t = removeNewlinesInsideBrackets(t)
|
||||
t = removeUnwantedLines(t)
|
||||
t = addModeline(t)
|
||||
|
||||
kind := utils.GetKind(name)
|
||||
var icon utils.Icon
|
||||
switch kind {
|
||||
case "deployment":
|
||||
icon = utils.IconPackage
|
||||
case "service":
|
||||
icon = utils.IconPlug
|
||||
case "ingress":
|
||||
icon = utils.IconWorld
|
||||
case "volumeclaim":
|
||||
icon = utils.IconCabinet
|
||||
case "configmap":
|
||||
icon = utils.IconConfig
|
||||
case "secret":
|
||||
icon = utils.IconSecret
|
||||
default:
|
||||
icon = utils.IconInfo
|
||||
}
|
||||
|
||||
servicename := template.Servicename
|
||||
if err := os.MkdirAll(filepath.Join(templateDir, servicename), 0o755); err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(icon, "Creating", kind, servicename)
|
||||
// if the name is a path, create the directory
|
||||
if strings.Contains(name, string(filepath.Separator)) {
|
||||
name = filepath.Join(templateDir, name)
|
||||
err := os.MkdirAll(filepath.Dir(name), 0o755)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
// remove the serivce name from the template name
|
||||
name = strings.Replace(name, servicename+".", "", 1)
|
||||
name = filepath.Join(templateDir, servicename, name)
|
||||
}
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
f.Write(t)
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
@@ -7,13 +7,13 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
// only used to check interface implementation
|
||||
@@ -23,7 +23,7 @@ var (
|
||||
)
|
||||
|
||||
// NewFileMap creates a new DataMap from a compose service. The appName is the name of the application taken from the project name.
|
||||
func NewFileMap(service types.ServiceConfig, appName string, kind string) DataMap {
|
||||
func NewFileMap(service types.ServiceConfig, appName, kind string) DataMap {
|
||||
switch kind {
|
||||
case "configmap":
|
||||
return NewConfigMap(service, appName)
|
||||
@@ -47,8 +47,8 @@ const (
|
||||
type ConfigMap struct {
|
||||
*corev1.ConfigMap
|
||||
service *types.ServiceConfig
|
||||
usage FileMapUsage
|
||||
path string
|
||||
usage FileMapUsage
|
||||
}
|
||||
|
||||
// NewConfigMap creates a new ConfigMap from a compose service. The appName is the name of the application taken from the project name.
|
||||
@@ -75,14 +75,14 @@ func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap {
|
||||
}
|
||||
|
||||
// get the secrets from the labels
|
||||
if secrets, err := labelStructs.SecretsFrom(service.Labels[LabelSecrets]); err != nil {
|
||||
secrets, err := labelStructs.SecretsFrom(service.Labels[LabelSecrets])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
}
|
||||
// drop the secrets from the environment
|
||||
for _, secret := range secrets {
|
||||
drop[secret] = true
|
||||
}
|
||||
}
|
||||
// get the label values from the labels
|
||||
varDescriptons := utils.GetValuesFromLabel(service, LabelValues)
|
||||
for value := range varDescriptons {
|
||||
@@ -95,7 +95,6 @@ func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap {
|
||||
done[value] = true
|
||||
continue
|
||||
}
|
||||
// val := `{{ tpl .Values.` + service.Name + `.environment.` + value + ` $ }}`
|
||||
val := utils.TplValue(service.Name, "environment."+value)
|
||||
service.Environment[value] = &val
|
||||
}
|
||||
@@ -112,10 +111,9 @@ func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap {
|
||||
}
|
||||
}
|
||||
for key, env := range service.Environment {
|
||||
if _, ok := done[key]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := drop[key]; ok {
|
||||
_, isDropped := drop[key]
|
||||
_, isDone := done[key]
|
||||
if isDropped || isDone {
|
||||
continue
|
||||
}
|
||||
cm.AddData(key, *env)
|
||||
@@ -127,7 +125,7 @@ func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap {
|
||||
// NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the
|
||||
// file or directory. If the path is a directory, all files in the directory are added to the ConfigMap.
|
||||
// Each subdirectory are ignored. Note that the Generate() function will create the subdirectories ConfigMaps.
|
||||
func NewConfigMapFromDirectory(service types.ServiceConfig, appName string, path string) *ConfigMap {
|
||||
func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap {
|
||||
normalized := path
|
||||
normalized = strings.TrimLeft(normalized, ".")
|
||||
normalized = strings.TrimLeft(normalized, "/")
|
||||
@@ -163,7 +161,7 @@ func (c *ConfigMap) SetData(data map[string]string) {
|
||||
}
|
||||
|
||||
// AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
|
||||
func (c *ConfigMap) AddData(key string, value string) {
|
||||
func (c *ConfigMap) AddData(key, value string) {
|
||||
c.Data[key] = value
|
||||
}
|
||||
|
||||
|
@@ -12,13 +12,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
|
||||
"katenary/generator/extrafiles"
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/parser"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
goyaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const headerHelp = `# This file is autogenerated by katenary
|
||||
@@ -76,10 +75,11 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
||||
// check if the chart directory exists
|
||||
// if yes, prevent the user from overwriting it and ask for confirmation
|
||||
if _, err := os.Stat(config.OutputDir); err == nil {
|
||||
fmt.Print(utils.IconWarning, " The chart directory "+config.OutputDir+" already exists, do you want to overwrite it? [y/N] ")
|
||||
var answer string
|
||||
fmt.Scanln(&answer)
|
||||
if strings.ToLower(answer) != "y" {
|
||||
overwrite := utils.Confirm(
|
||||
"The chart directory "+config.OutputDir+" already exists, do you want to overwrite it?",
|
||||
utils.IconWarning,
|
||||
)
|
||||
if !overwrite {
|
||||
fmt.Println("Aborting")
|
||||
os.Exit(126) // 126 is the exit code for "Command invoked cannot execute"
|
||||
}
|
||||
@@ -109,168 +109,27 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for name, template := range chart.Templates {
|
||||
t := template.Content
|
||||
t = removeNewlinesInsideBrackets(t)
|
||||
t = removeUnwantedLines(t)
|
||||
t = addModeline(t)
|
||||
// write the templates to the disk
|
||||
chart.SaveTemplates(templateDir)
|
||||
|
||||
kind := utils.GetKind(name)
|
||||
var icon utils.Icon
|
||||
switch kind {
|
||||
case "deployment":
|
||||
icon = utils.IconPackage
|
||||
case "service":
|
||||
icon = utils.IconPlug
|
||||
case "ingress":
|
||||
icon = utils.IconWorld
|
||||
case "volumeclaim":
|
||||
icon = utils.IconCabinet
|
||||
case "configmap":
|
||||
icon = utils.IconConfig
|
||||
case "secret":
|
||||
icon = utils.IconSecret
|
||||
default:
|
||||
icon = utils.IconInfo
|
||||
}
|
||||
// write the Chart.yaml file
|
||||
buildCharYamlFile(chart, project, chartPath)
|
||||
|
||||
servicename := template.Servicename
|
||||
if err := os.MkdirAll(filepath.Join(templateDir, servicename), 0o755); err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(icon, "Creating", kind, servicename)
|
||||
// if the name is a path, create the directory
|
||||
if strings.Contains(name, string(filepath.Separator)) {
|
||||
name = filepath.Join(templateDir, name)
|
||||
err := os.MkdirAll(filepath.Dir(name), 0o755)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
// remove the serivce name from the template name
|
||||
name = strings.Replace(name, servicename+".", "", 1)
|
||||
name = filepath.Join(templateDir, servicename, name)
|
||||
}
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// build and write the values.yaml file
|
||||
buildValues(chart, project, valuesPath)
|
||||
|
||||
f.Write(t)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// calculate the sha1 hash of the services
|
||||
buf := bytes.NewBuffer(nil)
|
||||
encoder := goyaml.NewEncoder(buf)
|
||||
encoder.SetIndent(2)
|
||||
if err := encoder.Encode(chart); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
yamlChart := buf.Bytes()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// concat chart adding a comment with hash of services on top
|
||||
yamlChart = append([]byte(fmt.Sprintf("# compose hash (sha1): %s\n", *chart.composeHash)), yamlChart...)
|
||||
// add the list of compose files
|
||||
files := []string{}
|
||||
for _, file := range project.ComposeFiles {
|
||||
base := filepath.Base(file)
|
||||
files = append(files, base)
|
||||
}
|
||||
yamlChart = append([]byte(fmt.Sprintf("# compose files: %s\n", strings.Join(files, ", "))), yamlChart...)
|
||||
// add generated date
|
||||
yamlChart = append([]byte(fmt.Sprintf("# generated at: %s\n", time.Now().Format(time.RFC3339))), yamlChart...)
|
||||
|
||||
// document Chart.yaml file
|
||||
yamlChart = addChartDoc(yamlChart, project)
|
||||
|
||||
f, err := os.Create(chartPath)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
f.Write(yamlChart)
|
||||
f.Close()
|
||||
|
||||
buf.Reset()
|
||||
encoder = goyaml.NewEncoder(buf)
|
||||
encoder.SetIndent(2)
|
||||
if err = encoder.Encode(&chart.Values); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
values := buf.Bytes()
|
||||
values = addDescriptions(values, *project)
|
||||
values = addDependencyDescription(values, chart.Dependencies)
|
||||
values = addCommentsToValues(values)
|
||||
values = addStorageClassHelp(values)
|
||||
values = addImagePullSecretsHelp(values)
|
||||
values = addImagePullPolicyHelp(values)
|
||||
values = addVariablesDoc(values, project)
|
||||
values = addMainTagAppDoc(values, project)
|
||||
values = addResourceHelp(values)
|
||||
values = addYAMLSelectorPath(values)
|
||||
values = append([]byte(headerHelp), values...)
|
||||
|
||||
f, err = os.Create(valuesPath)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
f.Write(values)
|
||||
f.Close()
|
||||
|
||||
f, err = os.Create(helpersPath)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
f.Write([]byte(chart.Helper))
|
||||
f.Close()
|
||||
// write the _helpers.tpl to the disk
|
||||
writeContent(helpersPath, []byte(chart.Helper))
|
||||
|
||||
// write the readme to the disk
|
||||
readme := extrafiles.ReadMeFile(chart.Name, chart.Description, chart.Values)
|
||||
f, err = os.Create(readmePath)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
f.Write([]byte(readme))
|
||||
f.Close()
|
||||
writeContent(readmePath, []byte(readme))
|
||||
|
||||
services := make([]string, 0)
|
||||
for _, service := range project.Services {
|
||||
services = append(services, service.Name)
|
||||
}
|
||||
notes := extrafiles.NotesFile(services)
|
||||
f, err = os.Create(notesPath)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
f.Write([]byte(notes))
|
||||
f.Close()
|
||||
// get the list of services to write in the notes
|
||||
buildNotesFile(project, notesPath)
|
||||
|
||||
executeAndHandleError := func(fn func(ConvertOptions) error, config ConvertOptions, message string) {
|
||||
if err := fn(config); err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(utils.IconSuccess, message)
|
||||
}
|
||||
|
||||
if config.HelmUpdate {
|
||||
executeAndHandleError(helmUpdate, config, "Helm dependencies updated")
|
||||
executeAndHandleError(helmLint, config, "Helm chart linted")
|
||||
fmt.Println(utils.IconSuccess, "Helm chart created successfully")
|
||||
}
|
||||
// call helm update if needed
|
||||
callHelmUpdate(config)
|
||||
}
|
||||
|
||||
const ingressClassHelp = `# Default value for ingress.class annotation
|
||||
@@ -501,13 +360,21 @@ func addResourceHelp(values []byte) []byte {
|
||||
func addVariablesDoc(values []byte, project *types.Project) []byte {
|
||||
lines := strings.Split(string(values), "\n")
|
||||
|
||||
currentService := ""
|
||||
for _, service := range project.Services {
|
||||
lines = addDocToVariable(service, lines)
|
||||
}
|
||||
return []byte(strings.Join(lines, "\n"))
|
||||
}
|
||||
|
||||
func addDocToVariable(service types.ServiceConfig, lines []string) []string {
|
||||
currentService := ""
|
||||
variables := utils.GetValuesFromLabel(service, LabelValues)
|
||||
for i, line := range lines {
|
||||
// if the line is a service, it is a name followed by a colon
|
||||
if regexp.MustCompile(`(?m)^` + service.Name + `:`).MatchString(line) {
|
||||
currentService = service.Name
|
||||
}
|
||||
// for each variable in the service, add the description
|
||||
for varname, variable := range variables {
|
||||
if variable == nil {
|
||||
continue
|
||||
@@ -524,8 +391,7 @@ func addVariablesDoc(values []byte, project *types.Project) []byte {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return []byte(strings.Join(lines, "\n"))
|
||||
return lines
|
||||
}
|
||||
|
||||
const mainTagAppDoc = `This is the version of the main application.
|
||||
@@ -535,8 +401,6 @@ func addMainTagAppDoc(values []byte, project *types.Project) []byte {
|
||||
lines := strings.Split(string(values), "\n")
|
||||
|
||||
for _, service := range project.Services {
|
||||
inService := false
|
||||
inRegistry := false
|
||||
// read the label LabelMainApp
|
||||
if v, ok := service.Labels[LabelMainApp]; !ok {
|
||||
continue
|
||||
@@ -546,6 +410,15 @@ func addMainTagAppDoc(values []byte, project *types.Project) []byte {
|
||||
fmt.Printf("%s Adding main tag app doc %s\n", utils.IconConfig, service.Name)
|
||||
}
|
||||
|
||||
lines = addMainAppDoc(lines, service)
|
||||
}
|
||||
|
||||
return []byte(strings.Join(lines, "\n"))
|
||||
}
|
||||
|
||||
func addMainAppDoc(lines []string, service types.ServiceConfig) []string {
|
||||
inService := false
|
||||
inRegistry := false
|
||||
for i, line := range lines {
|
||||
if regexp.MustCompile(`^` + service.Name + `:`).MatchString(line) {
|
||||
inService = true
|
||||
@@ -564,9 +437,7 @@ func addMainTagAppDoc(values []byte, project *types.Project) []byte {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return []byte(strings.Join(lines, "\n"))
|
||||
return lines
|
||||
}
|
||||
|
||||
func removeNewlinesInsideBrackets(values []byte) []byte {
|
||||
@@ -715,3 +586,89 @@ func addYAMLSelectorPath(values []byte) []byte {
|
||||
}
|
||||
return []byte(strings.Join(toReturn, "\n"))
|
||||
}
|
||||
|
||||
func writeContent(path string, content []byte) {
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
f.Write(content)
|
||||
}
|
||||
|
||||
func buildValues(chart *HelmChart, project *types.Project, valuesPath string) {
|
||||
values, err := utils.EncodeBasicYaml(&chart.Values)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
values = addDescriptions(values, *project)
|
||||
values = addDependencyDescription(values, chart.Dependencies)
|
||||
values = addCommentsToValues(values)
|
||||
values = addStorageClassHelp(values)
|
||||
values = addImagePullSecretsHelp(values)
|
||||
values = addImagePullPolicyHelp(values)
|
||||
values = addVariablesDoc(values, project)
|
||||
values = addMainTagAppDoc(values, project)
|
||||
values = addResourceHelp(values)
|
||||
values = addYAMLSelectorPath(values)
|
||||
values = append([]byte(headerHelp), values...)
|
||||
|
||||
// add vim modeline
|
||||
values = append(values, []byte("\n# vim: ft=yaml\n")...)
|
||||
|
||||
// write the values to the disk
|
||||
writeContent(valuesPath, values)
|
||||
}
|
||||
|
||||
func buildNotesFile(project *types.Project, notesPath string) {
|
||||
// get the list of services to write in the notes
|
||||
services := make([]string, 0)
|
||||
for _, service := range project.Services {
|
||||
services = append(services, service.Name)
|
||||
}
|
||||
// write the notes to the disk
|
||||
notes := extrafiles.NotesFile(services)
|
||||
writeContent(notesPath, []byte(notes))
|
||||
}
|
||||
|
||||
func buildCharYamlFile(chart *HelmChart, project *types.Project, chartPath string) {
|
||||
// calculate the sha1 hash of the services
|
||||
yamlChart, err := utils.EncodeBasicYaml(chart)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// concat chart adding a comment with hash of services on top
|
||||
yamlChart = append([]byte(fmt.Sprintf("# compose hash (sha1): %s\n", *chart.composeHash)), yamlChart...)
|
||||
// add the list of compose files
|
||||
files := []string{}
|
||||
for _, file := range project.ComposeFiles {
|
||||
base := filepath.Base(file)
|
||||
files = append(files, base)
|
||||
}
|
||||
yamlChart = append([]byte(fmt.Sprintf("# compose files: %s\n", strings.Join(files, ", "))), yamlChart...)
|
||||
// add generated date
|
||||
yamlChart = append([]byte(fmt.Sprintf("# generated at: %s\n", time.Now().Format(time.RFC3339))), yamlChart...)
|
||||
|
||||
// document Chart.yaml file
|
||||
yamlChart = addChartDoc(yamlChart, project)
|
||||
|
||||
writeContent(chartPath, yamlChart)
|
||||
}
|
||||
|
||||
func callHelmUpdate(config ConvertOptions) {
|
||||
executeAndHandleError := func(fn func(ConvertOptions) error, config ConvertOptions, message string) {
|
||||
if err := fn(config); err != nil {
|
||||
fmt.Println(utils.IconFailure, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(utils.IconSuccess, message)
|
||||
}
|
||||
if config.HelmUpdate {
|
||||
executeAndHandleError(helmUpdate, config, "Helm dependencies updated")
|
||||
executeAndHandleError(helmLint, config, "Helm chart linted")
|
||||
fmt.Println(utils.IconSuccess, "Helm chart created successfully")
|
||||
}
|
||||
}
|
||||
|
@@ -4,14 +4,14 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
// only used to check interface implementation
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestBasicCronJob(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
cron:
|
||||
image: fedora
|
||||
@@ -23,7 +23,7 @@ services:
|
||||
schedule: "*/1 * * * *"
|
||||
rbac: false
|
||||
`
|
||||
tmpDir := setup(compose_file)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
@@ -64,7 +64,7 @@ services:
|
||||
}
|
||||
|
||||
func TestCronJobbWithRBAC(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
cron:
|
||||
image: fedora
|
||||
@@ -76,7 +76,7 @@ services:
|
||||
rbac: true
|
||||
`
|
||||
|
||||
tmpDir := setup(compose_file)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
|
@@ -9,14 +9,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Deployment)(nil)
|
||||
@@ -204,13 +204,16 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
isSamePod = v != ""
|
||||
}
|
||||
|
||||
for _, volume := range service.Volumes {
|
||||
d.bindVolumes(volume, isSamePod, tobind, service, appName)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Deployment) bindVolumes(volume types.ServiceVolumeConfig, isSamePod bool, tobind map[string]bool, service types.ServiceConfig, appName string) {
|
||||
container, index := utils.GetContainerByName(service.Name, d.Spec.Template.Spec.Containers)
|
||||
defer func(d *Deployment, container *corev1.Container, index int) {
|
||||
d.Spec.Template.Spec.Containers[index] = *container
|
||||
}(d, container, index)
|
||||
|
||||
for _, volume := range service.Volumes {
|
||||
// not declared as a bind volume, skip
|
||||
if _, ok := tobind[volume.Source]; !isSamePod && volume.Type == "bind" && !ok {
|
||||
utils.Warn(
|
||||
"Bind volumes are not supported yet, " +
|
||||
@@ -219,18 +222,18 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
", skipping volume " + volume.Source +
|
||||
" from service " + service.Name,
|
||||
)
|
||||
continue
|
||||
return
|
||||
}
|
||||
|
||||
if container == nil {
|
||||
utils.Warn("Container not found for volume", volume.Source)
|
||||
continue
|
||||
return
|
||||
}
|
||||
|
||||
// ensure that the volume is not already present in the container
|
||||
for _, vm := range container.VolumeMounts {
|
||||
if vm.Name == volume.Source {
|
||||
continue
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +266,14 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
}
|
||||
|
||||
if stat.IsDir() {
|
||||
d.appendDirectoryToConfigMap(service, appName, volume)
|
||||
} else {
|
||||
d.appendFileToConfigMap(service, appName, volume)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Deployment) appendDirectoryToConfigMap(service types.ServiceConfig, appName string, volume types.ServiceVolumeConfig) {
|
||||
pathnme := utils.PathToName(volume.Source)
|
||||
if _, ok := d.configMaps[pathnme]; !ok {
|
||||
d.configMaps[pathnme] = &ConfigMapMount{
|
||||
@@ -282,7 +293,9 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
mountPath: volume.Target,
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
func (d *Deployment) appendFileToConfigMap(service types.ServiceConfig, appName string, volume types.ServiceVolumeConfig) {
|
||||
// In case of a file, add it to the configmap and use "subPath" to mount it
|
||||
// Note that the volumes and volume mounts are not added to the deployment yet, they will be added later
|
||||
// in generate.go
|
||||
@@ -312,9 +325,6 @@ func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) {
|
||||
|
||||
}
|
||||
cm.AppendFile(volume.Source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) {
|
||||
|
@@ -10,20 +10,22 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
const webTemplateOutput = `templates/web/deployment.yaml`
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
`
|
||||
tmpDir := setup(compose_file)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
|
||||
// dt := DeploymentTest{}
|
||||
dt := v1.Deployment{}
|
||||
@@ -42,7 +44,7 @@ services:
|
||||
}
|
||||
|
||||
func TestGenerateOneDeploymentWithSamePod(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -57,14 +59,15 @@ services:
|
||||
katenary.v3/same-pod: web
|
||||
`
|
||||
|
||||
tmpDir := setup(compose_file)
|
||||
outDir := "./chart"
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
@@ -76,8 +79,8 @@ services:
|
||||
// endsure that the fpm service is not created
|
||||
|
||||
var err error
|
||||
output, err = helmTemplate(ConvertOptions{
|
||||
OutputDir: "./chart",
|
||||
_, err = helmTemplate(ConvertOptions{
|
||||
OutputDir: outDir,
|
||||
}, "-s", "templates/fpm/deployment.yaml")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got nil")
|
||||
@@ -85,7 +88,7 @@ services:
|
||||
|
||||
// ensure that the web service is created and has got 2 ports
|
||||
output, err = helmTemplate(ConvertOptions{
|
||||
OutputDir: "./chart",
|
||||
OutputDir: outDir,
|
||||
}, "-s", "templates/web/service.yaml")
|
||||
if err != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
@@ -101,7 +104,7 @@ services:
|
||||
}
|
||||
|
||||
func TestDependsOn(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -115,14 +118,14 @@ services:
|
||||
ports:
|
||||
- 3306:3306
|
||||
`
|
||||
tmpDir := setup(compose_file)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
@@ -138,7 +141,7 @@ services:
|
||||
}
|
||||
|
||||
func TestHelmDependencies(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -156,15 +159,15 @@ services:
|
||||
version: 18.x.X
|
||||
|
||||
`
|
||||
compose_file = fmt.Sprintf(compose_file, Prefix())
|
||||
tmpDir := setup(compose_file)
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
@@ -198,7 +201,7 @@ services:
|
||||
}
|
||||
|
||||
func TestLivenessProbesFromHealthCheck(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -210,14 +213,14 @@ services:
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
`
|
||||
tmpDir := setup(compose_file)
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
@@ -229,7 +232,7 @@ services:
|
||||
}
|
||||
|
||||
func TestProbesFromLabels(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -246,15 +249,15 @@ services:
|
||||
path: /ready
|
||||
port: 80
|
||||
`
|
||||
compose_file = fmt.Sprintf(compose_file, Prefix())
|
||||
tmpDir := setup(compose_file)
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
@@ -280,7 +283,7 @@ services:
|
||||
}
|
||||
|
||||
func TestSetValues(t *testing.T) {
|
||||
compose_file := `
|
||||
composeFile := `
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29
|
||||
@@ -292,15 +295,15 @@ services:
|
||||
- FOO
|
||||
`
|
||||
|
||||
compose_file = fmt.Sprintf(compose_file, Prefix())
|
||||
tmpDir := setup(compose_file)
|
||||
composeFile = fmt.Sprintf(composeFile, Prefix())
|
||||
tmpDir := setup(composeFile)
|
||||
defer teardown(tmpDir)
|
||||
|
||||
currentDir, _ := os.Getwd()
|
||||
os.Chdir(tmpDir)
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
output := _compile_test(t, "-s", "templates/web/deployment.yaml")
|
||||
output := _compile_test(t, "-s", webTemplateOutput)
|
||||
dt := v1.Deployment{}
|
||||
if err := yaml.Unmarshal([]byte(output), &dt); err != nil {
|
||||
t.Errorf(unmarshalError, err)
|
||||
|
@@ -2,13 +2,12 @@ package extrafiles
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
@@ -1,7 +1,5 @@
|
||||
package generator
|
||||
|
||||
// TODO: configmap from files 20%
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
@@ -10,11 +8,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
// Generate a chart from a compose project.
|
||||
@@ -388,7 +386,7 @@ func buildVolumes(service types.ServiceConfig, chart *HelmChart, deployments map
|
||||
y, _ := pvc.Yaml()
|
||||
chart.Templates[pvc.Filename()] = &ChartTemplate{
|
||||
Content: y,
|
||||
Servicename: service.Name, // TODO, use name
|
||||
Servicename: service.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,13 +4,13 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
networkv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/generator/labelStructs"
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Ingress)(nil)
|
||||
|
@@ -10,9 +10,9 @@ import (
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
|
||||
"katenary/utils"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
var testingKatenaryPrefix = Prefix()
|
||||
|
||||
const mainAppLabel = "main-app"
|
||||
|
||||
func TestPrefix(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -27,7 +29,7 @@ func TestPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_labelName(t *testing.T) {
|
||||
func TestLabelName(t *testing.T) {
|
||||
type args struct {
|
||||
name string
|
||||
}
|
||||
@@ -39,9 +41,9 @@ func Test_labelName(t *testing.T) {
|
||||
{
|
||||
name: "Test_labelName",
|
||||
args: args{
|
||||
name: "main-app",
|
||||
name: mainAppLabel,
|
||||
},
|
||||
want: testingKatenaryPrefix + "/main-app",
|
||||
want: testingKatenaryPrefix + "/" + mainAppLabel,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -65,7 +67,7 @@ func TestGetLabelHelp(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetLabelHelpFor(t *testing.T) {
|
||||
help := GetLabelHelpFor("main-app", false)
|
||||
help := GetLabelHelpFor(mainAppLabel, false)
|
||||
if help == "" {
|
||||
t.Errorf("GetLabelHelpFor() = %v, want %v", help, "Help")
|
||||
}
|
||||
|
@@ -1,13 +1,13 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -84,7 +84,7 @@ func (s *Secret) SetData(data map[string]string) {
|
||||
}
|
||||
|
||||
// AddData adds a key value pair to the secret.
|
||||
func (s *Secret) AddData(key string, value string) {
|
||||
func (s *Secret) AddData(key, value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
|
@@ -4,13 +4,13 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var _ Yaml = (*Service)(nil)
|
||||
|
@@ -6,9 +6,6 @@ import (
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
)
|
||||
|
||||
// Values is a map of all values for all services. Written to values.yaml.
|
||||
// var Values = map[string]any{}
|
||||
|
||||
// RepositoryValue is a docker repository image and tag that will be saved in values.yaml.
|
||||
type RepositoryValue struct {
|
||||
Image string `yaml:"image"`
|
||||
@@ -17,19 +14,19 @@ type RepositoryValue struct {
|
||||
|
||||
// PersistenceValue is a persistence configuration that will be saved in values.yaml.
|
||||
type PersistenceValue struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
StorageClass string `yaml:"storageClass"`
|
||||
Size string `yaml:"size"`
|
||||
AccessMode []string `yaml:"accessMode"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
// IngressValue is a ingress configuration that will be saved in values.yaml.
|
||||
type IngressValue struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Annotations map[string]string `yaml:"annotations"`
|
||||
Host string `yaml:"host"`
|
||||
Path string `yaml:"path"`
|
||||
Class string `yaml:"class"`
|
||||
Annotations map[string]string `yaml:"annotations"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
// Value will be saved in values.yaml. It contains configuraiton for all deployment and services.
|
||||
@@ -37,13 +34,13 @@ type Value struct {
|
||||
Repository *RepositoryValue `yaml:"repository,omitempty"`
|
||||
Persistence map[string]*PersistenceValue `yaml:"persistence,omitempty"`
|
||||
Ingress *IngressValue `yaml:"ingress,omitempty"`
|
||||
ImagePullPolicy string `yaml:"imagePullPolicy,omitempty"`
|
||||
Environment map[string]any `yaml:"environment,omitempty"`
|
||||
Replicas *uint32 `yaml:"replicas,omitempty"`
|
||||
CronJob *CronJobValue `yaml:"cronjob,omitempty"`
|
||||
NodeSelector map[string]string `yaml:"nodeSelector"`
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
Resources map[string]any `yaml:"resources"`
|
||||
ImagePullPolicy string `yaml:"imagePullPolicy,omitempty"`
|
||||
ServiceAccount string `yaml:"serviceAccount"`
|
||||
}
|
||||
|
||||
// CronJobValue is a cronjob configuration that will be saved in values.yaml.
|
||||
|
@@ -3,17 +3,19 @@ package generator
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"katenary/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary/utils"
|
||||
)
|
||||
|
||||
var _ Yaml = (*VolumeClaim)(nil)
|
||||
|
||||
const persistenceKey = "persistence"
|
||||
|
||||
// VolumeClaim is a kubernetes VolumeClaim. This is a PersistentVolumeClaim.
|
||||
type VolumeClaim struct {
|
||||
*v1.PersistentVolumeClaim
|
||||
@@ -41,7 +43,12 @@ func NewVolumeClaim(service types.ServiceConfig, volumeName, appName string) *Vo
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{
|
||||
v1.ReadWriteOnce,
|
||||
},
|
||||
StorageClassName: utils.StrPtr(`{{ .Values.` + service.Name + `.persistence.` + volumeName + `.storageClass }}`),
|
||||
StorageClassName: utils.StrPtr(
|
||||
`{{ .Values.` +
|
||||
service.Name +
|
||||
"." + persistenceKey +
|
||||
"." + volumeName + `.storageClass }}`,
|
||||
),
|
||||
Resources: v1.VolumeResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceStorage: resource.MustParse("1Gi"),
|
||||
@@ -69,7 +76,7 @@ func (v *VolumeClaim) Yaml() ([]byte, error) {
|
||||
strings.Replace(
|
||||
string(out),
|
||||
"1Gi",
|
||||
utils.TplValue(serviceName, "persistence."+volumeName+".size"),
|
||||
utils.TplValue(serviceName, persistenceKey+"."+volumeName+".size"),
|
||||
1,
|
||||
),
|
||||
)
|
||||
@@ -80,8 +87,8 @@ func (v *VolumeClaim) Yaml() ([]byte, error) {
|
||||
"- ReadWriteOnce",
|
||||
"{{- .Values."+
|
||||
serviceName+
|
||||
".persistence."+
|
||||
volumeName+
|
||||
"."+persistenceKey+
|
||||
"."+volumeName+
|
||||
".accessMode | toYaml | nindent __indent__ }}",
|
||||
1,
|
||||
),
|
||||
@@ -92,7 +99,10 @@ func (v *VolumeClaim) Yaml() ([]byte, error) {
|
||||
if strings.Contains(line, "storageClass") {
|
||||
lines[i] = utils.Wrap(
|
||||
line,
|
||||
"{{- if ne .Values."+serviceName+".persistence."+volumeName+".storageClass \"-\" }}",
|
||||
"{{- if ne .Values."+
|
||||
serviceName+
|
||||
"."+persistenceKey+
|
||||
"."+volumeName+".storageClass \"-\" }}",
|
||||
"{{- end }}",
|
||||
)
|
||||
}
|
||||
@@ -103,8 +113,8 @@ func (v *VolumeClaim) Yaml() ([]byte, error) {
|
||||
out = []byte(
|
||||
"{{- if .Values." +
|
||||
serviceName +
|
||||
".persistence." +
|
||||
volumeName +
|
||||
"." + persistenceKey +
|
||||
"." + volumeName +
|
||||
".enabled }}\n" +
|
||||
string(out) +
|
||||
"\n{{- end }}",
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
)
|
||||
|
||||
func TestDownloadLatestRelease(t *testing.T) {
|
||||
|
||||
// Reset the version to test the latest release
|
||||
Version = "0.0.0"
|
||||
|
||||
@@ -17,15 +16,14 @@ func TestDownloadLatestRelease(t *testing.T) {
|
||||
|
||||
// Now call the CheckLatestVersion function
|
||||
version, assets, err := CheckLatestVersion()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
t.Errorf("Error getting latest version: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println("Version found", version)
|
||||
|
||||
// Touch exe binary
|
||||
f, _ := os.OpenFile(exe, os.O_RDONLY|os.O_CREATE, 0755)
|
||||
f, _ := os.OpenFile(exe, os.O_RDONLY|os.O_CREATE, 0o755)
|
||||
f.Write(nil)
|
||||
f.Close()
|
||||
|
||||
@@ -48,5 +46,4 @@ func TestAlreadyUpToDate(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Log("Version is already the most recent", version)
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -114,8 +116,8 @@ func PathToName(path string) string {
|
||||
|
||||
// EnvConfig is a struct to hold the description of an environment variable.
|
||||
type EnvConfig struct {
|
||||
Description string
|
||||
Service types.ServiceConfig
|
||||
Description string
|
||||
}
|
||||
|
||||
// GetValuesFromLabel returns a map of values from a label.
|
||||
@@ -160,3 +162,27 @@ func MapKeys(m map[string]interface{}) []string {
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Confirm asks a question and returns true if the answer is y.
|
||||
func Confirm(question string, icon ...Icon) bool {
|
||||
if len(icon) > 0 {
|
||||
fmt.Printf("%s %s [y/N] ", icon[0], question)
|
||||
} else {
|
||||
fmt.Print(question + " [y/N] ")
|
||||
}
|
||||
var response string
|
||||
fmt.Scanln(&response)
|
||||
return strings.ToLower(response) == "y"
|
||||
}
|
||||
|
||||
// EncodeBasicYaml encodes a basic yaml from an interface.
|
||||
func EncodeBasicYaml(data any) ([]byte, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
enc := yaml.NewEncoder(buf)
|
||||
enc.SetIndent(2)
|
||||
err := enc.Encode(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user