summaryrefslogtreecommitdiffstats
path: root/eos_downloader/cvp.py
blob: 678daa8b890b10de0a78dd5c63bfc888df4e71f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#!/usr/bin/python
# coding: utf-8 -*-

"""
CVP Uploader content
"""

import os
from dataclasses import dataclass
from typing import Any, List, Optional

from cvprac.cvp_client import CvpClient
from cvprac.cvp_client_errors import CvpLoginError
from loguru import logger

# from eos_downloader.tools import exc_to_str

# logger = logging.getLogger(__name__)


@dataclass
class CvpAuthenticationItem:
    """
    Data structure to represent Cloudvision Authentication
    """

    server: str
    port: int = 443
    token: Optional[str] = None
    timeout: int = 1200
    validate_cert: bool = False


class Filer:
    # pylint: disable=too-few-public-methods
    """
    Filer Helper for file management
    """

    def __init__(self, path: str) -> None:
        self.file_exist = False
        self.filename = ""
        self.absolute_path = ""
        self.relative_path = path
        if os.path.exists(path):
            self.file_exist = True
            self.filename = os.path.basename(path)
            self.absolute_path = os.path.realpath(path)

    def __repr__(self) -> str:
        return self.absolute_path if self.file_exist else ""


class CvFeatureManager:
    """
    CvFeatureManager Object to interect with Cloudvision
    """

    def __init__(self, authentication: CvpAuthenticationItem) -> None:
        """
        __init__ Class Creator

        Parameters
        ----------
        authentication : CvpAuthenticationItem
            Authentication information to use to connect to Cloudvision
        """
        self._authentication = authentication
        # self._cv_instance = CvpClient()
        self._cv_instance = self._connect(authentication=authentication)
        self._cv_images = self.__get_images()
        # self._cv_bundles = self.__get_bundles()

    def _connect(self, authentication: CvpAuthenticationItem) -> CvpClient:
        """
        _connect Connection management

        Parameters
        ----------
        authentication : CvpAuthenticationItem
            Authentication information to use to connect to Cloudvision

        Returns
        -------
        CvpClient
            cvprac session to cloudvision
        """
        client = CvpClient()
        if authentication.token is not None:
            try:
                client.connect(
                    nodes=[authentication.server],
                    username="",
                    password="",
                    api_token=authentication.token,
                    is_cvaas=True,
                    port=authentication.port,
                    cert=authentication.validate_cert,
                    request_timeout=authentication.timeout,
                )
            except CvpLoginError as error_data:
                logger.error(
                    f"Cannot connect to Cloudvision server {authentication.server}"
                )
                logger.debug(f"Error message: {error_data}")
        logger.info("connected to Cloudvision server")
        logger.debug(f"Connection info: {authentication}")
        return client

    def __get_images(self) -> List[Any]:
        """
        __get_images Collect information about images on Cloudvision

        Returns
        -------
        dict
            Fact returned by Cloudvision
        """
        images = []
        logger.debug("  -> Collecting images")
        images = self._cv_instance.api.get_images()["data"]
        return images if self.__check_api_result(images) else []

    # def __get_bundles(self):
    #     """
    #     __get_bundles [Not In use] Collect information about bundles on Cloudvision

    #     Returns
    #     -------
    #     dict
    #         Fact returned by Cloudvision
    #     """
    #     bundles = []
    #     logger.debug('  -> Collecting images bundles')
    #     bundles = self._cv_instance.api.get_image_bundles()['data']
    #     # bundles = self._cv_instance.post(url='/cvpservice/image/getImageBundles.do?queryparam=&startIndex=0&endIndex=0')['data']
    #     return bundles if self.__check_api_result(bundles) else None

    def __check_api_result(self, arg0: Any) -> bool:
        """
        __check_api_result Check API calls return content

        Parameters
        ----------
        arg0 : any
            Element to test

        Returns
        -------
        bool
            True if data are correct False in other cases
        """
        logger.debug(arg0)
        return len(arg0) > 0

    def _does_image_exist(self, image_name: str) -> bool:
        """
        _does_image_exist Check if an image is referenced in Cloudvision facts

        Parameters
        ----------
        image_name : str
            Name of the image to search for

        Returns
        -------
        bool
            True if present
        """
        return (
            any(image_name == image["name"] for image in self._cv_images)
            if isinstance(self._cv_images, list)
            else False
        )

    def _does_bundle_exist(self, bundle_name: str) -> bool:
        # pylint: disable=unused-argument
        """
        _does_bundle_exist Check if an image is referenced in Cloudvision facts

        Returns
        -------
        bool
            True if present
        """
        # return any(bundle_name == bundle['name'] for bundle in self._cv_bundles)
        return False

    def upload_image(self, image_path: str) -> bool:
        """
        upload_image Upload an image to Cloudvision server

        Parameters
        ----------
        image_path : str
            Path to the local file to upload

        Returns
        -------
        bool
            True if succeeds
        """
        image_item = Filer(path=image_path)
        if image_item.file_exist is False:
            logger.error(f"File not found: {image_item.relative_path}")
            return False
        logger.info(f"File path for image: {image_item}")
        if self._does_image_exist(image_name=image_item.filename):
            logger.error(
                "Image found in Cloudvision , Please delete it before running this script"
            )
            return False
        try:
            upload_result = self._cv_instance.api.add_image(
                filepath=image_item.absolute_path
            )
        except Exception as e:  # pylint: disable=broad-exception-caught
            logger.error("An error occurred during upload, check CV connection")
            logger.error(f"Exception message is: {e}")
            return False
        logger.debug(f"Upload Result is : {upload_result}")
        return True

    def build_image_list(self, image_list: List[str]) -> List[Any]:
        """
        Builds a list of the image data structures, for a given list of image names.
        Parameters
        ----------
        image_list : list
            List of software image names
        Returns
        -------
        List:
            Returns a list of images, with complete data or None in the event of failure
        """
        internal_image_list = []
        image_data = None
        success = True

        for entry in image_list:
            for image in self._cv_images:
                if image["imageFileName"] == entry:
                    image_data = image

            if image_data is not None:
                internal_image_list.append(image_data)
                image_data = None
            else:
                success = False

        return internal_image_list if success else []

    def create_bundle(self, name: str, images_name: List[str]) -> bool:
        """
        create_bundle Create a bundle with a list of images.

        Parameters
        ----------
        name : str
            Name of the bundle
        images_name : List[str]
            List of images available on Cloudvision

        Returns
        -------
        bool
            True if succeeds
        """
        logger.debug(
            f"Init creation of an image bundle {name} with following images {images_name}"
        )
        all_images_present: List[bool] = []
        self._cv_images = self.__get_images()
        all_images_present.extend(
            self._does_image_exist(image_name=image_name) for image_name in images_name
        )
        # Bundle Create
        if self._does_bundle_exist(bundle_name=name) is False:
            logger.debug(
                f"Creating image bundle {name} with following images {images_name}"
            )
            images_data = self.build_image_list(image_list=images_name)
            if images_data is not None:
                logger.debug("Images information: {images_data}")
                try:
                    data = self._cv_instance.api.save_image_bundle(
                        name=name, images=images_data
                    )
                except Exception as e:  # pylint: disable=broad-exception-caught
                    logger.critical(f"{e}")
                else:
                    logger.debug(data)
                return True
            logger.critical("No data found for images")
        return False