Exemple #1
0
    def set_versions(self, new_version: str) -> bool:
        """
        Patches the Terraform version of the workspaces.

        :param new_version: The new Terraform version to assign to the workspaces.
        :return: Whether all patch operations were successful. If even a single one failed, returns
                 False.
        """
        if not self.check_versions(new_version):
            if self.write_output:
                # yapf: disable
                print((
                    "Error: at least one of the target workspaces has a version newer than the one "
                    "you are attempting to change to. No workspaces were updated."
                ), file=sys.stderr)
                # yapf: enable
            return False
        else:
            return batch_operation(
                self.terraform_domain,
                self.organization,
                self.workspaces,
                field_mappers=[lambda w: w.terraform_version],
                field_names=["terraform-version"],
                new_values=[new_version],
                no_tls=self.no_tls,
                token=self.token,
                write_output=self.write_output)
 def test5() -> None:
     assert not batch_operation(TEST_TERRAFORM_DOMAIN,
                                TEST_ORGANIZATION,
                                [_test_workspace1, _test_workspace2],
                                field_mappers=[],
                                field_names=["test"],
                                new_values=["test"],
                                write_output=write_output)
 def test4() -> None:
     assert not batch_operation(TEST_TERRAFORM_DOMAIN,
                                TEST_ORGANIZATION,
                                [_test_workspace1, _test_workspace2],
                                field_mappers=[name, name],
                                field_names=["test", "test"],
                                new_values=["test", "test"],
                                report_only_value_mappers=[str],
                                write_output=write_output)
Exemple #4
0
    def set_speculative(self, set_speculative: bool) -> bool:
        """
        Patches the speculative-enabled setting of the workspaces.

        :param set_speculative: The desired value of the workspaces' speculative-enabled setting.
        :return: Whether all patch operations were successful. If even a single one failed, returns
                 False.
        """
        return batch_operation(self.terraform_domain,
                               self.organization,
                               self.workspaces,
                               field_mappers=[lambda w: w.speculative],
                               field_names=["speculative-enabled"],
                               new_values=[set_speculative],
                               no_tls=self.no_tls,
                               token=self.token,
                               write_output=self.write_output)
Exemple #5
0
    def set_working_directories(self,
                                new_working_directory: Optional[str]) -> bool:
        """
        Patches the working directories of the workspaces.

        :param new_working_directory: The new working directory to assign to the workspaces.
        :return: Whether all patch operations were successful. If even a single one failed, returns
                 False.
        """
        return batch_operation(
            self.terraform_domain,
            self.organization,
            self.workspaces,
            field_mappers=[lambda w: w.working_directory],
            field_names=["working-directory"],
            new_values=[coalesce(new_working_directory, "")],
            report_only_value_mappers=[lambda d: coalesce(d, "<none>")],
            no_tls=self.no_tls,
            token=self.token,
            write_output=self.write_output)
Exemple #6
0
    def set_execution_modes(self,
                            new_execution_mode: str,
                            *,
                            agent_pool_id: Optional[str] = None) -> bool:
        """
        Patches the execution modes of the workspaces.

        :param new_execution_mode: The new execution mode to assign to the workspaces. The value
                                   must be either "remote", "local", or "agent" (case-sensitive).
        :param agent_pool_id: The agent-pool-id to assign to the workspaces. Only specify this
                              argument if you are switching to "agent" execution mode AND you are
                              targeting Terraform Cloud.
        :return: Whether all patch operations were successful. If even a single one failed, returns
                 False. If the new_execution_mode and agent_pool_id arguments are not compatible,
                 or you are not targeting Terraform Cloud but you specify "agent" mode, returns
                 False.
        """
        if new_execution_mode not in ["remote", "local", "agent"]:
            if self.write_output:
                print(
                    f"Error: invalid execution-mode specified: {new_execution_mode}",
                    file=sys.stderr)
            return False
        elif new_execution_mode == "agent" and not self.is_terraform_cloud:
            if self.write_output:
                # yapf: disable
                print((
                    f'Error: desired execution-mode is "agent" but you are not targeting Terraform '
                    f'Cloud (selected domain is "{self.terraform_domain}").'
                ), file=sys.stderr)
                # yapf: enable
            return False
        elif new_execution_mode == "agent" and is_empty(agent_pool_id):
            if self.write_output:
                print(
                    f'Error: desired execution-mode is "agent" but no agent-pool-id was specified.',
                    file=sys.stderr)
            return False
        elif new_execution_mode != "agent" and not is_empty(agent_pool_id):
            if self.write_output:
                # yapf: disable
                print((
                    f'Error: desired execution-mode is "{new_execution_mode}" but an agent-pool-id '
                    f"was specified."
                ), file=sys.stderr)
                # yapf: enable
            return False
        else:
            field_mappers = [lambda w: w.execution_mode]
            field_names = ["execution-mode"]
            new_values = [new_execution_mode]
            if new_execution_mode == "agent":
                field_mappers.append(lambda w: w.agent_pool_id)
                field_names.append("agent-pool-id")
                new_values.append(agent_pool_id)
            return batch_operation(self.terraform_domain,
                                   self.organization,
                                   self.workspaces,
                                   field_mappers=field_mappers,
                                   field_names=field_names,
                                   new_values=new_values,
                                   no_tls=self.no_tls,
                                   token=self.token,
                                   write_output=self.write_output)
def test_batch_operation(mocker: MockerFixture) -> None:
    for write_output in [True, False]:
        _establish_mocks(mocker)
        print_mock: MagicMock = mocker.patch("builtins.print")
        error_json = {"data": {"id": _test_workspace2.workspace_id}}
        responses.add(
            responses.PATCH,
            f"{TEST_API_URL}/workspaces/{_test_workspace1.workspace_id}",
            status=200)
        responses.add(
            responses.PATCH,
            f"{TEST_API_URL}/workspaces/{_test_workspace2.workspace_id}",
            json=error_json,
            status=500)

        (field1, value1) = ("test-field1", _test_workspace1.terraform_version)
        (field2, value2) = ("test-field2", "test2")
        assert not batch_operation(
            TEST_TERRAFORM_DOMAIN,
            TEST_ORGANIZATION, [_test_workspace1, _test_workspace2],
            field_mappers=[lambda w: w.terraform_version, lambda w: w.name],
            field_names=[field1, field2],
            new_values=[value1, value2],
            report_only_value_mappers=[
                lambda x: "test-" + x, lambda x: "test-" + x
            ],
            write_output=write_output)

        if write_output:
            # yapf: disable
            print_mock.assert_has_calls([
                call((
                    f'Terraform workspace {"/".join([field1, field2])} patch results for '
                    f'organization "{TEST_ORGANIZATION}" at "{TEST_TERRAFORM_DOMAIN}":'
                )),
                call(),
                call(
                    tabulate(
                        [
                            [
                                _test_workspace2.name,
                                field1,
                                "test-" + _test_workspace2.terraform_version,
                                "test-" + _test_workspace2.terraform_version,
                                "error",
                                str(error_json)
                            ],
                            [
                                _test_workspace2.name,
                                field2,
                                "test-" + _test_workspace2.name,
                                "test-" + _test_workspace2.name,
                                "error",
                                str(error_json)
                            ],
                            [
                                _test_workspace1.name,
                                field1,
                                "test-" + _test_workspace1.terraform_version,
                                "test-" + value1,
                                "success",
                                "value unchanged"
                            ],
                            [
                                _test_workspace1.name,
                                field2,
                                "test-" + _test_workspace1.name,
                                "test-" + value2,
                                "success",
                                "none"
                            ]
                        ],
                        headers=["Workspace", "Field", "Before", "After", "Status", "Message"]
                    )
                ),
                call()
            ])
            # yapf: enable
            assert print_mock.call_count == 4
        else:
            print_mock.assert_not_called()