mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
434 lines
17 KiB
Python
434 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
import re
|
|
import __builtin__
|
|
|
|
from salt.modules import jboss7_cli
|
|
from salt.exceptions import CommandExecutionError
|
|
|
|
from salttesting import TestCase
|
|
|
|
try:
|
|
# will pass if executed along with other tests
|
|
__salt__
|
|
except NameError:
|
|
# if executed separately we need to export __salt__ dictionary ourselves
|
|
__builtin__.__salt__ = {}
|
|
|
|
|
|
class CmdMock(object):
|
|
commands = []
|
|
command_response_func = None # if you want to test complete response object (with retcode, stdout and stderr)
|
|
cli_commands = []
|
|
|
|
default_response = {'retcode': 0, 'stdout': ''' {
|
|
"outcome" => "success"
|
|
}''', 'stderr': ''}
|
|
|
|
def __init__(self, command_response_func=None):
|
|
self.command_response_func = command_response_func
|
|
|
|
def run_all(self, command):
|
|
self.commands.append(command)
|
|
if self.command_response_func is not None:
|
|
return self.command_response_func(command)
|
|
|
|
cli_command = self.__get_cli_command(command)
|
|
self.cli_commands.append(cli_command)
|
|
return self.default_response
|
|
|
|
@staticmethod
|
|
def __get_cli_command(command):
|
|
command_re = re.compile(r'--command=\"\s*(.+?)\s*\"$', re.DOTALL)
|
|
m = command_re.search(command) # --command has to be the last argument
|
|
if m:
|
|
cli_command = m.group(1)
|
|
return cli_command
|
|
return None
|
|
|
|
def get_last_command(self):
|
|
if len(self.commands) > 0:
|
|
return self.commands[-1]
|
|
else:
|
|
return None
|
|
|
|
def get_last_cli_command(self):
|
|
if len(self.cli_commands) > 0:
|
|
return self.cli_commands[-1]
|
|
else:
|
|
return None
|
|
|
|
def clear(self):
|
|
self.commands = []
|
|
self.command_response_func = None
|
|
self.cli_commands = []
|
|
|
|
|
|
class JBoss7CliTestCase(TestCase):
|
|
org_cmd_run_all = None
|
|
cmd = CmdMock()
|
|
jboss_config = {
|
|
'cli_path': '/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh',
|
|
'controller': '123.234.345.456:9999',
|
|
'instance_name': 'Instance1',
|
|
'cli_user': 'jbossadm',
|
|
'cli_password': 'jbossadm',
|
|
'status_url': 'http://sampleapp.company.com:8080/'
|
|
}
|
|
|
|
def setUp(self):
|
|
self.cmd.clear()
|
|
if 'cmd.run_all' in __salt__:
|
|
self.org_cmd_run_all = __salt__['cmd.run_all']
|
|
__salt__['cmd.run_all'] = self.cmd.run_all
|
|
|
|
def tearDown(self):
|
|
if self.org_cmd_run_all is not None:
|
|
__salt__['cmd.run_all'] = self.org_cmd_run_all
|
|
|
|
def test_controller_authentication(self):
|
|
jboss7_cli.run_operation(self.jboss_config, 'some cli operation')
|
|
|
|
self.assertEqual(self.cmd.get_last_command(), '/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh --connect --controller="123.234.345.456:9999" --user="jbossadm" --password="jbossadm" --command="some cli operation"')
|
|
|
|
def test_controller_without_authentication(self):
|
|
jboss_config = {
|
|
'cli_path': '/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh',
|
|
'controller': '123.234.345.456:9999'
|
|
}
|
|
jboss7_cli.run_operation(jboss_config, 'some cli operation')
|
|
|
|
self.assertEqual(self.cmd.get_last_command(), '/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh --connect --controller="123.234.345.456:9999" --command="some cli operation"')
|
|
|
|
def test_operation_execution(self):
|
|
operation = r'sample_operation'
|
|
jboss7_cli.run_operation(self.jboss_config, operation)
|
|
|
|
self.assertEqual(self.cmd.get_last_command(), r'/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh --connect --controller="123.234.345.456:9999" --user="jbossadm" --password="jbossadm" --command="sample_operation"')
|
|
|
|
def test_handling_jboss_error(self):
|
|
def command_response(command):
|
|
return {'retcode': 1,
|
|
'stdout': r'''{
|
|
"outcome" => "failed",
|
|
"failure-description" => "JBAS014807: Management resource '[
|
|
(\"subsystem\" => \"datasources\"),
|
|
(\"data-source\" => \"non-existing\")
|
|
]' not found",
|
|
"rolled-back" => true,
|
|
"response-headers" => {"process-state" => "reload-required"}
|
|
}
|
|
''',
|
|
'stderr': 'some err'}
|
|
self.cmd.command_response_func = command_response
|
|
|
|
result = jboss7_cli.run_operation(self.jboss_config, 'some cli command')
|
|
|
|
self.assertFalse(result['success'])
|
|
self.assertEqual(result['err_code'], 'JBAS014807')
|
|
|
|
def test_handling_cmd_not_exists(self):
|
|
def command_response(command):
|
|
return {'retcode': 127,
|
|
'stdout': '''Command not exists''',
|
|
'stderr': 'some err'}
|
|
self.cmd.command_response_func = command_response
|
|
|
|
try:
|
|
jboss7_cli.run_operation(self.jboss_config, 'some cli command')
|
|
# should throw an exception
|
|
assert False
|
|
except CommandExecutionError as e:
|
|
self.assertTrue(str(e).startswith('Could not execute jboss-cli.sh script'))
|
|
|
|
def test_handling_other_cmd_error(self):
|
|
def command_response(command):
|
|
return {'retcode': 1,
|
|
'stdout': '''Command not exists''',
|
|
'stderr': 'some err'}
|
|
self.cmd.command_response_func = command_response
|
|
|
|
try:
|
|
jboss7_cli.run_command(self.jboss_config, 'some cli command')
|
|
# should throw an exception
|
|
self.fail('An exception should be thrown')
|
|
except CommandExecutionError as e:
|
|
self.assertTrue(str(e).startswith('Command execution failed'))
|
|
|
|
def test_matches_cli_output(self):
|
|
text = '''{
|
|
"key1" => "value1"
|
|
"key2" => "value2"
|
|
}
|
|
'''
|
|
|
|
self.assertTrue(jboss7_cli._is_cli_output(text))
|
|
|
|
def test_not_matches_cli_output(self):
|
|
text = '''Some error '''
|
|
|
|
self.assertFalse(jboss7_cli._is_cli_output(text))
|
|
|
|
def test_parse_flat_dictionary(self):
|
|
text = '''{
|
|
"key1" => "value1"
|
|
"key2" => "value2"
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(len(result), 2)
|
|
self.assertEqual(result['key1'], 'value1')
|
|
self.assertEqual(result['key2'], 'value2')
|
|
|
|
def test_parse_nested_dictionary(self):
|
|
text = '''{
|
|
"key1" => "value1",
|
|
"key2" => {
|
|
"nested_key1" => "nested_value1"
|
|
}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(len(result), 2)
|
|
self.assertEqual(result['key1'], 'value1')
|
|
self.assertEqual(len(result['key2']), 1)
|
|
self.assertEqual(result['key2']['nested_key1'], 'nested_value1')
|
|
|
|
def test_parse_string_after_dict(self):
|
|
text = '''{
|
|
"result" => {
|
|
"jta" => true
|
|
},
|
|
"response-headers" => {"process-state" => "reload-required"}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertTrue(result['result']['jta'])
|
|
self.assertEqual(result['response-headers']['process-state'], 'reload-required')
|
|
|
|
def test_parse_all_datatypes(self):
|
|
text = '''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"allocation-retry" => undefined,
|
|
"connection-url" => "jdbc:mysql://localhost:3306/appdb",
|
|
"driver-name" => "mysql",
|
|
"enabled" => false,
|
|
"jta" => true
|
|
},
|
|
"response-headers" => {"process-state" => "reload-required"}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
self.assertIsNone(result['result']['allocation-retry'])
|
|
self.assertEqual(result['result']['connection-url'], 'jdbc:mysql://localhost:3306/appdb')
|
|
self.assertEqual(result['result']['driver-name'], 'mysql')
|
|
self.assertEqual(result['result']['enabled'], False)
|
|
self.assertTrue(result['result']['jta'])
|
|
self.assertEqual(result['response-headers']['process-state'], 'reload-required')
|
|
|
|
def test_multiline_strings_with_escaped_quotes(self):
|
|
text = r'''{
|
|
"outcome" => "failed",
|
|
"failure-description" => "JBAS014807: Management resource '[
|
|
(\"subsystem\" => \"datasources\"),
|
|
(\"data-source\" => \"asc\")
|
|
]' not found",
|
|
"rolled-back" => true,
|
|
"response-headers" => {"process-state" => "reload-required"}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(result['outcome'], 'failed')
|
|
self.assertTrue(result['rolled-back'])
|
|
self.assertEqual(result['response-headers']['process-state'], 'reload-required')
|
|
self.assertEqual(result['failure-description'], r'''JBAS014807: Management resource '[
|
|
(\"subsystem\" => \"datasources\"),
|
|
(\"data-source\" => \"asc\")
|
|
]' not found''')
|
|
|
|
def test_handling_double_backslash_in_return_values(self):
|
|
text = r'''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"binding-type" => "simple",
|
|
"value" => "DOMAIN\\user"
|
|
}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
self.assertEqual(result['result']['binding-type'], 'simple')
|
|
self.assertEqual(result['result']['value'], r'DOMAIN\user')
|
|
|
|
def test_numbers_without_quotes(self):
|
|
text = r'''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"min-pool-size" => 1233,
|
|
"new-connection-sql" => undefined
|
|
}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
self.assertEqual(result['result']['min-pool-size'], 1233)
|
|
self.assertIsNone(result['result']['new-connection-sql'])
|
|
|
|
def test_all_datasource_properties(self):
|
|
text = r'''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"allocation-retry" => undefined,
|
|
"allocation-retry-wait-millis" => undefined,
|
|
"allow-multiple-users" => undefined,
|
|
"background-validation" => undefined,
|
|
"background-validation-millis" => undefined,
|
|
"blocking-timeout-wait-millis" => undefined,
|
|
"check-valid-connection-sql" => undefined,
|
|
"connection-properties" => undefined,
|
|
"connection-url" => "jdbc:mysql:thin:@db.company.com",
|
|
"datasource-class" => undefined,
|
|
"driver-class" => undefined,
|
|
"driver-name" => "mysql",
|
|
"enabled" => true,
|
|
"exception-sorter-class-name" => undefined,
|
|
"exception-sorter-properties" => undefined,
|
|
"flush-strategy" => "FailingConnectionOnly",
|
|
"idle-timeout-minutes" => undefined,
|
|
"jndi-name" => "java:/appDS",
|
|
"jta" => true,
|
|
"max-pool-size" => 20,
|
|
"min-pool-size" => 3,
|
|
"new-connection-sql" => undefined,
|
|
"password" => "Password4321",
|
|
"pool-prefill" => undefined,
|
|
"pool-use-strict-min" => undefined,
|
|
"prepared-statements-cache-size" => undefined,
|
|
"query-timeout" => undefined,
|
|
"reauth-plugin-class-name" => undefined,
|
|
"reauth-plugin-properties" => undefined,
|
|
"security-domain" => undefined,
|
|
"set-tx-query-timeout" => false,
|
|
"share-prepared-statements" => false,
|
|
"spy" => false,
|
|
"stale-connection-checker-class-name" => undefined,
|
|
"stale-connection-checker-properties" => undefined,
|
|
"track-statements" => "NOWARN",
|
|
"transaction-isolation" => undefined,
|
|
"url-delimiter" => undefined,
|
|
"url-selector-strategy-class-name" => undefined,
|
|
"use-ccm" => "true",
|
|
"use-fast-fail" => false,
|
|
"use-java-context" => "false",
|
|
"use-try-lock" => undefined,
|
|
"user-name" => "user1",
|
|
"valid-connection-checker-class-name" => undefined,
|
|
"valid-connection-checker-properties" => undefined,
|
|
"validate-on-match" => false,
|
|
"statistics" => {
|
|
"jdbc" => undefined,
|
|
"pool" => undefined
|
|
}
|
|
},
|
|
"response-headers" => {"process-state" => "reload-required"}
|
|
}'''
|
|
|
|
result = jboss7_cli._parse(text)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
self.assertEqual(result['result']['max-pool-size'], 20)
|
|
self.assertIsNone(result['result']['new-connection-sql'])
|
|
self.assertIsNone(result['result']['url-delimiter'])
|
|
self.assertFalse(result['result']['validate-on-match'])
|
|
|
|
def test_datasource_resource_one_attribute_description(self):
|
|
cli_output = '''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"description" => "A JDBC data-source configuration",
|
|
"head-comment-allowed" => true,
|
|
"tail-comment-allowed" => true,
|
|
"attributes" => {
|
|
"connection-url" => {
|
|
"type" => STRING,
|
|
"description" => "The JDBC driver connection URL",
|
|
"expressions-allowed" => true,
|
|
"nillable" => false,
|
|
"min-length" => 1L,
|
|
"max-length" => 2147483647L,
|
|
"access-type" => "read-write",
|
|
"storage" => "configuration",
|
|
"restart-required" => "no-services"
|
|
}
|
|
},
|
|
"children" => {"connection-properties" => {"description" => "The connection-properties element allows you to pass in arbitrary connection properties to the Driver.connect(url, props) method"}}
|
|
}
|
|
}
|
|
'''
|
|
result = jboss7_cli._parse(cli_output)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
conn_url_attributes = result['result']['attributes']['connection-url']
|
|
self.assertEqual(conn_url_attributes['type'], 'STRING')
|
|
self.assertEqual(conn_url_attributes['description'], 'The JDBC driver connection URL')
|
|
self.assertTrue(conn_url_attributes['expressions-allowed'])
|
|
self.assertFalse(conn_url_attributes['nillable'])
|
|
self.assertEqual(conn_url_attributes['min-length'], 1)
|
|
self.assertEqual(conn_url_attributes['max-length'], 2147483647)
|
|
self.assertEqual(conn_url_attributes['access-type'], 'read-write')
|
|
self.assertEqual(conn_url_attributes['storage'], 'configuration')
|
|
self.assertEqual(conn_url_attributes['restart-required'], 'no-services')
|
|
|
|
def test_datasource_complete_resource_description(self):
|
|
cli_output = '''{
|
|
"outcome" => "success",
|
|
"result" => {
|
|
"description" => "A JDBC data-source configuration",
|
|
"head-comment-allowed" => true,
|
|
"tail-comment-allowed" => true,
|
|
"attributes" => {
|
|
"connection-url" => {
|
|
"type" => STRING,
|
|
"description" => "The JDBC driver connection URL",
|
|
"expressions-allowed" => true,
|
|
"nillable" => false,
|
|
"min-length" => 1L,
|
|
"max-length" => 2147483647L,
|
|
"access-type" => "read-write",
|
|
"storage" => "configuration",
|
|
"restart-required" => "no-services"
|
|
}
|
|
},
|
|
"children" => {"connection-properties" => {"description" => "The connection-properties element allows you to pass in arbitrary connection properties to the Driver.connect(url, props) method"}}
|
|
}
|
|
}
|
|
'''
|
|
|
|
result = jboss7_cli._parse(cli_output)
|
|
|
|
self.assertEqual(result['outcome'], 'success')
|
|
conn_url_attributes = result['result']['attributes']['connection-url']
|
|
self.assertEqual(conn_url_attributes['type'], 'STRING')
|
|
self.assertEqual(conn_url_attributes['description'], 'The JDBC driver connection URL')
|
|
self.assertTrue(conn_url_attributes['expressions-allowed'])
|
|
self.assertFalse(conn_url_attributes['nillable'])
|
|
self.assertEqual(conn_url_attributes['min-length'], 1)
|
|
self.assertEqual(conn_url_attributes['max-length'], 2147483647)
|
|
self.assertEqual(conn_url_attributes['access-type'], 'read-write')
|
|
self.assertEqual(conn_url_attributes['storage'], 'configuration')
|
|
self.assertEqual(conn_url_attributes['restart-required'], 'no-services')
|
|
|
|
def test_escaping_operation_with_backslashes_and_quotes(self):
|
|
operation = r'/subsystem=naming/binding="java:/sampleapp/web-module/ldap/username":add(binding-type=simple, value="DOMAIN\\\\user")'
|
|
jboss7_cli.run_operation(self.jboss_config, operation)
|
|
|
|
self.assertEqual(self.cmd.get_last_command(), r'/opt/jboss/jboss-eap-6.0.1/bin/jboss-cli.sh --connect --controller="123.234.345.456:9999" --user="jbossadm" --password="jbossadm" --command="/subsystem=naming/binding=\"java:/sampleapp/web-module/ldap/username\":add(binding-type=simple, value=\"DOMAIN\\\\\\\\user\")"')
|