[![Build](https://github.com/eclipse-csi/otterdog/actions/workflows/build.yml/badge.svg)](https://github.com/eclipse-csi/otterdog/actions/workflows/build.yml)
[![Documentation status](https://readthedocs.org/projects/otterdog/badge/?version=latest)](https://otterdog.readthedocs.io/en/latest/?badge=latest)
[![PyPI](https://img.shields.io/pypi/v/otterdog?color=blue)](https://pypi.org/project/otterdog)
[![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/otterdog)](https://pypi.org/project/otterdog)
[![EPLv2 License](https://img.shields.io/github/license/eclipse-csi/otterdog)](https://github.com/eclipse-csi/otterdog/blob/main/LICENSE)
# Otterdog
## Introduction
Otterdog is a tool to manage GitHub organizations at scale using a configuration as code approach.
It is actively developed by the Eclipse Foundation and used to manage its numerous projects hosted on GitHub.
## Quickstart
To install and use the cli part of otterdog you have to install the following:
* otterdog (mandatory): install using `pipx install otterdog`
* go (mandatory for installing jsonnet-bundler): install using `apt install golang`
* jsonnet-bundler (mandatory): install using `go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.5.1`
* bitwarden cli tool (optional): install using `snap install bw`
* pass cli tool (optional): install using `apt install pass`
[Otterdog Presentation @ Open Source Summit 2023](https://docs.google.com/presentation/d/1lLqbhDQf9s5U2A2TkcoFYA39qtODcSot2308vnKbkbA/edit?usp=sharing)
[Default Configuration used @ Eclipse Foundation](https://github.com/EclipseFdn/otterdog-defaults/)
## Documentation
The documentation is available at [otterdog.readthedocs.io](https://otterdog.readthedocs.io).
## Build instructions
### System requirements:
* python3.10 (mandatory): install using `apt install python3`
* poetry (mandatory): install using `curl -sSL https://install.python-poetry.org | python3 -` or `pipx install poetry`
* go (mandatory for installing jsonnet-bundler): install using `apt install golang`
* jsonnet-bundler (mandatory): install using `go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.5.1`
* bitwarden cli tool (optional): install using `snap install bw`
* pass cli tool (optional): install using `apt install pass`
### Building Steps
* Create a virtual python environment and install necessary python dependencies using poetry:
```console
$ make init
```
* Testing build
```console
$ ./otterdog.sh -h
```
## Setup
The general configuration for supported organizations and their corresponding credentials in order
to access their GitHub settings has to be placed in a json file (default: __otterdog.json__, can be changed
with the __-c__ flag), e.g.:
```json
{
"organizations": [
{
"name": "<org name>",
"github_id": "<github org id>",
"credentials": {
"provider": "<bitwarden | pass>",
"item_id" : "39adacc9-2b51-41a9-a27e-ac7c00eea6a5"
}
}
]
}
```
## Credentials
Otterdog needs certain credentials to access information from an organization and its repositories on GitHub:
* username / password / 2FA seed
* API token
The login / username / 2FA seed are required to access the web interface of GitHub in order to retrieve certain
settings that are not accessible via its rest / graphql API.
The GitHub api token needs to have the following scopes enabled:
* repo
* workflow
* admin:org
* admin:org_hook
* delete_repo
The credentials can be stored in different providers (bitwarden, pass).
### Bitwarden
When using **bitwarden** to store the credentials, you need to enter a valid __item id__ as additional credential data:
```json
{
"organizations": [
{
"name": "<org name>",
"github_id": "<github org id>",
"credentials": {
"provider": "bitwarden",
"item_id" : "<bitwarden item id>"
}
}
]
}
```
The item stored in bitwarden needs to contain the following information (a sample json output of such an item):
```json
{
"object": "item",
"id": "<bitwarden item id>",
"name": "<item name>",
"fields": [
{
"name": "api_token_admin",
"value": "<github API token>"
}
],
"login": {
"username": "<github username>",
"password": "<github password>",
"totp": "<github TOTP text code>"
}
}
```
Mandatory items:
* Field with name "api_token_admin" and as value the GitHub token to access the organization
* __login.username__ of a user that can access the organization with enabled 2FA
* __login.password__ the password of that user
* __login.totp__ the TOTP text code
### Pass
When using **pass** to store the credentials, you need to enter fully qualified pass names to access the various
required credential data:
```json
{
"organizations": [
{
"name": "<org name>",
"github_id": "<github org id>",
"credentials": {
"provider": "pass",
"api_token": "<path/to/api_token>",
"username": "<path/to/username>",
"password": "<path/to/password>",
"2fa_seed": "<path/to/2fa_seed>"
}
}
]
}
```
In case your password storage dir is not located at the default location, you can
configurate that in the `defaults`:
```json
{
"defaults": {
"pass": {
"password_store_dir": "path/to/storage/dir"
}
}
}
```
## Usage
Run the **import** operation to retrieve the current live configuration for an organization:
```console
$ otterdog.sh import <organization>
```
The created configuration file for the organization can be found at `<data-directory>/orgs/<organization>.jsonnet`
Run the **plan** operation to highlight differences between the live configuration and the written configuration:
```console
$ otterdog.sh plan <organization>
```
Run **apply** operation to reflect the written configuration on github itself:
```console
$ otterdog.sh apply <organization>
```
Raw data
{
"_id": null,
"home_page": "https://github.com/eclipse-csi/otterdog",
"name": "otterdog",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "infrastructure-as-code, supply-chain-security, github, gitops",
"author": "Thomas Neidhart",
"author_email": "thomas.neidhart@eclipse-foundation.org",
"download_url": "https://files.pythonhosted.org/packages/52/d5/cbcd06dead7f4a2484d696593c289aa50f9446e8ad0a37facf150a1f5b95/otterdog-0.6.0.tar.gz",
"platform": null,
"description": "[![Build](https://github.com/eclipse-csi/otterdog/actions/workflows/build.yml/badge.svg)](https://github.com/eclipse-csi/otterdog/actions/workflows/build.yml)\n[![Documentation status](https://readthedocs.org/projects/otterdog/badge/?version=latest)](https://otterdog.readthedocs.io/en/latest/?badge=latest)\n[![PyPI](https://img.shields.io/pypi/v/otterdog?color=blue)](https://pypi.org/project/otterdog)\n[![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/otterdog)](https://pypi.org/project/otterdog)\n[![EPLv2 License](https://img.shields.io/github/license/eclipse-csi/otterdog)](https://github.com/eclipse-csi/otterdog/blob/main/LICENSE)\n\n# Otterdog\n\n## Introduction\n\nOtterdog is a tool to manage GitHub organizations at scale using a configuration as code approach.\nIt is actively developed by the Eclipse Foundation and used to manage its numerous projects hosted on GitHub.\n\n## Quickstart\n\nTo install and use the cli part of otterdog you have to install the following:\n\n* otterdog (mandatory): install using `pipx install otterdog`\n* go (mandatory for installing jsonnet-bundler): install using `apt install golang`\n* jsonnet-bundler (mandatory): install using `go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.5.1`\n* bitwarden cli tool (optional): install using `snap install bw`\n* pass cli tool (optional): install using `apt install pass`\n\n[Otterdog Presentation @ Open Source Summit 2023](https://docs.google.com/presentation/d/1lLqbhDQf9s5U2A2TkcoFYA39qtODcSot2308vnKbkbA/edit?usp=sharing)\n\n[Default Configuration used @ Eclipse Foundation](https://github.com/EclipseFdn/otterdog-defaults/)\n\n## Documentation\n\nThe documentation is available at [otterdog.readthedocs.io](https://otterdog.readthedocs.io).\n\n## Build instructions\n\n### System requirements:\n\n* python3.10 (mandatory): install using `apt install python3`\n* poetry (mandatory): install using `curl -sSL https://install.python-poetry.org | python3 -` or `pipx install poetry`\n* go (mandatory for installing jsonnet-bundler): install using `apt install golang`\n* jsonnet-bundler (mandatory): install using `go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.5.1`\n* bitwarden cli tool (optional): install using `snap install bw`\n* pass cli tool (optional): install using `apt install pass`\n\n### Building Steps\n\n* Create a virtual python environment and install necessary python dependencies using poetry:\n\n```console\n$ make init\n```\n\n* Testing build\n\n```console\n$ ./otterdog.sh -h\n```\n\n## Setup\n\nThe general configuration for supported organizations and their corresponding credentials in order\nto access their GitHub settings has to be placed in a json file (default: __otterdog.json__, can be changed\nwith the __-c__ flag), e.g.:\n\n```json\n{\n \"organizations\": [\n {\n \"name\": \"<org name>\",\n \"github_id\": \"<github org id>\",\n \"credentials\": {\n \"provider\": \"<bitwarden | pass>\",\n \"item_id\" : \"39adacc9-2b51-41a9-a27e-ac7c00eea6a5\"\n }\n }\n ]\n}\n```\n\n## Credentials\n\nOtterdog needs certain credentials to access information from an organization and its repositories on GitHub:\n\n* username / password / 2FA seed\n* API token\n\nThe login / username / 2FA seed are required to access the web interface of GitHub in order to retrieve certain\nsettings that are not accessible via its rest / graphql API.\n\nThe GitHub api token needs to have the following scopes enabled:\n\n* repo\n* workflow\n* admin:org\n* admin:org_hook\n* delete_repo\n\nThe credentials can be stored in different providers (bitwarden, pass).\n\n### Bitwarden\n\nWhen using **bitwarden** to store the credentials, you need to enter a valid __item id__ as additional credential data:\n\n```json\n{\n \"organizations\": [\n {\n \"name\": \"<org name>\",\n \"github_id\": \"<github org id>\",\n \"credentials\": {\n \"provider\": \"bitwarden\",\n \"item_id\" : \"<bitwarden item id>\"\n }\n }\n ]\n}\n```\n\nThe item stored in bitwarden needs to contain the following information (a sample json output of such an item):\n\n```json\n{\n \"object\": \"item\",\n \"id\": \"<bitwarden item id>\",\n \"name\": \"<item name>\",\n \"fields\": [\n {\n \"name\": \"api_token_admin\",\n \"value\": \"<github API token>\"\n }\n ],\n \"login\": {\n \"username\": \"<github username>\",\n \"password\": \"<github password>\",\n \"totp\": \"<github TOTP text code>\"\n }\n}\n```\n\nMandatory items:\n\n* Field with name \"api_token_admin\" and as value the GitHub token to access the organization\n* __login.username__ of a user that can access the organization with enabled 2FA\n* __login.password__ the password of that user\n* __login.totp__ the TOTP text code\n\n### Pass\n\nWhen using **pass** to store the credentials, you need to enter fully qualified pass names to access the various\nrequired credential data:\n\n```json\n{\n \"organizations\": [\n {\n \"name\": \"<org name>\",\n \"github_id\": \"<github org id>\",\n \"credentials\": {\n \"provider\": \"pass\",\n \"api_token\": \"<path/to/api_token>\",\n \"username\": \"<path/to/username>\",\n \"password\": \"<path/to/password>\",\n \"2fa_seed\": \"<path/to/2fa_seed>\"\n }\n }\n ]\n}\n```\n\nIn case your password storage dir is not located at the default location, you can\nconfigurate that in the `defaults`:\n\n```json\n{\n \"defaults\": {\n \"pass\": {\n \"password_store_dir\": \"path/to/storage/dir\"\n }\n }\n}\n```\n\n## Usage\n\nRun the **import** operation to retrieve the current live configuration for an organization:\n\n```console\n$ otterdog.sh import <organization>\n```\n\nThe created configuration file for the organization can be found at `<data-directory>/orgs/<organization>.jsonnet`\n\nRun the **plan** operation to highlight differences between the live configuration and the written configuration:\n\n```console\n$ otterdog.sh plan <organization>\n```\n\nRun **apply** operation to reflect the written configuration on github itself:\n\n```console\n$ otterdog.sh apply <organization>\n```\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Tool to manage GitHub organizations and their repositories.",
"version": "0.6.0",
"project_urls": {
"Documentation": "https://otterdog.readthedocs.io",
"Homepage": "https://github.com/eclipse-csi/otterdog",
"Repository": "https://github.com/eclipse-csi/otterdog"
},
"split_keywords": [
"infrastructure-as-code",
" supply-chain-security",
" github",
" gitops"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6467798df9104addef3f652cdfe69cfbcb2ded74961ed0646c81041522681bbf",
"md5": "0fcb4cbf54d070b1df98077cda2566a5",
"sha256": "232fdea45b1650d0475959871fb68ac47c63a4ddf9b05f3d1d7748d0b2752b23"
},
"downloads": -1,
"filename": "otterdog-0.6.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0fcb4cbf54d070b1df98077cda2566a5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 268329,
"upload_time": "2024-04-24T20:37:21",
"upload_time_iso_8601": "2024-04-24T20:37:21.684357Z",
"url": "https://files.pythonhosted.org/packages/64/67/798df9104addef3f652cdfe69cfbcb2ded74961ed0646c81041522681bbf/otterdog-0.6.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "52d5cbcd06dead7f4a2484d696593c289aa50f9446e8ad0a37facf150a1f5b95",
"md5": "e94b49d0a08ae15e597bc6f02927d9ff",
"sha256": "390df06c2000cc231352ac141fbe040b431b096ad2c579e1c38defc8001aa6d9"
},
"downloads": -1,
"filename": "otterdog-0.6.0.tar.gz",
"has_sig": false,
"md5_digest": "e94b49d0a08ae15e597bc6f02927d9ff",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 171234,
"upload_time": "2024-04-24T20:37:23",
"upload_time_iso_8601": "2024-04-24T20:37:23.131463Z",
"url": "https://files.pythonhosted.org/packages/52/d5/cbcd06dead7f4a2484d696593c289aa50f9446e8ad0a37facf150a1f5b95/otterdog-0.6.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-24 20:37:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "eclipse-csi",
"github_project": "otterdog",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "otterdog"
}