Skip to content

Commit

Permalink
startup-config action moves to the beginning of definition (instead o…
Browse files Browse the repository at this point in the history
…f the end)
  • Loading branch information
advornic committed Jan 12, 2015
1 parent b132205 commit bf5d9ec
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 53 deletions.
1 change: 1 addition & 0 deletions test/server/server_test_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def add_action(self, **kwargs):
action['name'] = kwargs.get('name', 'test action')
action['action'] = kwargs.get('action', 'test_action')
action['attributes'] = kwargs.get('attributes', dict())
action['always_execute'] = kwargs.get('always_execute', dict())
self.actions.append(action)

def as_dict(self):
Expand Down
51 changes: 48 additions & 3 deletions test/server/test_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ def test_get_definition_success(self, m_repository):
(resp, state) = controller.get_definition(dict(),
resource=random_string())

self.assertEqual(state, 'do_validation')
self.assertEqual(state, 'get_attributes')
self.assertIsInstance(resp, dict)

@patch('ztpserver.controller.replace_config_action')
Expand All @@ -811,9 +811,10 @@ def test_get_startup_config_success(self, m_replace_config_action):
(resp, state) = controller.get_startup_config(response,
resource=random_string())

self.assertEqual(state, 'do_actions')
self.assertEqual(state, 'get_definition')
self.assertIsInstance(resp, dict)


@patch('ztpserver.controller.replace_config_action')
def test_get_startup_config_success_no_definition(self,
m_replace_config_action):
Expand All @@ -827,7 +828,7 @@ def test_get_startup_config_success_no_definition(self,
controller = ztpserver.controller.NodesController()
(resp, state) = controller.get_startup_config(dict(), resource=resource)

self.assertEqual(state, 'do_actions')
self.assertEqual(state, 'get_definition')
self.assertIsInstance(resp, dict)
self.assertTrue(resp['get_startup_config'])
self.assertTrue(resp['definition'], 'Autogenerated definition')
Expand Down Expand Up @@ -1343,6 +1344,50 @@ def m_get_file(arg):
self.assertFalse('foo' in attrs)
self.assertEqual(attrs['url'], l_attr_url)

class DefinitionStartupConfigTests(unittest.TestCase):

@patch('ztpserver.controller.create_repository')
@patch('ztpserver.controller.load_pattern')
def test_get_definition_w_startuo_config(self, m_load_pattern,
m_repository):

node = create_node()

action_name_1 = random_string()
action_name_2 = random_string()
definitions_file = create_definition()
definitions_file.add_action(action=action_name_1)
definitions_file.add_action(action=action_name_2,
always_execute=True)

cfg = dict()

def m_get_file(arg):
m_file_object = Mock()
if arg.endswith('.node'):
m_file_object.read.return_value = dict(node.as_dict())
elif arg.endswith('definition'):
m_file_object.read.return_value = \
dict(definitions_file.as_dict())
elif arg.endswith('attributes'):
raise ztpserver.repository.FileObjectNotFound
return m_file_object

cfg['return_value.get_file.side_effect'] = m_get_file
m_repository.configure_mock(**cfg)
m_load_pattern.return_value.match_node.return_value = Mock()

url = '/nodes/%s' % node.serialnumber
request = Request.blank(url, method='GET')

resp = request.get_response(ztpserver.controller.Router())
self.assertEqual(resp.status_code, constants.HTTP_STATUS_OK)
self.assertEqual(resp.content_type, constants.CONTENT_TYPE_JSON)
actions = [x['action'] for x in json.loads(resp.body)['actions']]
self.assertEqual(actions, ['replace_config',
action_name_2])


if __name__ == '__main__':
enable_logging()
unittest.main()
100 changes: 50 additions & 50 deletions ztpserver/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,31 +509,9 @@ def show(self, request, resource, *args, **kwargs):
response = self.http_bad_request()
return self.response(**response)

return self.fsm('get_definition', resource=resource, request=request,
return self.fsm('do_validation', resource=resource, request=request,
node=node, node_id=node_id)

def get_definition(self, response, *args, **kwargs):
''' Reads the node specific definition from disk and stores it in the
repsonse dict with key `definition`
'''

try:
filename = self.expand(kwargs['resource'], DEFINITION_FN)
fobj = self.repository.get_file(filename)
definition = fobj.read(CONTENT_TYPE_YAML,
kwargs['resource'])
response['definition'] = definition
log.debug('%s: defintion is %s (%s)' % (kwargs['resource'],
filename,
definition['actions']))
except FileObjectNotFound:
log.warning('%s: missing definition %s' %
(kwargs['resource'], filename))
except FileObjectError as err:
log.error(err.message)
raise Exception('failed to load definition %s' % filename)
return (response, 'do_validation')

def do_validation(self, response, *args, **kwargs):
if not runtime.default.disable_topology_validation:
log.info('%s: topology validation is ENABLED' % kwargs['resource'])
Expand Down Expand Up @@ -573,39 +551,61 @@ def get_startup_config(self, response, *args, **kwargs):
filename = self.expand(kwargs['resource'], STARTUP_CONFIG_FN)
self.repository.get_file(filename)
response['get_startup_config'] = True
if 'definition' not in response:
response['definition'] = dict(name='Autogenerated definition',
actions=list())
response['definition']['actions'].append(\
replace_config_action(kwargs['resource'],
STARTUP_CONFIG_FN))
actions = [replace_config_action(kwargs['resource'],
STARTUP_CONFIG_FN)]
response['definition'] = dict(name='Autogenerated definition',
actions=actions)
except FileObjectNotFound:
log.debug('%s: no startup-config %s' %
(kwargs['resource'], filename))

return (response, 'do_actions')
return (response, 'get_definition')

def do_actions(self, response, *args, **kwargs):
actions = response['definition']['actions']
_actions = list()
for action in actions:
always_execute = action.get('always_execute', False)
if always_execute:
_actions.append(action)
log.debug('%s: always_execute action %s included '
'in definition' %
(kwargs['resource'], action.get('name')))
elif not response['get_startup_config']:
_actions.append(action)
log.debug('%s: action %s included '
'in definition' %
(kwargs['resource'], action.get('name')))
def get_definition(self, response, *args, **kwargs):
''' Reads the node specific definition from disk and stores it in the
repsonse dict with key `definition`
'''

try:
filename = self.expand(kwargs['resource'], DEFINITION_FN)
fobj = self.repository.get_file(filename)
definition = fobj.read(CONTENT_TYPE_YAML,
kwargs['resource'])
actions = []
if 'actions' in definition:
actions = definition['actions']

if 'definition' in response:
# startup-config already present
_actions = list()
for action in actions:
always_execute = action.get('always_execute', False)
if always_execute:
_actions.append(action)
log.debug('%s: always_execute action %s included '
'in definition' %
(kwargs['resource'], action.get('name')))
else:
log.debug('%s: action %s not included '
'in definition' %
(kwargs['resource'], action.get('name')))
response['definition']['actions'] += _actions
else:
log.debug('%s: action %s not included '
'in definition' %
(kwargs['resource'], action.get('name')))
response['definition']['actions'] = _actions

# no startup-config
for action in actions:
log.debug('%s: action %s included '
'in definition' %
(kwargs['resource'], action.get('name')))
response['definition'] = definition
log.debug('%s: defintion is %s (%s)' % (kwargs['resource'],
filename,
definition['actions']))
except FileObjectNotFound:
log.warning('%s: missing definition %s' %
(kwargs['resource'], filename))
except FileObjectError as err:
log.error(err.message)
raise Exception('failed to load definition %s' % filename)
return (response, 'get_attributes')

def get_attributes(self, response, *args, **kwargs):
Expand Down

0 comments on commit bf5d9ec

Please sign in to comment.