Skip to content

Commit

Permalink
Merge branch 'feature/fix-prospector-issues' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgeneOskin committed Jan 27, 2016
2 parents 332ad89 + 886bf50 commit 3fafbb7
Show file tree
Hide file tree
Showing 46 changed files with 857 additions and 630 deletions.
20 changes: 20 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
- repo: https://github.com/pre-commit/pre-commit-hooks
sha: 64943e86417774b9d6ba63c74e00f8cc3e2119e0
hooks:
- id: check-ast
- id: check-added-large-files
- id: check-case-conflict
- id: check-docstring-first
- id: check-merge-conflict
- id: check-yaml
- id: debug-statements
- id: detect-private-key
- id: double-quote-string-fixer
- id: fix-encoding-pragma
- id: trailing-whitespace
- id: name-tests-test

- repo: https://github.com/guykisel/prospector-mirror
sha: 00fbd80101566b1b9c873c71f2ab7b95b8bd0a7d
hooks:
- id: prospector
17 changes: 12 additions & 5 deletions .prospector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ inherits:

ignore-paths:
- .git
- setup.py
- build
- serverauditor_sshconfig/core/ssh_config.py # it's too complex
- serverauditor_sshconfig/core/cryptor.py # it's too complex

# TODO Remove this file in production
- serverauditor_sshconfig/sync/services/aws.py

pep257:
disable:
- D203 # 1 blank line required before

pylint:
options:
max-parents: 12
disable:
# - broad-except
# - pointless-except
# - bad-super-call
# - nonstandard-exception

21 changes: 11 additions & 10 deletions pavement.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
from paver.easy import * # noqa
from paver.setuputils import setup
from setuptools import find_packages

# -*- coding: utf-8 -*-
"""Config-like for paver tool."""
import sys
from setuptools import find_packages
from paver.easy import task, sh, needs # noqa
from paver.setuputils import setup # noqa

sys.path.append('.')
from serverauditor_sshconfig import get_version # noqa


def get_version():
from serverauditor_sshconfig import __version__
return '.'.join(map(str, __version__))


# pylint: disable=invalid-name
requires = [
'cliff==1.15',
'stevedore==1.10.0',
Expand All @@ -23,6 +21,7 @@ def get_version():
'pyasn1',
]

# pylint: disable=invalid-name
handlers = [
'sync = serverauditor_sshconfig.sync.commands:SyncCommand',
'snippet = serverauditor_sshconfig.cloud.commands:SnippetCommand',
Expand Down Expand Up @@ -85,15 +84,17 @@ def get_version():
@task
@needs('generate_setup', 'minilib', 'setuptools.command.sdist')
def sdist():
"""Overrides sdist to make sure that our setup.py is generated."""
"""Override sdist to make sure that our setup.py is generated."""
pass


@task
def lint():
"""Check code style and conventions."""
sh('prospector')


@task
def bats():
"""Run tests on CLI usage."""
sh('bats tests/integration')
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pycrypto==2.6
pycrypto==2.6
7 changes: 7 additions & 0 deletions serverauditor_sshconfig/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
# -*- coding: utf-8 -*-
"""Package with CLI tool and API."""
__version__ = (0, 7, 2)


def get_version():
"""Return current version."""
return '.'.join([str(i) for i in __version__])
2 changes: 2 additions & 0 deletions serverauditor_sshconfig/account/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
"""Package with account command set."""
27 changes: 18 additions & 9 deletions serverauditor_sshconfig/account/commands.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,60 @@
# coding: utf-8
"""
Copyright (c) 2013 Crystalnix.
License BSD, see LICENSE for more details.
"""
# -*- coding: utf-8 -*-
"""Module to keep login and logout command."""
import six
from getpass import getpass
from ..core.commands import AbstractCommand
from .managers import AccountManager


# pylint: disable=abstract-method
class BaseAccountCommand(AbstractCommand):
"""Base class for login and logout commands."""

def __init__(self, app, app_args, cmd_name=None):
"""Construct new instance."""
super(BaseAccountCommand, self).__init__(app, app_args, cmd_name)
self.manager = AccountManager(self.config)


class LoginCommand(BaseAccountCommand):

"""Sign into serverauditor cloud."""

# pylint: disable=no-self-use
def prompt_username(self):
"""Ask username prompt."""
return six.moves.input("Serverauditor's username: ")

def get_parser(self, prog_name):
"""Create command line argument parser.
Use it to add extra options to argument parser.
"""
parser = super(LoginCommand, self).get_parser(prog_name)
parser.add_argument('-u', '--username', metavar='USERNAME')
parser.add_argument('-p', '--password', metavar='PASSWORD')
parser.add_argument('--sync-sshconfig', action='store_true')
return parser

def take_action(self, parsed_args):
"""Process CLI call."""
username = parsed_args.username or self.prompt_username()
password = parsed_args.password or self.prompt_password()
self.manager.login(username, password)
self.log.info('Sign into serverauditor cloud.')


class LogoutCommand(BaseAccountCommand):

"""Sign out serverauditor cloud."""

def get_parser(self, prog_name):
"""Create command line argument parser.
Use it to add extra options to argument parser.
"""
parser = super(LogoutCommand, self).get_parser(prog_name)
parser.add_argument('--clear-sshconfig', action='store_true')
return parser

def take_action(self, parsed_args):
def take_action(self, _):
"""Process CLI call."""
self.manager.logout()
self.log.info('Sign out serverauditor cloud.')
13 changes: 6 additions & 7 deletions serverauditor_sshconfig/account/managers.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
# coding: utf-8

"""
Copyright (c) 2013 Crystalnix.
License BSD, see LICENSE for more details.
"""

# -*- coding: utf-8 -*-
"""Module with Account manager."""
from ..core.api import API


class AccountManager(object):
"""Class to keep logic for login and logout."""

def __init__(self, config):
"""Create new account manager."""
self.config = config
self.api = API()

def login(self, username, password):
"""Retrieve apikey and crypto settings from server."""
response = self.api.login(username, password)
self.config.set('User', 'username', username)
apikey = response['key']
Expand All @@ -26,5 +24,6 @@ def login(self, username, password):
self.config.write()

def logout(self):
"""Remove apikey and other credentials."""
self.config.remove_section('User')
self.config.write()
15 changes: 9 additions & 6 deletions serverauditor_sshconfig/app.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
# coding: utf-8
# -*- coding: utf-8 -*-
"""Module for main app class."""
import logging
# pylint: disable=import-error
from cliff.app import App
# pylint: disable=import-error
from cliff.commandmanager import CommandManager

from . import __version__


def get_version():
return '.'.join(map(str, __version__))
from . import get_version


# pylint: disable=too-few-public-methods
class ServerauditorApp(App):
"""Class for CLI application."""

def __init__(self):
"""Construct new CLI application."""
super(ServerauditorApp, self).__init__(
description='Serverauditor app',
version=get_version(),
command_manager=CommandManager('serverauditor.handlers'),
)

def configure_logging(self):
"""Change logging level for request package."""
super(ServerauditorApp, self).configure_logging()
logging.getLogger('requests').setLevel(logging.WARNING)
return
2 changes: 2 additions & 0 deletions serverauditor_sshconfig/cloud/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
"""Package with user data manipulation command."""
23 changes: 15 additions & 8 deletions serverauditor_sshconfig/cloud/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
# -*- coding: utf-8 -*-
"""Package with sync-cloud commands."""
from ...core.commands import AbstractCommand

from .host import HostCommand, HostsCommand
from .group import GroupCommand, GroupsCommand
from .snippet import SnippetCommand, SnippetsCommand
from .pf_rule import PFRuleCommand, PFRulesCommand
from .ssh_identity import SshIdentityCommand, SshIdentitiesCommand
from .tag import TagsCommand
from .sync import PushCommand, PullCommand
from .host import HostCommand, HostsCommand # noqa
from .group import GroupCommand, GroupsCommand # noqa
from .snippet import SnippetCommand, SnippetsCommand # noqa
from .pf_rule import PFRuleCommand, PFRulesCommand # noqa
from .ssh_identity import SshIdentityCommand, SshIdentitiesCommand # noqa
from .tag import TagsCommand # noqa
from .sync import PushCommand, PullCommand # noqa


class InfoCommand(AbstractCommand):

"""Show info about host or group."""

def get_parser(self, prog_name):
"""Create command line argument parser.
Use it to add extra options to argument parser.
"""
parser = super(InfoCommand, self).get_parser(prog_name)
parser.add_argument(
'-G', '--group', dest='entry_type',
Expand All @@ -36,6 +41,8 @@ def get_parser(self, prog_name):
parser.add_argument('id_or_name', metavar='ID or NAME')
return parser

# pylint: disable=unused-argument
def take_action(self, parsed_args):
"""Process CLI call."""
self.log.info('Info about group or host.')
assert False, 'Not implemented'
49 changes: 28 additions & 21 deletions serverauditor_sshconfig/cloud/commands/group.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
"""Module with Group commands."""
from operator import attrgetter
from ...core.exceptions import (
InvalidArgumentException, TooManyEntriesException, DoesNotExistException,
)
from ...core.commands import DetailCommand, ListCommand
from ..models import Group, SshConfig, SshIdentity
from ..models import Group
from .ssh_config import SshConfigArgs


class GroupCommand(DetailCommand):

"""Operate with Group object."""

allowed_operations = DetailCommand.all_operations
model_class = Group

def __init__(self, *args, **kwargs):
"""Construct new group command."""
super(GroupCommand, self).__init__(self, *args, **kwargs)
self.ssh_config_args = SshConfigArgs()

def get_parser(self, prog_name):
"""Create command line argument parser.
Use it to add extra options to argument parser.
"""
parser = super(GroupCommand, self).get_parser(prog_name)
parser.add_argument(
'--generate-key', action='store_true',
Expand All @@ -28,44 +35,41 @@ def get_parser(self, prog_name):
metavar='PARENT_GROUP', help="Parent group's id or name."
)

ssh_config_args = SshConfigArgs()
ssh_config_args.add_agrs(parser)
self.ssh_config_args.add_agrs(parser)
return parser

def create(self, parsed_args):
"""Handle create new instance command."""
self.create_instance(parsed_args)

# pylint: disable=no-self-use
def serialize_args(self, args, instance=None):
"""Convert args to instance."""
if instance:
ssh_identity = (instance.ssh_config and instance.ssh_config.ssh_identity) or SshIdentity()
ssh_config = instance.ssh_config or SshConfig()
ssh_config = self.ssh_config_args.serialize_args(
args, instance.ssh_config
)
group = instance
else:
group, ssh_config, ssh_identity = Group(), SshConfig(), SshIdentity()
group = Group()
ssh_config = self.ssh_config_args.serialize_args(args, None)

if args.generate_key:
raise NotImplementedError('Not implemented')
if args.parent_group:
raise NotImplementedError('Not implemented')
if args.ssh_identity:
raise NotImplementedError('Not implemented')

ssh_identity.username = args.username
ssh_identity.password = args.password

ssh_config.port = args.port
ssh_config.ssh_identity = ssh_identity

group.label = args.label
group.ssh_config = ssh_config
return group


class GroupsCommand(ListCommand):

"""Manage group objects."""

def get_parser(self, prog_name):
"""Create command line argument parser.
Use it to add extra options to argument parser.
"""
parser = super(GroupsCommand, self).get_parser(prog_name)
parser.add_argument(
'-r', '--recursive', action='store_true',
Expand All @@ -78,7 +82,10 @@ def get_parser(self, prog_name):
)
return parser

# pylint: disable=unused-argument
def take_action(self, parsed_args):
"""Process CLI call."""
assert False, 'Filtering and recursive not implemented.'
groups = self.storage.get_all(Group)
fields = Group.allowed_fields()
getter = attrgetter(*fields)
Expand Down
Loading

0 comments on commit 3fafbb7

Please sign in to comment.