Example #1
0
class CabritaCommand:
    """Cabrita Command class."""
    def __init__(
        self,
        cabrita_path: str,
        compose_path: tuple,
        background_color: Optional[str] = "black",
        version: str = "dev",
    ) -> None:
        """Init class."""
        self.version = version
        self.cabrita_path = cabrita_path
        self.config = Config()
        self.config.add_path(self.cabrita_path)
        self.config.load_file_data()
        self.config.manual_compose_paths = list(compose_path)
        self.compose = None  # type: Compose
        self.dashboard = None  # type: Dashboard
        self._background_color = background_color

    @property
    def background_color(self):
        """Return Background Color enum.

        :return: BoxColor instance
        """
        return (getattr(BoxColor, self._background_color)
                if self._background_color else self.config.background_color)

    @property
    def has_a_valid_config(self) -> bool:
        """Return if Config data is valid.

        :return: bool
        """
        return self.config.is_valid

    @property
    def has_a_valid_compose(self) -> bool:
        """Return if Compose data is valid.

        :return: bool
        """
        return self.compose.is_valid

    def read_compose_files(self) -> None:
        """Read docker compose files data.

        :return: None
        """
        self.compose = Compose()
        for compose in self.config.compose_files:
            base_compose_path = os.path.dirname(compose)
            if "." in base_compose_path:
                base_compose_path = self.config.base_path
            self.compose.add_path(compose, base_path=base_compose_path)
            if not self.compose.is_valid:
                sys.exit(1)
        self.compose.load_file_data()
        if self.config.version == 0:
            self.config.generate_boxes(self.compose.services)

    def _add_watchers(self) -> None:
        """Configure and add watchers to dashboard.

        :return: None
        """
        git = GitInspect(target_branch="", interval=30, compose=self.compose)
        self.dashboard.compose_watch = DockerComposeWatch(
            background_color=self.background_color,
            git=git,
            config=self.config,
            version=self.version,
        )
        self.dashboard.system_watch = SystemWatch(
            background_color=self.background_color)
        self.dashboard.user_watches = UserWatch(
            background_color=self.background_color,
            git=git,
            config=self.config)

    def _add_services_in_boxes(self) -> None:
        """Configure and add docker services to dashboard boxes.

        The 'main' box are the last to be processed, because this
        box will include any non-ignored service which aren't
        included in any box before.

        :return: None
        """
        included_services = []  # type: List[str]
        main_box = None

        for name in self.config.boxes:
            box_data = self.config.boxes[name]
            docker = DockerInspect(
                compose=self.compose,
                interval=box_data.get("interval", 0),
                port_view=box_data.get("port_view", PortView.hidden),
                port_detail=box_data.get("port_detail", PortDetail.external),
                files_to_watch=box_data.get("watch_for_build_using_files", []),
                services_to_check_git=box_data.get("watch_for_build_using_git",
                                                   []),
            )
            git = GitInspect(
                target_branch=box_data.get("watch_branch", ""),
                interval=box_data.get("git_fetch_interval", 30),
                compose=self.compose,
            )

            services_in_box = []
            for service in self.compose.services:
                if (service not in included_services
                        and service not in self.config.ignore_services):
                    services_list = set([
                        s.lower() for s in box_data.get("includes", []) +
                        box_data.get("categories", [])
                    ])
                    for service_name in services_list:
                        if service_name.lower() in service.lower():
                            services_in_box.append(service)
                            included_services.append(service)

            box = Box(
                compose=self.compose,
                docker=docker,
                git=git,
                background_color=self.background_color,
            )
            box.services = services_in_box
            box.load_data(box_data)

            if box.main:
                main_box = box
            else:
                self.dashboard.add_box(box)
        if main_box:
            for service in self.compose.services:
                if (service not in included_services
                        and service not in self.config.ignore_services):
                    main_box.add_service(service)
            self.dashboard.add_box(main_box)

    def prepare_dashboard(self) -> None:
        """Prepare the dashboard.

        :return: None
        """
        self.dashboard = Dashboard(config=self.config)
        self._add_watchers()
        self._add_services_in_boxes()

    def execute(self) -> None:
        """Execute dashboard to show data in terminal.

        :return: None
        """
        self.dashboard.run()
Example #2
0
class TestConfig(TestCase):
    def setUp(self):
        self.maxDiff = None
        self._generate_config()

    def _generate_config(self):
        self.config = Config()
        self.config.add_path("./sheep/config/cabrita-v1.yml")
        self.config.load_file_data()
        self.assertTrue(self.config.is_valid)

    def test_ignore_services(self):
        self.assertListEqual(self.config.ignore_services, ["portainer"])

    def test_compose_files(self):
        self.assertListEqual(self.config.compose_files,
                             ["$TEST_PROJECT_PATH/docker-compose.yml"])

    def test_layout(self):
        self.assertEqual(self.config.layout, "horizontal")

    def test_boxes(self):
        self.assertEqual(len(self.config.boxes.keys()), 3)
        for box_name in self.config.boxes.keys():
            self.assertTrue(box_name in ["all", "workers", "devops"])

    def test_title(self):
        self.assertEqual(self.config.title, "Docker-Compose")

    def test_background_color(self):
        from cabrita.components import BoxColor

        self.assertEqual(self.config.background_color, BoxColor.black)

    def test_background_color_value(self):
        self.assertEqual(self.config.background_color_value, 16)

    def test_watchers(self):
        pass

    def test_get_compose_path(self):
        current_dir = os.path.dirname(os.path.abspath(__file__))
        parent_dir = str(Path(current_dir).parent.parent)
        os.environ["TEST_PROJECT_PATH"] = os.path.join(parent_dir, "sheep")
        self.assertEqual(
            Path(
                self.config.get_compose_path(
                    "$TEST_PROJECT_PATH/docker-compose.yml", parent_dir)),
            Path(os.path.join(parent_dir,
                              "sheep/docker-compose.yml")).resolve(),
        )

    def test_generate_boxes(self):
        services_list = {"django": {}, "django-worker": {}, "flask": {}}
        expected_box = {
            "box_0": {
                "includes": ["django", "django-worker", "flask"],
                "name": "Docker Services",
                "port_view": "column",
                "show_revision": True,
                "size": "small",
            }
        }
        self.config.generate_boxes(services_list)
        self.assertListEqual(self.config.boxes["box_0"]["includes"],
                             expected_box["box_0"]["includes"])
        self.assertEqual(self.config.boxes["box_0"]["name"],
                         expected_box["box_0"]["name"])
        self.assertEqual(self.config.boxes["box_0"]["port_view"],
                         expected_box["box_0"]["port_view"])
        self.assertEqual(
            self.config.boxes["box_0"]["show_revision"],
            expected_box["box_0"]["show_revision"],
        )
        self.assertEqual(self.config.boxes["box_0"]["size"],
                         expected_box["box_0"]["size"])
Example #3
0
class TestConfig(TestCase):
    def setUp(self):
        self.maxDiff = None
        self._generate_config()

    def _generate_config(self):
        self.config = Config()
        self.config.add_path(LATEST_CONFIG_PATH)
        self.config.load_file_data()
        self.assertTrue(self.config.is_valid)

    def test_ignore_services(self):
        self.assertEqual(self.config.ignore_services, ["portainer"])

    def test_compose_files(self):
        self.assertEqual(
            self.config.compose_files,
            [
                "$TEST_PROJECT_PATH/docker-compose.yml",
                "$TEST_PROJECT_PATH/docker-compose.override.yml",
            ],
        )

    def test_layout(self):
        self.assertEqual(self.config.layout, "horizontal")

    def test_boxes(self):
        self.assertEqual(len(self.config.boxes.keys()), 3)
        for box_name in self.config.boxes.keys():
            self.assertTrue(box_name in ["all", "workers", "devops"])

    def test_title(self):
        self.assertEqual(self.config.title, "My Docker Project")

    def test_background_color(self):
        from cabrita.components import BoxColor

        self.assertEqual(self.config.background_color, BoxColor.grey)

    def test_background_color_value(self):
        self.assertEqual(self.config.background_color_value, 0)

    def test_watchers(self):
        pass

    def test_get_compose_path(self):
        current_dir = os.path.dirname(os.path.abspath(__file__))
        parent_dir = str(Path(current_dir).parent.parent)
        os.environ["TEST_PROJECT_PATH"] = os.path.join(parent_dir, "sheep")
        self.assertEqual(
            Path(
                self.config.get_compose_path(
                    "$TEST_PROJECT_PATH/docker-compose.yml", parent_dir
                )
            ),
            Path(os.path.join(parent_dir, "sheep/docker-compose.yml")).resolve(),
        )

    def test_generate_boxes(self):
        services_list = {"django": {}, "django-worker": {}, "flask": {}}
        expected_box = {
            "box_0": {
                "includes": ["django", "django-worker", "flask"],
                "name": "Docker Services",
                "port_view": "column",
                "show_revision": True,
                "size": "small",
            }
        }
        self.config.generate_boxes(services_list)
        self.assertListEqual(
            self.config.boxes["box_0"]["includes"], expected_box["box_0"]["includes"]
        )
        self.assertEqual(
            self.config.boxes["box_0"]["name"], expected_box["box_0"]["name"]
        )
        self.assertEqual(
            self.config.boxes["box_0"]["port_view"], expected_box["box_0"]["port_view"]
        )
        self.assertEqual(
            self.config.boxes["box_0"]["show_revision"],
            expected_box["box_0"]["show_revision"],
        )
        self.assertEqual(
            self.config.boxes["box_0"]["size"], expected_box["box_0"]["size"]
        )

    def test_bad_config(self):
        self.config = Config()
        self.config.add_path("./sheep/config/cabrita-v2.yml")
        self.config.load_file_data()
        self.config.data["layout"] = "triangular"
        self.config.data["background_color"] = "no_color"
        self.config.data["compose_files"] = {}
        self.config.data["boxes"] = {
            "wrong_box": {
                "size": "ultra_large",
                "port_view": "wrong_option",
                "port_detail": "wrong_option",
                "watch_for_build_using_files": {},
                "watch_for_build_using_git": {},
                "includes": {},
                "categories": {},
            }
        }
        self.config.data["ignore_services"] = {}
        self.assertFalse(self.config.is_valid)
Example #4
0
class TestConfig(TestCase):
    def setUp(self):
        self.maxDiff = None
        self.manual_files = [
            "./sheep/docker-compose.yml",
            "./sheep/docker-compose.override.yml",
        ]
        self._generate_config()

    def _generate_config(self):
        self.config = Config()
        self.config.manual_compose_paths = self.manual_files
        self.config.load_file_data()
        self.assertTrue(self.config.is_valid)

    def test_ignore_services(self):
        self.assertEqual(self.config.ignore_services, [])

    def test_compose_files(self):
        self.assertEqual(self.config.compose_files, self.manual_files)

    def test_layout(self):
        self.assertEqual(self.config.layout, "horizontal")

    def test_title(self):
        self.assertEqual(self.config.title, "Docker-Compose")

    def test_background_color(self):
        from cabrita.components import BoxColor

        self.assertEqual(self.config.background_color, BoxColor.black)

    def test_background_color_value(self):
        self.assertEqual(self.config.background_color_value, 16)

    def test_get_compose_path(self):
        current_dir = os.path.dirname(os.path.abspath(__file__))
        parent_dir = Path(current_dir).parent.parent
        self.assertEqual(
            Path(
                self.config.get_compose_path(self.manual_files[0],
                                             str(parent_dir))),
            Path(os.path.join(str(parent_dir),
                              self.manual_files[0])).resolve(),
        )

    def test_generate_boxes(self):
        services_list = {"django": {}, "django-worker": {}, "flask": {}}
        expected_box = {
            "box_0": {
                "includes": ["django", "django-worker", "flask"],
                "name": "Docker Services",
                "port_view": "column",
                "show_revision": True,
                "size": "small",
            }
        }
        self.config.generate_boxes(services_list)
        self.assertListEqual(self.config.boxes["box_0"]["includes"],
                             expected_box["box_0"]["includes"])
        self.assertEqual(self.config.boxes["box_0"]["name"],
                         expected_box["box_0"]["name"])
        self.assertEqual(self.config.boxes["box_0"]["port_view"],
                         expected_box["box_0"]["port_view"])
        self.assertEqual(
            self.config.boxes["box_0"]["show_revision"],
            expected_box["box_0"]["show_revision"],
        )
        self.assertEqual(self.config.boxes["box_0"]["size"],
                         expected_box["box_0"]["size"])