{"id":20270441,"url":"https://github.com/lukasjarosch/skipper","last_synced_at":"2025-04-11T04:02:50.550Z","repository":{"id":45971852,"uuid":"503429660","full_name":"lukasjarosch/skipper","owner":"lukasjarosch","description":"Inventory based templated configuration library inspired by the kapitan project","archived":false,"fork":false,"pushed_at":"2024-08-31T13:12:10.000Z","size":9140,"stargazers_count":11,"open_issues_count":19,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T04:02:39.682Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://lukasjarosch.github.io/skipper/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukasjarosch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-14T16:04:31.000Z","updated_at":"2024-08-31T13:11:50.000Z","dependencies_parsed_at":"2023-10-02T14:35:15.775Z","dependency_job_id":"865372d7-5156-4f57-bc16-c159a3e7b428","html_url":"https://github.com/lukasjarosch/skipper","commit_stats":{"total_commits":260,"total_committers":5,"mean_commits":52.0,"dds":0.08846153846153848,"last_synced_commit":"f76529cd8ec9f1c92a65ed75fa318da11b87ff8a"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasjarosch%2Fskipper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasjarosch%2Fskipper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasjarosch%2Fskipper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasjarosch%2Fskipper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukasjarosch","download_url":"https://codeload.github.com/lukasjarosch/skipper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248339285,"owners_count":21087215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T12:30:25.372Z","updated_at":"2025-04-11T04:02:50.530Z","avatar_url":"https://github.com/lukasjarosch.png","language":"Go","readme":"\u003cdiv align=\"center\"\u003e\n  \u003c!-- BADGES --\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://pkg.go.dev/github.com/lukasjarosch/skipper\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/lukasjarosch/skipper.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/lukasjarosch/skipper\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/lukasjarosch/skipper\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cbr/\u003e\n\n  \u003c!-- LOGO --\u003e\n  \u003ca href=\"https://github.com/lukasjarosch/skipper\"\u003e\n    \u003cimg src=\"./docs/docs/assets/logo.png\" alt=\"Logo\"\u003e\n  \u003c/a\u003e\n\n  \u003c!-- SKIPPER TLDR --\u003e\n  \u003ch1 align=\"center\"\u003eSkipper\u003c/h3\u003e\n  \u003cp\u003eInventory based templated configuration library inspired by the kapitan project\u003c/p\u003e\n  \u003c/br\u003e\n\u003c/div\u003e\n\n\u003e Although Skipper is already used in production, the code on `main` should be considered unstable.\n\u003e Skipper is currently undergoing a heavy rework as the current implementation only served as POC.\n\u003e\n\u003e The development for the \"new\" skipper takes place on [develop](https://github.com/lukasjarosch/skipper/tree/develop)  \n\u003e **Note**: Some time in the future, Skipper on `main` will be replaced by this new version.\n\n\n# What is skipper?\n\nSkipper is a library which helps you to manage complex configuration and enables\nyou to use your large data-set inside templates.\nHaving one - central - set of agnostic configuration files will make managing\nyour clusters, infrastrucutre stages, etc. much easier. You can rely on \nthe inventory of data, modify it to target-specific needs, use the data in \ntemplates, and be sure that whatever you're generating is always in sync with your inventoyu.\nWhether you generate only a single file, or manage multi-stage multi-region infrastructure deployments doesn't matter.\nSkipper is a library which enables you to easily build your own - company or project specific - configuration management.\n\nSkipper is heavily inspired by the [Kapitan](https://kapitan.dev/) project. The difference\nis that skipper is a library which does not make any assumptions of your needs (aka. not opinionated). \nThis allows you for example to have way more control over how you want to process your inventory.\n\nSkipper is not meant to be a *one-size-fits-all* solution. The goal of Skipper is to enable\nyou to create the own - custom built - template and inventory engine, without having to do the heavy lifing.\n\n# Core Concepts\nSkipper has a few concepts, but not all of them are necessary to understand how Skipper works.\nMore in-depth informatation about Skippers concepts can be found [in our docs](https://lukasjarosch.github.io/skipper/concepts/).\n\n## Inventory\nThe inventory is the heart of every Skipper-enabled project. It is your data storage, the single source of truth.\nIt is a user-defined collection of YAML files (classes and targets).\n\n### Classes\nClasses are YAML files in which you can define information about every part of your project.\nThese classes become your building blocks and therefore the heart of your project.\n\n### Targets\nA target represents an instance of your project. Targets are defined with YAML files as well.\nThey use skipper-keywords to *includ* classes, relevant for that instance.\nInside a target config you are also able to overwrite any kind of information (change the location in which your resources are deployed for example).\n\n## Templates\nTemplates (Skipper is using [go templates](https://pkg.go.dev/text/template)) have access to your target and classes.\nYou can build generic templates and aggregate your data into it, without having to re-write files for different stages.\nHaving a documentation, specific to an instance (stage) of your project, can be quite useful and is easy to implement with Skipper.\n\n\n# Idea collection\n\n- [ ] Allow static file copying instead of rendering it as template (e.g. copy a zip file from templates to compiled)\n- [ ] Add timing stats (benchmark, 'compiled in xxx') to compare with kapitan\n- [ ] Class inheritance. Currently only targets can `use` classes but it would be nice if classes could also use different classes\n  - This would introduce a higher level of inheritance which users can set-up for their inventory.\n\n\n# Documentation\n\u003e This documentation is \n\n## Classes\nA class is a yaml file which defines arbitrary information about your project.\n\nThere is only two rules for classes:\n  - The filename of the class must be the root key of the yaml struct\n  - The filename **cannot** be `target.yaml`, resulting in a root key of `target`.\n    - Although this will not return an error, you simply will not be able to use the class as the actual target will overwrite it completely.\n\nThis means that if your class is called `pizza.yaml`, the class must look like this:\n\n```yaml\npizza:\n  # any value\n```\n\n## Targets\nA target usually is a speparate environment in your infrastructure or a single namespace in your Kubernetes cluster.\nTargets `use` classes to pull in the required innventory data in order to produce the correct tree which is required in order to render the templates.\n\nOn any given run, Skipper only allows to set **one** target. This is to ensure that the generated map of data is consistent.\n\nThe way a target makes uses of the inventory is by using the `use` clause which tells Skipper which classes to include in the assembly of the target inventory.\n\n\n### Naming\n\nThe name of the target is given by its filename. So if your target is called `development.yaml`, the target name will be `development`. \n\nThe structure of a target file is pretty simple, there are only two rules:\n\n- The top-level key of the target **must** be `target`\n- There must be a key `target.use` which *has to be* an array and tells Skipper which classes this particular target requires.\n\nBelow you'll find the most basic example of a target.\nThe target does not define values itself, it just uses values from a class `project.common`.\nThe class must be located in the `classPath` passed into `Inventory.Load()`, where path separators are replaced by a dot.\n\nSo if your classPath is `./inventory/classes`, referencing `foo.bar` will make Skipper attempt to load `./inventory/classes/foo/bar.yaml`.\n\n```yaml\ntarget:\n  use:\n    project.common\n```\n\n## Variables\nVariables in Skipper always have the same format: `${variable_name}` \n\nSkipper has *three* different types of variables.\n\n1. [Dynamic Variables](#dynamic-variables)\n2. [Predefined Variables](#predefined-variables)\n3. [User-defined Variables](#user-defined-variables)\n\n### Dynamic Variables\n\nDynamic variables are variables which use a *selector path* to point to existing values which are defined in your inventory.\n\nConsider the following class **images.yaml**\n```yaml\nimages:\n  base_image: some/image\n\n  production:\n    image: ${images:base_image}:v1.0.0\n  staging:\n    image: ${images:base_image}:v2.0.0-rc1\n  development:\n    image: ${images:base_image}:latest\n```\n\nOnce the class is processed, the class looks like this:\n```yaml\nimages:\n  base_image: some/image\n\n  production:\n    image: some/image:v1.0.0\n  staging:\n    image: some/image:v2.0.0-rc1\n  development:\n    image: some/image:latest\n```\n\nThe name of the variable uses common *dot-notation*, except that we're using ':' instead of dots.\nWe chose to use colons because they are easier to read inside the curly braces.\n\n### Predefined Variables\n\nPredefined variables could also be considered constants - at least from a user perspective.\nThe predefined variables can easily be defined as `map[string]interface{}`, where the keys are\nthe variable names.\n\nYou have to pass your predefined variables to the `Inventory.Data()` call, then they are evaluated.\nIf you do not pass these variables, the function will return an error as it will attempt to treat them as dynamic variables.\n\nConsider the following example (your main.go)\n```go\n// ...\n\npredefinedVariables := map[string]interface{}{\n    \"target_name\": \"develop\",\n    \"output_path\": \"foo/bar/baz\",\n    \"company_name\": \"AcmeCorp\"\n}\n\ndata, err := inventory.Data(target, predefinedVariables)\nif err != nil {\n    panic(err)\n}\n\n// ...\n```\n\nYou will now be able to use the variables `${target_name}`, `${output_path}` and `${company_name}`\nthroughout your yaml files and have Skipper replace them dynamically once you call `Data()` on the inventory.\n\n### User-defined Variables\n\n**TODO**\n\n### Acknowledgments\n- Logo: \u003ca href=\"https://www.flaticon.com/de/kostenlose-icons/kapitan\" title=\"kapitän Icons\"\u003eSkipper Logo designed by freepik - Flaticon\u003c/a\u003e\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasjarosch%2Fskipper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukasjarosch%2Fskipper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasjarosch%2Fskipper/lists"}