# 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.

import logging
import voluptuous as v
import yaml

log = logging.getLogger(__name__)


class ConfigValidator:
    """Check the layout and certain configuration options"""

    def __init__(self, config_file):
        self.config_file = config_file

    def validate(self):
        cron = {
            'check': str,
            'cleanup': str,
            'image-update': str,
        }

        images = {
            'name': str,
            'base-image': str,
            'min-ram': int,
            'name-filter': str,
            'diskimage': str,
            'meta': dict,
            'setup': str,
            'username': str,
            'private-key': str,
            'config-drive': bool,
        }

        providers = {
            'name': str,
            'region-name': str,
            'service-type': str,
            'service-name': str,
            'availability-zones': [str],
            'keypair': str,
            'cloud': str,
            'username': str,
            'password': str,
            'auth-url': str,
            'project-id': str,
            'max-servers': int,
            'pool': str,
            'image-type': str,
            'networks': [{
                'net-id': str,
                'net-label': str,
            }],
            'boot-timeout': int,
            'api-timeout': int,
            'rate': float,
            'images': [images]
        }

        labels = {
            'name': str,
            'image': str,
            'min-ready': int,
            'ready-script': str,
            'subnodes': int,
            'providers': [{
                'name': str,
            }],
        }

        targets = {
            'name': str,
            'jenkins': {
                'url': str,
                'user': str,
                'apikey': str,
                'credentials-id': str,
            }
        }

        diskimages = {
            'name': str,
            'elements': [str],
            'release': v.Any(str, int),
            'env-vars': dict,
        }

        top_level = {
            'script-dir': str,
            'elements-dir': str,
            'images-dir': str,
            'dburi': str,
            'zmq-publishers': [str],
            'gearman-servers': [{
                'host': str
            }],
            'cron': cron,
            'providers': [providers],
            'labels': [labels],
            'targets': [targets],
            'diskimages': [diskimages],
        }

        log.info("validating %s" % self.config_file)
        config = yaml.load(open(self.config_file))

        # validate the overall schema
        schema = v.Schema(top_level)
        schema(config)

        # labels must list valid providers
        all_providers = [p['name'] for p in config['providers']]
        for label in config['labels']:
            for provider in label['providers']:
                if not provider['name'] in all_providers:
                    raise AssertionError('label %s requests '
                                         'non-existent provider %s'
                                         % (label['name'], provider['name']))

@@ -1926,16 +1926,54 @@
 %5Bimages%5D
+,%0A            'template-hostname': str
 %0A       
@@ -2259,32 +2259,98 @@
    'name': str,%0A
+            'hostname': str,%0A            'subnode-hostname': str,%0A
             'jen

Add hostname templates to config validator