-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add profile clear command line and associated tests. Closes #38.
- Loading branch information
1 parent
97c146b
commit cf69162
Showing
3 changed files
with
292 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/usr/bin/env python | ||
# | ||
# Copyright (c) 2017 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public License, | ||
# version 3 (GPLv3). There is NO WARRANTY for this software, express or | ||
# implied, including the implied warranties of MERCHANTABILITY or FITNESS | ||
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv3 | ||
# along with this software; if not, see | ||
# https://www.gnu.org/licenses/gpl-3.0.txt. | ||
# | ||
""" NetworkClearCommand is used to clear specific network profile | ||
or all network profiles | ||
""" | ||
|
||
from __future__ import print_function | ||
import sys | ||
from requests import codes | ||
from cli.utils import handle_error_response | ||
from cli.clicommand import CliCommand | ||
import cli.network as network | ||
from cli.request import GET, DELETE, request | ||
|
||
|
||
# pylint: disable=too-few-public-methods | ||
class NetworkClearCommand(CliCommand): | ||
""" | ||
This command is for clearing a specific network profile or all network | ||
profiles. | ||
""" | ||
SUBCOMMAND = network.SUBCOMMAND | ||
ACTION = network.CLEAR | ||
|
||
def __init__(self, subparsers): | ||
# pylint: disable=no-member | ||
CliCommand.__init__(self, self.SUBCOMMAND, self.ACTION, | ||
subparsers.add_parser(self.ACTION), GET, | ||
network.NETWORK_URI, [codes.ok]) | ||
group = self.parser.add_mutually_exclusive_group(required=True) | ||
group.add_argument('--name', dest='name', metavar='NAME', | ||
help='profile name') | ||
group.add_argument('--all', dest='all', action='store_true', | ||
help='remove all network profiles') | ||
|
||
def _build_req_params(self): | ||
if self.args.name: | ||
self.req_params = {'name': self.args.name} | ||
|
||
def _delete_entry(self, profile_entry, print_out=True): | ||
deleted = False | ||
delete_uri = network.NETWORK_URI + str(profile_entry['id']) + '/' | ||
response = request(DELETE, delete_uri, parser=self.parser) | ||
name = profile_entry['name'] | ||
# pylint: disable=no-member | ||
if response.status_code == codes.no_content: | ||
deleted = True | ||
if print_out: | ||
print('Profile "%s" was removed' % name) | ||
else: | ||
handle_error_response(response) | ||
if print_out: | ||
print('Failed to remove profile "%s"' % name) | ||
return deleted | ||
|
||
def _handle_response_success(self): | ||
json_data = self.response.json() | ||
response_len = len(json_data) | ||
if self.args.name and response_len == 0: | ||
print('Profile "%s" was not found' % self.args.name) | ||
sys.exit(1) | ||
elif self.args.name and response_len == 1: | ||
# delete single credential | ||
entry = json_data[0] | ||
if self._delete_entry(entry) is False: | ||
sys.exit(1) | ||
elif response_len == 0: | ||
print("No profiles exist to be removed") | ||
sys.exit(1) | ||
else: | ||
# remove all entries | ||
remove_error = [] | ||
for entry in json_data: | ||
if self._delete_entry(entry, print_out=False) is False: | ||
remove_error.append(entry['name']) | ||
if remove_error != []: | ||
cred_err = ','.join(remove_error) | ||
print('Some profiles were removed, however an error' | ||
' occurred removing the following profiles: %s' | ||
% cred_err) | ||
sys.exit(1) | ||
else: | ||
print('All profiles were removed') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# | ||
# Copyright (c) 2017 Red Hat, Inc. | ||
# | ||
# This software is licensed to you under the GNU General Public License, | ||
# version 3 (GPLv3). There is NO WARRANTY for this software, express or | ||
# implied, including the implied warranties of MERCHANTABILITY or FITNESS | ||
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv3 | ||
# along with this software; if not, see | ||
# https://www.gnu.org/licenses/gpl-3.0.txt. | ||
# | ||
"""Test the CLI module""" | ||
|
||
import unittest | ||
import sys | ||
from io import StringIO | ||
from argparse import ArgumentParser, Namespace | ||
import requests | ||
import requests_mock | ||
from cli.tests_utilities import HushUpStderr, redirect_stdout | ||
from cli.request import BASE_URL, CONNECTION_ERROR_MSG, SSL_ERROR_MSG | ||
from cli.network import NETWORK_URI | ||
from cli.network.clear import NetworkClearCommand | ||
|
||
PARSER = ArgumentParser() | ||
SUBPARSER = PARSER.add_subparsers(dest='subcommand') | ||
|
||
|
||
class NetworkClearCliTests(unittest.TestCase): | ||
"""Class for testing the profile clear commands for qpc""" | ||
def setUp(self): | ||
# Temporarily disable stderr for these tests, CLI errors clutter up | ||
# nosetests command. | ||
self.orig_stderr = sys.stderr | ||
sys.stderr = HushUpStderr() | ||
|
||
def tearDown(self): | ||
# Restore stderr | ||
sys.stderr = self.orig_stderr | ||
|
||
def test_clear_network_ssl_err(self): | ||
"""Testing the clear profile command with a connection error | ||
""" | ||
network_out = StringIO() | ||
url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(url, exc=requests.exceptions.SSLError) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
self.assertEqual(network_out.getvalue(), SSL_ERROR_MSG) | ||
|
||
def test_clear_network_conn_err(self): | ||
"""Testing the clear profile command with a connection error | ||
""" | ||
network_out = StringIO() | ||
url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(url, exc=requests.exceptions.ConnectTimeout) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
self.assertEqual(network_out.getvalue(), | ||
CONNECTION_ERROR_MSG) | ||
|
||
def test_clear_network_internal_err(self): | ||
"""Testing the clear profile command with an internal error | ||
""" | ||
network_out = StringIO() | ||
url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(url, status_code=500, json={'error': ['Server Error']}) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
self.assertEqual(network_out.getvalue(), 'Server Error') | ||
|
||
def test_clear_network_empty(self): | ||
"""Testing the clear profile command successfully with empty data | ||
""" | ||
network_out = StringIO() | ||
url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(url, status_code=200, json=[]) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
self.assertEqual(network_out.getvalue(), | ||
'Profile "profile1" was not found\n') | ||
|
||
def test_clear_by_name(self): | ||
"""Testing the clear profile command successfully with stubbed data | ||
when specifying a name | ||
""" | ||
network_out = StringIO() | ||
get_url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
delete_url = BASE_URL + NETWORK_URI + '1/' | ||
profile_entry = {'id': 1, 'name': 'profile1', 'hosts': ['1.2.3.4'], | ||
'auth': ['auth1', 'auth2'], 'ssh_port': 22} | ||
data = [profile_entry] | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(get_url, status_code=200, json=data) | ||
mocker.delete(delete_url, status_code=204) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
expected = 'Profile "profile1" was removed\n' | ||
self.assertEqual(network_out.getvalue(), expected) | ||
|
||
def test_clear_by_name_err(self): | ||
"""Testing the clear profile command successfully with stubbed data | ||
when specifying a name with an error response | ||
""" | ||
network_out = StringIO() | ||
get_url = BASE_URL + NETWORK_URI + '?name=profile1' | ||
delete_url = BASE_URL + NETWORK_URI + '1/' | ||
profile_entry = {'id': 1, 'name': 'profile1', 'hosts': ['1.2.3.4'], | ||
'auth': ['auth1', 'auth2'], 'ssh_port': 22} | ||
data = [profile_entry] | ||
err_data = {'error': ['Server Error']} | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(get_url, status_code=200, json=data) | ||
mocker.delete(delete_url, status_code=500, json=err_data) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name='profile1') | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
expected = 'Failed to remove profile "profile1"' | ||
self.assertTrue(expected in network_out.getvalue()) | ||
|
||
def test_clear_all_empty(self): | ||
"""Testing the clear profile command successfully with stubbed data | ||
empty list of profiles | ||
""" | ||
network_out = StringIO() | ||
get_url = BASE_URL + NETWORK_URI | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(get_url, status_code=200, json=[]) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name=None) | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
expected = 'No profiles exist to be removed\n' | ||
self.assertEqual(network_out.getvalue(), expected) | ||
|
||
def test_clear_all_with_error(self): | ||
"""Testing the clear profile command successfully with stubbed data | ||
a list of profiles with delete error | ||
""" | ||
network_out = StringIO() | ||
get_url = BASE_URL + NETWORK_URI | ||
delete_url = BASE_URL + NETWORK_URI + '1/' | ||
profile_entry = {'id': 1, 'name': 'profile1', 'hosts': ['1.2.3.4'], | ||
'auth': ['auth1', 'auth2'], 'ssh_port': 22} | ||
data = [profile_entry] | ||
err_data = {'error': ['Server Error']} | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(get_url, status_code=200, json=data) | ||
mocker.delete(delete_url, status_code=500, json=err_data) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name=None) | ||
with self.assertRaises(SystemExit): | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
expected = 'Some profiles were removed, however and' \ | ||
' error occurred removing the following' \ | ||
' credentials:' | ||
self.assertTrue(expected in network_out.getvalue()) | ||
|
||
def test_clear_all(self): | ||
"""Testing the clear profile command successfully with stubbed data | ||
a list of profiles | ||
""" | ||
network_out = StringIO() | ||
get_url = BASE_URL + NETWORK_URI | ||
delete_url = BASE_URL + NETWORK_URI + '1/' | ||
profile_entry = {'id': 1, 'name': 'profile1', 'hosts': ['1.2.3.4'], | ||
'auth': ['auth1', 'auth2'], 'ssh_port': 22} | ||
data = [profile_entry] | ||
with requests_mock.Mocker() as mocker: | ||
mocker.get(get_url, status_code=200, json=data) | ||
mocker.delete(delete_url, status_code=204) | ||
ncc = NetworkClearCommand(SUBPARSER) | ||
args = Namespace(name=None) | ||
with redirect_stdout(network_out): | ||
ncc.main(args) | ||
expected = 'All profiles were removed\n' | ||
self.assertEqual(network_out.getvalue(), expected) |