Merge "implement simulator for valence"

This commit is contained in:
Jenkins 2017-03-13 23:46:37 +00:00 committed by Gerrit Code Review
commit 3e2409d096
16 changed files with 803 additions and 0 deletions

15
simulator/README.md Normal file
View File

@ -0,0 +1,15 @@
Valence Simulator
This part is used for Valence fresh users or developers who don't have
real hardware.
User can use this part to setup a mocked up running hardware environment
like PodManager.

0
simulator/__init__.py Normal file
View File

View File

@ -0,0 +1,41 @@
PodManager Mocked Up Environment
# Introduction
As we know, PodManager now has two announced API spec versions 1.2.1 and
2.1, so we mocked up both of them to match valence's whole requirement.
Please note that the mocked up date just use for test and development.
The two mocked up PodManager environment are use same Flask framework
with same layout logic. Understand on can easily understand another.
And our final result for this simulator would generate a PodManager
which looks like this : http://imgur.com/a/FP4c9
# How to Deploy
### Install dependencies
```
pip install -r pod_manager/requirements.txt
```
### Test run
First run the Flask webservice
```
cd valence/simulator
python pod_manager/rsd_v1_2_1/run.py
```
Then test the api by following python codes' running result
```python
import requests
auth=(name='admin',password='Passw0rd')
requests.get('https://localhost/redfish/v1', auth=auth)
```
Also , we could access the url in browser to get the api result, like:
https://localhost/redfish/v1
# How to Use

View File

View File

@ -0,0 +1,3 @@
Flask==0.11.1
Flask-Cors==3.0.2
Flask-RESTful==0.3.5

View File

@ -0,0 +1,54 @@
import uuid
from functools import wraps
from flask import request
from flask import Response
from flask_restful import Resource
def generate_members(element_name, url, total_num):
members = []
i = 0
while i < total_num:
dic = dict()
dic["@odata.id"] = url + element_name + str(i + 1)
members.append(dic)
i += 1
return members
def generate_uuid_by_element_id(element_id):
return str(uuid.uuid3(uuid.NAMESPACE_DNS, element_id))
def check_auth(username, password):
"""check if a username password combination is valid"""
return username == 'admin' and password == 'Passw0rd'
def authenticate():
"""Sends a 401 response that enables basic auth"""
return Response(
'Could not verify your access level for that URL.\n'
'You have to login with proper credentials',
401,
{
'WWW-Authenticate': 'Basic realm="Login Required"'
}
)
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
return authenticate()
return f(*args, **kwargs)
return decorated
class AuthResource(Resource):
method_decorators = [requires_auth]

View File

@ -0,0 +1,356 @@
import sys
sys.path.append("..")
import uuid
from common import generate_members
# init system and nodes numbers
systems_num = 48
nodes_num = 6
# cache for components info
computer_systems = {}
composed_nodes = {}
# init components collection info
systems_members = generate_members('System',
'/redfish/v1/Systems/',
systems_num)
nodes_members = generate_members('Node', '/redfish/v1/Nodes/', 6)
chassis_members = generate_members("Pod", "/redfish/v1/Chassis/", 1) \
+ generate_members("Rack", "/redfish/v1/Chassis/", 2) \
+ generate_members("Chassis", "/redfish/v1/Chassis/", 3) \
+ generate_members("Drawer", "/redfish/v1/Chassis/", 6)
# init hardware locations info
chassis_location = {
'Pod1': ['', '', ''],
'Rack1': ['', '', 'Pod1'],
'Rack2': ['', '', 'Pod1'],
'Chassis1': ['25 U', '10 U', 'Rack1'],
'Chassis2': ['6 U', '10 U', 'Rack1'],
'Chassis3': ['11 U', '10 U', 'Rack2'],
'Drawer1': ['19 U', '2 U', 'Rack1'],
'Drawer2': ['34 U', '2 U', 'Rack2'],
'Drawer3': ['32 U', '2 U', 'Rack2'],
'Drawer4': ['17 U', '1 U', 'Rack1'],
'Drawer5': ['26 U', '1 U', 'Rack2'],
'Drawer6': ['25 U', '1 U', 'Rack2'],
}
# Hardware distribution map : http://imgur.com/a/FP4c9
def generate_computer_systems():
for number in range(1, systems_num+1):
system_id = 'System%d' % number
system_url = '/redfish/v1/Systems/%s' % system_id
system_uuid = str(uuid.uuid3(uuid.NAMESPACE_DNS, system_id))
sku = system_uuid[:13]
assert_tag = 'asset tag%s' % system_id
serial_number = system_uuid[-12:]
part_number = system_uuid[9:18]
manufacturer = 'Dual socket Xeon Server'
if 43 <= number <= 48:
type_ = 'Logical'
name = 'ServerNode%d' % (number - 42)
description = 'Nova node%d' % (number - 42)
model = 'Lenovo System x3120' if number <= 45 else \
'Lenovo System x3650'
hostname = 'nova-%d' % (number - 42)
chassis_id = 'Drawer%d' % (number - 42)
managed_by = '/redfish/v1/Managers/BMC%d' % (number - 39)
u_location = chassis_location[chassis_id][0]
system_location = 1
u_height = chassis_location[chassis_id][1]
u_width = '1 U'
else:
type_ = 'Physical'
name = 'LTE-%d' % number
description = 'Nova node%d' % number
model = 'Lenovo System x3120' if number <= 8 else \
'Lenovo System x3650'
hostname = 'nova-%d' % number
system_location = number % 14 if number % 14 != 0 else 14
u_height = '1 U'
u_width = '0.5 U'
# Chassis1's computer system
if 29 <= number <= 42:
chassis_id = 'Chassis3'
managed_by = '/redfish/v1/Managers/BMC3'
# Chassis1's computer system
elif 15 <= number <= 28:
chassis_id = 'Chassis2'
managed_by = '/redfish/v1/Managers/BMC2'
# Chassis1's computer system
else:
chassis_id = 'Chassis1'
managed_by = '/redfish/v1/Managers/BMC1'
base_u_location = chassis_location[chassis_id][0]
base_u_num = int(filter(str.isdigit, base_u_location))
u_location = '%d U' % ((system_location + 1) / 2 + base_u_num)
system_info = {
"@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity",
"@odata.id": system_url,
"@odata.type": "#ComputerSystem.1.0.0.ComputerSystem",
"Id": system_id,
"Name": name,
"SystemType": type_,
"AssetTag": assert_tag,
"Manufacturer": manufacturer,
"Model": model,
"SKU": sku,
"SerialNumber": serial_number,
"PartNumber": part_number,
"Description": description,
"UUID": system_uuid,
"HostName": hostname,
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollUp": "OK"
},
"IndicatorLED": "On",
"PowerState": "On",
"Boot": {
"BootSourceOverrideEnabled": "Once",
"BootSourceOverrideTarget": "Pxe",
"BootSourceOverrideTarget@Redfish.AllowableValues": ["None",
"Pxe",
"Hdd"],
},
"BiosVersion": "P79 v1.00",
"ProcessorSummary": {
"Count": 2,
"Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollUp": "OK"
}
},
"MemorySummary": {
"TotalSystemMemoryGiB": 64,
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollUp": "OK"
}
},
"Processors": {
"@odata.id": "/redfish/v1/Systems/%s/Processors" % system_id},
"EthernetInterfaces": {
"@odata.id": "/redfish/v1/Systems/%s/EthernetInterfaces" %
system_id
},
"SimpleStorage": {},
"DimmConfig": {
"@odata.id": "/redfish/v1/Systems/%s/DimmConfig" % system_id
},
"MemoryChunks": {
"@odata.id": "/redfish/v1/Systems/%s/MemoryChunk" % system_id
},
"Links": {
"Chassis": [{
"@odata.id": "/redfish/v1/Chassis/%s" % chassis_id
}],
"ManagedBy": [{
"@odata.id": managed_by
}],
"Oem": {}
},
"Actions": {
"#ComputerSystem.Reset": {
"target":
"/redfish/v1/Systems/%s/Actions/ComputerSystem.Reset" %
system_id,
"ResetType@Redfish.AllowableValues": [
"On",
"ForceOff",
"GracefulShutdown",
"ForceRestart",
"Nmi",
"GracefulRestart",
"ForceOn",
"PushPowerButton"]
},
"Oem": {
"Lenovo_RackScale": {
"#ComputerSystem.StartDeepDiscovery": {
"target":
"/redfish/v1/Systems/%s/Actions/ComputerSystem"
".StartDeepDiscovery" % system_id
},
}
}
},
"Oem": {
"Lenovo_RackScale": {
"SystemLocation": system_location,
"Location": {
"ULocation": u_location,
"UHeight": u_height,
"UWidth": u_width,
"Chassis": chassis_id
},
"@odata.type": "#Intel.Oem.ComputerSystem",
"Adapters": {
"@odata.id": "/redfish/v1/Systems/%s/Adapters" %
system_id
},
"PciDevices": [{
"VendorId": "0x8086",
"DeviceId": "0x1234"
}],
"DiscoveryState": "Basic",
"ProcessorSockets": 8, "MemorySockets": 8
}
}
}
computer_systems[system_url] = system_info
# Hardware distribution map : http://imgur.com/a/FP4c9
def generate_composed_nodes():
for number in range(1, 7):
node_id = 'Node%d' % number
node_url = "/redfish/v1/Nodes/Node%d" % number
name = 'composedNode%d' % number
description = 'Nova node%s' % number
system_url = "/redfish/v1/Systems/System%d" % (number + 42)
system_info = computer_systems[system_url]
node_info = {
"@odata.context": "/redfish/v1/$metadata#Nodes/Members/$entity",
"@odata.id": node_url,
"@odata.type": "#ComposedNode.1.0.0.ComposedNode",
"Id": node_id,
"Name": name,
"Description": description,
"SystemType": "Logical",
"AssetTag": "free form asset tag",
"Manufacturer": system_info['Manufacturer'],
"Model": system_info['Model'],
"SKU": system_info['SKU'],
"SerialNumber": system_info['SerialNumber'],
"PartNumber": system_info['PartNumber'],
"UUID": system_info['UUID'],
"HostName": system_info['HostName'],
"PowerState": "On",
"BiosVersion": system_info['BiosVersion'],
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollUp": "OK"
},
"Processors": {
"Count": 2,
"Model": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
"Status": {
"State": "Enabled",
"Health": "OK"
}
},
"Memory": {
"TotalSystemMemoryGiB": 64,
"Status": {
"State": "Enabled",
"Health": "OK"
}
},
"ComposedNodeState": "Allocated",
"Boot": {
"BootSourceOverrideEnabled": "Disabled",
"BootSourceOverrideTarget": "None",
"BootSourceOverrideTarget@Redfish.AllowableValues": [
"None",
"Pxe",
"Hdd"
]
},
"Oem": {},
"Links": {
"ComputerSystem": {
"@odata.id": system_url
},
"Processors": [
{
"@odata.id": "%s/Processors/CPU1" % system_url
},
{
"@odata.id": "%s/Processors/CPU2" % system_url
}
],
"Memory": [
{
"@odata.id": "%s/DimmConfig/Dimm1" % system_url
},
{
"@odata.id": "%s/DimmConfig/Dimm2" % system_url
},
{
"@odata.id": "%s/DimmConfig/Dimm3" % system_url
},
{
"@odata.id": "%s/DimmConfig/Dimm4" % system_url
}
],
"EthernetInterfaces": [
{
"@odata.id": "%s/EthernetInterfaces/LAN1" % system_url
}
],
"LocalDrives": [
{
"@odata.id": "%s/StorageControllers/"
"Controller1/Drives/Drive1" % system_url
}
],
"RemoteDrives": [
{
"@odata.id": "/redfish/v1/Services/RSS1/Targets/target"
}
],
"ManagedBy": [
{
"@odata.id": "/redfish/v1/Managers/PODM"
}
],
"Oem": {}
},
"Actions": {
"#ComposedNode.Reset": {
"target": "%s/Actions/ComposedNode.Reset" % system_url,
"ResetType@Redfish.AllowableValues": [
"On",
"ForceOff",
"GracefulRestart",
"ForceRestart",
"Nmi",
"ForceOn",
"PushPowerButton",
"GracefulShutdown"
]
},
"#ComposedNode.Assemble": {
"target": "%s/Actions/ComposedNode.Assemble" % system_url
}
}
}
composed_nodes[node_url] = node_info
def init_data_generation():
generate_computer_systems()
generate_composed_nodes()

View File

@ -0,0 +1,166 @@
import uuid
from common import AuthResource
from resources import chassis_location
from resources import chassis_members
from resources import systems_members
class ChassisCollection(AuthResource):
def get(self):
return {
"@odata.context": "/redfish/v1/$metadata#Chassis",
"@odata.id": "/redfish/v1/Chassis",
"@odata.type": "#ChassisCollection.ChassisCollection",
"Name": "Chassis Collection",
"Members@odata.count": 12,
"Members": chassis_members
}
class Chassis(AuthResource):
def get(self, chassis_id):
chassis_id = str(chassis_id)
number = int(filter(str.isdigit, chassis_id))
chassis_uuid = str(uuid.uuid3(uuid.NAMESPACE_DNS, chassis_id))
# chassis hardware properties values
manufacturer = 'Intel Corporaion'
sku = chassis_uuid[:13]
assert_tag = chassis_id
serial_number = chassis_uuid[-12:]
part_number = chassis_uuid[9:18]
# Racks info
if 'Rack' in chassis_id and number <= 2:
name = 'Rack%s' % number
chassis_type = 'Rack'
model = 'Intel RSA Chassis-Rack'
contained_by = 'Rack' + str(number)
managed_by = '/redfish/v1/Chassis/rackManager' % number
# rack contains content is chassis (chassis and drawers)
if number == 1:
contains_content = chassis_members[3:5] + \
chassis_members[6:7] + \
chassis_members[9:10]
else:
contains_content = chassis_members[5:6] + \
chassis_members[7:9] + \
chassis_members[10:]
# Rack's computer systems
# Rack1
if number == 1:
systems = systems_members[0: 28] + \
systems_members[42: 43] + \
systems_members[45: 46]
# rack2
else:
systems = systems_members[28: 42] + \
systems_members[43: 45] + \
systems_members[46: 48]
# Enclosures Chassis info
elif 'Chassis' in chassis_id and number <= 3:
name = 'FLEX-%s' % number
chassis_type = 'Enclosure'
model = 'Lenovo FLEX 8731'
contained_by = 'Rack1' if number <= 2 else 'Rack2'
managed_by = '/redfish/v1/Managers/BMC%d' % number
# chassis contains content is systems, same with systems values
sys_num = (number - 1) * 14
systems = systems_members[sys_num: sys_num + 14]
contains_content = systems
# Drawers info
elif 'Drawer' in chassis_id:
name = 'ServerNode%s' % number
chassis_type = 'Drawer'
model = 'Lenovo System x3120'
contained_by = 'Rack1' if number == 1 or number == 4 else 'Rack2'
managed_by = '/redfish/v1/Managers/BMC%d' % (number + 3)
sys_num = number + 41
systems = systems_members[sys_num]
contains_content = systems
# Pod info
elif 'Pod' in chassis_id:
name = 'Pod1'
chassis_type = 'Pod'
model = 'Intel Pod Manager'
manufacturer = 'Intel Corporaion'
sku = ''
assert_tag = ''
serial_number = ''
part_number = ''
contained_by = 'Pod1'
contains_content = chassis_members[1:3]
managed_by = '/redfish/v1/Chassis/Pod1'
systems = systems_members
# Others not considered now
else:
return {}
return {
"@odata.context": "/redfish/v1/$metadata#Chassis/Members/$entity",
"@odata.id": "/redfish/v1/Chassis/" + chassis_id,
"@odata.type": "#Chassis.1.0.0.Chassis",
"Id": chassis_id,
"ChassisType": chassis_type,
"Name": name,
"Description": name,
"Manufacturer": manufacturer,
"Model": model,
"SKU": sku,
"SerialNumber": serial_number,
"PartNumber": part_number,
"AssetTag": assert_tag,
"IndicatorLED": "On",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
},
"Oem": {
"Lenovo_RackScale": {
"@odata.type": "#Intel.Oem.Chassis",
"Location": {
"Rack": chassis_location[chassis_id][2],
"ULocation": chassis_location[chassis_id][0],
"UHeight": chassis_location[chassis_id][1],
"UWidth": '1 U'
},
"UUID": chassis_uuid
}
},
"Links": {
"Contains": contains_content,
"ContainedBy": {
"@odata.id": "/redfish/v1/Chassis/%s" % contained_by
},
"ComputerSystems": systems,
"Switches": [
{
"@odata.id": "/redfish/v1/EthernetSwitches/switch1"
}
],
"ManagedBy": [
{
"@odata.id": managed_by
}
],
"ManagersIn": [
{
"@odata.id": managed_by
}
],
"Oem": {}
}
}

View File

@ -0,0 +1,23 @@
from common import AuthResource
from resources import composed_nodes
from resources import nodes_members
from resources import nodes_num
class NodeCollection(AuthResource):
def get(self):
return {
"@odata.context": "/redfish/v1/$metadata#ComposedNodeCollection."
"ComposedNodeCollection",
"@odata.id": "/redfish/v1/Nodes",
"@odata.type": "#ComposedNodeCollection.CComposedNodeCollection",
"Name": "Composed Node Collection",
"Members@odata.count": nodes_num,
"Members": nodes_members
}
class Node(AuthResource):
def get(self, node_id):
node_url = '/redfish/v1/Nodes/%s' % node_id
return composed_nodes[node_url]

View File

@ -0,0 +1,23 @@
from common import AuthResource
from resources import computer_systems
from resources import systems_members
from resources import systems_num
class SystemCollection(AuthResource):
def get(self):
return {
"@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection."
"ComputerSystemCollection",
"@odata.id": "/redfish/v1/Systems",
"@odata.type": "ComputerSystemCollection.ComputerSystemCollection",
"Name": "Computer System Collection",
"Members@odata.count": systems_num,
"Members": systems_members
}
class System(AuthResource):
def get(self, system_id):
system_url = '/redfish/v1/Systems/%s' % system_id
return computer_systems[system_url]

View File

@ -0,0 +1,41 @@
from common import AuthResource
class Redfishv1Resource(AuthResource):
def get(self):
return {
"@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
"@odata.id": "/redfish/v1/",
"@odata.type": "#ServiceRoot.1.0.0.ServiceRoot",
"Id": "RootService",
"Name": "Root Service",
"RedfishVersion": "1.0.0",
"UUID": "92384634-2938-2342-8820-489239905423",
"Systems": {"@odata.id": "/redfish/v1/Systems"
},
"Chassis": {
"@odata.id": "/redfish/v1/Chassis"
},
"Managers": {
"@odata.id": "/redfish/v1/Managers"
},
"EventService": {
"@odata.id": "/redfish/v1/EventService"
},
"Services": {
"@odata.id": "/redfish/v1/Services"
},
"Nodes": {
"@odata.id": "/redfish/v1/Nodes"
},
"EthernetSwitches": {
"@odata.id": "/redfish/v1/EthernetSwitches"
},
"Oem": {
"Intel:RackScale": {
"@odata.type": "#Intel.Oem.ServiceRoot",
"ApiVersion": "1.2.0",
}
},
"Links": {}
}

View File

@ -0,0 +1,22 @@
from resources import chassis
from resources import composed_node
from resources import computer_system
from resources import redfish_v1
def init_routes(api):
pre = '/redfish/v1'
api.add_resource(redfish_v1.Redfishv1Resource, pre)
pre_chassis = '/redfish/v1/Chassis'
api.add_resource(chassis.ChassisCollection, pre_chassis)
api.add_resource(chassis.Chassis, pre_chassis + '/<string:chassis_id>')
pre_systems = '/redfish/v1/Systems'
api.add_resource(computer_system.SystemCollection, pre_systems)
api.add_resource(computer_system.System,
pre_systems + '/<string:system_id>')
pre_nodes = '/redfish/v1/Nodes'
api.add_resource(composed_node.NodeCollection, pre_nodes)
api.add_resource(composed_node.Node, pre_nodes + '/<string:node_id>')

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# !flask/bin/python
from flask import Flask
from flask_restful import Api
from resources import init_data_generation
from route import init_routes
# initialize flask and flask restful
app = Flask(__name__)
app.config['SECRET_KEY'] = "Valence-Simulator"
app.debug = True
api = Api(app)
if __name__ == "__main__":
init_data_generation()
init_routes(api)
app.run(host='0.0.0.0',
port=443,
ssl_context=(
__file__.replace('run.py', 'server.crt'),
__file__.replace('run.py', 'server.key'))
)

View File

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICbzCCAdgCCQDAeFEN+F+ZVTANBgkqhkiG9w0BAQUFADB8MQswCQYDVQQGEwJD
TjELMAkGA1UECAwCU0gxCzAJBgNVBAcMAlNIMQ8wDQYDVQQKDAZMZW5vdm8xDDAK
BgNVBAsMA0RDRzEPMA0GA1UEAwwGTGVub3ZvMSMwIQYJKoZIhvcNAQkBFhR5YW5n
eGluZzRAbGVub3ZvLmNvbTAeFw0xNzAxMTcwMzA2NDVaFw0xODAxMTcwMzA2NDVa
MHwxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJTSDELMAkGA1UEBwwCU0gxDzANBgNV
BAoMBkxlbm92bzEMMAoGA1UECwwDRENHMQ8wDQYDVQQDDAZMZW5vdm8xIzAhBgkq
hkiG9w0BCQEWFHlhbmd4aW5nNEBsZW5vdm8uY29tMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQCo4RFSMjqlGW6m5W+A1BiTufmwOvji3i3jNZqSkyClDkGoA9gd
4rWMnvuwpzyK/CX4p7umYDxtyAfQLbwyEInVyxiwNWEZ+Gvc9daGFLI4olQU3Eg8
6Txc9Oer0o6fiuRctZIIvQpX3akfp6dySu1WXr+j4o0meXOiWzDvnu0HpQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBAHPQbFiHakFBt+RoQsBLKUA3zI4WoQMXiNJVxL7U
brXqpKf/hVuFc1rSi/KLJIWuxHDqqLhRsD63+IssvUsKApvBoBb7URCLXGlY0Ib0
zBMd1qEJgV/pP7sOrzf5aVme7qEAqmyHRM7UnYcCsy/CR+N5D0zi9A7hiaSvN22/
V7zh
-----END CERTIFICATE-----

View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCo4RFSMjqlGW6m5W+A1BiTufmwOvji3i3jNZqSkyClDkGoA9gd
4rWMnvuwpzyK/CX4p7umYDxtyAfQLbwyEInVyxiwNWEZ+Gvc9daGFLI4olQU3Eg8
6Txc9Oer0o6fiuRctZIIvQpX3akfp6dySu1WXr+j4o0meXOiWzDvnu0HpQIDAQAB
AoGAO3VSheANacd0f+pTwcXrCUf3MybwLeAPw+lBjM2kNri4QRFpa8xAI0xuTRn0
ZPK148Aaf09utzAwIAmaMv5DqKGuCuhFSMI3TSJVyd008NJJDDProdQd77+CssDO
CO8td/D0cRJf4nz0La8PIQTnoWMO42VgelNhQPD9mlfU0UECQQDVDl2E2dRv02BE
7in8niVIyl9JArpIt9aLMDeHoQ8HRFfjh1d+jiuofDCOYWOdLR2Q19sK3EsKpvIm
sr0clzZNAkEAyusvRY0B3HihVHTAF0r414f+yjE7W3HGxMFNsEIytK55VS1leusn
pkpC6rYL+KIV2ScE/spEdQoa7wiqwpryuQJBAKJZHvQD1PgdVudPoFjp3TlZVEBb
Pr34sBhB9p54IO6Fqn8re4VpKmVptMpZ9cEoRrY/dZ8R/HCyhCTu4GHv66UCQH2Y
nCW8ZU6FC7YunUbNjMA62KVlW4v6HEFkNCXIk4HqDAeAlbNDIcN3a3vDOh2mlUdX
M2xQ3ZZjrtAM2USii2ECQHGY4ai7m5BsTHWuiBEhBn5GPlr9kNQwwCK3OywnydxZ
B+uS++gjxnHYgBSXp7Ay+3gJQdz63UCKvLmxRmZMxnY=
-----END RSA PRIVATE KEY-----