From e8eba7c7f891920d857947f139911851efe22fff Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Fri, 18 Oct 2024 09:34:57 +0200 Subject: [PATCH] Enhance documentation - upgraded mkdocs and dependencise (+ add mermaid) - linted markdown - add more details --- doc/docs/coding.md | 33 +++++- doc/docs/dependencies.md | 12 +- doc/docs/faq.md | 78 ++++++++----- doc/docs/index.md | 30 +++-- doc/docs/packages/generator.md | 117 ++++++++++---------- doc/docs/packages/generator/extrafiles.md | 2 +- doc/docs/packages/generator/labelStructs.md | 22 ++-- doc/docs/packages/parser.md | 4 +- doc/docs/packages/utils.md | 32 +++--- doc/docs/usage.md | 60 +++++----- doc/mkdocs.yml | 6 +- doc/requirements.txt | 14 +-- 12 files changed, 227 insertions(+), 183 deletions(-) diff --git a/doc/docs/coding.md b/doc/docs/coding.md index d039527..25bc8cb 100644 --- a/doc/docs/coding.md +++ b/doc/docs/coding.md @@ -9,7 +9,7 @@ Katenary is developed in Go. The version currently supported is 1.20. For reason preferred to `interface{}`. Since version v3, Katenary uses, in addition to `go-compose`, the `k8s` library to generate objects that are guaranteed -to work before transformation. Katenary adds Helm syntax entries to add loops, transformations and conditions. +to work before transformation. Katenary adds Helm syntax entries to add loops, transformations, and conditions. We really try to follow best practices and code principles. But, Katenary needs a lot of workarounds and string manipulation during the process. There are, also, some drawbacks using standard k8s packages that makes a lot of type @@ -25,6 +25,35 @@ During conversion, the `generator` package is primarily responsible for creating one `Deployment` per `compose` service. If the container coming from "compose" exposes ports (explicitly), then a service is created. +```mermaid +flowchart TD + + D[Deployment]:::outputs@{shape: curv-trap} + C[Container List]@{shape: docs} + ConfigMap:::outputs@{shape: curv-trap} + Secrets:::outputs@{shape: curv-trap} + H[Helm Chart.yaml file]:::outputs@{shape: curv-trap} + Val[Values files]:::outputs@{shape: curv-trap} + PVC:::outputs@{shape: curv-trap} + S[Service]:::outputs@{shape: curv-trap} + + A[Compose file]:::inputs --> B[Compose parser] + B --> G[Generator] + G --> P[Ports exposed to services] ---> S + G ------> H + G --> C --> D + G ------> Val + G ....-> M[Merge Continainers if same-pod] + M ..-> C + G --> E[Environment variables] ----> Secrets & ConfigMap + G--> V[Bind volumes] -------> PVC + V -----> CF[ Create ConfigMap\nfor static files as\nconfigmap-files] --> ConfigMap + + Secrets & ConfigMap -- create envFrom --> D + V -- bind volumes --> D + +``` + If the declaration of a container is to be integrated into another pod (via the `same-pod` label), this `Deployment` and its associated service are still created. They are deleted last, once the merge has been completed. @@ -34,7 +63,6 @@ The `generator` package is where object struct are defined, and where the `Gener The generation is made by using a `HelmChart` object: -```golang ```golang for _, service := range project.Services { dep := NewDeployment(service) @@ -44,6 +72,7 @@ for _, service := range project.Services { Servicename: service.Name, } } +``` **A lot** of string manipulations are made by each `Yaml()` methods. This is where you find the complex and impacting operations. The `Yaml` methods **don't return a valid YAML content**. This is a Helm Chart Yaml content with template diff --git a/doc/docs/dependencies.md b/doc/docs/dependencies.md index 36f8975..29b73b7 100644 --- a/doc/docs/dependencies.md +++ b/doc/docs/dependencies.md @@ -2,15 +2,17 @@ Katenary uses `compose-go` and several kubernetes official packages. -- `github.com/compose-spec/compose-go`: to parse compose files. It ensures that: - - the project respects the "compose" specification - - katenary uses the "compose" struct exactly the same way that podman-compose or docker does +- `github.com/compose-spec/compose-go`: to parse compose files. It ensures : + - that the project respects the "compose" specification + - that Katenary uses the "compose" struct exactly the same way `podman compose` or `docker copose` does - `github.com/spf13/cobra`: to parse command line arguments, subcommands and flags. It also generates completion for - bash, zsh, fish and powershell. + bash, zsh, fish and PowerShell. - `github.com/thediveo/netdb`: to get the standard names of a service from its port number - `gopkg.in/yaml.v3`: - to generate `Chart.yaml` and `values.yaml` files (only) - to parse Katenary labels in the compose file - `k8s.io/api` and `k8s.io/apimachinery` to create Kubernetes objects -- `sigs.k8s.io/yaml`: to generate Katenary yaml files +- `sigs.k8s.io/yaml`: to generate Katenary YAML files in the format of Kubernetes objects +There are also some other packages used in the project, like `gopkg.in/yaml` to parse labels. I'm sorry to not list the +entire dependencies. You can check the `go.mod` file to see all the dependencies. diff --git a/doc/docs/faq.md b/doc/docs/faq.md index a54805b..902aaaa 100644 --- a/doc/docs/faq.md +++ b/doc/docs/faq.md @@ -2,86 +2,108 @@ ## Why Katenary? -The main author[^1] of Katenary is a big fan of Podman, Docker and makes a huge use of Compose. He uses it a lot in his daily work. When he started to work with Kubernetes, he wanted to have the same experience as with Docker Compose. He wanted to have a tool that could convert his `docker-compose` files to Kubernetes manifests, but also to Helm charts. +The main author[^1] of Katenary is a big fan of Podman, Docker and makes a huge use of Compose. He uses it a lot in his +daily work. When he started to work with Kubernetes, he wanted to have the same experience as with Docker Compose. +He wanted to have a tool that could convert his `docker-compose` files to Kubernetes manifests, but also to Helm charts. -Kompose was a good option. But the lacks of some options and configuration for the output Helm chart made him think about creating a new tool. He wanted to have a tool that could generate a complete Helm chart, with a lot of options and flexibility. +Kompose was a good option. But the lacks of some options and configuration for the output Helm chart made him think +about creating a new tool. He wanted to have a tool that could generate a complete Helm chart, with a lot of options +and flexibility. -[^1]: I'm talking about myself :sunglasses: - Patrice FERLET, aka metal3d, Tech Lead and DevOps Engineer at Klee Group. +[^1]: I'm talking about myself :sunglasses: - Patrice FERLET, aka Metal3d, Tech Lead and DevOps Engineer at Klee Group. ## What's the difference between Katenary and Kompose? -[Kompose](https://kompose.io/) is a very nice tool, made by the Kubernetes community. It's a tool to convert `docker-compose` files to Kubernetes manifests. It's a very good tool, and it's more mature than Katenary. +[Kompose](https://kompose.io/) is a very nice tool, made by the Kubernetes community. It's a tool to convert +`docker-compose` files to Kubernetes manifests. It's a very good tool, and it's more mature than Katenary. -Kompose is able to genererate Helm charts, but [it could be not the case in future releases](https://github.com/kubernetes/kompose/issues/1716) for several reasons[^2]. +Kompose is able to generate Helm charts, but [it could be not the case in future releases](https://github.com/kubernetes/kompose/issues/1716) for several reasons[^2]. -[^2]: The author of Kompose explains that they have no bandwidth to maintain the Helm chart generation. It's a complex task, and we can confirm. Katenary takes a lot of time to be developed and maintained. This issue mentions Katenary as an alternative to Helm chart generation :smile: +[^2]: The author of Kompose explains that they have no bandwidth to maintain the Helm chart generation. It's a complex +task, and we can confirm. Katenary takes a lot of time to be developed and maintained. This issue mentions Katenary as +an alternative to Helm chart generation :smile: -The project is focused on Kubernetes manifests and proposes to use "kusomize" to adapt the manifests. Helm seems to be not the priority. +The project is focused on Kubernetes manifests and proposes to use "kusomize" to adapt the manifests. Helm seems to be +not the priority. -Anyway, before this decision, the Helm chart generation was not what we expected. We wanted to have a more complete chart, with more options and more flexibility. +Anyway, before this decision, the Helm chart generation was not what we expected. We wanted to have a more complete +chart, with more options and more flexibility. > That's why we decided to create Katenary. -Kompose didn't manage to generate a values file, complexe volume binding, and many other things. It was also not able to manage dependencies between services. +Kompose didn't manage to generate a values file, complex volume binding, and many other things. It was also not able +to manage dependencies between services. > Be sure that we don't want to compete with Kompose. We just want to propose a different approach to the problem. -Kompose is an excellent tool, and we use it in some projects. It's a good choice if you want to convert your `docker-compose` files to Kubernetes manifests, but if you want to use Helm, Katenary is the tool you need. +Kompose is an excellent tool, and we use it in some projects. It's a good choice if you want to convert +your `docker-compose` files to Kubernetes manifests, but if you want to use Helm, Katenary is the tool you need. ## Why not using "one label" for all the configuration? -That was a dicsussion I had with my colleagues. The idea was to use a single label to store all the configuration. But, it's not a good idea. +That was a dicsussion I had with my colleagues. The idea was to use a single label to store all the configuration. +But, it's not a good idea. -Sometimes, you will have a long list of things to configure, like ports, ingress, dependecies, etc. It's better to have a clear and readable configuration. Segmented labels are easier to read and to maintain. It also avoids to have too many indentation levels in the YAML file. +Sometimes, you will have a long list of things to configure, like ports, ingress, dependencies, etc. It's better to have +a clear and readable configuration. Segmented labels are easier to read and to maintain. It also avoids having too +many indentation levels in the YAML file. It is also more flexible. You can add or remove labels without changing the others. ## Why not using a configuration file? -The idea was to keep the configuration at a same place, and using the go-compose library to read the labels. It's easier to have a single file to manage. +The idea was to keep the configuration at a same place, and using the go-compose library to read the labels. It's +easier to have a single file to manage. -By the way, Katenary auto accepts a `compose.katenary.yaml` file in the same directory. It's a way to separate the configuration from the compose file. It uses the [overrides mecanism](https://docs.docker.com/compose/multiple-compose-files/merge/) like "compose" does. +By the way, Katenary auto accepts a `compose.katenary.yaml` file in the same directory. It's a way to separate the +configuration from the compose file. It uses +the [overrides' mechanism](https://docs.docker.com/compose/multiple-compose-files/merge/) like "compose" does. - -## Why not developping with Rust? +## Why not developing with Rust? Seriously... OK, I will answer. -Rust is a good language. But, Podman, Docker, Kubernetes, Helm, and mostly all technologies around Kubernetes are written in Go. We have a large ecosystem in Go to manipulate, read, and write Kubernetes manifests as parsing Compose files. +Rust is a good language. But, Podman, Docker, Kubernetes, Helm, and mostly all technologies around Kubernetes are +written in Go. We have a large ecosystem in Go to manipulate, read, and write Kubernetes manifests as parsing +Compose files. -Go is better for this task. +> Go is better for this task. There is no reason to use Rust for this project. ## Any chance to have a GUI? -Yes, it's a possibility. But, it's not a priority. We have a lot of things to do before. We need to stabilize the project, to have a good documentation, to have a good test coverage, and to have a good community. +Yes, it's a possibility. But, it's not a priority. We have a lot of things to do before. We need to stabilize the +project, to have a good documentation, to have a good test coverage, and to have a good community. But, in a not so far future, we could have a GUI. The choice of [Fyne.io](https://fyne.io) is already made and we tested some concepts. - ## I'm rich (or not), I want to help you. How can I do? You can help us in many ways. -- The first things we really need, more than money, more than anything else, is to have feedback. If you use Katenary, if you have some issues, if you have some ideas, please open an issue on the [GitHub repository](https://github.com/metal3d/katenary). -- The second things is to help us to fix issues. If you're a Go developper, or if you want to fix the documentation, your help is greatly appreciated. +- The first things we really need, more than money, more than anything else, is to have feedback. If you use Katenary, +if you have some issues, if you have some ideas, please open an issue on the [GitHub repository](https://github.com/metal3d/katenary). +- The second things is to help us to fix issues. If you're a Go developper, or if you want to fix the documentation, +your help is greatly appreciated. - And then, of course, we need money, or sponsors. ### If you're a company -We will be happy to communicate your help by putting your logo on the website and in the documentaiton. You can sponsor us by giving us some money, or by giving us some time of your developers, or leaving us some time to work on the project. +We will be happy to communicate your help by putting your logo on the website and in the documentaiton. You can sponsor +us by giving us some money, or by giving us some time of your developers, or leaving us some time to work on the project. ### If you're an individual -All donators will be listed on the website and in the documentation. You can give us some money by using the [GitHub Sponsors]() +All donators will be listed on the website and in the documentation. You can give us some money by using +the [GitHub Sponsors]() -All main contributors[^3] will be listed on the website and in the documentation. +All main contributors[^3] will be listed on the website and in the documentation. > If you want to be anonymous, please tell us. - -[^3]: Main contributors are the people who have made a significant contribution to the project. It could be code, documentation, or any other help. There is no defined rules, at this time, to evaluate the contribution. It's a subjective decision. - +[^3]: Main contributors are the people who have made a significant contribution to the project. It could be code, +documentation, or any other help. There is no defined rules, at this time, to evaluate the contribution. +It's a subjective decision. diff --git a/doc/docs/index.md b/doc/docs/index.md index fc3c4c7..5c75dd3 100644 --- a/doc/docs/index.md +++ b/doc/docs/index.md @@ -6,10 +6,10 @@ 🚀 Unleash Productivity with Katenary! 🚀 -Tired of manual conversions? Katenary harnesses the labels from your "compose" file to craft complete Helm Charts +Tired of manual conversions? Katenary harnesses the labels from your "compose" file to craft complete Helm Charts effortlessly, saving you time and energy. -🛠️ Simple autmated CLI: Katenary handles the grunt work, generating everything needed for seamless service binding +🛠️ Simple autmated CLI: Katenary handles the grunt work, generating everything needed for seamless service binding and Helm Chart creation. 💡 Effortless Efficiency: You only need to add labels when it's necessary to precise things. Then call `katenary convert` @@ -19,13 +19,12 @@ and let the magic happen. ![](statics/workflow.svg) - # What is it? Katenary is a tool made to help you to transform "compose" files (`compose.yaml`, `docker-compose.yml`, `podman-compose.yml`...) to complete and production ready [Helm Chart](https://helm.sh). -You'll be able to deploy your project in [:material-kubernetes: Kubernetes](https://kubernetes.io) in a few seconds +You'll be able to deploy your project in [:material-kubernetes: Kubernetes](https://kubernetes.io) in a few seconds (of course, more if you need to tweak with labels). It uses your current file and optionnaly labels to configure the result. @@ -42,19 +41,19 @@ share it with the community. The main developer is [Patrice FERLET](https://github.com/metal3d). -The project source +The project source code is hosted on the [:fontawesome-brands-github: Katenary GitHub Repository](https://github.com/metal3d/katenary). ## Install Katenary -Katenary is developped using the :fontawesome-brands-golang:{ .gopher } [Go](https://go.dev) language. +Katenary is developped using the :fontawesome-brands-golang:{ .gopher } [Go](https://go.dev) language. The binary is statically linked, so you can simply download it from the [release page](https://github.com/metal3d/katenary/releases) of the project in GutHub. -You need to select the right binary for your operating system and architecture, and copy the binary in a directory +You need to select the right binary for your operating system and architecture, and copy the binary in a directory that is in your `PATH`. -If you are a Linux user, you can use the "one line installation command" which will download the binary in your +If you are a Linux user, you can use the "one line installation command" which will download the binary in your `$HOME/.local/bin` directory if it exists. ```bash @@ -66,10 +65,9 @@ sh <(curl -sSL https://raw.githubusercontent.com/metal3d/katenary/master/install Of course, you need to install Katenary once :smile: - !!! Note "You prefer to compile it, no need to install Go" - You can also build and install it yourself, the provided Makefile has got a `build` command that uses `podman` or - `docker` to build the binary. + You can also build and install it yourself, the provided Makefile has got a `build` command that uses `podman` or + `docker` to build the binary. So, you don't need to install Go compiler :+1:. @@ -85,7 +83,7 @@ make build make install ``` -`make install` copies `./katenary` binary to your user binary path (`~/.local/bin`) +`make install` copies `./katenary` binary to your user binary path (`~/.local/bin`) You can install it in other directory by changing the `PREFIX` variable. E.g.: @@ -109,8 +107,7 @@ source <(katenary completion bash) Add this line in you `~/.profile`, `~/.bash_aliases` or `~/.bashrc` file to have completion at startup. - -## What a name... +## What a name A catenary is the curve that a hanging chain or cable assumes under its own weight when supported only at its ends. I, the maintainer, decided to name "Katenary" this project because it's like a chain that links a boat to a dock. @@ -122,14 +119,13 @@ Anyway, it's too late to change the name now :smile: I spent time to find it :wink: -## Special thanks to... +## Special thanks to I really want to thank all the contributors, testers, and of course, the authors of the packages and tools that are used in this project. There is too many to list here. Katenary can works because of all these people. Open source is a great thing! :heart: - -!!! Edit "Special thanks" +!!! Edit "Special thanks" **Katenary is built with:**
diff --git a/doc/docs/packages/generator.md b/doc/docs/packages/generator.md index 924a942..5df58a5 100644 --- a/doc/docs/packages/generator.md +++ b/doc/docs/packages/generator.md @@ -35,7 +35,7 @@ var Version = "master" // changed at compile time ``` -## func [Convert]() +## func [Convert]() ```go func Convert(config ConvertOptions, dockerComposeFile ...string) @@ -44,7 +44,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) 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 [GetLabelHelp]() +## func [GetLabelHelp]() ```go func GetLabelHelp(asMarkdown bool) string @@ -53,7 +53,7 @@ func GetLabelHelp(asMarkdown bool) string Generate the help for the labels. -## func [GetLabelHelpFor]() +## func [GetLabelHelpFor]() ```go func GetLabelHelpFor(labelname string, asMarkdown bool) string @@ -62,7 +62,7 @@ func GetLabelHelpFor(labelname string, asMarkdown bool) string GetLabelHelpFor returns the help for a specific label. -## func [GetLabelNames]() +## func [GetLabelNames]() ```go func GetLabelNames() []string @@ -107,7 +107,7 @@ func NewCronJob(service types.ServiceConfig, chart *HelmChart, appName string) ( NewCronJob creates a new CronJob from a compose service. The appName is the name of the application taken from the project name. -## func [Prefix]() +## func [Prefix]() ```go func Prefix() string @@ -116,7 +116,7 @@ func Prefix() string -## type [ChartTemplate]() +## type [ChartTemplate]() 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. @@ -128,7 +128,7 @@ type ChartTemplate struct { ``` -## type [ConfigMap]() +## type [ConfigMap]() ConfigMap is a kubernetes ConfigMap. Implements the DataMap interface. @@ -140,16 +140,16 @@ type ConfigMap struct { ``` -### func [NewConfigMap]() +### func [NewConfigMap]() ```go -func NewConfigMap(service types.ServiceConfig, appName string) *ConfigMap +func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *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". -### func [NewConfigMapFromDirectory]() +### func [NewConfigMapFromDirectory]() ```go func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap @@ -158,7 +158,7 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string 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 \(\*ConfigMap\) [AddData]() +### func \(\*ConfigMap\) [AddData]() ```go func (c *ConfigMap) AddData(key, value string) @@ -167,7 +167,7 @@ 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. -### func \(\*ConfigMap\) [AppendDir]() +### func \(\*ConfigMap\) [AppendDir]() ```go func (c *ConfigMap) AppendDir(path string) @@ -176,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. -### func \(\*ConfigMap\) [AppendFile]() +### func \(\*ConfigMap\) [AppendFile]() ```go func (c *ConfigMap) AppendFile(path string) @@ -185,7 +185,7 @@ func (c *ConfigMap) AppendFile(path string) -### func \(\*ConfigMap\) [Filename]() +### func \(\*ConfigMap\) [Filename]() ```go func (c *ConfigMap) Filename() string @@ -194,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. -### func \(\*ConfigMap\) [SetData]() +### func \(\*ConfigMap\) [SetData]() ```go func (c *ConfigMap) SetData(data map[string]string) @@ -203,7 +203,7 @@ func (c *ConfigMap) SetData(data map[string]string) SetData sets the data of the configmap. It replaces the entire data. -### func \(\*ConfigMap\) [Yaml]() +### func \(\*ConfigMap\) [Yaml]() ```go func (c *ConfigMap) Yaml() ([]byte, error) @@ -212,7 +212,7 @@ func (c *ConfigMap) Yaml() ([]byte, error) Yaml returns the yaml representation of the configmap -## type [ConfigMapMount]() +## type [ConfigMapMount]() @@ -223,7 +223,7 @@ type ConfigMapMount struct { ``` -## type [ConvertOptions]() +## type [ConvertOptions]() ConvertOptions are the options to convert a compose project to a helm chart. @@ -232,9 +232,11 @@ type ConvertOptions struct { AppVersion *string OutputDir string ChartVersion string + Icon string Profiles []string Force bool HelmUpdate bool + EnvFiles []string } ``` @@ -273,7 +275,7 @@ Yaml returns the yaml representation of the cronjob. Implements the Yaml interface. -## type [CronJobValue]() +## type [CronJobValue]() CronJobValue is a cronjob configuration that will be saved in values.yaml. @@ -299,7 +301,7 @@ type DataMap interface { ``` -### func [NewFileMap]() +### func [NewFileMap]() ```go func NewFileMap(service types.ServiceConfig, appName, kind string) DataMap @@ -308,7 +310,7 @@ 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. -## type [Deployment]() +## type [Deployment]() Deployment is a kubernetes Deployment. @@ -320,7 +322,7 @@ type Deployment struct { ``` -### func [NewDeployment]() +### func [NewDeployment]() ```go func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment @@ -329,7 +331,7 @@ func NewDeployment(service types.ServiceConfig, chart *HelmChart) *Deployment NewDeployment creates a new Deployment from a compose service. The appName is the name of the application taken from the project name. It also creates the Values map that will be used to create the values.yaml file. -### func \(\*Deployment\) [AddContainer]() +### func \(\*Deployment\) [AddContainer]() ```go func (d *Deployment) AddContainer(service types.ServiceConfig) @@ -338,7 +340,7 @@ func (d *Deployment) AddContainer(service types.ServiceConfig) AddContainer adds a container to the deployment. -### func \(\*Deployment\) [AddHealthCheck]() +### func \(\*Deployment\) [AddHealthCheck]() ```go func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *corev1.Container) @@ -347,7 +349,7 @@ func (d *Deployment) AddHealthCheck(service types.ServiceConfig, container *core -### func \(\*Deployment\) [AddIngress]() +### func \(\*Deployment\) [AddIngress]() ```go func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *Ingress @@ -356,7 +358,7 @@ func (d *Deployment) AddIngress(service types.ServiceConfig, appName string) *In AddIngress adds an ingress to the deployment. It creates the ingress object. -### func \(\*Deployment\) [AddVolumes]() +### func \(\*Deployment\) [AddVolumes]() ```go func (d *Deployment) AddVolumes(service types.ServiceConfig, appName string) @@ -365,7 +367,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. -### func \(\*Deployment\) [BindFrom]() +### func \(\*Deployment\) [BindFrom]() ```go func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) @@ -374,7 +376,7 @@ func (d *Deployment) BindFrom(service types.ServiceConfig, binded *Deployment) -### func \(\*Deployment\) [DependsOn]() +### func \(\*Deployment\) [DependsOn]() ```go func (d *Deployment) DependsOn(to *Deployment, servicename string) error @@ -383,7 +385,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. -### func \(\*Deployment\) [Filename]() +### func \(\*Deployment\) [Filename]() ```go func (d *Deployment) Filename() string @@ -392,7 +394,7 @@ func (d *Deployment) Filename() string Filename returns the filename of the deployment. -### func \(\*Deployment\) [SetEnvFrom]() +### func \(\*Deployment\) [SetEnvFrom]() ```go func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) @@ -401,7 +403,7 @@ func (d *Deployment) SetEnvFrom(service types.ServiceConfig, appName string) SetEnvFrom sets the environment variables to a configmap. The configmap is created. -### func \(\*Deployment\) [Yaml]() +### func \(\*Deployment\) [Yaml]() ```go func (d *Deployment) Yaml() ([]byte, error) @@ -410,7 +412,7 @@ func (d *Deployment) Yaml() ([]byte, error) Yaml returns the yaml representation of the deployment. -## type [FileMapUsage]() +## type [FileMapUsage]() FileMapUsage is the usage of the filemap. @@ -428,7 +430,7 @@ const ( ``` -## type [HelmChart]() +## type [HelmChart]() HelmChart is a Helm Chart representation. It contains all the tempaltes, values, versions, helpers... @@ -439,6 +441,7 @@ type HelmChart struct { VolumeMounts map[string]any `yaml:"-"` Name string `yaml:"name"` + Icon string `yaml:"icon,omitempty"` ApiVersion string `yaml:"apiVersion"` Version string `yaml:"version"` AppVersion string `yaml:"appVersion"` @@ -450,7 +453,7 @@ type HelmChart struct { ``` -### func [Generate]() +### func [Generate]() ```go func Generate(project *types.Project) (*HelmChart, error) @@ -470,7 +473,7 @@ The Generate function will create the HelmChart object this way: - Merge the same\-pod services. -### func [NewChart]() +### func [NewChart]() ```go func NewChart(name string) *HelmChart @@ -479,7 +482,7 @@ func NewChart(name string) *HelmChart NewChart creates a new empty chart with the given name. -### func \(\*HelmChart\) [SaveTemplates]() +### func \(\*HelmChart\) [SaveTemplates]() ```go func (chart *HelmChart) SaveTemplates(templateDir string) @@ -488,7 +491,7 @@ func (chart *HelmChart) SaveTemplates(templateDir string) SaveTemplates the templates of the chart to the given directory. -## type [Help]() +## type [Help]() Help is the documentation of a label. @@ -523,7 +526,7 @@ func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress NewIngress creates a new Ingress from a compose service. -### func \(\*Ingress\) [Filename]() +### func \(\*Ingress\) [Filename]() ```go func (ingress *Ingress) Filename() string @@ -532,7 +535,7 @@ func (ingress *Ingress) Filename() string -### func \(\*Ingress\) [Yaml]() +### func \(\*Ingress\) [Yaml]() ```go func (ingress *Ingress) Yaml() ([]byte, error) @@ -556,7 +559,7 @@ type IngressValue struct { ``` -## type [Label]() +## type [Label]() Label is a katenary label to find in compose files. @@ -646,7 +649,7 @@ type Role struct { ``` -### func \(\*Role\) [Filename]() +### func \(\*Role\) [Filename]() ```go func (r *Role) Filename() string @@ -655,7 +658,7 @@ func (r *Role) Filename() string -### func \(\*Role\) [Yaml]() +### func \(\*Role\) [Yaml]() ```go func (r *Role) Yaml() ([]byte, error) @@ -676,7 +679,7 @@ type RoleBinding struct { ``` -### func \(\*RoleBinding\) [Filename]() +### func \(\*RoleBinding\) [Filename]() ```go func (r *RoleBinding) Filename() string @@ -685,7 +688,7 @@ func (r *RoleBinding) Filename() string -### func \(\*RoleBinding\) [Yaml]() +### func \(\*RoleBinding\) [Yaml]() ```go func (r *RoleBinding) Yaml() ([]byte, error) @@ -717,7 +720,7 @@ func NewSecret(service types.ServiceConfig, appName string) *Secret NewSecret creates a new Secret from a compose service -### func \(\*Secret\) [AddData]() +### func \(\*Secret\) [AddData]() ```go func (s *Secret) AddData(key, value string) @@ -726,7 +729,7 @@ func (s *Secret) AddData(key, value string) AddData adds a key value pair to the secret. -### func \(\*Secret\) [Filename]() +### func \(\*Secret\) [Filename]() ```go func (s *Secret) Filename() string @@ -735,7 +738,7 @@ func (s *Secret) Filename() string Filename returns the filename of the secret. -### func \(\*Secret\) [SetData]() +### func \(\*Secret\) [SetData]() ```go func (s *Secret) SetData(data map[string]string) @@ -744,7 +747,7 @@ func (s *Secret) SetData(data map[string]string) SetData sets the data of the secret. -### func \(\*Secret\) [Yaml]() +### func \(\*Secret\) [Yaml]() ```go func (s *Secret) Yaml() ([]byte, error) @@ -783,7 +786,7 @@ func (s *Service) AddPort(port types.ServicePortConfig, serviceName ...string) AddPort adds a port to the service. -### func \(\*Service\) [Filename]() +### func \(\*Service\) [Filename]() ```go func (s *Service) Filename() string @@ -792,7 +795,7 @@ func (s *Service) Filename() string Filename returns the filename of the service. -### func \(\*Service\) [Yaml]() +### func \(\*Service\) [Yaml]() ```go func (s *Service) Yaml() ([]byte, error) @@ -813,7 +816,7 @@ type ServiceAccount struct { ``` -### func \(\*ServiceAccount\) [Filename]() +### func \(\*ServiceAccount\) [Filename]() ```go func (r *ServiceAccount) Filename() string @@ -822,7 +825,7 @@ func (r *ServiceAccount) Filename() string -### func \(\*ServiceAccount\) [Yaml]() +### func \(\*ServiceAccount\) [Yaml]() ```go func (r *ServiceAccount) Yaml() ([]byte, error) @@ -851,7 +854,7 @@ type Value struct { ``` -### func [NewValue]() +### func [NewValue]() ```go func NewValue(service types.ServiceConfig, main ...bool) *Value @@ -862,7 +865,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. -### func \(\*Value\) [AddIngress]() +### func \(\*Value\) [AddIngress]() ```go func (v *Value) AddIngress(host, path string) @@ -871,7 +874,7 @@ func (v *Value) AddIngress(host, path string) -### func \(\*Value\) [AddPersistence]() +### func \(\*Value\) [AddPersistence]() ```go func (v *Value) AddPersistence(volumeName string) @@ -901,7 +904,7 @@ func NewVolumeClaim(service types.ServiceConfig, volumeName, appName string) *Vo NewVolumeClaim creates a new VolumeClaim from a compose service. -### func \(\*VolumeClaim\) [Filename]() +### func \(\*VolumeClaim\) [Filename]() ```go func (v *VolumeClaim) Filename() string @@ -910,7 +913,7 @@ func (v *VolumeClaim) Filename() string Filename returns the suggested filename for a VolumeClaim. -### func \(\*VolumeClaim\) [Yaml]() +### func \(\*VolumeClaim\) [Yaml]() ```go func (v *VolumeClaim) Yaml() ([]byte, error) diff --git a/doc/docs/packages/generator/extrafiles.md b/doc/docs/packages/generator/extrafiles.md index 123cd95..cb56223 100644 --- a/doc/docs/packages/generator/extrafiles.md +++ b/doc/docs/packages/generator/extrafiles.md @@ -17,7 +17,7 @@ func NotesFile(services []string) string NotesFile returns the content of the note.txt file. -## func [ReadMeFile]() +## func [ReadMeFile]() ```go func ReadMeFile(charname, description string, values map[string]any) string diff --git a/doc/docs/packages/generator/labelStructs.md b/doc/docs/packages/generator/labelStructs.md index 4b86499..923c4ce 100644 --- a/doc/docs/packages/generator/labelStructs.md +++ b/doc/docs/packages/generator/labelStructs.md @@ -55,11 +55,11 @@ Dependency is a dependency of a chart to other charts. ```go type Dependency struct { + Values map[string]any `yaml:"-"` Name string `yaml:"name"` Version string `yaml:"version"` Repository string `yaml:"repository"` Alias string `yaml:"alias,omitempty"` - Values map[string]any `yaml:"-"` // do not export to Chart.yaml } ``` @@ -91,29 +91,23 @@ func EnvFromFrom(data string) (EnvFrom, error) EnvFromFrom returns a EnvFrom from the given string. -## type [Ingress]() +## type [Ingress]() ```go type Ingress struct { - // Hostname is the hostname to match against the request. It can contain wildcards. - Hostname string `yaml:"hostname"` - // Path is the path to match against the request. It can contain wildcards. - Path string `yaml:"path"` - // Enabled is a flag to enable or disable the ingress. - Enabled bool `yaml:"enabled"` - // Class is the ingress class to use. - Class string `yaml:"class"` - // Port is the port to use. - Port *int32 `yaml:"port,omitempty"` - // Annotations is a list of key-value pairs to add to the ingress. + Port *int32 `yaml:"port,omitempty"` Annotations map[string]string `yaml:"annotations,omitempty"` + Hostname string `yaml:"hostname"` + Path string `yaml:"path"` + Class string `yaml:"class"` + Enabled bool `yaml:"enabled"` } ``` -### func [IngressFrom]() +### func [IngressFrom]() ```go func IngressFrom(data string) (*Ingress, error) diff --git a/doc/docs/packages/parser.md b/doc/docs/packages/parser.md index 834b50a..8f310aa 100644 --- a/doc/docs/packages/parser.md +++ b/doc/docs/packages/parser.md @@ -8,10 +8,10 @@ import "katenary/parser" Parser package is a wrapper around compose\-go to parse compose files. -## func [Parse]() +## func [Parse]() ```go -func Parse(profiles []string, dockerComposeFile ...string) (*types.Project, error) +func Parse(profiles []string, envFiles []string, dockerComposeFile ...string) (*types.Project, error) ``` Parse compose files and return a project. The project is parsed with dotenv, osenv and profiles. diff --git a/doc/docs/packages/utils.md b/doc/docs/packages/utils.md index bb31f13..6fb81fb 100644 --- a/doc/docs/packages/utils.md +++ b/doc/docs/packages/utils.md @@ -8,7 +8,7 @@ import "katenary/utils" Utils package provides some utility functions used in katenary. It defines some constants and functions used in the whole project. -## func [Confirm]() +## func [Confirm]() ```go func Confirm(question string, icon ...Icon) bool @@ -17,7 +17,7 @@ func Confirm(question string, icon ...Icon) bool Confirm asks a question and returns true if the answer is y. -## func [CountStartingSpaces]() +## func [CountStartingSpaces]() ```go func CountStartingSpaces(line string) int @@ -26,7 +26,7 @@ func CountStartingSpaces(line string) int CountStartingSpaces counts the number of spaces at the beginning of a string. -## func [EncodeBasicYaml]() +## func [EncodeBasicYaml]() ```go func EncodeBasicYaml(data any) ([]byte, error) @@ -35,7 +35,7 @@ func EncodeBasicYaml(data any) ([]byte, error) EncodeBasicYaml encodes a basic yaml from an interface. -## func [GetContainerByName]() +## func [GetContainerByName]() ```go func GetContainerByName(name string, containers []corev1.Container) (*corev1.Container, int) @@ -44,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. -## func [GetKind]() +## func [GetKind]() ```go func GetKind(path string) (kind string) @@ -53,7 +53,7 @@ func GetKind(path string) (kind string) GetKind returns the kind of the resource from the file path. -## func [GetServiceNameByPort]() +## func [GetServiceNameByPort]() ```go func GetServiceNameByPort(port int) string @@ -62,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. -## func [GetValuesFromLabel]() +## func [GetValuesFromLabel]() ```go func GetValuesFromLabel(service types.ServiceConfig, LabelValues string) map[string]*EnvConfig @@ -80,7 +80,7 @@ func HashComposefiles(files []string) (string, error) HashComposefiles returns a hash of the compose files. -## func [Int32Ptr]() +## func [Int32Ptr]() ```go func Int32Ptr(i int32) *int32 @@ -89,7 +89,7 @@ func Int32Ptr(i int32) *int32 Int32Ptr returns a pointer to an int32. -## func [MapKeys]() +## func [MapKeys]() ```go func MapKeys(m map[string]interface{}) []string @@ -98,7 +98,7 @@ func MapKeys(m map[string]interface{}) []string -## func [PathToName]() +## func [PathToName]() ```go func PathToName(path string) string @@ -107,7 +107,7 @@ func PathToName(path string) string PathToName converts a path to a kubernetes complient name. -## func [StrPtr]() +## func [StrPtr]() ```go func StrPtr(s string) *string @@ -125,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. -## func [TplValue]() +## func [TplValue]() ```go func TplValue(serviceName, variable string, pipes ...string) string @@ -143,7 +143,7 @@ func Warn(msg ...interface{}) Warn prints a warning message -## func [WordWrap]() +## func [WordWrap]() ```go func WordWrap(text string, lineWidth int) string @@ -152,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. -## func [Wrap]() +## func [Wrap]() ```go func Wrap(src, above, below string) string @@ -161,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. -## func [WrapBytes]() +## func [WrapBytes]() ```go func WrapBytes(src, above, below []byte) []byte @@ -170,7 +170,7 @@ 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. -## type [EnvConfig]() +## type [EnvConfig]() EnvConfig is a struct to hold the description of an environment variable. diff --git a/doc/docs/usage.md b/doc/docs/usage.md index dae8059..a8ccb48 100644 --- a/doc/docs/usage.md +++ b/doc/docs/usage.md @@ -4,9 +4,9 @@ Basically, you can use `katenary` to transpose a docker-compose file (or any com `podman-compose` and `docker-compose`) to a configurable Helm Chart. This resulting helm chart can be installed with `helm` command to your Kubernetes cluster. -!!! Warning "YAML in multiline label" - - Compose only accept text label. So, to put a complete YAML content in the target label, you need to use a pipe char (`|` or `|-`) +!!! Warning "YAML in multiline label" + + Compose only accept text label. So, to put a complete YAML content in the target label, you need to use a pipe char (`|` or `|-`) and to **indent** your content. For example : @@ -23,16 +23,15 @@ Basically, you can use `katenary` to transpose a docker-compose file (or any com - 1234 ``` - Katenary transforms compose services this way: - Takes the service and create a "Deployment" file -- if a port is declared, katenary creates a service (ClusterIP) -- if a port is exposed, katenary creates a service (NodePort) +- if a port is declared, Katenary creates a service (ClusterIP) +- if a port is exposed, Katenary creates a service (NodePort) - environment variables will be stored inside a configMap - image, tags, and ingresses configuration are also stored in `values.yaml` file -- if named volumes are declared, katenary create PersistentVolumeClaims - not enabled in values file -- `depends_on` needs that the pointed service declared a port. If not, you can use labels to inform katenary +- if named volumes are declared, Katenary create PersistentVolumeClaims - not enabled in values file +- `depends_on` needs that the pointed service declared a port. If not, you can use labels to inform Katenary For any other specific configuration, like binding local files as configMap, bind variables, add values with documentation, etc. You'll need to use labels. @@ -44,21 +43,21 @@ For more complete label usage, see [the labels page](labels.md). !!! Info "Overriding file" - It could be sometimes more convinient to separate the + It could be sometimes more convinient to separate the configuration related to Katenary inside a secondary file. Instead of adding labels inside the `compose.yaml` file, - you can create a file named `compose.katenary.yaml` and - declare your labels inside. Katenary will detect it by - default. + you can create a file named `compose.katenary.yaml` and + declare your labels inside. Katenary will detect it by + default. **No need to precise the file in the command line.** -## Make convertion +## Make conversion After having installed `katenary`, the standard usage is to call: -katenary convert + katenary convert It will search standard compose files in the current directory and try to create a helm chart in "chart" directory. @@ -66,10 +65,9 @@ It will search standard compose files in the current directory and try to create Katenary uses the compose-go library which respects the Docker and Docker-Compose specification. Keep in mind that it will find files exactly the same way as `docker-compose` and `podman-compose` do it. +Of course, you can provide others files than the default with (cumulative) `-c` options: -Of course, you can provide others files than the default with (cummulative) `-c` options: - -katenary convert -c file1.yaml -c file2.yaml + katenary convert -c file1.yaml -c file2.yaml ## Some common labels to use @@ -78,15 +76,14 @@ Katenary proposes a lot of labels to configure the helm chart generation, but so !!! Info For more complete label usage, see [the labels page](labels.md). - ### Work with Depends On? -Kubernetes does not propose service or pod starting detection from others pods. But katenary will create init containers +Kubernetes does not provide service or pod starting detection from others pods. But katenary will create init containers to make you able to wait for a service to respond. But you'll probably need to adapt a bit the compose file. See this compose file: -```yaml +```yaml version: "3" services: @@ -105,8 +102,7 @@ In this case, `webapp` needs to know the `database` port because the `depends_on (yet) solution to check the database startup. Katenary wants to create a `initContainer` to hit on the related service. So, instead of exposing the port in the compose definition, let's declare this to katenary with labels: - -```yaml +```yaml version: "3" services: @@ -126,12 +122,12 @@ services: ### Declare ingresses -It's very common to have an Ingress resource on web application to deploy on Kuberenetes. It allows to expose the -service to the outside of the cluster (you need to install an ingress controller). +It's very common to have an Ingress resource on web application to deploy on Kubernetes. It allows exposing the +service to the outside of the cluster (you need to install an ingress controller). Katenary can create this resource for you. You just need to declare the hostname and the port to bind. -```yaml +```yaml services: webapp: image: ... @@ -146,15 +142,14 @@ services: Note that the port to bind is the one used by the container, not the used locally. This is because Katenary create a service to bind the container itself. - ### Map environment to helm values -A lot of framework needs to receive service host or IP in an environment variable to configure the connexion. For +A lot of framework needs to receive service host or IP in an environment variable to configure the connection. For example, to connect a PHP application to a database. -With a compose file, there is no problem as Docker/Podman allows to resolve the name by container name: +With a compose file, there is no problem as Docker/Podman allows resolving the name by container name: -```yaml +```yaml services: webapp: image: php:7-apache @@ -168,7 +163,6 @@ services: Katenary prefixes the services with `{{ .Release.Name }}` (to make it possible to install the application several times in a namespace), so you need to "remap" the environment variable to the right one. - ```yaml services: webapp: @@ -180,7 +174,7 @@ services: DB_HOST: "{{ .Release.Name }}-database" database: - image: mariadb + image: mariadb ``` This label can be used to map others environment for any others reason. E.g. to change an informational environment @@ -189,7 +183,7 @@ variable. ```yaml services: webapp: - #... + #... environment: RUNNING: docker labels: @@ -198,4 +192,4 @@ services: ``` In the above example, `RUNNING` will be set to `kubernetes` when you'll deploy the application with helm, and it's -`docker` for "podman" and "docker" executions. +`docker` for "Podman" and "Docker" executions. diff --git a/doc/mkdocs.yml b/doc/mkdocs.yml index f165f88..342fe8d 100644 --- a/doc/mkdocs.yml +++ b/doc/mkdocs.yml @@ -28,7 +28,11 @@ markdown_extensions: - pymdownx.highlight: anchor_linenums: true use_pygments: false - - pymdownx.superfences + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format extra_css: - statics/main.css extra_javascript: diff --git a/doc/requirements.txt b/doc/requirements.txt index b34c282..18a915f 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,7 +1,7 @@ -mkdocs>=1.5.3 -Jinja2>=3.1.3 -MarkupSafe>=2.1.5 -pymdown-extensions>=10.7.1 -mkdocs-material>=9.5.17 -mkdocs-material-extensions>=1.3.1 -mkdocs-plugin-inline-svg-mod>=0.0.1 +mkdocs==1.* +Jinja2==3.* +MarkupSafe==3.* +pymdown-extensions==10.* +mkdocs-material==9.* +mkdocs-material-extensions==1.* +mkdocs-plugin-inline-svg-mod