cloud-radar


Namecloud-radar JSON
Version 0.11.0 PyPI version JSON
download
home_pagehttps://github.com/DontShaveTheYak/cloud-radar
SummaryRun functional tests on cloudformation stacks.
upload_time2023-12-18 11:26:46
maintainer
docs_urlNone
authorLevi Blaney
requires_python>=3.8.1,<4.0.0
licenseApache-2.0
keywords aws cloudformation cloud-radar testing taskcat cloud radar
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <!-- PROJECT SHIELDS -->
<!--
*** I'm using markdown "reference style" links for readability.
*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
*** See the bottom of this document for the declaration of the reference variables
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->
[![Python][python-shield]][pypi-url]
[![Latest][version-shield]][pypi-url]
[![Tests][test-shield]][test-url]
[![Coverage][codecov-shield]][codecov-url]
[![License][license-shield]][license-url]
<!-- [![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url] -->

<!-- PROJECT LOGO -->
<br />
<p align="center">
  <!-- <a href="https://github.com/DontShaveTheYak/cloud-radar">
    <img src="images/logo.png" alt="Logo" width="80" height="80">
  </a> -->

  <h3 align="center">Cloud-Radar</h3>

  <p align="center">
    Write unit and functional tests for AWS Cloudformation.
    <!-- <br />
    <a href="https://github.com/DontShaveTheYak/cloud-radar"><strong>Explore the docs »</strong></a>
    <br /> -->
    <br />
    <!-- <a href="https://github.com/DontShaveTheYak/cloud-radar">View Demo</a>
    · -->
    <a href="https://github.com/DontShaveTheYak/cloud-radar/issues">Report Bug</a>
    ·
    <a href="https://github.com/DontShaveTheYak/cloud-radar/issues">Request Feature</a>
    ·
    <a href="https://la-tech.co/post/hypermodern-cloudformation/getting-started/">Guide</a>
  </p>
</p>



<!-- TABLE OF CONTENTS -->
<details open="open">
  <summary>Table of Contents</summary>
  <ol>
    <li>
      <a href="#about-the-project">About The Project</a>
      <ul>
        <li><a href="#built-with">Built With</a></li>
      </ul>
    </li>
    <li>
      <a href="#getting-started">Getting Started</a>
      <ul>
        <li><a href="#prerequisites">Prerequisites</a></li>
        <li><a href="#installation">Installation</a></li>
      </ul>
    </li>
    <li><a href="#usage">Usage</a></li>
    <li><a href="#roadmap">Roadmap</a></li>
    <li><a href="#contributing">Contributing</a></li>
    <li><a href="#license">License</a></li>
    <li><a href="#contact">Contact</a></li>
    <li><a href="#acknowledgements">Acknowledgements</a></li>
  </ol>
</details>

## About The Project

<!-- [![Product Name Screen Shot][product-screenshot]](https://example.com) -->

Cloud-Radar is a python module that allows testing of Cloudformation Templates/Stacks using Python.

### Unit Testing

You can now unit test the logic contained inside your Cloudformation template. Cloud-Radar takes your template, the desired region and some parameters. We render the template into its final state and pass it back to you.

You can Test:
* That Conditionals in your template evaluate to the correct value.
* Conditional resources were created or not.
* That resources have the correct properties.
* That resources are named as expected because of `!Sub`.

You can test all this locally without worrying about AWS Credentials.

### Functional Testing

This project is a wrapper around Taskcat. Taskcat is a great tool for ensuring your Cloudformation Template can be deployed in multiple AWS Regions. Cloud-Radar enhances Taskcat by making it easier to write more complete functional tests.

Here's How:
* You can interact with the deployed resources directly with tools you already know like boto3.
* You can control the lifecycle of the stack. This allows testing if resources were retained after the stacks were deleted.
* You can run tests without hardcoding them in a taskcat config file.

This project is new and it's possible not all features or functionality of Taskcat/Cloudformation are supported (see [Roadmap](#roadmap)). If you find something missing or have a use case that isn't covered then please let me know =)

### Built With

* [Taskcat](https://github.com/aws-quickstart/taskcat)
* [cfn_tools from cfn-flip](https://github.com/awslabs/aws-cfn-template-flip)

## Getting Started

Cloud-Radar is available as an easy to install pip package.

### Prerequisites

Cloud-Radar requires python >= 3.8

### Installation

1. Install with pip.
   ```sh
   pip install cloud-radar
   ```

## Usage
<details>
<summary>Unit Testing <span style='font-size: .67em'>(Click to expand)</span></summary>

Using Cloud-Radar starts by importing it into your test file or framework. We will use this [Template](./tests/templates/log_bucket/log_bucket.yaml) for an example shown below. More scenario based examples are currently being built up in the [examples/unit](./examples/unit) directory of this project.

```python
from pathlib import Path
from cloud_radar.cf.unit import Template

template_path = Path("tests/templates/log_bucket/log_bucket.yaml")

# template_path can be a str or a Path object
template = Template.from_yaml(template_path.resolve())

params = {"BucketPrefix": "testing", "KeepBucket": "TRUE"}

# parameters and region are optional arguments.
stack = template.create_stack(params, region="us-west-2")

stack.no_resource("LogsBucket")

bucket = stack.get_resource("RetainLogsBucket")

assert "DeletionPolicy" in bucket

assert bucket["DeletionPolicy"] == "Retain"

bucket_name = bucket.get_property_value("BucketName")

assert "us-west-2" in bucket_name
```

The AWS [pseudo parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) are all class attributes and can be modified before rendering a template.
```python
# The value of 'AWS::AccountId' in !Sub "My AccountId is ${AWS::AccountId}" can be changed:
Template.AccountId = '8675309'
```
_Note: Region should only be changed to change the default value. To change the region during testing pass the desired region to render(region='us-west-2')_

The default values for pseudo parameters:

| Name             | Default Value   |
| ---------------- | --------------- |
| AccountId        | "555555555555"  |
| NotificationARNs | []              |
| **NoValue**      | ""              |
| **Partition**    | "aws"           |
| Region           | "us-east-1"     |
| **StackId**      | ""              |
| **StackName**    | ""              |
| **URLSuffix**    | "amazonaws.com" |
_Note: Bold variables are not fully impletmented yet see the [Roadmap](#roadmap)_

At the point of creating the `Template` instance additional configuration is required to be provided if you are using certain approaches to resolving values.

If you use [Fn::ImportValue](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html), a dictionary of key/value pairs is required containing all the keys that your template uses. If an import name is referenced by the template which is not included in this dictionary, an error will be raised.

```
imports = {
  "FakeKey": "FakeValue"
}

template = Template(template_content, imports=imports)
```

If you use [Dynamic References](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html), a dictionary containing the service and key/value pairs is required containing all the dynamic references that your template uses. If a dynamic reference is included in the template and not contained in the configuration object, an error will be raised.

```
template_content = {
    "Resources": {
        "Foo": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": (
                    "mgt-{{resolve:ssm:/account/current/short_name}}-launch-role-pol"
                ),
            },
        },
    },
}

dynamic_references = {
  "ssm": {
    "/account/current/short_name": "dummy"
  }
}

template = Template(template_content, dynamic_references=dynamic_references)
```

A real unit testing example using Pytest can be seen [here](./tests/test_cf/test_examples/test_unit.py)

</details>

<details>
<summary>Functional Testing <span style='font-size: .67em'>(Click to expand)</span></summary>
Using Cloud-Radar starts by importing it into your test file or framework.

```python
from pathlib import Path

from cloud_radar.cf.e2e import Stack

# Stack is a context manager that makes sure your stacks are deleted after testing.
template_path = Path("tests/templates/log_bucket/log_bucket.yaml")
params = {"BucketPrefix": "testing", "KeepBucket": "False"}
regions = ['us-west-2']

# template_path can be a string or a Path object.
# params can be optional if all your template params have default values
# regions can be optional, default region is 'us-east-1'
with Stack(template_path, params, regions) as stacks:
    # Stacks will be created and returned as a list in the stacks variable.

    for stack in stacks:
        # stack will be an instance of Taskcat's Stack class.
        # It has all the expected properties like parameters, outputs and resources

        print(f"Testing {stack.name}")

        bucket_name = ""

        for output in stack.outputs:

            if output.key == "LogsBucketName":
                bucket_name = output.value
                break

        assert "logs" in bucket_name

        assert stack.region.name in bucket_name

        print(f"Created bucket: {bucket_name}")

# Once the test is over then all resources will be deleted from your AWS account.
```

You can use taskcat [tokens](https://aws.amazon.com/blogs/infrastructure-and-automation/a-deep-dive-into-testing-with-taskcat/) in your parameter values.

```python
parameters = {
  "BucketPrefix": "taskcat-$[taskcat_random-string]",
  "KeepBucket": "FALSE",
}
```

You can skip the context manager. Here is an example for `unittest`

```python
import unittest

from cloud-radar.cf.e2e import Stack

class TestLogBucket(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        template_path = Path("tests/templates/log_bucket/log_bucket.yaml")
        cls.test = Stack(template_path)
        cls.test.create()

    @classmethod
    def tearDownClass(cls):
        cls.test.delete()

    def test_bucket(self):
        stacks = self.__class__.test.stacks

        for stack in stacks:
            # Test
```

All the properties and methods of a [stack instance](https://github.com/aws-quickstart/taskcat/blob/main/taskcat/_cfn/stack.py#L188).

A real functional testing example using Pytest can be seen [here](./tests/test_cf/test_examples/test_functional.py)

</details>

## Roadmap

### Project
- Add Logo
- Easier to pick regions for testing

### Unit
- Add full functionality to pseudo variables.
  * Variables like `Partition`, `URLSuffix` should change if the region changes.
  * Variables like `StackName` and `StackId` should have a better default than ""
- Handle References to resources that shouldn't exist.
  * It's currently possible that a `!Ref` to a Resource stays in the final template even if that resource is later removed because of a conditional.

### Functional
- Add the ability to update a stack instance to Taskcat.

See the [open issues](https://github.com/DontShaveTheYak/cloud-radar/issues) for a list of proposed features (and known issues).

## Contributing

Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.

This project uses poetry to manage dependencies and pre-commit to run formatting, linting and tests. You will need to have both installed to your system as well as python 3.9.

1. Fork the Project
2. Setup environment (`poetry install`)
3. Setup commit hooks (`pre-commit install`)
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## License

Distributed under the Apache-2.0 License. See [LICENSE.txt](./LICENSE.txt) for more information.

## Contact

Levi - [@shady_cuz](https://twitter.com/shady_cuz)

<!-- ACKNOWLEDGEMENTS -->
## Acknowledgements
* [Taskcat](https://aws-quickstart.github.io/taskcat/)
* [Hypermodern Python](https://cjolowicz.github.io/posts/hypermodern-python-01-setup/)
* [Best-README-Template](https://github.com/othneildrew/Best-README-Template)
* @dhutchison - He was the first contributor to this project and finished the last couple of features to make this project complete. Thank you!

<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
[python-shield]: https://img.shields.io/pypi/pyversions/cloud-radar?style=for-the-badge
[version-shield]: https://img.shields.io/pypi/v/cloud-radar?label=latest&style=for-the-badge
[pypi-url]: https://pypi.org/project/cloud-radar/
[test-shield]: https://img.shields.io/github/actions/workflow/status/DontShaveTheYak/cloud-radar/test.yml?label=Tests&style=for-the-badge
[test-url]: https://github.com/DontShaveTheYak/cloud-radar/actions?query=workflow%3ATests+branch%3Amaster
[codecov-shield]: https://img.shields.io/codecov/c/gh/DontShaveTheYak/cloud-radar?color=green&style=for-the-badge&token=NE5C92139X
[codecov-url]: https://codecov.io/gh/DontShaveTheYak/cloud-radar
[contributors-shield]: https://img.shields.io/github/contributors/DontShaveTheYak/cloud-radar.svg?style=for-the-badge
[contributors-url]: https://github.com/DontShaveTheYak/cloud-radar/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/DontShaveTheYak/cloud-radar.svg?style=for-the-badge
[forks-url]: https://github.com/DontShaveTheYak/cloud-radar/network/members
[stars-shield]: https://img.shields.io/github/stars/DontShaveTheYak/cloud-radar.svg?style=for-the-badge
[stars-url]: https://github.com/DontShaveTheYak/cloud-radar/stargazers
[issues-shield]: https://img.shields.io/github/issues/DontShaveTheYak/cloud-radar.svg?style=for-the-badge
[issues-url]: https://github.com/DontShaveTheYak/cloud-radar/issues
[license-shield]: https://img.shields.io/github/license/DontShaveTheYak/cloud-radar.svg?style=for-the-badge
[license-url]: https://github.com/DontShaveTheYak/cloud-radar/blob/master/LICENSE.txt
[product-screenshot]: images/screenshot.png

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/DontShaveTheYak/cloud-radar",
    "name": "cloud-radar",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8.1,<4.0.0",
    "maintainer_email": "",
    "keywords": "aws,cloudformation,cloud-radar,testing,taskcat,cloud,radar",
    "author": "Levi Blaney",
    "author_email": "shadycuz@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/6a/69/0e1e06e1486c343265349d295848a059485ec00c324f8dcf0b41e3507efe/cloud_radar-0.11.0.tar.gz",
    "platform": null,
    "description": "<!-- PROJECT SHIELDS -->\n<!--\n*** I'm using markdown \"reference style\" links for readability.\n*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).\n*** See the bottom of this document for the declaration of the reference variables\n*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.\n*** https://www.markdownguide.org/basic-syntax/#reference-style-links\n-->\n[![Python][python-shield]][pypi-url]\n[![Latest][version-shield]][pypi-url]\n[![Tests][test-shield]][test-url]\n[![Coverage][codecov-shield]][codecov-url]\n[![License][license-shield]][license-url]\n<!-- [![Contributors][contributors-shield]][contributors-url]\n[![Forks][forks-shield]][forks-url]\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url] -->\n\n<!-- PROJECT LOGO -->\n<br />\n<p align=\"center\">\n  <!-- <a href=\"https://github.com/DontShaveTheYak/cloud-radar\">\n    <img src=\"images/logo.png\" alt=\"Logo\" width=\"80\" height=\"80\">\n  </a> -->\n\n  <h3 align=\"center\">Cloud-Radar</h3>\n\n  <p align=\"center\">\n    Write unit and functional tests for AWS Cloudformation.\n    <!-- <br />\n    <a href=\"https://github.com/DontShaveTheYak/cloud-radar\"><strong>Explore the docs \u00bb</strong></a>\n    <br /> -->\n    <br />\n    <!-- <a href=\"https://github.com/DontShaveTheYak/cloud-radar\">View Demo</a>\n    \u00b7 -->\n    <a href=\"https://github.com/DontShaveTheYak/cloud-radar/issues\">Report Bug</a>\n    \u00b7\n    <a href=\"https://github.com/DontShaveTheYak/cloud-radar/issues\">Request Feature</a>\n    \u00b7\n    <a href=\"https://la-tech.co/post/hypermodern-cloudformation/getting-started/\">Guide</a>\n  </p>\n</p>\n\n\n\n<!-- TABLE OF CONTENTS -->\n<details open=\"open\">\n  <summary>Table of Contents</summary>\n  <ol>\n    <li>\n      <a href=\"#about-the-project\">About The Project</a>\n      <ul>\n        <li><a href=\"#built-with\">Built With</a></li>\n      </ul>\n    </li>\n    <li>\n      <a href=\"#getting-started\">Getting Started</a>\n      <ul>\n        <li><a href=\"#prerequisites\">Prerequisites</a></li>\n        <li><a href=\"#installation\">Installation</a></li>\n      </ul>\n    </li>\n    <li><a href=\"#usage\">Usage</a></li>\n    <li><a href=\"#roadmap\">Roadmap</a></li>\n    <li><a href=\"#contributing\">Contributing</a></li>\n    <li><a href=\"#license\">License</a></li>\n    <li><a href=\"#contact\">Contact</a></li>\n    <li><a href=\"#acknowledgements\">Acknowledgements</a></li>\n  </ol>\n</details>\n\n## About The Project\n\n<!-- [![Product Name Screen Shot][product-screenshot]](https://example.com) -->\n\nCloud-Radar is a python module that allows testing of Cloudformation Templates/Stacks using Python.\n\n### Unit Testing\n\nYou can now unit test the logic contained inside your Cloudformation template. Cloud-Radar takes your template, the desired region and some parameters. We render the template into its final state and pass it back to you.\n\nYou can Test:\n* That Conditionals in your template evaluate to the correct value.\n* Conditional resources were created or not.\n* That resources have the correct properties.\n* That resources are named as expected because of `!Sub`.\n\nYou can test all this locally without worrying about AWS Credentials.\n\n### Functional Testing\n\nThis project is a wrapper around Taskcat. Taskcat is a great tool for ensuring your Cloudformation Template can be deployed in multiple AWS Regions. Cloud-Radar enhances Taskcat by making it easier to write more complete functional tests.\n\nHere's How:\n* You can interact with the deployed resources directly with tools you already know like boto3.\n* You can control the lifecycle of the stack. This allows testing if resources were retained after the stacks were deleted.\n* You can run tests without hardcoding them in a taskcat config file.\n\nThis project is new and it's possible not all features or functionality of Taskcat/Cloudformation are supported (see [Roadmap](#roadmap)). If you find something missing or have a use case that isn't covered then please let me know =)\n\n### Built With\n\n* [Taskcat](https://github.com/aws-quickstart/taskcat)\n* [cfn_tools from cfn-flip](https://github.com/awslabs/aws-cfn-template-flip)\n\n## Getting Started\n\nCloud-Radar is available as an easy to install pip package.\n\n### Prerequisites\n\nCloud-Radar requires python >= 3.8\n\n### Installation\n\n1. Install with pip.\n   ```sh\n   pip install cloud-radar\n   ```\n\n## Usage\n<details>\n<summary>Unit Testing <span style='font-size: .67em'>(Click to expand)</span></summary>\n\nUsing Cloud-Radar starts by importing it into your test file or framework. We will use this [Template](./tests/templates/log_bucket/log_bucket.yaml) for an example shown below. More scenario based examples are currently being built up in the [examples/unit](./examples/unit) directory of this project.\n\n```python\nfrom pathlib import Path\nfrom cloud_radar.cf.unit import Template\n\ntemplate_path = Path(\"tests/templates/log_bucket/log_bucket.yaml\")\n\n# template_path can be a str or a Path object\ntemplate = Template.from_yaml(template_path.resolve())\n\nparams = {\"BucketPrefix\": \"testing\", \"KeepBucket\": \"TRUE\"}\n\n# parameters and region are optional arguments.\nstack = template.create_stack(params, region=\"us-west-2\")\n\nstack.no_resource(\"LogsBucket\")\n\nbucket = stack.get_resource(\"RetainLogsBucket\")\n\nassert \"DeletionPolicy\" in bucket\n\nassert bucket[\"DeletionPolicy\"] == \"Retain\"\n\nbucket_name = bucket.get_property_value(\"BucketName\")\n\nassert \"us-west-2\" in bucket_name\n```\n\nThe AWS [pseudo parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) are all class attributes and can be modified before rendering a template.\n```python\n# The value of 'AWS::AccountId' in !Sub \"My AccountId is ${AWS::AccountId}\" can be changed:\nTemplate.AccountId = '8675309'\n```\n_Note: Region should only be changed to change the default value. To change the region during testing pass the desired region to render(region='us-west-2')_\n\nThe default values for pseudo parameters:\n\n| Name             | Default Value   |\n| ---------------- | --------------- |\n| AccountId        | \"555555555555\"  |\n| NotificationARNs | []              |\n| **NoValue**      | \"\"              |\n| **Partition**    | \"aws\"           |\n| Region           | \"us-east-1\"     |\n| **StackId**      | \"\"              |\n| **StackName**    | \"\"              |\n| **URLSuffix**    | \"amazonaws.com\" |\n_Note: Bold variables are not fully impletmented yet see the [Roadmap](#roadmap)_\n\nAt the point of creating the `Template` instance additional configuration is required to be provided if you are using certain approaches to resolving values.\n\nIf you use [Fn::ImportValue](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html), a dictionary of key/value pairs is required containing all the keys that your template uses. If an import name is referenced by the template which is not included in this dictionary, an error will be raised.\n\n```\nimports = {\n  \"FakeKey\": \"FakeValue\"\n}\n\ntemplate = Template(template_content, imports=imports)\n```\n\nIf you use [Dynamic References](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html), a dictionary containing the service and key/value pairs is required containing all the dynamic references that your template uses. If a dynamic reference is included in the template and not contained in the configuration object, an error will be raised.\n\n```\ntemplate_content = {\n    \"Resources\": {\n        \"Foo\": {\n            \"Type\": \"AWS::IAM::Policy\",\n            \"Properties\": {\n                \"PolicyName\": (\n                    \"mgt-{{resolve:ssm:/account/current/short_name}}-launch-role-pol\"\n                ),\n            },\n        },\n    },\n}\n\ndynamic_references = {\n  \"ssm\": {\n    \"/account/current/short_name\": \"dummy\"\n  }\n}\n\ntemplate = Template(template_content, dynamic_references=dynamic_references)\n```\n\nA real unit testing example using Pytest can be seen [here](./tests/test_cf/test_examples/test_unit.py)\n\n</details>\n\n<details>\n<summary>Functional Testing <span style='font-size: .67em'>(Click to expand)</span></summary>\nUsing Cloud-Radar starts by importing it into your test file or framework.\n\n```python\nfrom pathlib import Path\n\nfrom cloud_radar.cf.e2e import Stack\n\n# Stack is a context manager that makes sure your stacks are deleted after testing.\ntemplate_path = Path(\"tests/templates/log_bucket/log_bucket.yaml\")\nparams = {\"BucketPrefix\": \"testing\", \"KeepBucket\": \"False\"}\nregions = ['us-west-2']\n\n# template_path can be a string or a Path object.\n# params can be optional if all your template params have default values\n# regions can be optional, default region is 'us-east-1'\nwith Stack(template_path, params, regions) as stacks:\n    # Stacks will be created and returned as a list in the stacks variable.\n\n    for stack in stacks:\n        # stack will be an instance of Taskcat's Stack class.\n        # It has all the expected properties like parameters, outputs and resources\n\n        print(f\"Testing {stack.name}\")\n\n        bucket_name = \"\"\n\n        for output in stack.outputs:\n\n            if output.key == \"LogsBucketName\":\n                bucket_name = output.value\n                break\n\n        assert \"logs\" in bucket_name\n\n        assert stack.region.name in bucket_name\n\n        print(f\"Created bucket: {bucket_name}\")\n\n# Once the test is over then all resources will be deleted from your AWS account.\n```\n\nYou can use taskcat [tokens](https://aws.amazon.com/blogs/infrastructure-and-automation/a-deep-dive-into-testing-with-taskcat/) in your parameter values.\n\n```python\nparameters = {\n  \"BucketPrefix\": \"taskcat-$[taskcat_random-string]\",\n  \"KeepBucket\": \"FALSE\",\n}\n```\n\nYou can skip the context manager. Here is an example for `unittest`\n\n```python\nimport unittest\n\nfrom cloud-radar.cf.e2e import Stack\n\nclass TestLogBucket(unittest.TestCase):\n    @classmethod\n    def setUpClass(cls):\n        template_path = Path(\"tests/templates/log_bucket/log_bucket.yaml\")\n        cls.test = Stack(template_path)\n        cls.test.create()\n\n    @classmethod\n    def tearDownClass(cls):\n        cls.test.delete()\n\n    def test_bucket(self):\n        stacks = self.__class__.test.stacks\n\n        for stack in stacks:\n            # Test\n```\n\nAll the properties and methods of a [stack instance](https://github.com/aws-quickstart/taskcat/blob/main/taskcat/_cfn/stack.py#L188).\n\nA real functional testing example using Pytest can be seen [here](./tests/test_cf/test_examples/test_functional.py)\n\n</details>\n\n## Roadmap\n\n### Project\n- Add Logo\n- Easier to pick regions for testing\n\n### Unit\n- Add full functionality to pseudo variables.\n  * Variables like `Partition`, `URLSuffix` should change if the region changes.\n  * Variables like `StackName` and `StackId` should have a better default than \"\"\n- Handle References to resources that shouldn't exist.\n  * It's currently possible that a `!Ref` to a Resource stays in the final template even if that resource is later removed because of a conditional.\n\n### Functional\n- Add the ability to update a stack instance to Taskcat.\n\nSee the [open issues](https://github.com/DontShaveTheYak/cloud-radar/issues) for a list of proposed features (and known issues).\n\n## Contributing\n\nContributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nThis project uses poetry to manage dependencies and pre-commit to run formatting, linting and tests. You will need to have both installed to your system as well as python 3.9.\n\n1. Fork the Project\n2. Setup environment (`poetry install`)\n3. Setup commit hooks (`pre-commit install`)\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\nDistributed under the Apache-2.0 License. See [LICENSE.txt](./LICENSE.txt) for more information.\n\n## Contact\n\nLevi - [@shady_cuz](https://twitter.com/shady_cuz)\n\n<!-- ACKNOWLEDGEMENTS -->\n## Acknowledgements\n* [Taskcat](https://aws-quickstart.github.io/taskcat/)\n* [Hypermodern Python](https://cjolowicz.github.io/posts/hypermodern-python-01-setup/)\n* [Best-README-Template](https://github.com/othneildrew/Best-README-Template)\n* @dhutchison - He was the first contributor to this project and finished the last couple of features to make this project complete. Thank you!\n\n<!-- MARKDOWN LINKS & IMAGES -->\n<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->\n[python-shield]: https://img.shields.io/pypi/pyversions/cloud-radar?style=for-the-badge\n[version-shield]: https://img.shields.io/pypi/v/cloud-radar?label=latest&style=for-the-badge\n[pypi-url]: https://pypi.org/project/cloud-radar/\n[test-shield]: https://img.shields.io/github/actions/workflow/status/DontShaveTheYak/cloud-radar/test.yml?label=Tests&style=for-the-badge\n[test-url]: https://github.com/DontShaveTheYak/cloud-radar/actions?query=workflow%3ATests+branch%3Amaster\n[codecov-shield]: https://img.shields.io/codecov/c/gh/DontShaveTheYak/cloud-radar?color=green&style=for-the-badge&token=NE5C92139X\n[codecov-url]: https://codecov.io/gh/DontShaveTheYak/cloud-radar\n[contributors-shield]: https://img.shields.io/github/contributors/DontShaveTheYak/cloud-radar.svg?style=for-the-badge\n[contributors-url]: https://github.com/DontShaveTheYak/cloud-radar/graphs/contributors\n[forks-shield]: https://img.shields.io/github/forks/DontShaveTheYak/cloud-radar.svg?style=for-the-badge\n[forks-url]: https://github.com/DontShaveTheYak/cloud-radar/network/members\n[stars-shield]: https://img.shields.io/github/stars/DontShaveTheYak/cloud-radar.svg?style=for-the-badge\n[stars-url]: https://github.com/DontShaveTheYak/cloud-radar/stargazers\n[issues-shield]: https://img.shields.io/github/issues/DontShaveTheYak/cloud-radar.svg?style=for-the-badge\n[issues-url]: https://github.com/DontShaveTheYak/cloud-radar/issues\n[license-shield]: https://img.shields.io/github/license/DontShaveTheYak/cloud-radar.svg?style=for-the-badge\n[license-url]: https://github.com/DontShaveTheYak/cloud-radar/blob/master/LICENSE.txt\n[product-screenshot]: images/screenshot.png\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Run functional tests on cloudformation stacks.",
    "version": "0.11.0",
    "project_urls": {
        "Homepage": "https://github.com/DontShaveTheYak/cloud-radar",
        "Repository": "https://github.com/DontShaveTheYak/cloud-radar"
    },
    "split_keywords": [
        "aws",
        "cloudformation",
        "cloud-radar",
        "testing",
        "taskcat",
        "cloud",
        "radar"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "04b3b67c39e3914be2126dad5aecc18b1d7f3a3e3c3d7d7743f755113e59df11",
                "md5": "60e68b8462d5bd704f97865f54ed53bc",
                "sha256": "887baf3ade8f361c93a575a31d9c393456ed1a070889c1cc4ea22f962ee0d04b"
            },
            "downloads": -1,
            "filename": "cloud_radar-0.11.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "60e68b8462d5bd704f97865f54ed53bc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8.1,<4.0.0",
            "size": 30447,
            "upload_time": "2023-12-18T11:26:45",
            "upload_time_iso_8601": "2023-12-18T11:26:45.268222Z",
            "url": "https://files.pythonhosted.org/packages/04/b3/b67c39e3914be2126dad5aecc18b1d7f3a3e3c3d7d7743f755113e59df11/cloud_radar-0.11.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6a690e1e06e1486c343265349d295848a059485ec00c324f8dcf0b41e3507efe",
                "md5": "17dc5f3c86ea63d2629f5ff96228061c",
                "sha256": "2ab2009651e9657064be450b2927fb22ec4dfdcba6a1fa44791fb78d5837ca42"
            },
            "downloads": -1,
            "filename": "cloud_radar-0.11.0.tar.gz",
            "has_sig": false,
            "md5_digest": "17dc5f3c86ea63d2629f5ff96228061c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8.1,<4.0.0",
            "size": 31246,
            "upload_time": "2023-12-18T11:26:46",
            "upload_time_iso_8601": "2023-12-18T11:26:46.890179Z",
            "url": "https://files.pythonhosted.org/packages/6a/69/0e1e06e1486c343265349d295848a059485ec00c324f8dcf0b41e3507efe/cloud_radar-0.11.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-18 11:26:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "DontShaveTheYak",
    "github_project": "cloud-radar",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "cloud-radar"
}
        
Elapsed time: 0.17380s