Skip to content

Commit

Permalink
Merge pull request #491 from GreyNoise-Intelligence/improve_ip_valida…
Browse files Browse the repository at this point in the history
…tion

Remove py2 and Implement IP Validation for Non-Routable IPs
  • Loading branch information
andrew-morris authored Jun 3, 2021
2 parents 951bf89 + 56c6103 commit 4f573ef
Show file tree
Hide file tree
Showing 23 changed files with 191 additions and 192 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.9.1
current_version = 1.0.0
tag = True
commit = True

Expand Down
9 changes: 0 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ workflows:
version: 2
build:
jobs:
- py27:
filters:
<<: *TAGS_FILTER
- py35:
filters:
<<: *TAGS_FILTER
Expand All @@ -29,7 +26,6 @@ workflows:
- pypi:
requires:
# release to pypi only when test cases pass in all python versions
- py27
- py35
- py36
- py37
Expand Down Expand Up @@ -57,11 +53,6 @@ DEFAULT_STEPS: &DEFAULT_STEPS
path: workspace/test_results

jobs:
py27:
docker:
- image: circleci/python:2.7
steps: *DEFAULT_STEPS

py35:
docker:
- image: circleci/python:3.5
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ celerybeat-schedule
# virtualenv
.venv
venv/
venv_py2/
venv3/
ENV/

Expand All @@ -105,4 +106,6 @@ ENV/

# idea
.idea/
workspace/
workspace/

.DS_Store
19 changes: 15 additions & 4 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,30 @@
Changelog
=========

Version `dev`_
Version `1.0.0`_
================
**Date**: unreleased
**Date**: June 02, 2021

*** Removed Support for Python2 - BREAKING CHANGE ***

* API client:

* Fixed error handling for both `error` and `message` responses
* Implemented ipaddress package for IP validation to prevent non-routable IP addresses from being
sent for query to the API

* CLI:

* Updated warning messages to help identify invalid vs non-routable IPs

* Dependencies:

* Updated cachetools to 4.2.2
* Updated six to 1.16.0
* Updated jinja2 to 3.0.0 for py36 and py37
* Updated jinja2 to 3.0.1 for py36 and py37
* Updated Click to 8.0.1
* Updated click-repl to 0.2.0
* Updated more-itertools to 8.8.0

Version `0.9.1`_
================
Expand Down Expand Up @@ -208,4 +219,4 @@ Version `0.2.0`_
.. _`0.8.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v0.7.0...0.8.0
.. _`0.9.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v0.8.0...0.9.0
.. _`0.9.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v0.9.0...0.9.1
.. _`dev`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v0.9.1...HEAD
.. _`1.0.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v0.9.1...1.0.0
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Copyright 2018 GreyNoise <>
Copyright 2021 GreyNoise <>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ This python package follows semantic versioning. According to this:
As such, we recommend you pin the dependency on this SDK to only allow minor version changes at most:

::

# allow patch version increments
greynoise~=1.4.0
# allow minor verison increments

# allow minor version increments
greynoise~=1.4


Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
author = "GreyNoise Intelligence"

# The full version, including alpha/beta/rc tags
release = "0.9.1"
release = "1.0.0"


# -- General configuration ---------------------------------------------------
Expand Down
8 changes: 0 additions & 8 deletions requirements/common-py2.txt

This file was deleted.

8 changes: 0 additions & 8 deletions requirements/common-py3.txt

This file was deleted.

15 changes: 10 additions & 5 deletions requirements/common.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Minimal requirements needed to run the application
-r common-py2.txt
-r common-py3.txt
Click==7.1.2
ansimarkup==1.4.0
cachetools==4.2.2;python_version>='3'
click-default-group==1.2.2
click-repl==0.1.6
click-repl==0.2.0
dict2xml==1.7.0;python_version>='3'
ipaddress==1.0.23
jinja2==2.11.3;python_version=='3.5' # pyup: ignore
jinja2==3.0.1;python_version>='3.6'
more-itertools==8.8.0;python_version>='3'
requests==2.25.1
six==1.16.0
Click==7.1.2
structlog==20.1.0;python_version=='3.5' # pyup: ignore
structlog==21.1.0;python_version>='3.6'
4 changes: 2 additions & 2 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Requirements needed to develop the application
-r test.txt
advbumpversion==1.2.0
ipython==7.23.1;python_version>='3'
pre-commit==2.12.1
ipython==7.24.0;python_version>='3'
pre-commit==2.13.0
tox==3.23.1
4 changes: 2 additions & 2 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Requirements needed to build the documentation
-r common.txt
Sphinx==4.0.1
sphinx-click==2.7.1
Sphinx==4.0.2
sphinx-click==3.0.0
sphinx-rtd-theme==0.5.2
8 changes: 0 additions & 8 deletions requirements/test-py2.txt

This file was deleted.

11 changes: 0 additions & 11 deletions requirements/test-py3.txt

This file was deleted.

17 changes: 12 additions & 5 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Requirements needed to run the test cases
-r common.txt
-r test-py2.txt
-r test-py3.txt
black==21.5b2;python_version>='3.6'
flake8==3.9.2
pytest-cov==2.11.1
isort==4.3.21;python_version=='3.5' # pyup: ignore
isort==5.8.0;python_version>='3.6'
mock==3.0.5;python_version=='3.5' # pyup: ignore
mock==4.0.3;python_version>='3.6'
pylint==2.6.2;python_version=='3.5' # pyup: ignore
pylint==2.8.2;python_version>='3.6'
pytest-cov==2.12.0
pytest==6.1.2;python_version=='3.5' # pyup: ignore
pytest==6.2.4;python_version>='3.6'
restructuredtext-lint==1.3.2
twine==3.4.1;python_version>='3.6'
yamllint==1.26.1;python_version>='3'
8 changes: 3 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def read(fname):


INSTALL_REQUIRES = [
"Click>=7.0",
"Click>=7.1.2",
"ansimarkup",
"cachetools",
"click-default-group",
Expand All @@ -27,7 +27,7 @@ def read(fname):

setup(
name="greynoise",
version="0.9.1",
version="1.0.0",
description="Abstraction to interact with GreyNoise API.",
url="https://greynoise.io/",
author="GreyNoise Intelligence",
Expand All @@ -38,15 +38,13 @@ def read(fname):
package_data={"greynoise.cli": ["templates/*.j2"]},
install_requires=INSTALL_REQUIRES,
long_description=read("README.rst") + "\n\n" + read("CHANGELOG.rst"),
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
python_requires=">=3.0, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
Expand Down
2 changes: 1 addition & 1 deletion src/greynoise/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
__maintainer__ = "GreyNoise Intelligence"
__email__ = "[email protected]"
__status__ = "BETA"
__version__ = "0.9.1"
__version__ = "1.0.0"
7 changes: 6 additions & 1 deletion src/greynoise/cli/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ def wrapper(*args, **kwargs):
return function(*args, **kwargs)
except RequestFailure as exception:
body = exception.args[1]
error_message = "API error: {}".format(body["message"])
if "message" in body:
error_message = "API error: {}".format(body["message"])
elif "error" in body:
error_message = "API error: {}".format(body["error"])
else:
error_message = "API error: {}".format(body)
LOGGER.error(error_message)
click.echo(error_message)
click.get_current_context().exit(-1)
Expand Down
29 changes: 18 additions & 11 deletions src/greynoise/util.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""Utility functions."""

import ipaddress
import logging
import os
import re
import sys

import structlog
Expand Down Expand Up @@ -57,8 +56,7 @@ def load_config():
if os.path.isfile(CONFIG_FILE):
LOGGER.debug("Parsing configuration file: %s...", CONFIG_FILE, path=CONFIG_FILE)
with open(CONFIG_FILE) as config_file:
# cannot update this to read_file() until py27 support is removed
config_parser.readfp(config_file)
config_parser.read_file(config_file)
else:
LOGGER.debug("Configuration file not found: %s", CONFIG_FILE, path=CONFIG_FILE)

Expand Down Expand Up @@ -160,16 +158,25 @@ def validate_ip(ip_address, strict=True):
:raises ValueError: When validation fails and strict is set to True.
"""
is_valid = False

valid_ip_regex = (
r"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|"
r"2[0-4][0-9]|[01]?[0-9][0-9]?)$"
)
if re.match(valid_ip_regex, ip_address):
return True
else:
try:
ipaddress.ip_address(ip_address)
is_valid = True
except ValueError:
error_message = "Invalid IP address: {!r}".format(ip_address)
LOGGER.warning(error_message, ip_address=ip_address)
if strict:
raise ValueError(error_message)
return False

if is_valid:
is_routable = ipaddress.ip_address(ip_address).is_global
if is_routable:
return True
else:
error_message = "Non-Routable IP address: {!r}".format(ip_address)
LOGGER.warning(error_message, ip_address=ip_address)
if strict:
raise ValueError(error_message)
return False
Loading

0 comments on commit 4f573ef

Please sign in to comment.