blob: 17037607c3de08e8bb60ba4181cd3451437e2f5e [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Constants and util methods for the inventory."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from skylab_inventory.protos import common_pb2
from skylab_inventory.protos import device_pb2
from skylab_inventory.protos import server_pb2
def invert_map(origin_map):
return {v: k for k, v in origin_map.iteritems()}
STATUS_MAP = {
'primary': server_pb2.Server.Status.Value('STATUS_PRIMARY'),
'backup': server_pb2.Server.Status.Value('STATUS_BACKUP'),
'repair_required': server_pb2.Server.Status.Value('STATUS_REPAIR_REQUIRED'),
}
ROLE_MAP = {
'afe': server_pb2.Server.Role.Value('ROLE_AFE'),
'crash_server': server_pb2.Server.Role.Value('ROLE_CRASH_SERVER'),
'database': server_pb2.Server.Role.Value('ROLE_DATABASE'),
'database_slave': server_pb2.Server.Role.Value('ROLE_DATABASE_SLAVE'),
'devserver': server_pb2.Server.Role.Value('ROLE_DEVSERVER'),
'drone': server_pb2.Server.Role.Value('ROLE_DRONE'),
'golo_proxy': server_pb2.Server.Role.Value('ROLE_GOLO_PROXY'),
'host_scheduler': server_pb2.Server.Role.Value('ROLE_HOST_SCHEDULER'),
'scheduler': server_pb2.Server.Role.Value('ROLE_SCHEDULER'),
'sentinel': server_pb2.Server.Role.Value('ROLE_SENTINEL'),
'shard': server_pb2.Server.Role.Value('ROLE_SHARD'),
'suite_scheduler': server_pb2.Server.Role.Value('ROLE_SUITE_SCHEDULER'),
'skylab_drone': server_pb2.Server.Role.Value('ROLE_SKYLAB_DRONE'),
'skylab_suite_proxy': server_pb2.Server.Role.Value(
'ROLE_SKYLAB_SUITE_PROXY'),
}
ENVIRONMENT_MAP = {
'prod': common_pb2.Environment.Value('ENVIRONMENT_PROD'),
'staging': common_pb2.Environment.Value('ENVIRONMENT_STAGING'),
}
SERVER_ATTRIBUTE_TYPE_MAP = {
'ip': str,
'max_processes': int,
'mysql_server_id': str,
'devserver_restricted_subnet': str,
'devserver_port': int,
}
DUT_POOL_MAP = {
'cq': device_pb2.SchedulableLabels.DUTPool.Value('DUT_POOL_CQ'),
'bvt': device_pb2.SchedulableLabels.DUTPool.Value('DUT_POOL_BVT'),
'suites': device_pb2.SchedulableLabels.DUTPool.Value('DUT_POOL_SUITES'),
'cts': device_pb2.SchedulableLabels.DUTPool.Value('DUT_POOL_CTS'),
'cts_prebuild': device_pb2.SchedulableLabels.DUTPool.Value(
'DUT_POOL_CTS_PERBUILD'),
}
INVERTED_DUT_POOL_MAP = invert_map(DUT_POOL_MAP)
EC_TYPE_MAP = {
'invalid': device_pb2.SchedulableLabels.ECType.Value('EC_TYPE_INVALID'),
'chromeos': device_pb2.SchedulableLabels.ECType.Value('EC_TYPE_CHROME_OS'),
}
INVERTED_EC_TYPE_MAP = invert_map(EC_TYPE_MAP)
DEVICE_TYPE_TO_CLASS_MAP = {
'duts': device_pb2.DeviceUnderTest,
'servo_hosts': device_pb2.ServoHostDevice,
'chamelons': device_pb2.ChameleonDevice,
}
CONNECTION_TYPES = {'servo_host_connections', 'chameleon_connections'}
DATA_SUBDIR = {'prod', 'staging', 'skylab'}
HARDWARE_CAPABILITIES_LABELS = {'modem', 'telephony', 'gpu_family', 'graphics',
'storage', 'power'}
TOPLEVEL_LABELS = {'platform', 'board', 'model', 'critical_pool',
'self_serve_pool', 'ec_type'}
SCHEDULABLE_LABELS = TOPLEVEL_LABELS | HARDWARE_CAPABILITIES_LABELS
# Each device should only have one label value for the unique label key.
UNIQUE_LABEL_KEY = ({'platform', 'board', 'model', 'ec_type'} |
HARDWARE_CAPABILITIES_LABELS)
class InvalidDataException(Exception):
"""Error raised when the data provided is invalid."""
class InvalidDataSubdir(InvalidDataException):
"""Error raised when the data_subdir is invalid."""
class InvalidEnvironment(InvalidDataException):
"""Error raised when environment is invalid."""
class InvalidEnvironmentSet(InvalidDataException):
"""Error raised when environment set is invalid."""
class InvalidRole(InvalidDataException):
"""Error raised when role is invalid."""
class InvalidStatus(InvalidDataException):
"""Error raised when status is invalid."""
class InvalidAttribute(InvalidDataException):
"""Error raised when attribute is invalid."""
class InvalidDeviceType(InvalidDataException):
"""Error raised when device_type is invalid."""
def validate_data_subdir(subdir):
"""Validate the subdir is one of DATA_SUBDIR.
Args:
subdir: The path to the data sub-directory.
"""
if subdir not in DATA_SUBDIR:
raise InvalidDataSubdir('Got %s. Data subdir must be one of %s. ' %
(subdir, DATA_SUBDIR))
def validate_environment(environment):
"""Validate that environment is one of ENVIRONMENT_MAP.keys.
Args:
environment: An environment of inventory data.
Returns:
Enum value for environment in ENVIRONMENT_MAP.
"""
if environment not in ENVIRONMENT_MAP.keys():
raise InvalidEnvironment('Got %s. environment must be one of %s. ' %
(environment, ENVIRONMENT_MAP.keys()))
return ENVIRONMENT_MAP[environment]
def validate_environments(environments):
"""Validate environments is a subset of ENVIRONMENT_MAP.keys.
Args:
environments: A set of environments of inventory data.
Returns:
A set of enum values for |environments| in ENVIRONMENT_MAP.
"""
if not isinstance(environments, set):
raise InvalidEnvironmentSet('Got environments in %s type. environments must'
' be a set.' % type(environments))
environment_values = set()
for e in environments:
environment_values.add(validate_environment(e))
return environment_values
def validate_server_role(role):
"""Validate server role is one of ROLE_MAP.keys.
Args:
role: server role.
"""
if role not in ROLE_MAP.keys():
raise InvalidRole('Got %s. role must be one of %s. ' %
(role, ROLE_MAP.keys()))
def validate_server_status(status):
"""Validate server status is one of STATUS_MAP.keys.
Args:
status: server status.
"""
if status not in STATUS_MAP.keys():
raise InvalidStatus('Got %s. status must be one of %s.' %
(status, STATUS_MAP.keys()))
def validate_server_attribute(attribute):
"""Validate server attribute is one of SERVER_ATTRIBUTE_TYPE_MAP.keys.
Args:
attribute: The key of server attribute.
"""
if attribute not in SERVER_ATTRIBUTE_TYPE_MAP:
raise InvalidAttribute('Got %s. attribute key must be one of %s. ' %
(attribute, SERVER_ATTRIBUTE_TYPE_MAP.keys()))
def validate_device_type(device_type):
"""Validate device_type is one of DEVICE_TYPE_TO_CLASS_MAP.keys.
Args:
device_type: a type of device.
"""
if device_type not in DEVICE_TYPE_TO_CLASS_MAP:
raise InvalidDeviceType('Got %s. device_type must be one of %s' %
(device_type, DEVICE_TYPE_TO_CLASS_MAP.keys()))