rally-openstack/rally_openstack/task/contexts/magnum/ca_certs.py

135 lines
5.3 KiB
Python

# 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.
import os
from rally.common import utils as rutils
from rally.common import validation
from rally_openstack.common import consts
from rally_openstack.task import context
from rally_openstack.task.scenarios.magnum import utils as magnum_utils
@validation.add("required_platform", platform="openstack", users=True)
@context.configure(name="ca_certs", platform="openstack", order=490)
class CaCertGenerator(context.OpenStackContext):
"""Creates ca certs."""
CONFIG_SCHEMA = {
"type": "object",
"$schema": consts.JSON_SCHEMA,
"properties": {
"directory": {
"type": "string",
}
},
"additionalProperties": False
}
def _generate_csr_and_key(self):
"""Return a dict with a new csr and key."""
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography import x509
from cryptography.x509.oid import NameOID
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=backends.default_backend())
csr = x509.CertificateSigningRequestBuilder().subject_name(
x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u"admin"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME,
u"system:masters")
])).sign(key, hashes.SHA256(), backends.default_backend())
result = {
"csr": csr.public_bytes(encoding=serialization.Encoding.PEM),
"key": key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()),
}
return result
def setup(self):
for user, tenant_id in self._iterate_per_tenants():
magnum_scenario = magnum_utils.MagnumScenario({
"user": user,
"task": self.context["task"],
"config": {"api_versions": self.context["config"].get(
"api_versions", [])}
})
# get the cluster and cluster_template
cluster_uuid = str(self.context["tenants"][tenant_id]["cluster"])
cluster = magnum_scenario._get_cluster(cluster_uuid)
cluster_template = magnum_scenario._get_cluster_template(
cluster.cluster_template_id)
if not cluster_template.tls_disabled:
tls = self._generate_csr_and_key()
dir = ""
if self.config.get("directory") is not None:
dir = self.config.get("directory")
self.context["ca_certs_directory"] = dir
fname = os.path.join(dir, cluster_uuid + ".key")
with open(fname, "w") as key_file:
key_file.write(tls["key"])
# get CA certificate for this cluster
ca_cert = magnum_scenario._get_ca_certificate(cluster_uuid)
fname = os.path.join(dir, cluster_uuid + "_ca.crt")
with open(fname, "w") as ca_cert_file:
ca_cert_file.write(ca_cert.pem)
# send csr to Magnum to have it signed
csr_req = {"cluster_uuid": cluster_uuid,
"csr": tls["csr"]}
cert = magnum_scenario._create_ca_certificate(csr_req)
fname = os.path.join(dir, cluster_uuid + ".crt")
with open(fname, "w") as cert_file:
cert_file.write(cert.pem)
def cleanup(self):
for user, tenant_id in rutils.iterate_per_tenants(
self.context["users"]):
magnum_scenario = magnum_utils.MagnumScenario({
"user": user,
"task": self.context["task"],
"config": {"api_versions": self.context["config"].get(
"api_versions", [])}
})
# get the cluster and cluster_template
cluster_uuid = str(self.context["tenants"][tenant_id]["cluster"])
cluster = magnum_scenario._get_cluster(cluster_uuid)
cluster_template = magnum_scenario._get_cluster_template(
cluster.cluster_template_id)
if not cluster_template.tls_disabled:
dir = self.context["ca_certs_directory"]
fname = os.path.join(dir, cluster_uuid + ".key")
os.remove(fname)
fname = os.path.join(dir, cluster_uuid + "_ca.crt")
os.remove(fname)
fname = os.path.join(dir, cluster_uuid + ".crt")
os.remove(fname)