Add DNS domains during network config

- Node domains must be added to MAAS before assigning
  them to any domain. These domains can be added as the
  network they are assigned to is configured.

Change-Id: I4a10cc7779b74dd79b8ad4602ae0f9050081d6d4
This commit is contained in:
Scott Hussey 2018-08-06 08:50:56 -05:00
parent e044575e05
commit daf94bdeac
5 changed files with 73 additions and 11 deletions

View File

@ -398,7 +398,8 @@ class TaskBuilddataResource(StatefulResource):
@policy.ApiEnforcer('physical_provisioner:read_build_data') @policy.ApiEnforcer('physical_provisioner:read_build_data')
def on_get(self, req, resp, task_id): def on_get(self, req, resp, task_id):
try: try:
bd_list = self.state_manager.get_build_data(task_id=uuid.UUID(task_id)) bd_list = self.state_manager.get_build_data(
task_id=uuid.UUID(task_id))
if not bd_list: if not bd_list:
resp.status = falcon.HTTP_404 resp.status = falcon.HTTP_404
return return

View File

@ -41,6 +41,7 @@ import drydock_provisioner.drivers.node.maasdriver.models.rack_controller as maa
import drydock_provisioner.drivers.node.maasdriver.models.partition as maas_partition import drydock_provisioner.drivers.node.maasdriver.models.partition as maas_partition
import drydock_provisioner.drivers.node.maasdriver.models.volumegroup as maas_vg import drydock_provisioner.drivers.node.maasdriver.models.volumegroup as maas_vg
import drydock_provisioner.drivers.node.maasdriver.models.repository as maas_repo import drydock_provisioner.drivers.node.maasdriver.models.repository as maas_repo
import drydock_provisioner.drivers.node.maasdriver.models.domain as maas_domain
class BaseMaasAction(BaseAction): class BaseMaasAction(BaseAction):
@ -64,8 +65,8 @@ class BaseMaasAction(BaseAction):
data_format='text/plain', data_format='text/plain',
data_element=r.get_decoded_data()) data_element=r.get_decoded_data())
self.state_manager.post_build_data(bd) self.state_manager.post_build_data(bd)
log_href = "%s/tasks/%s/builddata" % ( log_href = "%s/tasks/%s/builddata" % (get_internal_api_href("v1.0"),
get_internal_api_href("v1.0"), str(self.task.task_id)) str(self.task.task_id))
self.task.result.add_link('detail_logs', log_href) self.task.result.add_link('detail_logs', log_href)
self.task.save() self.task.save()
@ -425,6 +426,9 @@ class CreateNetworkTemplate(BaseMaasAction):
subnets = maas_subnet.Subnets(self.maas_client) subnets = maas_subnet.Subnets(self.maas_client)
subnets.refresh() subnets.refresh()
domains = maas_domain.Domains(self.maas_client)
domains.refresh()
for l in design_links: for l in design_links:
if l.metalabels is not None: if l.metalabels is not None:
# TODO(sh8121att): move metalabels into config # TODO(sh8121att): move metalabels into config
@ -508,6 +512,18 @@ class CreateNetworkTemplate(BaseMaasAction):
continue continue
try: try:
domain = domains.singleton({'name': n.dns_domain})
if not domain:
self.logger.info(
'Network domain not found, adding: %s',
n.dns_domain)
domain = maas_domain.Domain(
self.maas_client,
name=n.dns_domain,
authoritative=False)
domain = domains.add(domain)
subnet = subnets.singleton({'cidr': n.cidr}) subnet = subnets.singleton({'cidr': n.cidr})
if subnet is None: if subnet is None:
@ -1042,8 +1058,8 @@ class IdentifyNode(BaseMaasAction):
for n in nodes: for n in nodes:
try: try:
machine = machine_list.identify_baremetal_node(n, machine = machine_list.identify_baremetal_node(
domain=n.get_domain(site_design)) n, domain=n.get_domain(site_design))
if machine is not None: if machine is not None:
self.task.success(focus=n.get_id()) self.task.success(focus=n.get_id())
self.task.add_status_msg( self.task.add_status_msg(
@ -1176,10 +1192,7 @@ class ConfigureHardware(BaseMaasAction):
'commission', 'commission',
result_type='commissioning') result_type='commissioning')
self._add_detail_logs( self._add_detail_logs(
n, n, machine, 'testing', result_type='testing')
machine,
'testing',
result_type='testing')
elif machine.status_name in ['Commissioning', 'Testing']: elif machine.status_name in ['Commissioning', 'Testing']:
msg = "Located node %s in MaaS, node already being commissioned. Skipping..." % ( msg = "Located node %s in MaaS, node already being commissioned. Skipping..." % (
n.name) n.name)
@ -2333,8 +2346,7 @@ class DeployNode(BaseMaasAction):
self.task.add_status_msg( self.task.add_status_msg(
msg=msg, error=True, ctx=n.name, ctx_type='node') msg=msg, error=True, ctx=n.name, ctx_type='node')
self.task.failure(focus=n.get_id()) self.task.failure(focus=n.get_id())
self._add_detail_logs( self._add_detail_logs(n, machine, 'deploy', result_type='deploy')
n, machine, 'deploy', result_type='deploy')
self.task.set_status(hd_fields.TaskStatus.Complete) self.task.set_status(hd_fields.TaskStatus.Complete)
self.task.save() self.task.save()

View File

@ -0,0 +1,31 @@
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model representing MaaS DNS domain resource."""
import drydock_provisioner.drivers.node.maasdriver.models.base as model_base
class Domain(model_base.ResourceBase):
"""Model for single domain."""
resource_url = 'domains/{resource_id}/'
fields = ['resource_id', 'name', 'authoritative', 'ttl']
json_fields = ['name', 'authoritative', 'ttl']
class Domains(model_base.ResourceCollectionBase):
"""Model for a collection of static routes."""
collection_url = 'domains/'
collection_resource = Domain

View File

@ -240,6 +240,7 @@ class BootActionAsset(base.DrydockObject):
node = site_design.get_baremetal_node(nodename) node = site_design.get_baremetal_node(nodename)
return dict( return dict(
hostname=nodename, hostname=nodename,
domain=node.get_domain(site_design),
tags=[t for t in node.tags], tags=[t for t in node.tags],
labels={k: v labels={k: v
for (k, v) in node.owner_data.items()}, for (k, v) in node.owner_data.items()},

View File

@ -90,3 +90,20 @@ class TestBootactionRenderAction(object):
assert 'bond0' in iface_ctx assert 'bond0' in iface_ctx
assert iface_ctx['bond0'].get('sriov') assert iface_ctx['bond0'].get('sriov')
assert iface_ctx['bond0'].get('vf_count') == 2 assert iface_ctx['bond0'].get('vf_count') == 2
def test_bootaction_node_domain(self, input_files, deckhand_orchestrator,
setup):
"""Test that a boot action creates proper node domain."""
input_file = input_files.join("deckhand_fullsite.yaml")
design_ref = "file://%s" % str(input_file)
design_status, design_data = deckhand_orchestrator.get_effective_site(
design_ref)
node_domain = "mgmt.sitename.example.com"
ba = design_data.get_bootaction('helloworld')
node_ctx = ba.asset_list[0]._get_node_context('compute01', design_data)
assert node_ctx['domain'] == node_domain