GithubHelp home page GithubHelp logo

checkpointsw / cpansible Goto Github PK

View Code? Open in Web Editor NEW
67.0 28.0 26.0 60 KB

Ansible module provides control over a Check Point Management server using Check Point's web-services APIs.

License: Apache License 2.0

Python 100.00%
management-api gaia-api

cpansible's Introduction

Ansible Module - check_point_mgmt by Check Point®

Note

This repository is being deprecated.
Starting with Ansible 2.9 release, users are encouraged to use the official Check Point integration.
For more details, see:
https://www.ansible.com/cybersecurity-automation-and-prevention-with-check-point-and-ansible
There are two ways to obtain the official Check Point integration:

  1. Download the official Check Point Management API modules collection from the Ansible Galaxy: https://galaxy.ansible.com/check_point/mgmt (recommended)
  2. Use the Check Point Management API modules included in the core of Ansible 2.9.

Installation instructions

  1. Clone the repository with this command:
git clone https://github.com/CheckPointSW/cpAnsible

or by clicking the Download ZIP button.
2. Download and install the Check Point API Python SDK repository, follow the instructions in the SDK repository.
3. Install Ansible.
4. Install a Python interpreter with version >= 2.7.9, but not Python 3 or above.
5. In your /etc/ansible/ansible.cfg file, there is a library line, uncomment it and set it to be whatever you want, this will be your library folder for modules.
6. Move the check_point_mgmt folder to your library folder.
7. Edit /etc/ansible/hosts so that it would contain a section similar to this one:

[localhost]
127.0.0.1
[localhost:vars]
ansible_user=[a username with SSH access to the ansible server, not the Check Point server]
ansible_ssh_pass=[password]
ansible_python_interpreter=[path to the Python installation (>=2.7.9 and < 3.0) on the Ansible server]
# Optional (variables detailing the Check Point's management server access):
mgmt_server=[management server's IP address. In case of a multi-domain setup, provide the IP address of the MDS]
mgmt_user=[Check Point admin username]
mgmt_password=[Check Point admin password]

Usage

Run a playbook:

ansible-playbook your_ansible_playbook.yml

or

Run a playbook in "check mode":

ansible-playbook -C your_ansible_playbook.yml

Before connecting to a Check Point management server for the first time, follow the instructions in step #4. Otherwise, an "unverified server" error could appear.

Description

This Ansible module provides control over a Check Point management server using Check Point's web-services APIs. The web-services API reference can be found here: https://sc1.checkpoint.com/documents/latest/APIs/index.html#ws~v1.2%20.

A typical ansible command in a playbook should look like this:

- name: "adding a demo host"
  check_point_mgmt:
    command: add-host                     # web-service command name.
    parameters:                           # The web-service request arguments.
                                          # Note that the API web-services samples use JSON format.
                                          # Ansible requires these arguments to use YAML format.
      name: "host_demo2"
      ip-address: "1.2.3.5"
    session-data: "{{ login_response }}"  # where {{ login_response }} is received from
                                          # the login command that was called previously.
                                          # This replaces the need for the HTTP
                                          # headers that are mentioned in the API reference.

Notes:

  1. Because this Ansible module is controlling the management server remotely via the web API, the ansible server needs to have access to the Check Point API server. Open SmartConsole, navigate to "Manage & Settings > Blades > Management API > Advanced settings" and check the API server's accessibility settings.

  2. The ansible "hosts" field in the playbook should refer to the Ansible machine (i.e. 127.0.0.1), there is no need to ssh to the management server, the commands are sent to the management server as API web-service requests.

  3. Asynchronous commands - A few Check Point APIs run asynchronously, for example: publish, install-policy and run-script. By default, all commands in an ansible playbook will run synchronously. In other words, the ansible playbook will wait as much time as needed for the command to complete, before moving to the next command. If you need to override this default behavior and run the command in asynchronous manner, use Ansible's "async: <timeout_in_seconds>" option, for more info: http://docs.ansible.com/ansible/playbooks_async.html

  4. Ansible has a feature called "Check Mode" that enables you to test the changes without actually changing anything. When running in Ansible's "check mode", calling Check Point's "publish" API would actually call Check Point's "discard" API. This would allow you to test your script without making changes in the Check Point database and without keeping objects in the database locked. In this mode, the "install-policy", "run-script" and "add-domain" APIs will be skipped.

  5. Logout - The last task in your playbook should typically be logout, to cleanly close the session, unless you intend otherwise. Simple example:

- name: logout
  check_point_mgmt:
    command: logout
    session-data: '{{login_response}}'

Every communication with the Check Point management server must start with a "login" command. The login command takes some parameters that are not listed in the API reference, The list of the parameters login takes can be seen in the options section:

Example of a login task:
```yaml
- name: "login task"
  check_point_mgmt:
    command: login
    parameters:
      username: user1
      password: pass1
      management: 192.168.1.193
    fingerprint: "7D:FE:DE:EE:C7:B9:D0:67:35:E4:C4:16:EC:7A:03:13:48:CD:CA:8D"
  register: login_response    # Register the output from the login command so
                              # it can later be used by subsequent commands.

You must add Ansible's "register" field to the Login task so that other management APIs could continue that session.

  - name: "adding a demo host"
    check_point_mgmt:
      command: add-host                     # web-service command name.
      parameters:                           # The web-service request arguments.
                                            # Note that the API web-services samples use JSON format.
                                            # Ansible requires these arguments to use YAML format.
        name: "host_demo2"
        ip-address: "1.2.3.5"
      session-data: "{{ login_response }}"  # The session data we received from
                                            # the login command is used here.
                                            # This replaces the need for the HTTP
                                            # headers that are mentioned in the API reference.

Before communicating with a Check Point management server for the first time

To keep the connection secure, the ansible server should trust the Check Point server certificate. In a typical deployment, the Check Point server is using a self-signed certificate (that should not to be trusted).

In order to make the ansible server trust the Check Point certificate, follow these steps:

  1. Use console access, or some other means of trusted communication to log into the Check Point server.
  2. On the Check Point server, run "api fingerprint". A typical response, should look like this:
    Fingerprint:
    SHA1: 7E:FF:DE:CE:C7:B9:D0:67:35:E4:C4:16:EC:7A:03:13:48:CD:CA:8D
    Using English words: FARM WAND MIMI GOWN HURD PHI QUO LOY BAH SEES JADE GAUL
    
  3. Copy the SHA1 fingerprint and pass it as an argument to the check_point_mgmt module in the first task of your playbook (login). Example:
    - name: "login task"
      check_point_mgmt:
        command: login
        parameters:
          username: user1
          password: pass1
          management: 192.168.1.123
        fingerprint: "7E:FF:DE:CE:C7:B9:D0:67:35:E4:C4:16:EC:7A:03:13:48:CD:CA:8D"
      register: login_response
    Note: After you do this once and run the playbook, the fingerprint will be saved in a fingerprints.txt file in the current working directory, so there is no need to do this procedure again, unless you move the playbook file.

Requirements

  • The Check Point server should be using R80 or above
  • The Check Point server should be open for API communication from the ansible server. Open SmartConsole ans check "Manage & Settings > Blades > Management API > Advanced settings".
  • The Ansible server's Python version should be 2.7.9 or higher (but not Python 3).

Options

command - the command to run on the management server (Required)
parameters - The parameters for the command (given as a dictionary - key: value)
fingerprint - Fingerprint to verify the server's fingerprint with (Unncesseray to give this after the login task as it is stored in session-data).
session-data - After logging in, use this variable to give the output of the login command, including details such as the session id, the management server's IP and port, the domain to log into, and the fingerprint.

Special case for the command 'login':

parameters:

management - IP address of the management server to control.
domain - Log in to this domain on the management server.
port - Port to connect through to the management server (Default: 443).
username - Check Point admin username
password - Check Point admin password

Example playbook

---
- hosts: "localhost"                        # Note #2 in the Description section
  tasks:
  - name: "login"                           # You have to login to the management
                                            # server before running any commands
    check_point_mgmt:
      command: login
      parameters:
        username: "{{mgmt_user}}"           # Variables set in /etc/ansible/hosts, to avoid needing
        password: "{{mgmt_password}}"       # to type your login details in every playbook.
        management: "{{mgmt_server}}"
      fingerprint: "C3:B4:54:8D:0E:C0:7E:D4:31:64:94:13:F5:14:CD:93:68:6A:4F:4D"
    register: login_response                # Register the output from the login
                                            # command so we can use it later to run commands.
  - name: "add host"
    check_point_mgmt:
      command: add-host                     # Name of the command
      parameters:                           #  The parameters for it, in dictionary form
        name: "host_demo"
        ip-address: "1.2.3.5"
      session-data: "{{ login_response }}"  # The session data we received from
                                            # the login command is used here to run 'add-host'
  - name: "add group"
    check_point_mgmt:
      command: add-group
      parameters:
        name: "group_demo"
        members:
          - "host_demo"
      session-data: "{{ login_response }}"
  - name: "publish"                         # Publishing is important if you want
                                            # your changes to be saved.
    check_point_mgmt:                       # This will actually 'discard' when
                                            # check mode is enabled (ansible-playbook -C)
                                            # unless you add 'always_run: yes' to the task.
      command: publish
      session-data: "{{login_response}}"

cpansible's People

Contributors

chkp-niram avatar chkp-orso avatar chkp-rdecker avatar chkp-roniz avatar chkp-ubialik avatar chkp-yaelg avatar chkp-yuvalfe avatar martin4kansas avatar methadata avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cpansible's Issues

run-script with multiple tragets

Hello Team,

I am trying to run run-script with multiple target firewalls, is this possible if so how we can add the variable values?

Python version requirements

Hi!

README contains the requirement:

  1. Install a Python interpreter with version >= 2.7.9, but not Python 3 or above.

I'm trying to operate with cpAnsible module from virtualenv with Python 3.5.2 and at first glance it works correct. Is there any obvious or hidden reasons to do not use Python 3 with cpAnsible module?

Run-script fails for scripts that include quotation marks

I am trying to run the following playbook:


  • hosts: "localhost"
    vars_files:
    • r80_vars.yml
      tasks:

    • name: "login"
      check_point_mgmt:
      command: login
      parameters:
      username: "{{mgmt_user}}"
      password: "{{mgmt_password}}"
      management: "{{mgmt_server}}"
      port: 8443
      domain: System Data
      fingerprint: "{{mgmt_fingerprint}}"
      register: login_response

    • name: "Check Core Dumps"
      check_point_mgmt:
      command: run-script
      parameters:
      script-name: Check Core Dumps
      script: clish -c 'show core-dump status'
      targets: "{{target_firewall}}"
      session-data: "{{login_response}}"

    • name: "publish"
      check_point_mgmt:
      command: publish
      session-data: "{{login_response}}"

    • name: "logout"
      check_point_mgmt:
      command: logout
      session-data: "{{login_response}}"

I get the following result using verbosity 3:

TASK [Check Core Dumps] *********************************************************************************************************************
task path: /mnt/c/Users/jm62602/Documents/CheckMates_Aug15_Demos/Ansible-R80-Scripts/GoldenImageScan.yml:18
Using module file /home/jordanmartin/lib/check_point_mgmt/check_point_mgmt.py
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansible/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<127.0.0.1> (0, '/home/jordanmartin\n', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansible/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "echo /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365" && echo ansible-tmp-1531854944.83-25136561340365="echo /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365" ) && sleep 0'"'"''
<127.0.0.1> (0, 'ansible-tmp-1531854944.83-25136561340365=/home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365\n', '')
<127.0.0.1> PUT /tmp/tmpYlRoGn TO /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/check_point_mgmt.py
<127.0.0.1> SSH: EXEC sshpass -d13 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansible/cp/8239a62529 '[127.0.0.1]'
<127.0.0.1> (0, 'sftp> put /tmp/tmpYlRoGn /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/check_point_mgmt.py\n', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansible/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'chmod u+x /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/ /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/check_point_mgmt.py && sleep 0'"'"''
<127.0.0.1> (0, '', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansible/cp/8239a62529 -tt 127.0.0.1 '/bin/sh -c '"'"'/usr/bin/python /home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/check_point_mgmt.py; rm -rf "/home/jordanmartin/.ansible/tmp/ansible-tmp-1531854944.83-25136561340365/" > /dev/null 2>&1 && sleep 0'"'"''
<127.0.0.1> (0, 'Traceback (most recent call last):\r\n File "/tmp/ansible_WCvZIz/ansible_module_check_point_mgmt.py", line 250, in \r\n main()\r\n File "/tmp/ansible_WCvZIz/ansible_module_check_point_mgmt.py", line 131, in main\r\n parameters = json.loads(parameters)\r\n File "/usr/lib/python2.7/json/init.py", line 339, in loads\r\n return _default_decoder.decode(s)\r\n File "/usr/lib/python2.7/json/decoder.py", line 364, in decode\r\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\r\n File "/usr/lib/python2.7/json/decoder.py", line 380, in raw_decode\r\n obj, end = self.scan_once(s, idx)\r\nValueError: Expecting property name: line 1 column 2 (char 1)\r\n', 'Shared connection to 127.0.0.1 closed.\r\n')
fatal: [127.0.0.1]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Shared connection to 127.0.0.1 closed.\r\n",
"module_stdout": "Traceback (most recent call last):\r\n File "/tmp/ansible_WCvZIz/ansible_module_check_point_mgmt.py", line 250, in \r\n main()\r\n File "/tmp/ansible_WCvZIz/ansible_module_check_point_mgmt.py", line 131, in main\r\n parameters = json.loads(parameters)\r\n File "/usr/lib/python2.7/json/init.py", line 339, in loads\r\n return _default_decoder.decode(s)\r\n File "/usr/lib/python2.7/json/decoder.py", line 364, in decode\r\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\r\n File "/usr/lib/python2.7/json/decoder.py", line 380, in raw_decode\r\n obj, end = self.scan_once(s, idx)\r\nValueError: Expecting property name: line 1 column 2 (char 1)\r\n",
"msg": "MODULE FAILURE",
"rc": 0
}

Any insights or examples would be great. Thanks!

Unable to run playbook

Hi,
I am running a basic playbook against the Management Server but getting error of Authentication Failure even the credentials are correct and working fine, can someone help on how i can debug the issue and resolve it.

Ansible to checkpoint No module named cpapi\n" "msg": "MODULE FAILURE!

Ansible to checkpoint wih R80.10 and ansible HFA and i am having issues using https://github.com/CheckPointSw/cpAnsible
using the example from there with out using the hosts file...

ansible --version
ansible 2.9.3
config file = /root/xxxxx/ansible.cfg
configured module search path = [u'/etc/ansible']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

Example playbook

  • hosts: "localhost" # Note #2 in the Description section
    tasks:
    • name: "login" # You have to login to the management
      # server before running any commands
      check_point_mgmt:
      command: login
      parameters:
      username: "{{z}" # Variables set in /etc/ansible/hosts, to avoid needing
      password: "{{y}}" # to type your login details in every playbook.
      management: "{{x}}"
      fingerprint: "xx"
      register: login_response # Register the output from the login
      # command so we can use it later to run commands.
    • name: "add host"
      check_point_mgmt:
      command: add-host # Name of the command
      parameters: # The parameters for it, in dictionary form
      name: "host_demo"
      ip-address: "1.2.3.5"
      session-data: "{{ login_response }}" # The session data we received from
      # the login command is used here to run 'add-host'
    • name: "add group"
      check_point_mgmt:
      command: add-group
      parameters:
      name: "group_demo"
      members:
      - "host_demo"
      session-data: "{{ login_response }}"
    • name: "publish" # Publishing is important if you want
      # your changes to be saved.
      check_point_mgmt: # This will actually 'discard' when
      # check mode is enabled (ansible-playbook -C)
      # unless you add 'always_run: yes' to the task.
      command: publish
      session-data: "{{login_response}}"

Error
The full traceback is:
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1582234960.1-32781520738983/AnsiballZ_che ck_point_mgmt.py", line 102, in
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1582234960.1-32781520738983/AnsiballZ_che ck_point_mgmt.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/root/.ansible/tmp/ansible-tmp-1582234960.1-32781520738983/AnsiballZ_che ck_point_mgmt.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible.modules.check_point_mgmt', init_globals=N one, run_name='main', alter_sys=True)
File "/usr/lib64/python2.7/runpy.py", line 176, in run_module
fname, loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 82, in _run_module_code
mod_name, mod_fname, mod_loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/tmp/ansible_check_point_mgmt_payload_Uz8c7z/ansible_check_point_mgmt_pa yload.zip/ansible/modules/check_point_mgmt.py", line 8, in
ImportError: No module named cpapi

fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File "/root/.ansibl e/tmp/ansible-tmp-1582234960.1-32781520738983/AnsiballZ_check_point_mgmt.py", l ine 102, in \n _ansiballz_main()\n File "/root/.ansible/tmp/ansible -tmp-1582234960.1-32781520738983/AnsiballZ_check_point_mgmt.py", line 94, in _a nsiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n Fil e "/root/.ansible/tmp/ansible-tmp-1582234960.1-32781520738983/AnsiballZ_check_p oint_mgmt.py", line 40, in invoke_module\n runpy.run_module(mod_name='ansibl e.modules.check_point_mgmt', init_globals=None, run_name='main', alter_sys=T rue)\n File "/usr/lib64/python2.7/runpy.py", line 176, in run_module\n fna me, loader, pkg_name)\n File "/usr/lib64/python2.7/runpy.py", line 82, in _ru n_module_code\n mod_name, mod_fname, mod_loader, pkg_name)\n File "/usr/lib 64/python2.7/runpy.py", line 72, in _run_code\n exec code in run_globals\n File "/tmp/ansible_check_point_mgmt_payload_Uz8c7z/ansible_check_point_mgmt_pay load.zip/ansible/modules/check_point_mgmt.py", line 8, in \nImportError : No module named cpapi\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}

PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 s kipped=0 rescued=0 ignored=0

Session-timeout parameter not working (proposed fix included)

During the login step, the Session-timeout parameter is not applied. The login commands gets into a specific conditionnal, and a bunch of parameters available in the mgmt_cli or others are simpliy not added in this call.

Proposed fix

In check_point_mgmt.py, main():, look for the **timeout ** and **payload ** sections

def main():
    global was_changed
    # Initializing parameters to variables:
    command = module.params["command"]
    parameters = module.params.get("parameters")
    session_data = module.params.get("session-data")
    fingerprint = module.params.get("fingerprint")
    if parameters:
        parameters = json.loads(parameters.replace("'", '"'))
    if command == "login":
        # Login parameters:
        username = parameters.get("user", parameters.get("username"))
        password = parameters.get("pass", parameters.get("password"))
        management = parameters.get("management", "127.0.0.1")
        port = parameters.get("port", 443)
        domain = parameters.get("domain")
        timeout = parameters.get("session-timeout", 600)
        payload = {"session-timeout": timeout}
        client_args = APIClientArgs(server=management, port=port)
        client = APIClient(client_args)
        # Validate fingerprint:
        validate_fingerprint(client, fingerprint)
        # Tries to login:
        login_res = client.login(username=username, password=password, domain=domain, payload=payload)

A double check for the other login parameters available should be done, or something more general to make sure the login function always use every parameter available.

Idempotence/Skip over errors

A common requirement for Anisble implementations is the ability to run many times and get the same result... e.g. If creating a file that is already there in the desired state, ansible skips to the next step.]

The cpAnsible library doesnt follow this pattern. For example if I run a playbook to create Checkpoint object, then run it again, it will fail the second time (and also seems to invalidate the session).

Are there any tips for ensuring the runs are re-runnable? Even skipping on to the next step would be useful. I tried the standard ansible option of ignore_errors: yes.... but the next API call is bounced as the session is invalid post error. Any suggestions?

How to use show-changes

Hi,
First off thanks for the module.
I've made a playbook that first checks for existing objects, then creates missing objects I need if they don't exist. It works.
Now instead of registering all changes along the way and compiling a list, I would like to use "show-changes" https://sc1.checkpoint.com/documents/latest/APIs/index.html#web/show-changes~v1.1%20 .
I just can't seem to get it to work.
I've tried the following:

  - name: show changes
    check_point_mgmt:
      command: show-changes
      parameters:
        from-session: "{{ showsession.response.uid }}"
        to-session: "{{ showsession2.response.uid }}"
        limit: 500
      session-data: '{{ login_response }}'

If I run above with only from session (=same session), I get 0 changes back. A diff on the same session would give 0 so that's expected - but I do get a valid response from the API.
My thought was then to
login -> show-session (get uid for this session) -> logout
login again -> show-session (get uid of this second session) -> do all changes (publish shows "numberOfPublishedChanges": 200)
-> show-changes
However, done with from-session and to-session I get:

"code": "generic_err_object_not_found"
"message": "Work Session with UID <uid here>"

The session it cannot find is the second session. I've tried making a 3rd session that gets changes from the previous two, same error the session with the changes can't be found.
Any pointers?
Thanks in advance

Unable to Run Playbook - error - ImportError: No module named cpapi

Hi all,

I facing error when integrating Ansible with checkpoint Management Server. I followed Ansible deployment guide. I get below error when running playbook.

ankur@ankur-virtual-machine:~/71442b35e6e8d830e19f776a7b1b6cc8$ ansible-playbook ansible-cp-test.yml

PLAY [GW] ******************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [127.0.0.1]

TASK [login] ***************************************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File "/home/ankur/.ansible/tmp/ansible-tmp-1561291034.04-84766382214963/AnsiballZ_check_point_mgmt.py", line 114, in \r\n _ansiballz_main()\r\n File "/home/ankur/.ansible/tmp/ansible-tmp-1561291034.04-84766382214963/AnsiballZ_check_point_mgmt.py", line 106, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File "/home/ankur/.ansible/tmp/ansible-tmp-1561291034.04-84766382214963/AnsiballZ_check_point_mgmt.py", line 49, in invoke_module\r\n imp.load_module('main', mod, module, MOD_DESC)\r\n File "/tmp/ansible_check_point_mgmt_payload_Z3CJEO/main.py", line 8, in \r\nImportError: No module named cpapi\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP *****************************************************************************************************************************************************************
127.0.0.1 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

I already copied cp_mgmt_api_python_sdk in path and imported it as well through python interpreter.

Below is the host file:

db-[99:101]-node.example.com

[GW]
127.0.0.1
[GW:vars]
ansible_user=ankur
mgmt_server=192.168.155.20
appliance_name=GW
ansible_python_interpreter=/usr/bin/python2.7
mgmt_user=admin
mgmt_password=vpn123
fingerprint=70:7C:35:40:15:8E:78:0A:A8:64:76:23:3C:1D:46:E5:6B:ED:E2:EA

Kindly help.

add-host command is returning invalid JSON response

i'm using a playbook akin to this (redacted variables where needed):

- name: "login task"
 hosts: localhost
 connection: local
 tasks:
 - name: login to mgmt
   check_point_mgmt:
     command: login
     parameters:
       username: "{{mgmt_user}}"
       password: "{{mgmt_password}}"
       management: <mgmt_ip>
     fingerprint: <fingerpring obtained from running playbook with -C option>
   register: login_response
 - name: adding a demo host
   check_point_mgmt:
     command: add-host
     parameters:
       name: <hostname>
       ip-address: <host_ip>
     session-data: "{{ login_response }}"
 - name: logout
   check_point_mgmt:
     command: logout
     session-data: '{{login_response}}'

and i'm getting a response like this:

fatal: [172.31.250.11]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "command": "add-host",
            "fingerprint": null,
            "parameters": "{'name': '<hostname>', 'ip-address': '<host_ip>'}",
            "session-data": "{'failed': False, 'changed': False, 'response': {'url': '<mgmt_ip>:443', 'domain': None, 'sid': None, 'fingerprint': <fingerpring obtained from running playbook with -C option>}}"
        }
    },
    "msg": "Command 'add-host {u'name': u'<hostname>', u'ip-address': u'<host_ip>'}' failed with error message: APIResponse received a response which is not a valid JSON.. All changes are discarded and the session is invalidated."
}

note that the login task is successful. am i missing something or is this a bug?

EDIT: found this issue under closed ones...

SOLUTION:
API was not activated on the management server, only on the firewall nodes that i was using to access the management server.

Module says fingerprint is empty but it's not

I'm running this task inside of a playbook

---
  - name: "loggin in to the server"
    check_point_mgmt:
      command: login
      parameters:
        username: "admin"
        password: "admin123"
        management: "192.168.1.123"
      fingerprint:  "41:7C:ED:4D:2E:F6:E4:C6:ED:D1:74:EB:A5:8D:41:7F:F9:0E:AF:AF"
    register: login_response

And the response from the module is:

TASK [loggin in to the server] **************************************************************************************************************************************************************************************************************
[WARNING]: The value {'username': 'admin', 'management': '192.168.1.123', 'password': 'admin123'} (type dict) in a string field was converted to u"{'username': 'admin', 'management': '192.168.1.123', 'password': 'admin123'}" (type
string). If this does not look like what you expect, quote the entire value to ensure it does not change.

fatal: [localhost]: FAILED! => {"changed": false, "msg": "Cannot operate on an unverified server. Please verify the server's fingerprint: '' and add it via the 'fingerprint' option of this module."}

Module Failure

Nice module, i just have to figure out how it works... i was doing some testing, but got stuck in this error:

TASK [login] *******************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File "/tmp/ansible_OUVfcL/ansible_module_check_point_mgmt.py", line 8, in \r\n from cp_mgmt_api_python_sdk.lib import APIClient, APIClientArgs\r\nImportError: No module named cp_mgmt_api_python_sdk.lib\r\n", "msg": "MODULE FAILURE", "rc": 0}

Any advice on how to fix this?

Read only?

Hi all,

just a question, is it possible to get only information?
To read the current rules and objects?

Can you show an example with ansible?

Thank you
starflighter

Fingerprint error when executing playbook

Greetings,

I've been playing with the module in hopes of leveraging this to add hosts to a group, but get the following message:

fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"command": "login",
"fingerprint": "33:4B:04:AF:D8:85:20:F6:B0:75:28:ED:06:DE:C7:AB:67:65:18:5E",
"parameters": "{'username': 'XXXXXX', 'management': 'XXXXXXXX', 'password': 'XXXXXXX'}",
"session-data": null
}
}
}

MSG:

Cannot operate on an unverified server. Please verify the server's fingerprint: 'A0B10324AA4EB32B18F2FB2DEAF854433D5183B7' and add it via the 'fingerprint' option of this module.

I'm running this within a Vagrant machine against a management server in AWS if that makes a difference. My playbook is essentially the same as some of the examples provided:


  • hosts: localhost
    connection: local
    gather_facts: false

    tasks:

    • name: login
      check_point_mgmt:
      command: login
      parameters:
      username: "{{ cp_mgmt_admin_username }}"
      password: "{{ cp_mgmt_admin_password }}"
      management: "{{ cp_mgmt_public_ip }}"
      fingerprint: "{{ cp_mgmt_fingerprint }}"
      register: login_response

    • name: white listing host
      check_point_mgmt:
      command: add host
      parameters:
      name: "DD_Test_Host"
      ip-address: "192.168.1.1"
      session-data: "{{ login_response }}"

    • name: add host to group
      check_point_mgmt:
      command: add group
      parameters:
      name: "PIN_Group_Demo"
      members:
      - "DD_Test_Host"
      session-data: "{{ login_response }}"

    • name: publish changes
      check_point_mgmt:
      command: publish
      session-data: "{{ login_response }}"

    • name: install policy
      check_point_mgmt:
      command: install-policy
      parameters:
      policy-package: "Standard"
      session-data: "{{login_response}}"

Not sure why this would see the fingerprint for the management server change since I have confirmed that this is static. Each time it is ran this essentially comes back with a new fingerprint and halts the playbook.

I'm at a loss on how I can get this to work and any help is appreciated.

Thanks,
David

Run-script fails as requested object is not found

Here is my playbook:

  • hosts: "localhost"
    vars_files:
    • r80_vars.yml
      tasks:

    • name: "Login"
      check_point_mgmt:
      command: login
      parameters:
      username: "{{mgmt_user}}"
      password: "{{mgmt_password}}"
      management: "{{mgmt_server}}"
      port: 8443
      domain: System Data
      fingerprint: "{{mgmt_fingerprint}}"
      register: login_response

    • name: "Create output file"
      check_point_mgmt:
      command: run-script
      parameters:
      script-name: "Create output file"
      script: "touch output.txt"
      targets: "ztestintfw1"
      session-data: "{{login_response}}"

    • name: "Publish"
      check_point_mgmt:
      command: publish
      session-data: "{{login_response}}"

    • name: "Logout"
      check_point_mgmt:
      command: logout
      session-data: "{{login_response}}"

The response I get when using verbosity 3 is:

PLAY [localhost] ****************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************ok: [127.0.0.1]

TASK [login] ********************************************************************************************************************************ok: [127.0.0.1]

TASK [Check Core Dumps] *********************************************************************************************************************fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed": true, "msg": "Command 'run-script {u'script-name': u'List files', u'script': u'ls'}' failed with error message: Missing parameter: [targets]. All changes are discarded and the session is invalidated."}
to retry, use: --limit @/mnt/c/Users/jm62602/Documents/CheckMates_Aug15_Demos/Ansible-R80-Scripts/GoldenImageScan.retry

PLAY RECAP **********************************************************************************************************************************127.0.0.1 : ok=2 changed=0 unreachable=0 failed=1

TASK [Create output file] ***************************************************************************************************************************************************************************
task path: /mnt/c/Users/jm62602/Documents/CheckMates_Aug15_Demos/Ansible-R80-Scripts/GoldenImageScan.yml:18
Using module file /home/jordanmartin/lib/check_point_mgmt/check_point_mgmt.py
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansibl
e/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<127.0.0.1> (0, '/home/jordanmartin\n', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansibl
e/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "echo /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574" && echo ansible-tmp-1531938210.39-8226925687057
4="echo /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574" ) && sleep 0'"'"''
<127.0.0.1> (0, 'ansible-tmp-1531938210.39-82269256870574=/home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574\n', '')
<127.0.0.1> PUT /tmp/tmpGLVEwn TO /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574/check_point_mgmt.py
<127.0.0.1> SSH: EXEC sshpass -d13 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/hom
e/jordanmartin/.ansible/cp/8239a62529 '[127.0.0.1]'
<127.0.0.1> (0, 'sftp> put /tmp/tmpGLVEwn /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574/check_point_mgmt.py\n', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansibl
e/cp/8239a62529 127.0.0.1 '/bin/sh -c '"'"'chmod u+x /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574/ /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-822692568705
74/check_point_mgmt.py && sleep 0'"'"''
<127.0.0.1> (0, '', '')
<127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: jordanmartin
<127.0.0.1> SSH: EXEC sshpass -d13 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=jordanmartin -o ConnectTimeout=10 -o ControlPath=/home/jordanmartin/.ansibl
e/cp/8239a62529 -tt 127.0.0.1 '/bin/sh -c '"'"'/usr/bin/python /home/jordanmartin/.ansible/tmp/ansible-tmp-1531938210.39-82269256870574/check_point_mgmt.py; rm -rf "/home/jordanmartin/.ansible/tmp/
ansible-tmp-1531938210.39-82269256870574/" > /dev/null 2>&1 && sleep 0'"'"''
<127.0.0.1> (0, '\r\n{"msg": "Command 'run-script {u'script-name': u'Create output file', u'targets': u'ztestintfw1', u'script': u'touch output.txt'}' failed with error message: Reque
sted object [ztestintfw1] not found. All changes are discarded and the session is invalidated.", "failed": true, "changed": false, "invocation": {"module_args": {"command": "run-script", "session-d
ata": "{'changed': False, 'response': {'url': '199.197.48.246:8443', 'domain': 'System Data', 'fingerprint': 'CF92395BEC6796E1E1E03DC079308AEFF2F3959B', 'sid': 'FDYOHwOl_cNuW6S_O
k14UWU6dJB9MCFzTKp0ei2At1A'}}", "parameters": "{'script-name': 'Create output file', 'targets': 'ztestintfw1', 'script': 'touch output.txt'}", "fingerprint": null}}}\r\n', 'Shared conn
ection to 127.0.0.1 closed.\r\n')
fatal: [127.0.0.1]: FAILED! => {
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"command": "run-script",
"fingerprint": null,
"parameters": "{'script-name': 'Create output file', 'targets': 'ztestintfw1', 'script': 'touch output.txt'}",
"session-data": "{'changed': False, 'response': {'url': '199.197.48.246:8443', 'domain': 'System Data', 'fingerprint': 'CF92395BEC6796E1E1E03DC079308AEFF2F3959B', 'sid': 'FDYOHwOl_cNuW6
S_Ok14UWU6dJB9MCFzTKp0ei2At1A'}}"
}
},
"msg": "Command 'run-script {u'script-name': u'Create output file', u'targets': u'ztestintfw1', u'script': u'touch output.txt'}' failed with error message: Requested object [ztestintfw1] not fo
und. All changes are discarded and the session is invalidated."
}
to retry, use: --limit @/mnt/c/Users/jm62602/Documents/CheckMates_Aug15_Demos/Ansible-R80-Scripts/GoldenImageScan.retry

PLAY RECAP ******************************************************************************************************************************************************************************************
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=1

It appears that "Requested object [ztestintfw1] not found." The problem is that this object a) exists and b) is found when making the same API call using Postman. This issue has be thoroughly confused. Any examples or insights would be greatly appreciated!

Cant execute tutorial-playbook

Hi, I am getting the following issue when i tried to execute tutorial-playbook. Unsure what is the issue. Kindly hep.

[root@localhost Playbooks]# ansible-playbook demo-playbook.yml
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.

The error appears to have been in '/etc/ansible/cpAnsible/Playbooks/demo-playbook.yml': line 6, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

tasks:
- name: login
^ here

Booleans from Ansible (Python) to JSON Format

When Ansible produces a string for JSON data to be loaded, the module check_point_mgmt.py does not handle booleans with capitalized first letter as the value is being treated as python true boolean. In Python True and in JSON true. See the value mappings from/to Python/JSON.
Also, it seems like the Management API only takes all lowercase booleans.

Cannot operate on an unverified server. Please verify the server's fingerprint: '' and add it via the 'fingerprint' option of this module

Hi Guys ,

I am getting the unverified server error . I have added the "api fingerprint" SHA1 in the code ; followed all the steps as mentioned in the Readme file and webapi docs ; still not able to identify what could be wrong . Can anyone please suggest ??

The CP api is listening on port - 443 ; can see the logs of the playbook hitting checkpoint manager on 443 , added the fingerprint in the playbook . But still the playbook complains of unverified server error .

fatal: [127.0.0.1]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"api_version": null,
"command": "login",
"context": "web_api",
"fingerprint": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"parameters": "{'username': 'XXXX', 'management': 'XXXXX', 'password': '@@@##$'}",
"session-data": null
}
},
"msg": "Cannot operate on an unverified server. Please verify the server's fingerprint: '' and add it via the 'fingerprint' option of this module."
}
to retry, use: --limit @/home/AA-ANSIBLE001/my_script.retry

Uses Outside the API

I'm curious if the CheckPoint folks have written any example playbooks that SSH directly into the Checkpoint Management Device so as to avoid the limitations of the rather small API library and Python SDK. I feel that there are a lot of uses that extend outside of those realms.

Looking for examples on dumping all firewall rules

Hi folks,

I'm still learning Ansible, so I'm not yet an expert on iterating through dictionaries, json, etc. I have been able to make the command show-access-layers. I want to use that result to loop through the access-layers and display the rules pertaining to each one. Does anyone have an example I may look at that accomplishes this?

Thanks!

Documentation about getting API fingerprint

I think your documentation for getting the API fingerprint is either incorrect or misleading as I cannot for the life of me figure out how to obtain it. I have typed api fingerprint, run api fingerprint, run "api fingerprint" and several other combinations into the SmartConsole command line, but it never recognizes the command. How do you obtain the API fingerprint? And can you please make it more clear in your documentation? Thanks!

failed with error message: APIResponse received a response which is not a valid JSON

Dear API Team,

I created a simple ansible playbook to test it with Checkpoint.

But the playbook ends with the following error :

PLAY [localhost] **********************************************************************************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************************************************************************
ok: [127.0.0.1]
TASK [login] **************************************************************************************************************************************************************************************************
ok: [127.0.0.1]
TASK [add group] **********************************************************************************************************************************************************************************************

fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed": true, "msg": "Command 'add-group {u'name': u'group_demo'}' failed with error message: APIResponse received a response which is not a valid JSON.. All changes are discarded and the session is invalidated."}

PLAY RECAP ****************************************************************************************************************************************************************************************************
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=1

This is my playbook :

  • hosts: "localhost"
    tasks:
    • name: "login"
      check_point_mgmt:
      command: login
      parameters:
      username: "{{mgmt_user}}"
      password: "{{mgmt_password}}"
      management: "{{mgmt_server}}"
      fingerprint: "{{mgmt_fingerprint}}"
      register: login_response

    • name: "add group"
      check_point_mgmt:
      command: add-group
      parameters:
      name: "group_demo"
      session-data: "{{ login_response }}"

Best regards.

Operation is not allowed in read only mode!

Hello guys,
sorry, may I ask you how I could solve this problem:

I'm trying to run the "tutorial-playbook.yml Playbook, and I get this error:

fatal: [127.0.0.1]: FAILED! => {"changed": false, "msg": "Command 'add-host {u'name': u'host_demo', u'ip-address': u'1.2.3.5'}' failed with error message: message: Runtime error: Operation is not allowed in read only mode!\ncode: generic_error\n. All changes are discarded and the session is invalidated."}

It's strange, because if I try to add a host using only python (same user) it works.

Thanks,
Luca

Troubles with api fingerprint

I'm receiving the following error message when trying to run the demo playbook.
fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed": true, "msg": "Cannot operate on an unverified server. Please verify the server's fingerprint: '' and add it via the 'fingerprint' option of this module."}
I have a fingerprint added though. I'm not sure why it's reading it as blank. Any support would be great.

Parameter "groups": The error was: ValueError: Expecting , delimiter: line

Hello,

I have a problem with the parameter "groups".
When i use it like in below code , the playbok ends with error :
But when i use it with just the loop variable "{{item.memberof}}" groups: "{{item.memberof}}" , it ends without errors.

  • name: "Modify groups"
    check_point_mgmt:
    command: set-group
    parameters:
    name: "{{obj.pre}}-{{item.name}}"
    groups: "{{obj.pre}}-{{item.memberof}}"
    session-data: "{{ login_response }}"
    with_items: "{{obj.obj_groups}}"

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ValueError: Expecting , delimiter: line 1 column 52 (char 51)
failed: [localhost] (item={u'memberof': [u'test1'], u'name': u'wifi'}) => {"failed": true, "item": {"memberof": ["test2"], "name": "Wire"}, "module_stderr": "Traceback (most recent call last):\n File "/tmp/ansible_JBexb_/ansible_module_check_point_mgmt.py", line 240, in \n main()\n File "/tmp/ansible_JBexb_/ansible_module_check_point_mgmt.py", line 128, in main\n parameters = json.loads(parameters.replace("'", '"'))\n File "/usr/local/lib/python2.7/json/init.py", line 339, in loads\n return _default_decoder.decode(s)\n File "/usr/local/lib/python2.7/json/decoder.py", line 364, in decode\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n File "/usr/local/lib/python2.7/json/decoder.py", line 380, in raw_decode\n obj, end = self.scan_once(s, idx)\nValueError: Expecting , delimiter: line 1 column 52 (char 51)\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}

show-access-rulebase can't show more than 500 rules

Currently show-access-rulebase can't show more than 500 rules. We would like to see all the rules in firewall and some of the firewalls we have has count close to 800 / 900.

Because of current limitation of rest service show-access-rulebase 1-500 we can not read rules beyond 500.

Thanks
Bhupinder

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.