示例#1
0
 def test_tag(self):
     tag_dict = {"Key": "my_key", "Value": "my_value"}
     tag = Tag(tag_dict)
     self.assertEqual(tag.key, "my_key")
     self.assertEqual(tag.value, "my_value")
     actual = tag.dump()
     self.assertEqual(tag_dict, actual)
示例#2
0
 def create_stacks(self, threads: int = 8):
     if self.stacks:
         raise TaskCatException(
             "Stacker already initialised with stack objects")
     tests = self._tests_to_list(self.tests)
     tags = [Tag({"Key": "taskcat-id", "Value": self.uid.hex})]
     tags += [
         Tag(t) for t in self.tags if t.key not in
         ["taskcat-project-name", "taskcat-test-name", "taskcat-id"]
     ]
     fan_out(self._create_stacks_for_test, {"tags": tags}, tests, threads)
示例#3
0
 def _create_stacks_for_test(self, test, tags, threads: int = 32):
     stack_name = test.stack_name
     tags.append(Tag({"Key": "taskcat-project-name", "Value": self.project_name}))
     tags.append(Tag({"Key": "taskcat-test-name", "Value": test.name}))
     tags += test.tags
     partial_kwargs = {
         "stack_name": stack_name,
         "template": test.template,
         "tags": tags,
         "test_name": test.name,
     }
     stacks = fan_out(Stack.create, partial_kwargs, test.regions, threads)
     self.stacks += stacks
示例#4
0
    def get_tests(self, templates, regions, buckets, parameters):
        tests = {}
        for test_name, test in self.config.tests.items():
            region_list = []
            tag_list = []
            if test.tags:
                for tag_key, tag_value in test.tags.items():
                    tag_list.append(Tag({"Key": tag_key, "Value": tag_value}))
            for region_obj in regions[test_name].values():
                region_list.append(
                    TestRegion.from_region_obj(
                        region_obj,
                        buckets[test_name][region_obj.name],
                        parameters[test_name][region_obj.name],
                    )
                )

            tests[test_name] = TestObj(
                name=test_name,
                template_path=self.project_root / test.template,
                template=templates[test_name],
                project_root=self.project_root,
                regions=region_list,
                tags=tag_list,
                uid=self.uid,
                _project_name=self.config.project.name,
                _shorten_stack_name=self.config.project.shorten_stack_name,
            )
        return tests
示例#5
0
 def _create_stacks_for_test(self, test, tags, threads: int = 32):
     prefix = f"{self.stack_name_prefix}-" if self.stack_name_prefix else ""
     stack_name = "{}{}-{}-{}".format(prefix, self.project_name, test.name,
                                      self.uid.hex)
     tags.append(
         Tag({
             "Key": "taskcat-project-name",
             "Value": self.project_name
         }))
     tags.append(Tag({"Key": "taskcat-test-name", "Value": test.name}))
     tags += test.tags
     partial_kwargs = {
         "stack_name": stack_name,
         "template": test.template,
         "tags": tags,
         "test_name": test.name,
     }
     stacks = fan_out(Stack.create, partial_kwargs, test.regions, threads)
     self.stacks += stacks
示例#6
0
 def test_filterable_list(self):
     tags = Tags([Tag({"Key": "my_key", "Value": "my_value"})])
     filtered = tags.filter()
     self.assertEqual(filtered, tags)
     filtered = tags.filter({"key": "blah"})
     self.assertEqual(filtered, [])
     filtered = tags.filter({"key": "my_key"})
     self.assertEqual(filtered, tags)
     filtered = tags.filter(key="my_key", value="blah")
     self.assertEqual(filtered, [])
     filtered = tags.filter(key="my_key", value="my_value")
     self.assertEqual(filtered, tags)
示例#7
0
 def run(  # noqa: C901
     self,
     project: str = "./",
     test_names: str = "ALL",
     regions: str = "ALL",
     name="",
     input_file: str = "./.taskcat.yml",
 ):
     """
     :param project: name of project to install can be a path to a local project,\
     a github org/repo, or an AWS Quick Start name
     :param test_names: comma separated list of tests (specified in .taskcat.yml) to run\
         defaults to the 'default' test. Set to 'ALL' to deploy every entry
     :param regions: comma separated list of regions to test in\
     default
     :param name: stack name to use, if not specified one will be automatically\
     generated
     :param input_file: path to either a taskcat project config file or a CloudFormation template
     """
     if not name:
         name = generate_name()
     path = Path(project).resolve()
     if Path(project).resolve().is_dir():
         package_type = "local"
     elif "/" in project:
         package_type = "github"
     else:  # assuming it's an AWS Quick Start
         package_type = "github"
         project = f"aws-quickstart/quickstart-{project}"
     if package_type == "github":
         if project.startswith("https://") or project.startswith("git@"):
             url = project
             org, repo = (project.replace(".git",
                                          "").replace(":",
                                                      "/").split("/")[-2:])
         else:
             org, repo = project.split("/")
             url = f"https://github.com/{org}/{repo}.git"
         path = Deploy.PKG_CACHE_PATH / org / repo
         LOG.info(f"fetching git repo {url}")
         self._git_clone(url, path)
         self._recurse_submodules(path, url)
     _extra_tags = [(Tag({"Key": "taskcat-installer", "Value": name}))]
     Test.run(
         regions=regions,
         no_delete=True,
         project_root=path,
         test_names=test_names,
         input_file=input_file,
         _extra_tags=_extra_tags,
     )
示例#8
0
    def test_criteria_matches(self):
        with self.assertRaises(ValueError) as cm:
            tag = Tag({"Key": "my_key", "Value": "my_value"})
            criteria_matches({"invalid": "blah"}, tag)
        self.assertEqual(
            "invalid is not a valid property of <class 'taskcat._dataclasses.Tag'>",
            str(cm.exception),
        )

        actual = criteria_matches({"key": "blah"}, tag)
        self.assertEqual(actual, False)
        actual = criteria_matches({"key": "my_key"}, tag)
        self.assertEqual(actual, True)
        actual = criteria_matches({"key": "my_key", "value": "blah"}, tag)
        self.assertEqual(actual, False)
        actual = criteria_matches({"key": "my_key", "value": "my_value"}, tag)
        self.assertEqual(actual, True)
示例#9
0
 def __init__(  # noqa: C901
     self,
     package: str,
     aws_profile: str = "default",
     region="default",
     parameters="",
     name="",
     wait=False,
 ):
     """
     :param package: name of package to install can be a path to a local package,
     a github org/repo, or an AWS Quick Start name
     :param aws_profile: aws profile to use for installation
     :param region: regions to install into, default will use aws cli configured
     default
     :param parameters: parameters to pass to the stack, in the format
     Key=Value,AnotherKey=AnotherValue or providing a path to a json or yaml file
     containing the parameters
     :param name: stack name to use, if not specified one will be automatically
     generated
     :param wait: if enabled, taskcat will wait for stack to complete before exiting
     """
     LOG.warning("deploy is in alpha feature, use with caution")
     boto3_cache = Boto3Cache()
     if not name:
         name = generate_name()
     if region == "default":
         region = boto3_cache.get_default_region(profile_name=aws_profile)
     path = Path(package).resolve()
     if Path(package).resolve().is_dir():
         package_type = "local"
     elif "/" in package:
         package_type = "github"
     else:  # assuming it's an AWS Quick Start
         package_type = "github"
         package = f"aws-quickstart/quickstart-{package}"
     if package_type == "github":
         if package.startswith("https://") or package.startswith("git@"):
             url = package
             org, repo = (package.replace(".git",
                                          "").replace(":",
                                                      "/").split("/")[-2:])
         else:
             org, repo = package.split("/")
             url = f"https://github.com/{org}/{repo}.git"
         path = Deploy.PKG_CACHE_PATH / org / repo
         LOG.info(f"fetching git repo {url}")
         self._git_clone(url, path)
         self._recurse_submodules(path, url)
     config = Config.create(
         args={"project": {
             "regions": [region]
         }},
         project_config_path=(path / ".taskcat.yml"),
         project_root=path,
     )
     # only use one region
     for test_name in config.config.tests:
         config.config.tests[
             test_name].regions = config.config.project.regions
     # if there's no test called default, take the 1st in the list
     if "default" not in config.config.tests:
         config.config.tests["default"] = config.config.tests[list(
             config.config.tests.keys())[0]]
     # until install offers a way to run different "plans" we only need one test
     for test_name in list(config.config.tests.keys()):
         if test_name != "default":
             del config.config.tests[test_name]
     buckets = config.get_buckets(boto3_cache)
     stage_in_s3(buckets, config.config.project.name, path)
     regions = config.get_regions(boto3_cache)
     templates = config.get_templates(project_root=path)
     parameters = config.get_rendered_parameters(buckets, regions,
                                                 templates)
     tests = config.get_tests(path, templates, regions, buckets, parameters)
     tags = [Tag({"Key": "taskcat-installer", "Value": name})]
     stacks = Stacker(config.config.project.name, tests, tags=tags)
     stacks.create_stacks()
     LOG.error(
         f" {stacks.uid.hex}",
         extra={"nametag": "\x1b[0;30;47m[INSTALL_ID  ]\x1b[0m"},
     )
     LOG.error(f" {name}",
               extra={"nametag": "\x1b[0;30;47m[INSTALL_NAME]\x1b[0m"})
     if wait:
         LOG.info(
             f"waiting for stack {stacks.stacks[0].name} to complete in "
             f"{stacks.stacks[0].region_name}")
         while stacks.status()["IN_PROGRESS"]:
             sleep(5)
     if stacks.status()["FAILED"]:
         LOG.error("Install failed:")
         for error in stacks.stacks[0].error_events():
             LOG.error(f"{error.logical_id}: {error.status_reason}")
         raise TaskCatException("Stack creation failed")