crc-bonfire


Namecrc-bonfire JSON
Version 1.5.1 PyPI version JSON
download
home_pagehttps://www.github.com/RedHatInsights/bonfire
SummaryA CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications
upload_time2021-06-18 17:31:04
maintainer
docs_urlNone
authorBrandon Squizzato
requires_python>=3.6
licenseMIT
keywords
VCS
bugtrack_url
requirements gql aiohttp async-timeout attrs certifi chardet click graphql-core idna multidict parsedatetime promise PyYAML requests Rx setuptools-scm sh six urllib3 wait-for websockets yarl tabulate python-dotenv ocviapy app-common-python cached-property
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # bonfire

A CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications

`bonfire` interacts with a local configuration file or a running instance of [qontract-server](https://github.com/app-sre/qontract-server) (the component that powers the [AppSRE team](https://github.com/app-sre/)'s internal `app-interface` graphql API) to obtain applications' OpenShift templates, process them, and deploy them.

It also interacts with OpenShift to manage the reservation of ephemeral namespaces for testing.

It is meant to be partnered with the [Clowder](https://github.com/RedHatInsights/clowder) operator to spin up an ephemeral environment for testing on either a remote OpenShift cluster or a local k8s cluster.

## Installation

We'd recommend setting up a virtual environment for bonfire:

```bash
VENV_DIR=~/bonfire_venv
mkdir -p $VENV_DIR
python3 -m venv $VENV_DIR
. $VENV_DIR/bin/activate
pip install crc-bonfire
bonfire --help
```

## Overview

The `bonfire process` command can be used to print processed app configs to stdout.

The `bonfire namespace reserve` command can be used to acquire a namespace on a cluster
if that cluster has been set up with bonfire's namespace reconciler.

The `bonfire deploy` command can be used as a helpful "1-liner" command to reserve a namespace,
process application configs, apply them into a desired namespace, and wait for them to come up successfully.

The `bonfire process-env` command can be used to print a processed ClowdEnvironment config to stdout.

The `bonfire deploy-env` command can be used as a helpful "1-liner" command to apply a ClowdEnvironment
configuration into a cluster and wait for environment resources to come up successfully.

### Using a local config

To get up and running without needing to contact app-interface's `qontract-server`, you can utilize
a local config file. `bonfire` ships with a [default config](bonfire/resources/default_config.yaml) that
should be enough to get started for most internal Red Hat employees. An internal repository holds
application configurations for the cloud.redhat.com platform that are valid for use in ephemeral environments.

By default, the configuration file will be stored in `~/.config/bonfire/config.yaml`. You can reset the config to default at any time using `bonfire config write-default`.

### App config overrides

You can edit your local config file to override any app configurations to allow for "local tinkering". If you define an app under the
`apps` key of the config, it will take precedence over any app's configuration that was fetched/downloaded.

#### Deploy app template using changes you've made locally

As an example, if you wanted to test out some changes you're making to an app but you have not yet pushed these changes to a git repo, the local config could look similar to:

```
apps:
- name: my_app
  components:
    - name: service
      host: local
      repo: ~/dev/projects/my-app
      path: /clowdapp.yaml
```

- Where **host** set `local` indicates to look for the repo in a local directory
- Where **repo** indicates the path to your git repo folder
- Where **path** specifies the relative path to your ClowdApp template file in your git repo

By default, bonfire will run `git rev-parse` to determine what IMAGE_TAG to set when the template is deployed. However, you can use `--set-image-tag` or `--set-parameter` to override this.

#### Deploy app template using changes you've made in a remote git branch

As an example, if you wanted to deploy changes to your app that you were working on which have been pushed to a PR/branch, the local config could look similar to:

```
apps:
- name: my_app
  components:
    - name: service
      host: github
      repo: MyOrg/MyRepo
      path: /clowdapp.yaml
```

- Where **host** set to `github` or `gitlab` indicates where the repo is hosted
- Where **repo** indicates the `OrganizationName/RepoName`
- Where **path** specifies the relative path to your ClowdApp template file in your git repo

By default, bonfire will use the commit hash of `master` to determine what IMAGE_TAG to deploy.

NOTE: For this particular use case, if your changes are already present in a git repo, and your app already has appropriate ephemeral deployment configs set up, then using the `--set-template-ref` and `--set-image-tag` flags in bonfire may be simpler than editing your app config.
### Loading an app's ephemeral config from app-interface

You can also run `bonfire process`/`bonfire deploy` using `--source appsre` which will pull configurations from app-interface.

You'll first need to set proper env variables to interface with your instance of `qontract-server`:

```bash
export QONTRACT_BASE_URL="https://myserver/graphql"
export QONTRACT_USERNAME=myUsername
export QONTRACT_PASSWORD=myPassword
```

If these env vars are not specified, bonfire will attempt to access a local `qontract-server` (see "Setting up a local qontract-server" below)

`bonfire` will query the qontract GraphQL API and read the desired application's deploy configuration.

You can edit the local configuration file (discussed above) if you wish to override any app configurations to allow for "local tinkering". If you define an app under the `apps` key of the config, it will take precedence over that app's configuration that was fetched from app-interface.


### Loading application configs

`bonfire process` relies on a few key pieces of info to process app configs:
1. The application name. This is typically the name of the listed in `app.yaml` in `app-interface`
1. *(applies to `--source=appsre` only)* a 'target env' -- the name of the `app-interface` environment that you want to pull application configs for. An app's config will only be processed if it has a deploy target set up that points to a namespace mapped to this environment (default: "ephemeral")
1. *(optional)* a 'ref env' -- the name of the `app-interface` environment that we want to use in order to set the applications `IMAGE_TAG` values and deploy template ref. This can be useful if you want to deploy applications using ephemeral template parameters, but you want to override the `IMAGE_TAG`/`ref` defined on all apps to use the values found in `prod` or `stage`.
1. Any template refs you wish to override -- in other words, if you want to download a different git hash of an application component's template.
1. Any image tags you wish to override -- in other words, if you want to use a different image tag for just a specific docker image.
1. Any parameters you wish to override -- if you want to set a different template parameter for a specific app.

By default, `bonfire` will dynamically load dependencies that all components of `app` relies on. This requires the `app` to be using the [Clowder](https://github.com/RedHatInsights/clowder) operator and to have the `dependencies` section of the ClowdApp set up.


### Example usage in a smoke test

The goal of a smoke test running against an `app` is to:
* deploy the PR's code for `app`
* deploy the production versions of `app`'s dependencies alongside it

Below we'll show how `bonfire deploy` will enable this:

Let's say that we are running a PR check against the `insights-puptoo` service. This service:
* is a member of the `ingress` application.
* has a kubernetes deploy manifest that resides in the same repo as the code
* has its CI/CD `pr_check.sh` set up such that if a PR is opened, a docker image is built and pushed to `quay.io/myorg/insights-puptoo` with the tag `pr-<git hash>`. The PR opened against the app has commit hash `abc1234`

If we intend to reserve a namespace and deploy the `ingress` application group into it, using the new template/image of the `insights-puptoo` PR, but using the production template/image for all other components, we could run:

```bash
APP_NAME=ingress
COMPONENT_NAME=insights-puptoo
GIT_COMMIT=pr-abc1234
IMAGE=quay.io/myorg/insights-puptoo
IMAGE_TAG=abc1234

NAMESPACE=$(bonfire deploy $APP_NAME \
    --ref-env insights-prod \
    --set-template-ref $COMPONENT_NAME=$GIT_COMMIT \
    --set-image-tag $IMAGE=$IMAGE_TAG)

echo "My environment is deployed into $NAMESPACE"
```

This is functionally equivalent to:
```bash
NAMESPACE=$(bonfire namespace reserve)

bonfire process $APP_NAME
    --ref-env insights-prod
    --set-template-ref $COMPONENT_NAME=$GIT_COMMIT
    --set-image-tag $IMAGE=$IMAGE_TAG
    --clowd-env env-$NAMESPACE

bonfire namespace wait-on-resources $NAMESPACE

echo "My environment is deployed into $NAMESPACE"
```

## Namespace management

`bonfire` is also used to reserve, release, and reconcile ephemeral namespaces running on our test OpenShift clusters.

The list of ephemeral namespaces is stored in `app-interface`.

The service account that bonfire logs in to the cluster with has a custom role bound to it which allows it to edit namespace labels:

```
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: namespace-editor
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - patch
  - update
  - watch
```

This role is bound to the service account in each ephemeral namespace.

Bonfire uses labels to keep track of which namespaces are reserved AND ready. A "ready" namespace is one which has been "wiped clean" and then had a fresh set of base test configurations copied into it.

When a tester is logged in using the proper account, namespace commands can be used such as:

`bonfire namespace reserve` -- find an available namespace and reserve it. By default the TTL is 1 hr.

`bonfire namespace release <namespace>` -- release a namespace reservation

Use `bonfire namespace -h` to see a list of all available namespace commands.

### Namespace reconciler

A separate cron job runs the `bonfire namespace reconcile` command every 2 minutes. This command does the following:

* Checks for any namespaces that are released, but not ready, and "prepares" them by wiping them and copying base test resources into them. After being prepared, the namespace is marked "ready". A namespace is prepared by:
    1. creating an ephemeral `ClowdEnvironment` resource for it, and
    2. copying any secrets defined in the `ephemeral-base` namespace into it
* Checks for any namespaces that are reserved, but do not have an "expires" time set on them yet. This would be a newly-reserved namespace. The reconciler is responsible for applying the "expires time"
* Checks the "expires time" on all reserved namespaces. If any have expired, bonfire will release them and re-prepare them.

### Interactions with Clowder

* For every namespace that `bonfire` prepares, it creates a Clowder `ClowdEnvironment` resource following [this template](https://github.com/RedHatInsights/bonfire/blob/master/bonfire/resources/ephemeral-clowdenvironment.yaml). The name of the environment matches [this format](https://github.com/RedHatInsights/bonfire/blob/master/bonfire/config.py#L16). So, if bonfire prepared a namespace called `ephemeral-01`, then the name of the `ClowdEnvironment` would be `env-ephemeral-01`.

* When `bonfire deploy` is executed for a namespace, it will attempt to find the ClowdEnvironment associated with that namespace and set the `ENV_NAME` parameter accordingly for all templates it processes. All templates that define a `ClowdApp` resource should set the `environment` mapping in their spec using an `${ENV_NAME}` parameter.

* When `bonfire namespace wait-on-resources` is executed, it follows this logic:
1. Wait for all resources owned by a 'ClowdEnvironment' to appear in the namespace
2. Wait for all the deployments in the namespace to reach 'active' state.
3. Wait for resources owned by a 'ClowdApp' to appear in the namespace
4. Wait for all the deployments in the namespace to reach 'active' state (deployments we already waited on in step 2 are not waited on again)


## Miscellaneous
### Running a local qontract-server

For testing/debug purposes, instead of committing changes directly to app-interface, you can run
your own local copy of the app-interface API server.

1. Clone https://github.com/app-sre/qontract-server
2. Clone the internal `app-interface` repo

In `qontract-server`, run:
```
npm install yarn
yarn install
yarn build
make bundle APP_INTERFACE_PATH=/path/to/app-interface
LOAD_METHOD=fs DATAFILES_FILE=bundle/bundle.json yarn run server
```



            

Raw data

            {
    "_id": null,
    "home_page": "https://www.github.com/RedHatInsights/bonfire",
    "name": "crc-bonfire",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "",
    "author": "Brandon Squizzato",
    "author_email": "bsquizza@redhat.com",
    "download_url": "https://files.pythonhosted.org/packages/aa/85/23a002a9d8a8818273a9f7fdf04b1ff5a0d284eaa01c0b23a0755444be56/crc-bonfire-1.5.1.tar.gz",
    "platform": "",
    "description": "# bonfire\n\nA CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications\n\n`bonfire` interacts with a local configuration file or a running instance of [qontract-server](https://github.com/app-sre/qontract-server) (the component that powers the [AppSRE team](https://github.com/app-sre/)'s internal `app-interface` graphql API) to obtain applications' OpenShift templates, process them, and deploy them.\n\nIt also interacts with OpenShift to manage the reservation of ephemeral namespaces for testing.\n\nIt is meant to be partnered with the [Clowder](https://github.com/RedHatInsights/clowder) operator to spin up an ephemeral environment for testing on either a remote OpenShift cluster or a local k8s cluster.\n\n## Installation\n\nWe'd recommend setting up a virtual environment for bonfire:\n\n```bash\nVENV_DIR=~/bonfire_venv\nmkdir -p $VENV_DIR\npython3 -m venv $VENV_DIR\n. $VENV_DIR/bin/activate\npip install crc-bonfire\nbonfire --help\n```\n\n## Overview\n\nThe `bonfire process` command can be used to print processed app configs to stdout.\n\nThe `bonfire namespace reserve` command can be used to acquire a namespace on a cluster\nif that cluster has been set up with bonfire's namespace reconciler.\n\nThe `bonfire deploy` command can be used as a helpful \"1-liner\" command to reserve a namespace,\nprocess application configs, apply them into a desired namespace, and wait for them to come up successfully.\n\nThe `bonfire process-env` command can be used to print a processed ClowdEnvironment config to stdout.\n\nThe `bonfire deploy-env` command can be used as a helpful \"1-liner\" command to apply a ClowdEnvironment\nconfiguration into a cluster and wait for environment resources to come up successfully.\n\n### Using a local config\n\nTo get up and running without needing to contact app-interface's `qontract-server`, you can utilize\na local config file. `bonfire` ships with a [default config](bonfire/resources/default_config.yaml) that\nshould be enough to get started for most internal Red Hat employees. An internal repository holds\napplication configurations for the cloud.redhat.com platform that are valid for use in ephemeral environments.\n\nBy default, the configuration file will be stored in `~/.config/bonfire/config.yaml`. You can reset the config to default at any time using `bonfire config write-default`.\n\n### App config overrides\n\nYou can edit your local config file to override any app configurations to allow for \"local tinkering\". If you define an app under the\n`apps` key of the config, it will take precedence over any app's configuration that was fetched/downloaded.\n\n#### Deploy app template using changes you've made locally\n\nAs an example, if you wanted to test out some changes you're making to an app but you have not yet pushed these changes to a git repo, the local config could look similar to:\n\n```\napps:\n- name: my_app\n  components:\n    - name: service\n      host: local\n      repo: ~/dev/projects/my-app\n      path: /clowdapp.yaml\n```\n\n- Where **host** set `local` indicates to look for the repo in a local directory\n- Where **repo** indicates the path to your git repo folder\n- Where **path** specifies the relative path to your ClowdApp template file in your git repo\n\nBy default, bonfire will run `git rev-parse` to determine what IMAGE_TAG to set when the template is deployed. However, you can use `--set-image-tag` or `--set-parameter` to override this.\n\n#### Deploy app template using changes you've made in a remote git branch\n\nAs an example, if you wanted to deploy changes to your app that you were working on which have been pushed to a PR/branch, the local config could look similar to:\n\n```\napps:\n- name: my_app\n  components:\n    - name: service\n      host: github\n      repo: MyOrg/MyRepo\n      path: /clowdapp.yaml\n```\n\n- Where **host** set to `github` or `gitlab` indicates where the repo is hosted\n- Where **repo** indicates the `OrganizationName/RepoName`\n- Where **path** specifies the relative path to your ClowdApp template file in your git repo\n\nBy default, bonfire will use the commit hash of `master` to determine what IMAGE_TAG to deploy.\n\nNOTE: For this particular use case, if your changes are already present in a git repo, and your app already has appropriate ephemeral deployment configs set up, then using the `--set-template-ref` and `--set-image-tag` flags in bonfire may be simpler than editing your app config.\n### Loading an app's ephemeral config from app-interface\n\nYou can also run `bonfire process`/`bonfire deploy` using `--source appsre` which will pull configurations from app-interface.\n\nYou'll first need to set proper env variables to interface with your instance of `qontract-server`:\n\n```bash\nexport QONTRACT_BASE_URL=\"https://myserver/graphql\"\nexport QONTRACT_USERNAME=myUsername\nexport QONTRACT_PASSWORD=myPassword\n```\n\nIf these env vars are not specified, bonfire will attempt to access a local `qontract-server` (see \"Setting up a local qontract-server\" below)\n\n`bonfire` will query the qontract GraphQL API and read the desired application's deploy configuration.\n\nYou can edit the local configuration file (discussed above) if you wish to override any app configurations to allow for \"local tinkering\". If you define an app under the `apps` key of the config, it will take precedence over that app's configuration that was fetched from app-interface.\n\n\n### Loading application configs\n\n`bonfire process` relies on a few key pieces of info to process app configs:\n1. The application name. This is typically the name of the listed in `app.yaml` in `app-interface`\n1. *(applies to `--source=appsre` only)* a 'target env' -- the name of the `app-interface` environment that you want to pull application configs for. An app's config will only be processed if it has a deploy target set up that points to a namespace mapped to this environment (default: \"ephemeral\")\n1. *(optional)* a 'ref env' -- the name of the `app-interface` environment that we want to use in order to set the applications `IMAGE_TAG` values and deploy template ref. This can be useful if you want to deploy applications using ephemeral template parameters, but you want to override the `IMAGE_TAG`/`ref` defined on all apps to use the values found in `prod` or `stage`.\n1. Any template refs you wish to override -- in other words, if you want to download a different git hash of an application component's template.\n1. Any image tags you wish to override -- in other words, if you want to use a different image tag for just a specific docker image.\n1. Any parameters you wish to override -- if you want to set a different template parameter for a specific app.\n\nBy default, `bonfire` will dynamically load dependencies that all components of `app` relies on. This requires the `app` to be using the [Clowder](https://github.com/RedHatInsights/clowder) operator and to have the `dependencies` section of the ClowdApp set up.\n\n\n### Example usage in a smoke test\n\nThe goal of a smoke test running against an `app` is to:\n* deploy the PR's code for `app`\n* deploy the production versions of `app`'s dependencies alongside it\n\nBelow we'll show how `bonfire deploy` will enable this:\n\nLet's say that we are running a PR check against the `insights-puptoo` service. This service:\n* is a member of the `ingress` application.\n* has a kubernetes deploy manifest that resides in the same repo as the code\n* has its CI/CD `pr_check.sh` set up such that if a PR is opened, a docker image is built and pushed to `quay.io/myorg/insights-puptoo` with the tag `pr-<git hash>`. The PR opened against the app has commit hash `abc1234`\n\nIf we intend to reserve a namespace and deploy the `ingress` application group into it, using the new template/image of the `insights-puptoo` PR, but using the production template/image for all other components, we could run:\n\n```bash\nAPP_NAME=ingress\nCOMPONENT_NAME=insights-puptoo\nGIT_COMMIT=pr-abc1234\nIMAGE=quay.io/myorg/insights-puptoo\nIMAGE_TAG=abc1234\n\nNAMESPACE=$(bonfire deploy $APP_NAME \\\n    --ref-env insights-prod \\\n    --set-template-ref $COMPONENT_NAME=$GIT_COMMIT \\\n    --set-image-tag $IMAGE=$IMAGE_TAG)\n\necho \"My environment is deployed into $NAMESPACE\"\n```\n\nThis is functionally equivalent to:\n```bash\nNAMESPACE=$(bonfire namespace reserve)\n\nbonfire process $APP_NAME\n    --ref-env insights-prod\n    --set-template-ref $COMPONENT_NAME=$GIT_COMMIT\n    --set-image-tag $IMAGE=$IMAGE_TAG\n    --clowd-env env-$NAMESPACE\n\nbonfire namespace wait-on-resources $NAMESPACE\n\necho \"My environment is deployed into $NAMESPACE\"\n```\n\n## Namespace management\n\n`bonfire` is also used to reserve, release, and reconcile ephemeral namespaces running on our test OpenShift clusters.\n\nThe list of ephemeral namespaces is stored in `app-interface`.\n\nThe service account that bonfire logs in to the cluster with has a custom role bound to it which allows it to edit namespace labels:\n\n```\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: namespace-editor\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  verbs:\n  - get\n  - list\n  - patch\n  - update\n  - watch\n```\n\nThis role is bound to the service account in each ephemeral namespace.\n\nBonfire uses labels to keep track of which namespaces are reserved AND ready. A \"ready\" namespace is one which has been \"wiped clean\" and then had a fresh set of base test configurations copied into it.\n\nWhen a tester is logged in using the proper account, namespace commands can be used such as:\n\n`bonfire namespace reserve` -- find an available namespace and reserve it. By default the TTL is 1 hr.\n\n`bonfire namespace release <namespace>` -- release a namespace reservation\n\nUse `bonfire namespace -h` to see a list of all available namespace commands.\n\n### Namespace reconciler\n\nA separate cron job runs the `bonfire namespace reconcile` command every 2 minutes. This command does the following:\n\n* Checks for any namespaces that are released, but not ready, and \"prepares\" them by wiping them and copying base test resources into them. After being prepared, the namespace is marked \"ready\". A namespace is prepared by:\n    1. creating an ephemeral `ClowdEnvironment` resource for it, and\n    2. copying any secrets defined in the `ephemeral-base` namespace into it\n* Checks for any namespaces that are reserved, but do not have an \"expires\" time set on them yet. This would be a newly-reserved namespace. The reconciler is responsible for applying the \"expires time\"\n* Checks the \"expires time\" on all reserved namespaces. If any have expired, bonfire will release them and re-prepare them.\n\n### Interactions with Clowder\n\n* For every namespace that `bonfire` prepares, it creates a Clowder `ClowdEnvironment` resource following [this template](https://github.com/RedHatInsights/bonfire/blob/master/bonfire/resources/ephemeral-clowdenvironment.yaml). The name of the environment matches [this format](https://github.com/RedHatInsights/bonfire/blob/master/bonfire/config.py#L16). So, if bonfire prepared a namespace called `ephemeral-01`, then the name of the `ClowdEnvironment` would be `env-ephemeral-01`.\n\n* When `bonfire deploy` is executed for a namespace, it will attempt to find the ClowdEnvironment associated with that namespace and set the `ENV_NAME` parameter accordingly for all templates it processes. All templates that define a `ClowdApp` resource should set the `environment` mapping in their spec using an `${ENV_NAME}` parameter.\n\n* When `bonfire namespace wait-on-resources` is executed, it follows this logic:\n1. Wait for all resources owned by a 'ClowdEnvironment' to appear in the namespace\n2. Wait for all the deployments in the namespace to reach 'active' state.\n3. Wait for resources owned by a 'ClowdApp' to appear in the namespace\n4. Wait for all the deployments in the namespace to reach 'active' state (deployments we already waited on in step 2 are not waited on again)\n\n\n## Miscellaneous\n### Running a local qontract-server\n\nFor testing/debug purposes, instead of committing changes directly to app-interface, you can run\nyour own local copy of the app-interface API server.\n\n1. Clone https://github.com/app-sre/qontract-server\n2. Clone the internal `app-interface` repo\n\nIn `qontract-server`, run:\n```\nnpm install yarn\nyarn install\nyarn build\nmake bundle APP_INTERFACE_PATH=/path/to/app-interface\nLOAD_METHOD=fs DATAFILES_FILE=bundle/bundle.json yarn run server\n```\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications",
    "version": "1.5.1",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "b72e3bbd67d4fb52e2c86e0d72671d28",
                "sha256": "d5e1105c665dd6af838a5aa2c803f0ea58980d37649e21c3ab7e8485b0a35654"
            },
            "downloads": -1,
            "filename": "crc_bonfire-1.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b72e3bbd67d4fb52e2c86e0d72671d28",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 35862,
            "upload_time": "2021-06-18T17:31:03",
            "upload_time_iso_8601": "2021-06-18T17:31:03.258695Z",
            "url": "https://files.pythonhosted.org/packages/fe/a9/cabb324a7ede98e1455a5e2b758112c5bd47ed63cea5d451f06763ebb104/crc_bonfire-1.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "b1573e2c891d917935d7d2d7f96c6f6f",
                "sha256": "ee2a9dde196e3c148e9e9da8d74fb090ccbaa6ced8ab0462b12a1c81d18a7a59"
            },
            "downloads": -1,
            "filename": "crc-bonfire-1.5.1.tar.gz",
            "has_sig": false,
            "md5_digest": "b1573e2c891d917935d7d2d7f96c6f6f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 48591,
            "upload_time": "2021-06-18T17:31:04",
            "upload_time_iso_8601": "2021-06-18T17:31:04.748273Z",
            "url": "https://files.pythonhosted.org/packages/aa/85/23a002a9d8a8818273a9f7fdf04b1ff5a0d284eaa01c0b23a0755444be56/crc-bonfire-1.5.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2021-06-18 17:31:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "RedHatInsights",
    "github_project": "bonfire",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "gql",
            "specs": [
                [
                    "==",
                    "3.0.0a1"
                ]
            ]
        },
        {
            "name": "aiohttp",
            "specs": [
                [
                    ">=",
                    "3.6.2"
                ]
            ]
        },
        {
            "name": "async-timeout",
            "specs": [
                [
                    ">=",
                    "3.0.1"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    ">=",
                    "20.2.0"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    ">=",
                    "2020.6.20"
                ]
            ]
        },
        {
            "name": "chardet",
            "specs": [
                [
                    "<",
                    "4.0"
                ],
                [
                    ">=",
                    "2.0"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    ">=",
                    "7.1.2"
                ]
            ]
        },
        {
            "name": "graphql-core",
            "specs": [
                [
                    ">=",
                    "3.1.2"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    ">=",
                    "2.10"
                ]
            ]
        },
        {
            "name": "multidict",
            "specs": [
                [
                    ">=",
                    "4.5"
                ],
                [
                    "<",
                    "5.0"
                ]
            ]
        },
        {
            "name": "parsedatetime",
            "specs": [
                [
                    ">=",
                    "2.6"
                ]
            ]
        },
        {
            "name": "promise",
            "specs": [
                [
                    ">=",
                    "2.3"
                ]
            ]
        },
        {
            "name": "PyYAML",
            "specs": [
                [
                    ">=",
                    "5.3.1"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    ">=",
                    "2.24.0"
                ]
            ]
        },
        {
            "name": "Rx",
            "specs": [
                [
                    ">=",
                    "1.6.1"
                ]
            ]
        },
        {
            "name": "setuptools-scm",
            "specs": [
                [
                    ">=",
                    "4.1.2"
                ]
            ]
        },
        {
            "name": "sh",
            "specs": [
                [
                    ">=",
                    "1.14.0"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    ">=",
                    "1.15.0"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    ">=",
                    "1.25.10"
                ]
            ]
        },
        {
            "name": "wait-for",
            "specs": [
                [
                    ">=",
                    "1.1.4"
                ]
            ]
        },
        {
            "name": "websockets",
            "specs": [
                [
                    ">=",
                    "8.1"
                ]
            ]
        },
        {
            "name": "yarl",
            "specs": [
                [
                    ">=",
                    "1.5.1"
                ]
            ]
        },
        {
            "name": "tabulate",
            "specs": [
                [
                    ">=",
                    "0.8.7"
                ]
            ]
        },
        {
            "name": "python-dotenv",
            "specs": [
                [
                    ">=",
                    "0.15.0"
                ]
            ]
        },
        {
            "name": "ocviapy",
            "specs": [
                [
                    ">=",
                    "0.3.2"
                ]
            ]
        },
        {
            "name": "app-common-python",
            "specs": [
                [
                    ">=",
                    "0.1.6"
                ]
            ]
        },
        {
            "name": "cached-property",
            "specs": [
                [
                    ">=",
                    "1.5.2"
                ]
            ]
        }
    ],
    "lcname": "crc-bonfire"
}
        
Elapsed time: 0.31348s