예제 #1
0
    def test_get_helm_list_without_namespace(self,
                                             mocker: MockFixture) -> None:
        mock_validate_helm_installed = mocker.patch(
            "opta.core.helm.Helm.validate_helm_installed", return_value=None)
        mock_namespace_placeholder = ["--all-namespaces"]
        mock_nice_run_helm_list_process = mocker.patch(
            "opta.core.helm.nice_run")

        mock_json_loads = mocker.patch("opta.core.helm.json.loads")

        Helm.get_helm_list("test-kube-context")
        mock_validate_helm_installed.assert_called_once()
        mock_nice_run_helm_list_process.assert_called_once_with(
            [
                "helm",
                "list",
                "--all",
                "--kube-context",
                "test-kube-context",
                "--kubeconfig",
                mocker.ANY,
                *mock_namespace_placeholder,
                "-o",
                "json",
            ],
            capture_output=True,
            check=True,
        )
        mock_json_loads.assert_called_once()
예제 #2
0
    def test_rollback_helm_base_revision_x(self, mocker: MockFixture) -> None:
        mock_validate_helm_installed = mocker.patch(
            "opta.core.helm.Helm.validate_helm_installed", return_value=None)
        mock_nice_run_helm_rollback = mocker.patch("opta.core.helm.nice_run")

        Helm.rollback_helm(
            "test-kube-context",
            self.MOCK_RELEASE,
            self.MOCK_NAMESPACE,
            revision=self.MOCK_REVISION_X,
        )

        mock_validate_helm_installed.assert_called_once()
        mock_nice_run_helm_rollback.assert_called_once_with(
            [
                "helm",
                "rollback",
                self.MOCK_RELEASE,
                self.MOCK_REVISION_X,
                "--kube-context",
                "test-kube-context",
                "--kubeconfig",
                mocker.ANY,
                "--namespace",
                self.MOCK_NAMESPACE,
            ],
            check=True,
        )
예제 #3
0
    def pre_hook(self, module_idx: int) -> None:
        release_name = f"{self.layer.name}-{self.module.name}"
        cloud_client = self.layer.get_cloud_client()

        # TODO(patrick): We could probably just always run this check
        # If we are running a BYOK cluster, make sure linkerd and nginx are installed.
        if isinstance(cloud_client, HelmCloudClient):
            self._check_byok_ready()

        kube_context = cloud_client.get_kube_context_name()
        pending_upgrade_helm_chart = Helm.get_helm_list(
            kube_context=kube_context, release=release_name, status="pending-upgrade"
        )
        if pending_upgrade_helm_chart:
            raise UserErrors(
                f"There is a pending upgrade for the helm chart: {release_name}."
                "\nIt will cause this command to fail. Please use `opta force-unlock` to rollback to a consistent state first."
            )
        return super().pre_hook(module_idx)
예제 #4
0
def force_unlock(
    config: str, env: Optional[str], local: Optional[bool], var: Dict[str, str],
) -> None:
    """Release a stuck lock on the current workspace

    Manually unlock the state for the defined configuration.

    This will not modify your infrastructure. This command removes the lock on the
    state for the current workspace.

    Examples:

    opta force-unlock -c my-config.yaml -e prod
    """
    try:
        opta_acquire_lock()
        tf_flags: List[str] = []
        config = check_opta_file_exists(config)
        if local:
            config = local_setup(config, input_variables=var)
        amplitude_client.send_event(amplitude_client.FORCE_UNLOCK_EVENT)
        layer = Layer.load_from_yaml(
            config, env, input_variables=var, strict_input_variables=False
        )
        layer.verify_cloud_credentials()
        modules = Terraform.get_existing_modules(layer)
        layer.modules = [x for x in layer.modules if x.name in modules]
        gen_all(layer)

        tf_lock_exists, _ = Terraform.tf_lock_details(layer)
        if tf_lock_exists:
            Terraform.init(layer=layer)
            click.confirm(
                "This will remove the lock on the remote state."
                "\nPlease make sure that no other instance of opta command is running on this file."
                "\nDo you still want to proceed?",
                abort=True,
            )
            tf_flags.append("-force")
            Terraform.force_unlock(layer, *tf_flags)

        if Terraform.download_state(layer):
            if layer.parent is not None or "k8scluster" in modules:
                set_kube_config(layer)
                kube_context = layer.get_cloud_client().get_kube_context_name()
                pending_upgrade_release_list = Helm.get_helm_list(
                    kube_context=kube_context, status="pending-upgrade"
                )
                click.confirm(
                    "Do you also wish to Rollback the Helm releases in Pending-Upgrade State?"
                    "\nPlease make sure that no other instance of opta command is running on this file."
                    "\nDo you still want to proceed?",
                    abort=True,
                )

                for release in pending_upgrade_release_list:
                    Helm.rollback_helm(
                        kube_context,
                        release["name"],
                        namespace=release["namespace"],
                        revision=release["revision"],
                    )
    finally:
        opta_release_lock()
예제 #5
0
 def required_path_dependencies(self) -> FrozenSet[str]:
     return super(
     ).required_path_dependencies | Helm.get_required_path_executables()
예제 #6
0
 def test_get_required_path_executables(self) -> None:
     deps = Helm.get_required_path_executables()
     assert len(deps) == 1