[443514] Set domain for nodes during deployment

- Resolve the FQDN of node based on the DNS domain of the primary
  network
- When identifying the node in MAAS, set the hostname and the domain
  for the node

Change-Id: I1fc5d89e07784ae8168461bcf4ffe400956616f9
This commit is contained in:
Scott Hussey 2018-08-03 07:57:06 -05:00
parent e2b3e8ee8e
commit 89ce941202
4 changed files with 107 additions and 3 deletions

View File

@ -1042,7 +1042,8 @@ class IdentifyNode(BaseMaasAction):
for n in nodes:
try:
machine = machine_list.identify_baremetal_node(n)
machine = machine_list.identify_baremetal_node(n,
domain=n.get_domain(site_design))
if machine is not None:
self.task.success(focus=n.get_id())
self.task.add_status_msg(

View File

@ -47,8 +47,9 @@ class Machine(model_base.ResourceBase):
'owner_data',
'block_devices',
'volume_groups',
'domain'
]
json_fields = ['hostname', 'power_type']
json_fields = ['hostname', 'power_type', 'domain']
def __init__(self, api_client, **kwargs):
super(Machine, self).__init__(api_client, **kwargs)
@ -533,7 +534,7 @@ class Machines(model_base.ResourceCollectionBase):
return node
def identify_baremetal_node(self, node_model, update_name=True):
def identify_baremetal_node(self, node_model, update_name=True, domain="local"):
"""Find MaaS node resource matching Drydock BaremetalNode.
Search all the defined MaaS Machines and attempt to match
@ -583,6 +584,7 @@ class Machines(model_base.ResourceCollectionBase):
if maas_node.hostname != node_model.name and update_name:
try:
maas_node.hostname = node_model.name
maas_node.domain = domain
maas_node.update()
if node_model.oob_type == 'libvirt':
self.logger.debug(

View File

@ -94,6 +94,41 @@ class BaremetalNode(drydock_provisioner.objects.hostprofile.HostProfile):
return
def get_domain(self, site_design):
"""Return the domain for this node.
The domain for this is the DNS domain of the primary network or local.
:param SiteDesign site_design: A instance containing definitions for the networks
this node is attached to.
"""
try:
pn = site_design.get_network(self.primary_network)
domain = pn.dns_domain or "local"
except errors.DesignError as dex:
self.logger.debug("Primary network not found, use domain 'local'.")
domain = "local"
except AttributeError as aex:
self.logger.debug("Primary network does not define a domain, use domain 'local'.")
domain = "local"
return domain
def get_fqdn(self, site_design):
"""Returns the FQDN for this node.
The FQDN for this node is composed of the node hostname ``self.name`` appended
with the domain name of the primary network if defined. If the primary network
does not define a domain name, the domain is ``local``.
:param site_design: A SiteDesign instance containing definitions for the networks
the node is attached to.
"""
hostname = self.name
domain = self.get_domain(site_design)
return "{}.{}".format(hostname, domain)
def resolve_kernel_params(self, site_design):
"""Check if any kernel parameter values are supported references."""
if not self.hardware_profile:

View File

@ -0,0 +1,66 @@
# 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.
"""Test node model hostname and FQDN."""
import drydock_provisioner.objects as objects
class TestNodeNaming(object):
def test_node_fqdn(self, deckhand_orchestrator, input_files, setup):
"""Test fqdn rendering."""
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)
assert design_status.status == objects.fields.ValidationResult.Success
# From the sample YAML, the domain assigned to the 'mgmt' network
# is 'mgmt.sitename.example.com'. This is the primary network for
# 'controller01'
nodename = 'controller01'
expected_fqdn = '{}.{}'.format(nodename, 'mgmt.sitename.example.com')
node_model = design_data.get_baremetal_node(nodename)
assert node_model
assert node_model.get_fqdn(design_data) == expected_fqdn
def test_node_domain(self, deckhand_orchestrator, input_files, setup):
"""Test domain rendering."""
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)
assert design_status.status == objects.fields.ValidationResult.Success
# From the sample YAML, the domain assigned to the 'mgmt' network
# is 'mgmt.sitename.example.com'. This is the primary network for
# 'controller01'
node_name = 'controller01'
expected_domain = 'mgmt.sitename.example.com'
node_model = design_data.get_baremetal_node(node_name)
assert node_model
assert node_model.get_domain(design_data) == expected_domain