Merge "Remove tpmconfig Sysinv APIs"
This commit is contained in:
commit
aa74264a26
@ -11,21 +11,38 @@
|
||||
import os
|
||||
from cgtsclient import exc
|
||||
from cgtsclient.common import utils
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
def _print_certificate_show(certificate):
|
||||
fields = ['uuid', 'certtype', 'signature', 'start_date', 'expiry_date']
|
||||
if type(certificate) is dict:
|
||||
data = [(f, certificate.get(f, '')) for f in fields]
|
||||
details = ('details', certificate.get('details', ''))
|
||||
else:
|
||||
data = [(f, getattr(certificate, f, '')) for f in fields]
|
||||
details = ('details', getattr(certificate, 'details', ''))
|
||||
if details[1]:
|
||||
data.append(details)
|
||||
|
||||
utils.print_tuple_list(data)
|
||||
|
||||
|
||||
@utils.arg('certificate_uuid', metavar='<certificate_uuid>',
|
||||
help="UUID of certificate")
|
||||
help="UUID of certificate or the reserved word 'tpm' "
|
||||
"to show TPM certificate")
|
||||
def do_certificate_show(cc, args):
|
||||
"""Show Certificate details."""
|
||||
if args.certificate_uuid == 'tpm':
|
||||
certificates = cc.certificate.list()
|
||||
for cert in certificates:
|
||||
if cert.certtype == 'tpm_mode':
|
||||
args.certificate_uuid = cert.uuid
|
||||
break
|
||||
else:
|
||||
print "No TPM certificate installed"
|
||||
return
|
||||
|
||||
certificate = cc.certificate.get(args.certificate_uuid)
|
||||
if certificate:
|
||||
_print_certificate_show(certificate)
|
||||
|
@ -69,7 +69,6 @@ from cgtsclient.v1 import sm_servicegroup
|
||||
from cgtsclient.v1 import health
|
||||
from cgtsclient.v1 import remotelogging
|
||||
from cgtsclient.v1 import sdn_controller
|
||||
from cgtsclient.v1 import tpmconfig
|
||||
from cgtsclient.v1 import firewallrules
|
||||
from cgtsclient.v1 import partition
|
||||
from cgtsclient.v1 import certificate
|
||||
@ -141,7 +140,6 @@ class Client(http.HTTPClient):
|
||||
self.health = health.HealthManager(self)
|
||||
self.remotelogging = remotelogging.RemoteLoggingManager(self)
|
||||
self.sdn_controller = sdn_controller.SDNControllerManager(self)
|
||||
self.tpmconfig = tpmconfig.TpmConfigManager(self)
|
||||
self.firewallrules = firewallrules.FirewallRulesManager(self)
|
||||
self.partition = partition.partitionManager(self)
|
||||
self.license = license.LicenseManager(self)
|
||||
|
@ -55,7 +55,6 @@ from cgtsclient.v1 import license_shell
|
||||
from cgtsclient.v1 import health_shell
|
||||
from cgtsclient.v1 import remotelogging_shell
|
||||
from cgtsclient.v1 import sdn_controller_shell
|
||||
from cgtsclient.v1 import tpmconfig_shell
|
||||
from cgtsclient.v1 import firewallrules_shell
|
||||
from cgtsclient.v1 import partition_shell
|
||||
from cgtsclient.v1 import certificate_shell
|
||||
@ -108,7 +107,6 @@ COMMAND_MODULES = [
|
||||
health_shell,
|
||||
remotelogging_shell,
|
||||
sdn_controller_shell,
|
||||
tpmconfig_shell,
|
||||
firewallrules_shell,
|
||||
partition_shell,
|
||||
license_shell,
|
||||
|
@ -1,50 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2017 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
|
||||
from cgtsclient.common import base
|
||||
from cgtsclient import exc
|
||||
|
||||
CREATION_ATTRIBUTES = ['cert_path', 'public_path', 'tpm_path']
|
||||
|
||||
|
||||
class TpmConfig(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<tpmconfig %s>" % self._info
|
||||
|
||||
|
||||
class TpmConfigManager(base.Manager):
|
||||
resource_class = TpmConfig
|
||||
|
||||
@staticmethod
|
||||
def _path(id=None):
|
||||
return '/v1/tpmconfig/%s' % id if id else '/v1/tpmconfig'
|
||||
|
||||
def list(self):
|
||||
return self._list(self._path(), "tpmconfigs")
|
||||
|
||||
def get(self, tpmconfig_id):
|
||||
try:
|
||||
return self._list(self._path(tpmconfig_id))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exc.InvalidAttribute('%s' % key)
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self, tpmconfig_id):
|
||||
return self._delete(self._path(tpmconfig_id))
|
||||
|
||||
def update(self, tpmconfig_id, patch):
|
||||
return self._update(self._path(tpmconfig_id), patch)
|
@ -1,130 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2017 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# All Rights Reserved.
|
||||
#
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
|
||||
from cgtsclient.common import utils
|
||||
from cgtsclient import exc
|
||||
|
||||
|
||||
def _print_tpmconfig_show(tpmconfig):
|
||||
fields = ['uuid',
|
||||
'tpm_path',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'state',
|
||||
]
|
||||
data = [(f, getattr(tpmconfig, f, '')) for f in fields]
|
||||
utils.print_tuple_list(data)
|
||||
|
||||
def do_tpmconfig_show(cc, args):
|
||||
"""Show TPM config details."""
|
||||
|
||||
tpmconfigs = cc.tpmconfig.list()
|
||||
if not tpmconfigs:
|
||||
return
|
||||
_print_tpmconfig_show(tpmconfigs[0])
|
||||
|
||||
@utils.arg('--cert_path',
|
||||
metavar='<cert_path>',
|
||||
default=None,
|
||||
help="Path to certificate to upload to TPM.")
|
||||
@utils.arg('--public_path',
|
||||
metavar='<public_path>',
|
||||
default=None,
|
||||
help="Path to store public certificate.")
|
||||
@utils.arg('--tpm_path',
|
||||
metavar='<tpm_path>',
|
||||
default=None,
|
||||
help="Path to store TPM object context")
|
||||
def do_tpmconfig_add(cc, args):
|
||||
"""Add TPM configuration."""
|
||||
|
||||
field_list = ['cert_path', 'public_path', 'tpm_path']
|
||||
|
||||
# use field list as filter
|
||||
user_specified_fields = dict((k, v) for (k, v) in vars(args).items()
|
||||
if k in field_list and not (v is None))
|
||||
try:
|
||||
tpmconfig = cc.tpmconfig.create(**user_specified_fields)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError("Failed to create TPM configuration entry: "
|
||||
"fields %s" % user_specified_fields)
|
||||
uuid = getattr(tpmconfig, 'uuid', '')
|
||||
try:
|
||||
tpmconfig = cc.tpmconfig.get(uuid)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError("Created TPM configuration UUID not found: %s"
|
||||
% uuid)
|
||||
_print_tpmconfig_show(tpmconfig)
|
||||
|
||||
def do_tpmconfig_delete(cc, args):
|
||||
"""Delete a TPM configuration."""
|
||||
try:
|
||||
tpmconfigs = cc.tpmconfig.list()
|
||||
if not tpmconfigs:
|
||||
return
|
||||
tpmconfig = tpmconfigs[0]
|
||||
|
||||
cc.tpmconfig.delete(tpmconfig.uuid)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError("Failed to delete TPM configuration entry: "
|
||||
"no configuration found")
|
||||
print 'Deleted TPM configuration: uuid %s' % tpmconfig.uuid
|
||||
|
||||
@utils.arg('--cert_path',
|
||||
metavar='<cert_path>',
|
||||
default=None,
|
||||
help="Path to certificate to upload to TPM.")
|
||||
@utils.arg('--public_path',
|
||||
metavar='<public_path>',
|
||||
default=None,
|
||||
help="Path to store public certificate.")
|
||||
@utils.arg('--tpm_path',
|
||||
metavar='<tpm_path>',
|
||||
default=None,
|
||||
help="Path to store TPM object context")
|
||||
def do_tpmconfig_modify(cc, args):
|
||||
"""Modify a TPM configuration."""
|
||||
# find the TPM configuration first
|
||||
tpmconfig = None
|
||||
try:
|
||||
tpmconfigs = cc.tpmconfig.list()
|
||||
if tpmconfigs:
|
||||
tpmconfig = tpmconfigs[0]
|
||||
|
||||
field_list = ['cert_path', 'public_path', 'tpm_path']
|
||||
# use field list as filter
|
||||
user_fields = dict((k, v) for (k, v) in vars(args).items()
|
||||
if k in field_list and not (v is None))
|
||||
configured_fields = tpmconfig.__dict__
|
||||
configured_fields.update(user_fields)
|
||||
|
||||
patch = []
|
||||
for (k,v) in user_fields.items():
|
||||
patch.append({'op': 'replace', 'path': '/' + k, 'value': v})
|
||||
try:
|
||||
updated_tpmconfig = cc.tpmconfig.update(tpmconfig.uuid, patch)
|
||||
except:
|
||||
raise exc.CommandError("Failed to modify TPM configuration: "
|
||||
"tpmconfig %s : patch %s" %
|
||||
(tpmconfig.uuid, patch))
|
||||
|
||||
_print_tpmconfig_show(updated_tpmconfig)
|
||||
return
|
||||
except exc.HTTPNotFound:
|
||||
pass
|
||||
finally:
|
||||
if not tpmconfig:
|
||||
raise exc.CommandError("Failed to modify TPM configuration: "
|
||||
"no configuration found")
|
@ -75,7 +75,6 @@ from sysinv.api.controllers.v1 import storage_external
|
||||
from sysinv.api.controllers.v1 import storage_tier
|
||||
from sysinv.api.controllers.v1 import system
|
||||
from sysinv.api.controllers.v1 import trapdest
|
||||
from sysinv.api.controllers.v1 import tpmconfig
|
||||
from sysinv.api.controllers.v1 import upgrade
|
||||
from sysinv.api.controllers.v1 import user
|
||||
|
||||
@ -220,9 +219,6 @@ class V1(base.APIBase):
|
||||
sdn_controller = [link.Link]
|
||||
"Links to the SDN controller resource"
|
||||
|
||||
tpmconfig = [link.Link]
|
||||
"Links to the TPM configuration resource"
|
||||
|
||||
firewallrules = [link.Link]
|
||||
"Links to customer firewall rules"
|
||||
|
||||
@ -688,14 +684,6 @@ class V1(base.APIBase):
|
||||
bookmark=True)
|
||||
]
|
||||
|
||||
v1.tpmconfig = [link.Link.make_link('self',
|
||||
pecan.request.host_url,
|
||||
'tpmconfig', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.host_url,
|
||||
'tpmconfig', '',
|
||||
bookmark=True)]
|
||||
|
||||
v1.firewallrules = [link.Link.make_link('self',
|
||||
pecan.request.host_url,
|
||||
'firewallrules', ''),
|
||||
@ -771,7 +759,6 @@ class Controller(rest.RestController):
|
||||
health = health.HealthController()
|
||||
remotelogging = remotelogging.RemoteLoggingController()
|
||||
sdn_controller = sdn_controller.SDNControllerController()
|
||||
tpmconfig = tpmconfig.TPMConfigController()
|
||||
firewallrules = firewallrules.FirewallRulesController()
|
||||
license = license.LicenseController()
|
||||
|
||||
|
@ -84,6 +84,9 @@ class Certificate(base.APIBase):
|
||||
mode = wtypes.text
|
||||
"Represents the desired mode"
|
||||
|
||||
details = types.MultiType({dict})
|
||||
"Represents additional details of the certificate"
|
||||
|
||||
updated_at = wtypes.datetime.datetime
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@ -93,6 +96,11 @@ class Certificate(base.APIBase):
|
||||
continue
|
||||
setattr(self, k, kwargs.get(k, wtypes.Unset))
|
||||
|
||||
# 'details' is not part of the object.certificate.fields
|
||||
# (it is an API-only attribute)
|
||||
self.fields.append('details')
|
||||
setattr(self, 'details', kwargs.get('details', None))
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, rpc_certificate, expand=False):
|
||||
certificate = Certificate(**rpc_certificate.as_dict())
|
||||
@ -101,9 +109,13 @@ class Certificate(base.APIBase):
|
||||
'certtype',
|
||||
'issuer',
|
||||
'signature',
|
||||
'details',
|
||||
'start_date',
|
||||
'expiry_date'])
|
||||
|
||||
# insert details for this certificate if they exist
|
||||
certificate = _insert_certificate_details(certificate)
|
||||
|
||||
certificate.links = \
|
||||
[link.Link.make_link('self', pecan.request.host_url,
|
||||
'certificates', certificate.uuid),
|
||||
@ -146,18 +158,31 @@ def _check_certificate_data(certificate):
|
||||
return certificate
|
||||
|
||||
|
||||
def _clear_existing_certificate_alarms():
|
||||
# Clear all existing CERTIFICATE configuration alarms,
|
||||
# for one or both controller hosts
|
||||
obj = fm_api.FaultAPIs()
|
||||
|
||||
alarms = obj.get_faults_by_id(fm_constants.FM_ALARM_ID_CERTIFICATE_INIT)
|
||||
if not alarms:
|
||||
def _insert_certificate_details(certificate):
|
||||
if not certificate:
|
||||
return
|
||||
for alarm in alarms:
|
||||
obj.clear_fault(
|
||||
fm_constants.FM_ALARM_ID_CERTIFICATE_INIT,
|
||||
alarm.entity_instance_id)
|
||||
|
||||
if certificate.certtype == constants.CERT_MODE_TPM:
|
||||
try:
|
||||
tpmconfig = pecan.request.dbapi.tpmconfig_get_one()
|
||||
except exception.NotFound:
|
||||
return certificate
|
||||
|
||||
tpmdevices = pecan.request.dbapi.tpmdevice_get_list()
|
||||
certificate.details = {}
|
||||
states = {}
|
||||
for device in tpmdevices:
|
||||
# extract the state info per host
|
||||
ihost = pecan.request.dbapi.ihost_get(device['host_id'])
|
||||
if ihost:
|
||||
states[ihost.hostname] = device.state
|
||||
if tpmdevices:
|
||||
certificate.details['state'] = states
|
||||
if tpmconfig.updated_at:
|
||||
certificate.details['updated_at'] = \
|
||||
tpmconfig.updated_at.isoformat()
|
||||
|
||||
return certificate
|
||||
|
||||
|
||||
LOCK_NAME = 'CertificateController'
|
||||
@ -251,7 +276,14 @@ class CertificateController(rest.RestController):
|
||||
fileitem = pecan.request.POST['file']
|
||||
passphrase = pecan.request.POST.get('passphrase')
|
||||
mode = pecan.request.POST.get('mode')
|
||||
|
||||
certificate_file = pecan.request.POST.get('certificate_file')
|
||||
# Ensure that the certificate_file is a valid file path
|
||||
if os.path.isabs(certificate_file):
|
||||
if not os.path.isfile(certificate_file):
|
||||
msg = "'certificate_file' is not a valid file path"
|
||||
LOG.info(msg)
|
||||
return dict(success="", error=msg)
|
||||
|
||||
LOG.info("certificate %s mode=%s" % (log_start, mode))
|
||||
|
||||
|
@ -1,386 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
#
|
||||
# Copyright 2013 UnitedStack Inc.
|
||||
# All 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.
|
||||
#
|
||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
import jsonpatch
|
||||
import os
|
||||
|
||||
import pecan
|
||||
from pecan import rest
|
||||
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from sysinv.api.controllers.v1 import base
|
||||
from sysinv.api.controllers.v1 import collection
|
||||
from sysinv.api.controllers.v1 import link
|
||||
from sysinv.api.controllers.v1 import types
|
||||
from sysinv.api.controllers.v1 import utils
|
||||
from sysinv.common import constants
|
||||
from sysinv.common import exception
|
||||
from sysinv.common import utils as cutils
|
||||
from sysinv import objects
|
||||
from sysinv.openstack.common import excutils
|
||||
from sysinv.openstack.common.gettextutils import _
|
||||
from sysinv.openstack.common import log
|
||||
|
||||
from fm_api import constants as fm_constants
|
||||
from fm_api import fm_api
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class TPMConfigPatchType(types.JsonPatchType):
|
||||
@staticmethod
|
||||
def mandatory_attrs():
|
||||
return []
|
||||
|
||||
|
||||
class TPMConfig(base.APIBase):
|
||||
"""API representation of TPM Configuration.
|
||||
|
||||
This class enforces type checking and value constraints, and converts
|
||||
between the internal object model and the API representation of
|
||||
an tpmconfig.
|
||||
"""
|
||||
|
||||
uuid = types.uuid
|
||||
"Unique UUID for this tpmconfig"
|
||||
|
||||
cert_path = wtypes.text
|
||||
"Represents the path of the SSL certificate to be stored in TPM"
|
||||
|
||||
public_path = wtypes.text
|
||||
"Represents the path of the SSL public key"
|
||||
|
||||
tpm_path = wtypes.text
|
||||
"Represents the path to store TPM certificate"
|
||||
|
||||
state = types.MultiType({dict})
|
||||
"Represents the state of the TPM config"
|
||||
|
||||
links = [link.Link]
|
||||
"A list containing a self link and associated tpmconfig links"
|
||||
|
||||
created_at = wtypes.datetime.datetime
|
||||
updated_at = wtypes.datetime.datetime
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = objects.tpmconfig.fields.keys()
|
||||
for k in self.fields:
|
||||
setattr(self, k, kwargs.get(k))
|
||||
|
||||
# 'cert_path' and 'public_path' are
|
||||
# not part of objects.tpmconfig.fields
|
||||
# (they are an API-only attribute)
|
||||
for fp in ['cert_path', 'public_path']:
|
||||
self.fields.append(fp)
|
||||
setattr(self, fp, kwargs.get(fp, None))
|
||||
|
||||
# 'state' is not part of objects.tpmconfig.fields
|
||||
# (it is an API-only attribute)
|
||||
self.fields.append('state')
|
||||
setattr(self, 'state', kwargs.get('state', None))
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, rpc_tpmconfig, expand=True):
|
||||
|
||||
tpm = TPMConfig(**rpc_tpmconfig.as_dict())
|
||||
if not expand:
|
||||
tpm.unset_fields_except(['uuid',
|
||||
'cert_path',
|
||||
'public_path',
|
||||
'tpm_path',
|
||||
'state',
|
||||
'created_at',
|
||||
'updated_at'])
|
||||
# insert state
|
||||
tpm = _insert_tpmdevices_state(tpm)
|
||||
|
||||
tpm.links = [link.Link.make_link('self', pecan.request.host_url,
|
||||
'tpmconfigs', tpm.uuid),
|
||||
link.Link.make_link('bookmark', pecan.request.host_url,
|
||||
'tpmconfigs', tpm.uuid,
|
||||
bookmark=True)]
|
||||
|
||||
return tpm
|
||||
|
||||
|
||||
class TPMConfigCollection(collection.Collection):
|
||||
"""API representation of a collection of tpmconfigs."""
|
||||
|
||||
tpmconfigs = [TPMConfig]
|
||||
"A list containing tpmconfig objects"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._type = 'tpmconfigs'
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, rpc_tpmconfigs, limit, url=None,
|
||||
expand=False, **kwargs):
|
||||
collection = TPMConfigCollection()
|
||||
collection.tpmconfigs = [TPMConfig.convert_with_links(p, expand)
|
||||
for p in rpc_tpmconfigs]
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
return collection
|
||||
|
||||
|
||||
##############
|
||||
# UTILS
|
||||
##############
|
||||
|
||||
def _check_tpmconfig_data(tpmconfig):
|
||||
|
||||
if not utils.get_https_enabled():
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Cannot configure TPM without HTTPS mode being enabled"))
|
||||
|
||||
if not tpmconfig.get('cert_path', None):
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Cannot configure TPM without cert_path provided"))
|
||||
|
||||
if not tpmconfig.get('public_path', None):
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Cannot configure TPM without public_path provided"))
|
||||
|
||||
if not tpmconfig.get('tpm_path', None):
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Cannot configure TPM without tpm_path provided"))
|
||||
|
||||
# validate the key paths
|
||||
values = [tpmconfig['cert_path'],
|
||||
tpmconfig['tpm_path'],
|
||||
tpmconfig['public_path']]
|
||||
|
||||
for i, item in enumerate(values):
|
||||
# ensure valid paths
|
||||
if os.path.isabs(item):
|
||||
if i == 0:
|
||||
# ensure key exists
|
||||
if not os.path.isfile(item):
|
||||
raise wsme.exc.ClientSideError(_(
|
||||
"Cert path is not a valid existing file"))
|
||||
else:
|
||||
raise wsme.exc.ClientSideError(_(
|
||||
"TPM configuration arguments must be file paths"))
|
||||
return tpmconfig
|
||||
|
||||
|
||||
def _clear_existing_tpmconfig_alarms():
|
||||
# Clear all existing TPM configuration alarms,
|
||||
# for one or both controller hosts
|
||||
obj = fm_api.FaultAPIs()
|
||||
|
||||
alarms = obj.get_faults_by_id(
|
||||
fm_constants.FM_ALARM_ID_TPM_INIT)
|
||||
if not alarms:
|
||||
return
|
||||
for alarm in alarms:
|
||||
obj.clear_fault(
|
||||
fm_constants.FM_ALARM_ID_TPM_INIT,
|
||||
alarm.entity_instance_id)
|
||||
|
||||
|
||||
def _insert_tpmdevices_state(tpmconfig):
|
||||
# update the tpmconfig state with the per host
|
||||
# tpmdevice state
|
||||
if not tpmconfig:
|
||||
return
|
||||
tpmdevices = pecan.request.dbapi.tpmdevice_get_list()
|
||||
tpmconfig.state = {}
|
||||
for device in tpmdevices:
|
||||
# extract the state info per host
|
||||
ihost = pecan.request.dbapi.ihost_get(device['host_id'])
|
||||
if ihost:
|
||||
tpmconfig.state[ihost.hostname] = device.state
|
||||
return tpmconfig
|
||||
|
||||
|
||||
class TPMConfigController(rest.RestController):
|
||||
"""REST controller for tpmconfigs."""
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
self._parent = parent
|
||||
|
||||
def _get_tpmconfigs_collection(self, uuid, marker, limit,
|
||||
sort_key, sort_dir, expand=False,
|
||||
resource_url=None):
|
||||
|
||||
limit = utils.validate_limit(limit)
|
||||
sort_dir = utils.validate_sort_dir(sort_dir)
|
||||
|
||||
marker_obj = None
|
||||
if marker:
|
||||
marker_obj = objects.tpmconfig.get_by_uuid(pecan.request.context,
|
||||
marker)
|
||||
|
||||
tpms = pecan.request.dbapi.tpmconfig_get_list(limit,
|
||||
marker_obj,
|
||||
sort_key=sort_key,
|
||||
sort_dir=sort_dir)
|
||||
|
||||
return TPMConfigCollection.convert_with_links(tpms, limit,
|
||||
url=resource_url,
|
||||
expand=expand,
|
||||
sort_key=sort_key,
|
||||
sort_dir=sort_dir)
|
||||
|
||||
def _get_updates(self, patch):
|
||||
"""Retrieve the updated attributes from the patch request."""
|
||||
updates = {}
|
||||
for p in patch:
|
||||
attribute = p['path'] if p['path'][0] != '/' else p['path'][1:]
|
||||
updates[attribute] = p['value']
|
||||
return updates
|
||||
|
||||
@wsme_pecan.wsexpose(TPMConfigCollection, types.uuid, types.uuid, int,
|
||||
wtypes.text, wtypes.text)
|
||||
def get_all(self, uuid=None, marker=None, limit=None,
|
||||
sort_key='id', sort_dir='asc'):
|
||||
"""Retrieve a list of tpmconfigs. Only one per system"""
|
||||
return self._get_tpmconfigs_collection(uuid, marker, limit,
|
||||
sort_key, sort_dir)
|
||||
|
||||
@wsme_pecan.wsexpose(TPMConfig, types.uuid)
|
||||
def get_one(self, tpmconfig_uuid):
|
||||
"""Retrieve information about the given tpmconfig."""
|
||||
rpc_tpmconfig = objects.tpmconfig.get_by_uuid(pecan.request.context,
|
||||
tpmconfig_uuid)
|
||||
return TPMConfig.convert_with_links(rpc_tpmconfig)
|
||||
|
||||
@wsme_pecan.wsexpose(TPMConfig, body=TPMConfig)
|
||||
def post(self, tpmconfig):
|
||||
"""Create a new tpmconfig."""
|
||||
# There must not already be an existing tpm config
|
||||
try:
|
||||
tpm = pecan.request.dbapi.tpmconfig_get_one()
|
||||
except exception.NotFound:
|
||||
pass
|
||||
else:
|
||||
raise wsme.exc.ClientSideError(_(
|
||||
"tpmconfig rejected: A TPM configuration already exists."))
|
||||
|
||||
_check_tpmconfig_data(tpmconfig.as_dict())
|
||||
try:
|
||||
new_tpmconfig = pecan.request.dbapi.tpmconfig_create(
|
||||
tpmconfig.as_dict())
|
||||
except exception.SysinvException as e:
|
||||
LOG.exception(e)
|
||||
raise wsme.exc.ClientSideError(_("Invalid data: failed to create "
|
||||
"a tpm config record."))
|
||||
|
||||
# apply TPM configuration via agent RPCs
|
||||
try:
|
||||
pecan.request.rpcapi.update_tpm_config(
|
||||
pecan.request.context,
|
||||
tpmconfig.as_dict())
|
||||
|
||||
pecan.request.rpcapi.update_tpm_config_manifests(
|
||||
pecan.request.context)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(e)
|
||||
|
||||
return tpmconfig.convert_with_links(new_tpmconfig)
|
||||
|
||||
@wsme.validate(types.uuid, [TPMConfigPatchType])
|
||||
@wsme_pecan.wsexpose(TPMConfig, types.uuid,
|
||||
body=[TPMConfigPatchType])
|
||||
def patch(self, tpmconfig_uuid, patch):
|
||||
"""Update the current tpm configuration."""
|
||||
|
||||
tpmconfig = objects.tpmconfig.get_by_uuid(pecan.request.context,
|
||||
tpmconfig_uuid)
|
||||
tpmdevices = pecan.request.dbapi.tpmdevice_get_list()
|
||||
|
||||
# if any of the tpm devices are in APPLYING state
|
||||
# then disallow a modification till previous config
|
||||
# either applies or fails
|
||||
for device in tpmdevices:
|
||||
if device.state == constants.TPMCONFIG_APPLYING:
|
||||
raise wsme.exc.ClientSideError(_("TPM Device %s is still "
|
||||
"in APPLYING state. Wait for the configuration "
|
||||
"to finish before attempting a modification." %
|
||||
device.uuid))
|
||||
|
||||
# get attributes to be updated
|
||||
updates = self._get_updates(patch)
|
||||
|
||||
# before we can update we have do a quick semantic check
|
||||
if 'uuid' in updates:
|
||||
raise wsme.exc.ClientSideError(_("uuid cannot be modified"))
|
||||
|
||||
_check_tpmconfig_data(updates)
|
||||
|
||||
# update only DB fields that have changed
|
||||
# we cannot use the entire set of updates
|
||||
# since some of them are API updates only
|
||||
for field in objects.tpmconfig.fields:
|
||||
if updates.get(field, None):
|
||||
tpmconfig.field = updates[field]
|
||||
tpmconfig.save()
|
||||
|
||||
new_tpmconfig = tpmconfig.as_dict()
|
||||
|
||||
# for conductor and agent updates, consider the entire
|
||||
# set of incoming updates
|
||||
new_tpmconfig.update(updates)
|
||||
|
||||
# set a modify flag within the tpmconfig, this will inform
|
||||
# the conductor as well as the agents that we are looking
|
||||
# to modify the TPM configuration, and not a creation
|
||||
new_tpmconfig['modify'] = True
|
||||
|
||||
# apply TPM configuration via agent RPCs
|
||||
try:
|
||||
pecan.request.rpcapi.update_tpm_config(
|
||||
pecan.request.context,
|
||||
new_tpmconfig)
|
||||
|
||||
pecan.request.rpcapi.update_tpm_config_manifests(
|
||||
pecan.request.context)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(e)
|
||||
|
||||
return TPMConfig.convert_with_links(tpmconfig)
|
||||
|
||||
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
|
||||
def delete(self, uuid):
|
||||
"""Delete a tpmconfig."""
|
||||
tpmconfig = objects.tpmconfig.get_by_uuid(pecan.request.context,
|
||||
uuid)
|
||||
|
||||
# clear all existing alarms for this TPM configuration
|
||||
_clear_existing_tpmconfig_alarms()
|
||||
|
||||
# clear all tpmdevice configurations for all hosts
|
||||
tpmdevices = pecan.request.dbapi.tpmdevice_get_list()
|
||||
for device in tpmdevices:
|
||||
pecan.request.dbapi.tpmdevice_destroy(device.uuid)
|
||||
|
||||
# need to cleanup the tpm file object
|
||||
tpm_file = tpmconfig.tpm_path
|
||||
|
||||
pecan.request.dbapi.tpmconfig_destroy(uuid)
|
||||
pecan.request.rpcapi.update_tpm_config_manifests(
|
||||
pecan.request.context,
|
||||
delete_tpm_file=tpm_file)
|
Loading…
Reference in New Issue
Block a user