mirror of
https://github.com/thegeeklab/corenetworks.git
synced 2024-11-25 06:20:39 +00:00
initial commit
This commit is contained in:
commit
252a30c087
283
.drone.jsonnet
Normal file
283
.drone.jsonnet
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
local PythonVersion(pyversion='2.7') = {
|
||||||
|
name: 'python' + std.strReplace(pyversion, '.', '') + '-ansible',
|
||||||
|
image: 'python:' + pyversion,
|
||||||
|
environment: {
|
||||||
|
PY_COLORS: 1,
|
||||||
|
},
|
||||||
|
commands: [
|
||||||
|
'pip install -r test-requirements.txt -qq',
|
||||||
|
'pip install -qq .',
|
||||||
|
'pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail',
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'clone',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineLint = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'lint',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'flake8',
|
||||||
|
image: 'python:3.8',
|
||||||
|
environment: {
|
||||||
|
PY_COLORS: 1,
|
||||||
|
},
|
||||||
|
commands: [
|
||||||
|
'pip install -r test-requirements.txt -qq',
|
||||||
|
'pip install -qq .',
|
||||||
|
'flake8 ./corenetworks',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineTest = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'test',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
PythonVersion(pyversion='2.7'),
|
||||||
|
PythonVersion(pyversion='3.5'),
|
||||||
|
PythonVersion(pyversion='3.6'),
|
||||||
|
PythonVersion(pyversion='3.7'),
|
||||||
|
PythonVersion(pyversion='3.8'),
|
||||||
|
{
|
||||||
|
name: 'codecov',
|
||||||
|
image: 'python:3.8',
|
||||||
|
environment: {
|
||||||
|
PY_COLORS: 1,
|
||||||
|
CODECOV_TOKEN: { from_secret: 'codecov_token' },
|
||||||
|
},
|
||||||
|
commands: [
|
||||||
|
'pip install codecov',
|
||||||
|
'codecov --required',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'dependencies',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineSecurity = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'security',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'bandit',
|
||||||
|
image: 'python:3.8',
|
||||||
|
environment: {
|
||||||
|
PY_COLORS: 1,
|
||||||
|
},
|
||||||
|
commands: [
|
||||||
|
'pip install -r test-requirements.txt -qq',
|
||||||
|
'pip install -qq .',
|
||||||
|
'bandit -r ./corenetworks -x ./corenetworks/tests',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'test',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineBuildPackage = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'build-package',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'build',
|
||||||
|
image: 'python:3.8',
|
||||||
|
environment: {
|
||||||
|
SETUPTOOLS_SCM_PRETEND_VERSION: '${DRONE_TAG##v}',
|
||||||
|
},
|
||||||
|
commands: [
|
||||||
|
'python setup.py sdist bdist_wheel',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'checksum',
|
||||||
|
image: 'alpine',
|
||||||
|
commands: [
|
||||||
|
'cd dist/ && sha256sum * > ../sha256sum.txt',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publish-github',
|
||||||
|
image: 'plugins/github-release',
|
||||||
|
settings: {
|
||||||
|
overwrite: true,
|
||||||
|
api_key: { from_secret: 'github_token' },
|
||||||
|
files: ['dist/*', 'sha256sum.txt'],
|
||||||
|
title: '${DRONE_TAG}',
|
||||||
|
note: 'CHANGELOG.md',
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
ref: ['refs/tags/**'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publish-pypi',
|
||||||
|
image: 'plugins/pypi',
|
||||||
|
settings: {
|
||||||
|
username: { from_secret: 'pypi_username' },
|
||||||
|
password: { from_secret: 'pypi_password' },
|
||||||
|
repository: 'https://upload.pypi.org/legacy/',
|
||||||
|
skip_build: true,
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
ref: ['refs/tags/**'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'security',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineDocs = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'docs',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
concurrency: {
|
||||||
|
limit: 1,
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'assets',
|
||||||
|
image: 'byrnedo/alpine-curl',
|
||||||
|
commands: [
|
||||||
|
'mkdir -p docs/themes/hugo-geekdoc/',
|
||||||
|
'curl -L https://github.com/xoxys/hugo-geekdoc/releases/latest/download/hugo-geekdoc.tar.gz | tar -xz -C docs/themes/hugo-geekdoc/ --strip-components=1',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
image: 'klakegg/hugo:0.59.1-ext-alpine',
|
||||||
|
commands: [
|
||||||
|
'cd docs/ && hugo-official',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'freeze',
|
||||||
|
image: 'appleboy/drone-ssh:1.5.5',
|
||||||
|
settings: {
|
||||||
|
host: { from_secret: 'ssh_host' },
|
||||||
|
key: { from_secret: 'ssh_key' },
|
||||||
|
script: [
|
||||||
|
'cp -R /var/www/virtual/geeklab/html/corenetworks.geekdocs.de/ /var/www/virtual/geeklab/html/corenetworks_freeze/',
|
||||||
|
'ln -sfn /var/www/virtual/geeklab/html/corenetworks_freeze /var/www/virtual/geeklab/corenetworks.geekdocs.de',
|
||||||
|
],
|
||||||
|
username: { from_secret: 'ssh_username' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publish',
|
||||||
|
image: 'appleboy/drone-scp',
|
||||||
|
settings: {
|
||||||
|
host: { from_secret: 'ssh_host' },
|
||||||
|
key: { from_secret: 'ssh_key' },
|
||||||
|
rm: true,
|
||||||
|
source: 'docs/public/*',
|
||||||
|
strip_components: 2,
|
||||||
|
target: '/var/www/virtual/geeklab/html/corenetworks.geekdocs.de/',
|
||||||
|
username: { from_secret: 'ssh_username' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cleanup',
|
||||||
|
image: 'appleboy/drone-ssh:1.5.5',
|
||||||
|
settings: {
|
||||||
|
host: { from_secret: 'ssh_host' },
|
||||||
|
key: { from_secret: 'ssh_key' },
|
||||||
|
script: [
|
||||||
|
'ln -sfn /var/www/virtual/geeklab/html/corenetworks.geekdocs.de /var/www/virtual/geeklab/corenetworks.geekdocs.de',
|
||||||
|
'rm -rf /var/www/virtual/geeklab/html/corenetworks_freeze/',
|
||||||
|
],
|
||||||
|
username: { from_secret: 'ssh_username' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'build-package',
|
||||||
|
'build-container-amd64',
|
||||||
|
'build-container-arm64',
|
||||||
|
'build-container-arm',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineNotifications = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'notifications',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'matrix',
|
||||||
|
image: 'plugins/matrix',
|
||||||
|
settings: {
|
||||||
|
homeserver: { from_secret: 'matrix_homeserver' },
|
||||||
|
roomid: { from_secret: 'matrix_roomid' },
|
||||||
|
template: 'Status: **{{ build.status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}<br/> Message: {{ build.message }}',
|
||||||
|
username: { from_secret: 'matrix_username' },
|
||||||
|
password: { from_secret: 'matrix_password' },
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
status: ['success', 'failure'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'docs',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/master', 'refs/tags/**'],
|
||||||
|
status: ['success', 'failure'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
[
|
||||||
|
PipelineLint,
|
||||||
|
PipelineTest,
|
||||||
|
PipelineSecurity,
|
||||||
|
PipelineBuildPackage,
|
||||||
|
PipelineDocs,
|
||||||
|
PipelineNotifications,
|
||||||
|
]
|
308
.drone.yml
Normal file
308
.drone.yml
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: lint
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: flake8
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- flake8 ./corenetworks
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: test
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: python27-ansible
|
||||||
|
image: python:2.7
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
depends_on:
|
||||||
|
- clone
|
||||||
|
|
||||||
|
- name: python35-ansible
|
||||||
|
image: python:3.5
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
depends_on:
|
||||||
|
- clone
|
||||||
|
|
||||||
|
- name: python36-ansible
|
||||||
|
image: python:3.6
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
depends_on:
|
||||||
|
- clone
|
||||||
|
|
||||||
|
- name: python37-ansible
|
||||||
|
image: python:3.7
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
depends_on:
|
||||||
|
- clone
|
||||||
|
|
||||||
|
- name: python38-ansible
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- pytest corenetworks/tests/ --cov=corenetworks/ --no-cov-on-fail
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
depends_on:
|
||||||
|
- clone
|
||||||
|
|
||||||
|
- name: codecov
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip install codecov
|
||||||
|
- codecov --required
|
||||||
|
environment:
|
||||||
|
CODECOV_TOKEN:
|
||||||
|
from_secret: codecov_token
|
||||||
|
PY_COLORS: 1
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- dependencies
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: security
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: bandit
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip install -r test-requirements.txt -qq
|
||||||
|
- pip install -qq .
|
||||||
|
- bandit -r ./corenetworks -x ./corenetworks/tests
|
||||||
|
environment:
|
||||||
|
PY_COLORS: 1
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- test
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build-package
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- python setup.py sdist bdist_wheel
|
||||||
|
environment:
|
||||||
|
SETUPTOOLS_SCM_PRETEND_VERSION: ${DRONE_TAG##v}
|
||||||
|
|
||||||
|
- name: checksum
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- cd dist/ && sha256sum * > ../sha256sum.txt
|
||||||
|
|
||||||
|
- name: publish-github
|
||||||
|
image: plugins/github-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: github_token
|
||||||
|
files:
|
||||||
|
- dist/*
|
||||||
|
- sha256sum.txt
|
||||||
|
note: CHANGELOG.md
|
||||||
|
overwrite: true
|
||||||
|
title: ${DRONE_TAG}
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/**
|
||||||
|
|
||||||
|
- name: publish-pypi
|
||||||
|
image: plugins/pypi
|
||||||
|
settings:
|
||||||
|
password:
|
||||||
|
from_secret: pypi_password
|
||||||
|
repository: https://upload.pypi.org/legacy/
|
||||||
|
skip_build: true
|
||||||
|
username:
|
||||||
|
from_secret: pypi_username
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/**
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- security
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: docs
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
limit: 1
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: assets
|
||||||
|
image: byrnedo/alpine-curl
|
||||||
|
commands:
|
||||||
|
- mkdir -p docs/themes/hugo-geekdoc/
|
||||||
|
- curl -L https://github.com/xoxys/hugo-geekdoc/releases/latest/download/hugo-geekdoc.tar.gz | tar -xz -C docs/themes/hugo-geekdoc/ --strip-components=1
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
image: klakegg/hugo:0.59.1-ext-alpine
|
||||||
|
commands:
|
||||||
|
- cd docs/ && hugo-official
|
||||||
|
|
||||||
|
- name: freeze
|
||||||
|
image: appleboy/drone-ssh:1.5.5
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: ssh_host
|
||||||
|
key:
|
||||||
|
from_secret: ssh_key
|
||||||
|
script:
|
||||||
|
- cp -R /var/www/virtual/geeklab/html/corenetworks.geekdocs.de/ /var/www/virtual/geeklab/html/corenetworks_freeze/
|
||||||
|
- ln -sfn /var/www/virtual/geeklab/html/corenetworks_freeze /var/www/virtual/geeklab/corenetworks.geekdocs.de
|
||||||
|
username:
|
||||||
|
from_secret: ssh_username
|
||||||
|
|
||||||
|
- name: publish
|
||||||
|
image: appleboy/drone-scp
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: ssh_host
|
||||||
|
key:
|
||||||
|
from_secret: ssh_key
|
||||||
|
rm: true
|
||||||
|
source: docs/public/*
|
||||||
|
strip_components: 2
|
||||||
|
target: /var/www/virtual/geeklab/html/corenetworks.geekdocs.de/
|
||||||
|
username:
|
||||||
|
from_secret: ssh_username
|
||||||
|
|
||||||
|
- name: cleanup
|
||||||
|
image: appleboy/drone-ssh:1.5.5
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: ssh_host
|
||||||
|
key:
|
||||||
|
from_secret: ssh_key
|
||||||
|
script:
|
||||||
|
- ln -sfn /var/www/virtual/geeklab/html/corenetworks.geekdocs.de /var/www/virtual/geeklab/corenetworks.geekdocs.de
|
||||||
|
- rm -rf /var/www/virtual/geeklab/html/corenetworks_freeze/
|
||||||
|
username:
|
||||||
|
from_secret: ssh_username
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- build-package
|
||||||
|
- build-container-amd64
|
||||||
|
- build-container-arm64
|
||||||
|
- build-container-arm
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: notifications
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: matrix
|
||||||
|
image: plugins/matrix
|
||||||
|
settings:
|
||||||
|
homeserver:
|
||||||
|
from_secret: matrix_homeserver
|
||||||
|
password:
|
||||||
|
from_secret: matrix_password
|
||||||
|
roomid:
|
||||||
|
from_secret: matrix_roomid
|
||||||
|
template: "Status: **{{ build.status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}<br/> Message: {{ build.message }}"
|
||||||
|
username:
|
||||||
|
from_secret: matrix_username
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/master
|
||||||
|
- refs/tags/**
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- docs
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: signature
|
||||||
|
hmac: e0cd32befb8e01ec9cb6bd0e7bc032fe0816bcda9e16d89f37789a7db9ba9b82
|
||||||
|
|
||||||
|
...
|
18
.flake8
Normal file
18
.flake8
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[flake8]
|
||||||
|
ignore = D103, D107, W503
|
||||||
|
max-line-length = 99
|
||||||
|
inline-quotes = double
|
||||||
|
exclude =
|
||||||
|
.git
|
||||||
|
.tox
|
||||||
|
__pycache__
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
tests
|
||||||
|
*.pyc
|
||||||
|
*.egg-info
|
||||||
|
.cache
|
||||||
|
.eggs
|
||||||
|
env*
|
||||||
|
application-import-names = corenetworks
|
||||||
|
format = ${cyan}%(path)s:%(row)d:%(col)d${reset}: ${red_bold}%(code)s${reset} %(text)s
|
112
.gitignore
vendored
Normal file
112
.gitignore
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# dotenv
|
||||||
|
.env
|
||||||
|
|
||||||
|
# virtualenv
|
||||||
|
.venv
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env/
|
||||||
|
env*/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# Ignore ide addons
|
||||||
|
.server-script
|
||||||
|
.on-save.json
|
||||||
|
.vscode
|
||||||
|
.pytest_cache
|
||||||
|
|
||||||
|
pip-wheel-metadata
|
||||||
|
|
||||||
|
# Hugo documentation
|
||||||
|
docs/themes/
|
||||||
|
docs/public/
|
||||||
|
resources/_gen/
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.local/
|
||||||
|
.corenetworks*
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Robert Kaussow <mail@geeklabor.de>
|
||||||
|
|
||||||
|
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 (including the next
|
||||||
|
paragraph) 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.
|
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# corenetworks
|
||||||
|
|
||||||
|
Python library for the [https://core-networks.de](https://beta.api.core-networks.de/doc/) DNS API.
|
13
corenetworks/__init__.py
Normal file
13
corenetworks/__init__.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Default package."""
|
||||||
|
|
||||||
|
from corenetworks.client import CoreNetworks # noqa
|
||||||
|
|
||||||
|
__author__ = "Robert Kaussow"
|
||||||
|
__project__ = "corenetworks"
|
||||||
|
__license__ = "MIT"
|
||||||
|
__maintainer__ = "Robert Kaussow"
|
||||||
|
__email__ = "mail@geeklabor.de"
|
||||||
|
__url__ = "https://github.com/xoxys/corenetworks"
|
||||||
|
__version__ = "0.1.0"
|
86
corenetworks/authenticators.py
Normal file
86
corenetworks/authenticators.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Custom authenticators."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from requests import ConnectionError
|
||||||
|
from requests import HTTPError
|
||||||
|
from requests import Request
|
||||||
|
from requests import Session
|
||||||
|
from requests.auth import AuthBase
|
||||||
|
|
||||||
|
from .exceptions import AuthError
|
||||||
|
from .exceptions import CorenetworksError
|
||||||
|
|
||||||
|
|
||||||
|
class CoreNetworksBasicAuth(AuthBase):
|
||||||
|
"""Define token based auth."""
|
||||||
|
|
||||||
|
def __init__(self, user, password, endpoint):
|
||||||
|
self.user = user
|
||||||
|
self.password = password
|
||||||
|
self.endpoint = endpoint
|
||||||
|
self.token = self._login()
|
||||||
|
|
||||||
|
def __eq__(self, other): # noqa
|
||||||
|
return all([
|
||||||
|
self.user == getattr(other, "user", None),
|
||||||
|
self.password == getattr(other, "password", None),
|
||||||
|
])
|
||||||
|
|
||||||
|
def __ne__(self, other): # noqa
|
||||||
|
return not self == other
|
||||||
|
|
||||||
|
def __call__(self, r): # noqa
|
||||||
|
r.headers["Authorization"] = "Bearer {0!s}".format(self.token)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def _login(self):
|
||||||
|
data = {}
|
||||||
|
data["login"] = self.user
|
||||||
|
data["password"] = self.password
|
||||||
|
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
url = "{endpoint}/auth/token".format(endpoint=self.endpoint)
|
||||||
|
|
||||||
|
request = Request(method="POST", url=url, data=json_data)
|
||||||
|
prepared_request = request.prepare()
|
||||||
|
|
||||||
|
try:
|
||||||
|
session = Session()
|
||||||
|
handle = session.send(prepared_request)
|
||||||
|
handle.raise_for_status()
|
||||||
|
except ConnectionError as e:
|
||||||
|
raise CorenetworksError(
|
||||||
|
"Server unreachable: {reason}".format(reason=e.message.reason), payload=e
|
||||||
|
)
|
||||||
|
except HTTPError as e:
|
||||||
|
raise AuthError(
|
||||||
|
"Login failed: {code} {reason}".format(
|
||||||
|
code=e.response.status_code, reason=e.response.reason
|
||||||
|
),
|
||||||
|
payload=e
|
||||||
|
)
|
||||||
|
|
||||||
|
response = handle.json()
|
||||||
|
|
||||||
|
return response["token"]
|
||||||
|
|
||||||
|
|
||||||
|
class CoreNetworksTokenAuth(AuthBase):
|
||||||
|
"""Define token based auth."""
|
||||||
|
|
||||||
|
def __init__(self, token):
|
||||||
|
self.token = token
|
||||||
|
|
||||||
|
def __eq__(self, other): # noqa
|
||||||
|
return all([
|
||||||
|
self.token == getattr(other, "api_token", None),
|
||||||
|
])
|
||||||
|
|
||||||
|
def __ne__(self, other): # noqa
|
||||||
|
return not self == other
|
||||||
|
|
||||||
|
def __call__(self, r): # noqa
|
||||||
|
r.headers["Authorization"] = "Bearer {0!s}".format(self.token)
|
||||||
|
return r
|
231
corenetworks/client.py
Normal file
231
corenetworks/client.py
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""API client."""
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from requests import ConnectionError
|
||||||
|
from requests import HTTPError
|
||||||
|
from requests import Request
|
||||||
|
from requests import Session
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
|
import corenetworks
|
||||||
|
|
||||||
|
from .authenticators import CoreNetworksBasicAuth
|
||||||
|
from .authenticators import CoreNetworksTokenAuth
|
||||||
|
from .exceptions import AuthError
|
||||||
|
from .exceptions import CorenetworksError
|
||||||
|
from .exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class CoreNetworks():
|
||||||
|
"""Create authenticated API client."""
|
||||||
|
|
||||||
|
def __init__(self, user=None, password=None, api_token=None):
|
||||||
|
self.__endpoint = "https://beta.api.core-networks.de"
|
||||||
|
self.__user_agent = "Core Networks Python API {version}".format(
|
||||||
|
version=corenetworks.__version__
|
||||||
|
)
|
||||||
|
|
||||||
|
self._schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ttl": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if api_token:
|
||||||
|
self._auth = CoreNetworksTokenAuth(api_token)
|
||||||
|
else:
|
||||||
|
if not user or not password:
|
||||||
|
raise AuthError("Insufficient authentication details provided")
|
||||||
|
|
||||||
|
self._auth = CoreNetworksBasicAuth(user, password, self.__endpoint)
|
||||||
|
|
||||||
|
# RECORDS
|
||||||
|
|
||||||
|
def records(self, zone, data={}):
|
||||||
|
"""
|
||||||
|
Get the list of records for the specific domain.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
zone (str): Name of the target DNS zone.
|
||||||
|
params (dict): Dictionary of filter parameters.
|
||||||
|
See https://beta.api.core-networks.de/doc/#functon_dnszones_records
|
||||||
|
but keep in mind that you have to pass a dict not a string. The required
|
||||||
|
filter string will be created automatically.
|
||||||
|
|
||||||
|
Example: params={"type": ["NS", "SOA"]} will result in filter=?type[]=NS&type[]=SOA
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: List of entry dicts.
|
||||||
|
|
||||||
|
"""
|
||||||
|
schema = copy.deepcopy(self._schema)
|
||||||
|
self.__validate(data, schema)
|
||||||
|
|
||||||
|
filter_string = self.__json_to_filter(data)
|
||||||
|
result = self.__rest_helper(
|
||||||
|
"/dnszones/{zone}/records/{filter}".format(zone=zone, filter=filter_string),
|
||||||
|
method="GET"
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.__normalize(result)
|
||||||
|
|
||||||
|
def add_record(self, zone, data):
|
||||||
|
"""
|
||||||
|
Create a record for the given domain.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
param1: The first parameter.
|
||||||
|
param2: The second parameter.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if successful, False otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
schema = copy.deepcopy(self._schema)
|
||||||
|
schema["required"] = ["name", "type", "data"]
|
||||||
|
self.__validate(data, schema)
|
||||||
|
|
||||||
|
result = self.__rest_helper(
|
||||||
|
"/dnszones/{zone}/records/".format(zone=zone), data=data, method="POST"
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.__normalize(result)
|
||||||
|
|
||||||
|
def delete_record(self, zone, data):
|
||||||
|
"""
|
||||||
|
Delete all DNS records of a zone that match the data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
"""
|
||||||
|
schema = copy.deepcopy(self._schema)
|
||||||
|
schema["properties"]["force_all"] = {"type": "boolean"}
|
||||||
|
schema["oneOf"] = [{
|
||||||
|
"required": ["name"]
|
||||||
|
}, {
|
||||||
|
"required": ["type"]
|
||||||
|
}, {
|
||||||
|
"required": ["data"]
|
||||||
|
}, {
|
||||||
|
"required": ["force_all"]
|
||||||
|
}]
|
||||||
|
self.__validate(data, schema)
|
||||||
|
|
||||||
|
if data.get("force_all"):
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
print(data)
|
||||||
|
|
||||||
|
# result = self.__rest_helper(
|
||||||
|
# "/dnszones/{zone}/records/delete/".format(zone=zone), data=data, method="POST"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# return self.__normalize(result)
|
||||||
|
|
||||||
|
def __rest_helper(self, url, data=None, params=None, method="GET"):
|
||||||
|
"""Handle requests to the Core Networks API."""
|
||||||
|
url = self.__endpoint + url
|
||||||
|
headers = {
|
||||||
|
"User-Agent": self.__user_agent,
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
if data:
|
||||||
|
json_data = json.dumps(data)
|
||||||
|
else:
|
||||||
|
json_data = None
|
||||||
|
|
||||||
|
request = Request(
|
||||||
|
method=method,
|
||||||
|
url=url,
|
||||||
|
headers=headers,
|
||||||
|
data=json_data,
|
||||||
|
params=params,
|
||||||
|
auth=self._auth
|
||||||
|
)
|
||||||
|
|
||||||
|
prepared_request = request.prepare()
|
||||||
|
|
||||||
|
r_json, r_headers = self.__request_helper(prepared_request)
|
||||||
|
|
||||||
|
return r_json
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __request_helper(request):
|
||||||
|
"""Handle firing off requests and exception raising."""
|
||||||
|
try:
|
||||||
|
session = Session()
|
||||||
|
handle = session.send(request)
|
||||||
|
|
||||||
|
handle.raise_for_status()
|
||||||
|
except ConnectionError as e:
|
||||||
|
raise CorenetworksError(
|
||||||
|
"Server unreachable: {reason}".format(reason=e.message.reason), payload=e
|
||||||
|
)
|
||||||
|
except HTTPError as e:
|
||||||
|
raise CorenetworksError(
|
||||||
|
"Invalid response: {code} {reason}".format(
|
||||||
|
code=e.response.status_code, reason=e.response.reason
|
||||||
|
),
|
||||||
|
payload=e
|
||||||
|
)
|
||||||
|
|
||||||
|
if handle.status_code == 200:
|
||||||
|
response = handle.json()
|
||||||
|
else:
|
||||||
|
response = []
|
||||||
|
|
||||||
|
return response, handle.headers
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __normalize(result):
|
||||||
|
if isinstance(result, list):
|
||||||
|
return [el for el in result]
|
||||||
|
elif isinstance(result, dict):
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
raise CorenetworksError("Unknown type: {}".format(type(result)))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __json_to_filter(data):
|
||||||
|
filter_list = []
|
||||||
|
|
||||||
|
for (key, value) in iteritems(data):
|
||||||
|
if isinstance(value, list):
|
||||||
|
for item in value:
|
||||||
|
filter_list.append("{key}[]={value}".format(key=key, value=item))
|
||||||
|
elif isinstance(value, str):
|
||||||
|
filter_list.append("{key}={value}".format(key=key, value=value))
|
||||||
|
else:
|
||||||
|
raise CorenetworksError("Unknown type: {}".format(type(value)))
|
||||||
|
|
||||||
|
filter_string = "&".join(filter_list)
|
||||||
|
|
||||||
|
if filter_string:
|
||||||
|
filter_string = "?{filter}".format(filter=filter_string)
|
||||||
|
|
||||||
|
return filter_string
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __validate(data, schema):
|
||||||
|
try:
|
||||||
|
jsonschema.validate(data, schema)
|
||||||
|
except jsonschema.exceptions.ValidationError as e:
|
||||||
|
raise ValidationError("Dataset invalid: {reason}".format(reason=e.message), payload=e)
|
31
corenetworks/exceptions.py
Normal file
31
corenetworks/exceptions.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Custom package exceptions."""
|
||||||
|
|
||||||
|
|
||||||
|
class CoreNetworksException(Exception):
|
||||||
|
"""The main exception class."""
|
||||||
|
|
||||||
|
def __init__(self, message, payload=None):
|
||||||
|
self.message = message
|
||||||
|
self.payload = payload
|
||||||
|
|
||||||
|
def __str__(self): # noqa
|
||||||
|
return str(self.message)
|
||||||
|
|
||||||
|
|
||||||
|
class CorenetworksError(CoreNetworksException):
|
||||||
|
"""Authentication errors exception class."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationError(CoreNetworksException):
|
||||||
|
"""Authentication errors exception class."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AuthError(CoreNetworksException):
|
||||||
|
"""Authentication errors exception class."""
|
||||||
|
|
||||||
|
pass
|
27
setup.cfg
Normal file
27
setup.cfg
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[metadata]
|
||||||
|
description-file = README.md
|
||||||
|
license_file = LICENSE
|
||||||
|
|
||||||
|
[bdist_wheel]
|
||||||
|
universal = 1
|
||||||
|
|
||||||
|
[isort]
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
known_first_party = corenetworks
|
||||||
|
sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
|
||||||
|
force_single_line = true
|
||||||
|
line_length = 99
|
||||||
|
skip_glob = **/.env*,**/env/*,**/docs/*
|
||||||
|
|
||||||
|
[yapf]
|
||||||
|
based_on_style = google
|
||||||
|
column_limit = 99
|
||||||
|
dedent_closing_brackets = true
|
||||||
|
coalesce_brackets = true
|
||||||
|
split_before_logical_operator = true
|
||||||
|
|
||||||
|
[tool:pytest]
|
||||||
|
filterwarnings =
|
||||||
|
ignore::FutureWarning
|
||||||
|
ignore:.*collections.*:DeprecationWarning
|
||||||
|
ignore:.*pep8.*:FutureWarning
|
65
setup.py
Normal file
65
setup.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Setup script for the package."""
|
||||||
|
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
from setuptools import find_packages
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
PACKAGE_NAME = "corenetworks"
|
||||||
|
|
||||||
|
|
||||||
|
def get_property(prop, project):
|
||||||
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
result = re.search(
|
||||||
|
r'{}\s*=\s*[\'"]([^\'"]*)[\'"]'.format(prop),
|
||||||
|
open(os.path.join(current_dir, project, "__init__.py")).read(),
|
||||||
|
)
|
||||||
|
return result.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_readme(filename="README.md"):
|
||||||
|
this = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
with io.open(os.path.join(this, filename), encoding="utf-8") as f:
|
||||||
|
long_description = f.read()
|
||||||
|
return long_description
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=get_property("__project__", PACKAGE_NAME),
|
||||||
|
description="Python API client for Domain Management Automation "
|
||||||
|
"with Core Networks https://www.core-networks.de/",
|
||||||
|
keywords="dns, automation, nameserver, corenetworks",
|
||||||
|
version=get_property("__version__", PACKAGE_NAME),
|
||||||
|
author=get_property("__author__", PACKAGE_NAME),
|
||||||
|
author_email=get_property("__email__", PACKAGE_NAME),
|
||||||
|
url=get_property("__url__", PACKAGE_NAME),
|
||||||
|
license=get_property("__license__", PACKAGE_NAME),
|
||||||
|
long_description=get_readme(),
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
|
packages=find_packages(exclude=["*.tests", "tests", "tests.*"]),
|
||||||
|
include_package_data=True,
|
||||||
|
zip_safe=False,
|
||||||
|
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4",
|
||||||
|
classifiers=[
|
||||||
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
"Environment :: Console",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Natural Language :: English",
|
||||||
|
"Operating System :: POSIX",
|
||||||
|
"Programming Language :: Python :: 2",
|
||||||
|
"Programming Language :: Python :: 2.7",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.5",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Topic :: Software Development",
|
||||||
|
],
|
||||||
|
install_requires=["six", "jsonschema"],
|
||||||
|
dependency_links=[],
|
||||||
|
test_suite="tests",
|
||||||
|
)
|
18
test-requirements.txt
Normal file
18
test-requirements.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
pipenv-setup
|
||||||
|
pydocstyle<4.0.0
|
||||||
|
flake8
|
||||||
|
flake8-colors
|
||||||
|
flake8-blind-except
|
||||||
|
flake8-builtins
|
||||||
|
flake8-docstrings<=3.0.0
|
||||||
|
flake8-isort
|
||||||
|
flake8-logging-format
|
||||||
|
flake8-polyfill
|
||||||
|
flake8-quotes
|
||||||
|
pep8-naming
|
||||||
|
pytest
|
||||||
|
pytest-mock
|
||||||
|
pytest-cov
|
||||||
|
bandit
|
||||||
|
autopep8
|
||||||
|
yapf
|
Loading…
Reference in New Issue
Block a user