Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix binary data, Add tests, Error management #91

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@

<div style="text-align:center; margin: auto 0 4em 0" align="center">
<img src="./doc/docs/statics/logo-vertical.svg" alt="Katenary Logo" style="max-width: 90%" align="center"/>

</div>

[![Documentation Status](https://readthedocs.org/projects/katenary/badge/?version=latest)](https://katenary.readthedocs.io/en/latest/?badge=latest)
Expand Down Expand Up @@ -262,7 +260,7 @@ return {
settings = {
yaml = {
schemas = {
["https://raw.githubusercontent.com/metal3d/katenary/refs/heads/master/katenary.json"] = "katenary.yaml",
["https://raw.githubusercontent.com/metal3d/katenary/master/katenary.json"] = "katenary.yaml",
},
},
},
Expand All @@ -278,12 +276,12 @@ Use this address to validate the `katenary.yaml` file in VSCode:
```json
{
"yaml.schemas": {
"https://raw.githubusercontent.com/metal3d/katenary/refs/heads/master/katenary.json": "katenary.yaml"
"https://raw.githubusercontent.com/metal3d/katenary/master/katenary.json": "katenary.yaml"
}
}
```

> You can, of course, replace the `refs/heads/master` with a specific tag or branch.
> You can, of course, replace the `master` with a specific tag or branch.

## What a name…

Expand Down
4 changes: 2 additions & 2 deletions cmd/katenary/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,11 @@ func generateConvertCommand() *cobra.Command {
convertCmd := &cobra.Command{
Use: "convert",
Short: "Converts a docker-compose file to a Helm Chart",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if givenAppVersion != "" {
appVersion = &givenAppVersion
}
generator.Convert(generator.ConvertOptions{
return generator.Convert(generator.ConvertOptions{
Force: force,
OutputDir: outputDir,
Profiles: profiles,
Expand Down
41 changes: 25 additions & 16 deletions doc/docs/packages/generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ type ChartTemplate struct {
```

<a name="ConfigMap"></a>
## type [ConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L35-L40>)
## type [ConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L36-L41>)

ConfigMap is a kubernetes ConfigMap. Implements the DataMap interface.

Expand All @@ -131,7 +131,7 @@ type ConfigMap struct {
```

<a name="NewConfigMap"></a>
### func [NewConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L44>)
### func [NewConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L45>)

```go
func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *ConfigMap
Expand All @@ -140,43 +140,52 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co
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#L117>)
### func [NewConfigMapFromDirectory](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L118>)

```go
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#L148>)
<a name="ConfigMap.AddBinaryData"></a>
### func \(\*ConfigMap\) [AddBinaryData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L154>)

```go
func (c *ConfigMap) AddData(key, value string)
func (c *ConfigMap) AddBinaryData(key string, value []byte)
```

AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
AddBinaryData adds binary data 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#L154>)
<a name="ConfigMap.AddData"></a>
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L149>)

```go
func (c *ConfigMap) AppendDir(path string)
func (c *ConfigMap) AddData(key, value 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.
AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.

<a name="ConfigMap.AppendFile"></a>
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L189>)
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L209>)

```go
func (c *ConfigMap) AppendFile(path string)
```



<a name="ConfigMap.AppenddDir"></a>
### func \(\*ConfigMap\) [AppenddDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L163>)

```go
func (c *ConfigMap) AppenddDir(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.Filename"></a>
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L207>)
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L232>)

```go
func (c *ConfigMap) Filename() string
Expand All @@ -185,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#L217>)
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L242>)

```go
func (c *ConfigMap) SetData(data map[string]string)
Expand All @@ -194,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#L222>)
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L247>)

```go
func (c *ConfigMap) Yaml() ([]byte, error)
Expand Down Expand Up @@ -421,7 +430,7 @@ func (d *Deployment) Yaml() ([]byte, error)
Yaml returns the yaml representation of the deployment.

<a name="FileMapUsage"></a>
## type [FileMapUsage](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L19>)
## type [FileMapUsage](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L20>)

FileMapUsage is the usage of the filemap.

Expand Down
4 changes: 2 additions & 2 deletions doc/docs/packages/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,13 @@ type Icon string
const (
IconSuccess Icon = "✅"
IconFailure Icon = "❌"
IconWarning Icon = "⚠️'"
IconWarning Icon = ""
IconNote Icon = "📝"
IconWorld Icon = "🌐"
IconPlug Icon = "🔌"
IconPackage Icon = "📦"
IconCabinet Icon = "🗄️"
IconInfo Icon = ""
IconInfo Icon = "🔵"
IconSecret Icon = "🔒"
IconConfig Icon = "🔧"
IconDependency Icon = "🔗"
Expand Down
50 changes: 39 additions & 11 deletions generator/configMap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package generator

import (
"fmt"
"katenary/generator/labels"
"katenary/generator/labels/labelStructs"
"katenary/utils"
Expand All @@ -9,6 +10,7 @@ import (
"path/filepath"
"regexp"
"strings"
"unicode/utf8"

"github.com/compose-spec/compose-go/types"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -149,58 +151,84 @@ func (c *ConfigMap) AddData(key, value string) {
c.Data[key] = value
}

// AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists.
func (c *ConfigMap) AddBinaryData(key string, value []byte) {
if c.BinaryData == nil {
c.BinaryData = make(map[string][]byte)
}
c.BinaryData[key] = value
}

// 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.
func (c *ConfigMap) AppendDir(path string) {
func (c *ConfigMap) AppendDir(path string) error {
// read all files in the path and add them to the configmap
stat, err := os.Stat(path)
if err != nil {
log.Fatalf("Path %s does not exist\n", path)
return fmt.Errorf("Path %s does not exist, %w\n", path, err)
}
// recursively read all files in the path and add them to the configmap
if stat.IsDir() {
files, err := os.ReadDir(path)
if err != nil {
log.Fatal(err)
return err
}
for _, file := range files {
if file.IsDir() {
utils.Warn("Subdirectories are ignored for the moment, skipping", filepath.Join(path, file.Name()))
continue
}
path := filepath.Join(path, file.Name())
content, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
return err
}
// remove the path from the file
filename := filepath.Base(path)
c.AddData(filename, string(content))
if utf8.Valid(content) {
c.AddData(filename, string(content))
} else {
c.AddBinaryData(filename, content)
}

}
} else {
// add the file to the configmap
content, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
return err
}
filename := filepath.Base(path)
if utf8.Valid(content) {
c.AddData(filename, string(content))
} else {
c.AddBinaryData(filename, content)
}
c.AddData(filepath.Base(path), string(content))
}
return nil
}

func (c *ConfigMap) AppendFile(path string) {
func (c *ConfigMap) AppendFile(path string) error {
// read all files in the path and add them to the configmap
stat, err := os.Stat(path)
if err != nil {
log.Fatalf("Path %s does not exist\n", path)
return fmt.Errorf("Path %s doesn not exists, %w", path, err)
}
// recursively read all files in the path and add them to the configmap
if !stat.IsDir() {
// add the file to the configmap
content, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
return err
}
c.AddData(filepath.Base(path), string(content))
if utf8.Valid(content) {
c.AddData(filepath.Base(path), string(content))
} else {
c.AddBinaryData(filepath.Base(path), content)
}

}
return nil
}

// Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
Expand Down
17 changes: 17 additions & 0 deletions generator/configMap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"testing"

"github.com/compose-spec/compose-go/types"
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -73,3 +74,19 @@ services:
t.Errorf("Expected FOO to be baz, got %s", v)
}
}

func TestAppendBadFile(t *testing.T) {
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
err := cm.AppendFile("foo")
if err == nil {
t.Errorf("Expected error, got nil")
}
}

func TestAppendBadDir(t *testing.T) {
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
err := cm.AppendDir("foo")
if err == nil {
t.Errorf("Expected error, got nil")
}
}
13 changes: 7 additions & 6 deletions generator/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ var keyRegExp = regexp.MustCompile(`^\s*[^#]+:.*`)

// Convert a compose (docker, podman...) project to a helm chart.
// It calls Generate() to generate the chart and then write it to the disk.
func Convert(config ConvertOptions, dockerComposeFile ...string) {
func Convert(config ConvertOptions, dockerComposeFile ...string) error {
var (
templateDir = filepath.Join(config.OutputDir, "templates")
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
Expand All @@ -105,7 +105,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
// go to the root of the project
if err := os.Chdir(filepath.Dir(dockerComposeFile[0])); err != nil {
fmt.Println(utils.IconFailure, err)
os.Exit(1)
return err
}
defer os.Chdir(currentDir) // after the generation, go back to the original directory

Expand All @@ -118,13 +118,13 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
project, err := parser.Parse(config.Profiles, config.EnvFiles, dockerComposeFile...)
if err != nil {
fmt.Println(err)
os.Exit(1)
return err
}

// check older version of labels
if err := checkOldLabels(project); err != nil {
fmt.Println(utils.IconFailure, err)
os.Exit(1)
return err
}

// TODO: use katenary.yaml file here to set the labels
Expand All @@ -140,7 +140,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
)
if !overwrite {
fmt.Println("Aborting")
os.Exit(126) // 126 is the exit code for "Command invoked cannot execute"
return nil
}
}
fmt.Println() // clean line
Expand All @@ -150,7 +150,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
chart, err := Generate(project)
if err != nil {
fmt.Println(err)
os.Exit(1)
return err
}

// if the app version is set from the command line, use it
Expand Down Expand Up @@ -194,6 +194,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {

// call helm update if needed
callHelmUpdate(config)
return nil
}

func addChartDoc(values []byte, project *types.Project) []byte {
Expand Down
4 changes: 3 additions & 1 deletion generator/tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ func internalCompileTest(t *testing.T, options ...string) string {
AppVersion: appVersion,
ChartVersion: chartVersion,
}
Convert(convertOptions, "compose.yml")
if err := Convert(convertOptions, "compose.yml"); err != nil {
return err.Error()
}

// launch helm lint to check the generated chart
if helmLint(convertOptions) != nil {
Expand Down
Loading
Loading