diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 259b486..8536ad8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,20 +1,10 @@ -name: SourceGuard Code Analysis +name: CI Pipeline + on: - push: - branches: - - master + - push + - pull_request jobs: - code-analysis: - runs-on: ubuntu-latest - container: - image: sourceguard/sourceguard-cli - steps: - - name: Scan - uses: CheckPointSW/sourceguard-action@main - with: - SG_CLIENT_ID: ${{ secrets.SG_CLIENT_ID }} - SG_SECRET_KEY: ${{ secrets.SG_SECRET_KEY }} build-n-publish: name: Build and publish Python 🐍 distributions 📦 to PyPI @@ -39,11 +29,11 @@ jobs: --wheel --outdir dist/ . - - name: Publish distribution 📦 to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ +# - name: Publish distribution 📦 to Test PyPI +# uses: pypa/gh-action-pypi-publish@master +# with: +# password: ${{ secrets.TEST_PYPI_API_TOKEN }} +# repository_url: https://test.pypi.org/legacy/ - name: Publish distribution 📦 to PyPI if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@master diff --git a/README.md b/README.md index f8b6788..6b053dd 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ Install the SDK by using the pip tool or by downloading the repository. #### Install with pip Run: ``` +pip install cp-mgmt-api-sdk +``` +Or: +``` pip install git+https://github.com/CheckPointSW/cp_mgmt_api_python_sdk ``` ###### Note: you might be required to use "sudo" for this command. @@ -47,7 +51,7 @@ pip install --upgrade git+https://github.com/CheckPointSW/cp_mgmt_api_python_sdk #### Uninstall Uninstall the SDK by using pip tool: ``` -pip uninstall cpapi +pip uninstall cp-mgmt-api-sdk ``` ###### Note: you might be required to use "sudo" for this command. @@ -62,6 +66,7 @@ export PYTHONPATH=$PYTHONPATH:<“CP-SDK” FULL PATH> ``` For example, if you copied the SDK to the path “/home/admin/” the command will be:
```export PYTHONPATH=$PYTHONPATH:/home/admin/cp_mgmt_api_python_sdk/``` +###### Note: When downloading the repository, directory name will be cp_mgmt_api_python_sdk-master. ## Development Environment The kit is developed using Python versions 2.7 and 3.7 diff --git a/cpapi/api_exceptions.py b/cpapi/api_exceptions.py index 6b6145a..625a01f 100644 --- a/cpapi/api_exceptions.py +++ b/cpapi/api_exceptions.py @@ -15,4 +15,4 @@ def __init__(self, value): class TimeoutException(APIException): def __init__(self, value): - APIException.__init__(self, value, None) \ No newline at end of file + APIException.__init__(self, value, None) diff --git a/cpapi/mgmt_api.py b/cpapi/mgmt_api.py index 3f79ba0..dc42370 100644 --- a/cpapi/mgmt_api.py +++ b/cpapi/mgmt_api.py @@ -42,7 +42,7 @@ class APIClientArgs: def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", http_debug_level=0, api_calls=None, debug_file="", proxy_host=None, proxy_port=8080, api_version=None, unsafe=False, unsafe_auto_accept=False, context="web_api", single_conn=True, - user_agent="python-api-wrapper", sync_frequency=2): + user_agent="python-api-wrapper", sync_frequency=2, cloud_mgmt_id=""): self.port = port # management server fingerprint self.fingerprint = fingerprint @@ -74,6 +74,8 @@ def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", ht self.user_agent = user_agent # Interval size in seconds of the task update self.sync_frequency = sync_frequency + # Smart-1 Cloud management UID + self.cloud_mgmt_id = cloud_mgmt_id class APIClient: @@ -124,6 +126,8 @@ def __init__(self, api_client_args=None): self.user_agent = api_client_args.user_agent # Interval size in seconds of the task update self.sync_frequency = api_client_args.sync_frequency + # Smart-1 Cloud management UID + self.cloud_mgmt_id = api_client_args.cloud_mgmt_id def __enter__(self): return self @@ -175,8 +179,7 @@ def _common_login_logic(self, credentials, continue_last_session, domain, read_o self.api_version = login_res.data["api-server-version"] return login_res - def login_with_api_key(self, api_key, continue_last_session=False, domain=None, read_only=False, - payload=None): + def login_with_api_key(self, api_key, continue_last_session=False, domain=None, read_only=False, payload=None): """ performs a 'login' API call to the management server @@ -271,7 +274,7 @@ def login_as_root(self, domain=None, payload=None): except (WindowsError) as err: raise APIClientException("Could not login as root:\n" + str(type(err)) + " - " + str(err)) - def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout=-1): + def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout=-1, method="POST"): """ performs a web-service API request to the management server @@ -284,6 +287,7 @@ def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout= when wait_for_task=False, it is up to the user to call the "show-task" API and check the status of the command. :param timeout: Optional positive timeout (in seconds) before stop waiting for the task even if not completed. + :param method: The HTTP method to use. Defaults is `POST`. :return: APIResponse object :side-effects: updates the class's uid and server variables """ @@ -318,11 +322,22 @@ def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout= # init https connection. if single connection is True, use last connection conn = self.get_https_connection() - url = "/" + self.context + "/" + (("v" + str(self.api_version) + "/") if self.api_version else "") + command + + url = "" + if self.cloud_mgmt_id != "": + url += "/" + self.cloud_mgmt_id + + url += "/" + self.context + + if self.api_version: + url += "/v" + str(self.api_version) + + url += "/" + command + response = None try: # Send the data to the server - conn.request("POST", url, _data, _headers) + conn.request(method, url, _data, _headers) # Get the reply from the server response = conn.getresponse() res = APIResponse.from_http_response(response) @@ -334,7 +349,8 @@ def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout= res = APIResponse("", False, err_message=err_message) else: res = APIResponse("", False, err_message=err) - except (http_client.CannotSendRequest, http_client.BadStatusLine, ConnectionAbortedError) as e: + except (http_client.CannotSendRequest, http_client.BadStatusLine, + ConnectionAbortedError, BrokenPipeError, IOError) as e: self.conn = self.create_https_connection() self.conn.request("POST", url, _data, _headers) response = self.conn.getresponse() @@ -352,7 +368,10 @@ def api_call(self, command, payload=None, sid=None, wait_for_task=True, timeout= # would not appear as plaintext in the debug file. if command == "login": json_data = compatible_loads(_data) - json_data["password"] = "****" + if "password" in json_data: + json_data["password"] = "****" + if "api-key" in json_data: + json_data["api-key"] = "****" _data = json.dumps(json_data) if self.debug_file: @@ -440,8 +459,8 @@ def gen_api_query(self, command, details_level="standard", container_keys=None, for key in container_keys: all_objects[key] = [] iterations = 0 # number of times we've made an API call - limit = 50 # page size to get for each api call - offset = 0 # skip n objects in the database + limit = 50 # page size to get for each api call + offset = 0 # skip n objects in the database if payload is None: payload = {} else: @@ -576,7 +595,7 @@ def check_tasks_status(task_result): :return: """ for task in task_result.data["tasks"]: - if task["status"] == "failed" or task["status"] == "partially succeeded" or task["status"] == "in progress": + if task["status"] == "failed" or task["status"] == "partially succeeded" or task["status"] == "in progress": task_result.set_success_status(False) break @@ -595,7 +614,7 @@ def check_fingerprint(self): local_fingerprint = self.read_fingerprint_from_file(self.server) server_fingerprint = self.get_server_fingerprint() - #Check if fingerprint is passed and matches + # Check if fingerprint is passed and matches if self.fingerprint == server_fingerprint: return True @@ -732,8 +751,8 @@ def read_fingerprint_from_file(server, filename="fingerprints.txt"): return "" def create_https_connection(self): - context = ssl.create_default_context() - context.check_hostname = True + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS) + context.verify_mode = ssl.CERT_NONE # create https connection if self.proxy_host and self.proxy_port: conn = HTTPSConnection(self.proxy_host, self.proxy_port, context=context) @@ -768,7 +787,7 @@ class HTTPSConnection(http_client.HTTPSConnection): """ def connect(self): http_client.HTTPConnection.connect(self) - self.sock = ssl.wrap_socket(self.sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) + self.sock = self._context.wrap_socket(self.sock, server_hostname=self.host) def get_fingerprint_hash(self): if self.sock is None: diff --git a/setup.py b/setup.py index 8f61347..b35bd99 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name="cp-mgmt-api-sdk", - version="1.4.0", + version="1.9.0", author="API team", author_email="api_team@checkpoint.com", license='Apache 2.0',