[ $OPENMANO_VER_NUM -ge 4036 ] && DATABASE_TARGET_VER_NUM=10 #0.4.36=> 10
[ $OPENMANO_VER_NUM -ge 4043 ] && DATABASE_TARGET_VER_NUM=11 #0.4.43=> 11
[ $OPENMANO_VER_NUM -ge 4046 ] && DATABASE_TARGET_VER_NUM=12 #0.4.46=> 12
+[ $OPENMANO_VER_NUM -ge 4047 ] && DATABASE_TARGET_VER_NUM=13 #0.4.47=> 13
#TODO ... put next versions here
echo "DELETE FROM schema_version WHERE version_int='12';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
}
+function upgrade_to_13(){
+ echo " upgrade database from version 0.12 to version 0.13"
+ echo " add cloud_config at 'scenarios', 'instance_scenarios'"
+ echo "ALTER TABLE scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER descriptor;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE instance_scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER modified_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (13, '0.13', '0.4.47', 'insert cloud-config at scenarios,instance_scenarios', '2016-08-30');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+function downgrade_from_12(){
+ echo " downgrade database from version 0.13 to version 0.12"
+ echo " remove cloud_config at 'scenarios', 'instance_scenarios'"
+ echo "ALTER TABLE scenarios DROP COLUMN cloud_config;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE instance_scenarios DROP COLUMN cloud_config;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "DELETE FROM schema_version WHERE version_int='13';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
+
function upgrade_to_X(){
echo " change 'datacenter_nets'"
echo "ALTER TABLE datacenter_nets ADD COLUMN vim_tenant_id VARCHAR(36) NOT NULL AFTER datacenter_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id, vim_tenant_id);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
#parse input data
http_content,used_schema = format_in( instance_scenario_create_schema_v01)
r = utils.remove_extra_items(http_content, used_schema)
- if r is not None: print "http_post_instances: Warning: remove extra items ", r
+ if r is not None:
+ logger.warning("http_post_instances: Warning: remove extra items %s", str(r))
data = nfvo.create_instance(mydb, tenant_id, http_content["instance"])
return format_out(data)
except (nfvo.NfvoException, db_base_Exception) as e:
#logger.error("start_scenario %s", error_text)
raise NfvoException(error_text, e.http_code)
+
+def unify_cloud_config(cloud_config):
+ index_to_delete = []
+ users = cloud_config.get("users", [])
+ for index0 in range(0,len(users)):
+ if index0 in index_to_delete:
+ continue
+ for index1 in range(index0+1,len(users)):
+ if index1 in index_to_delete:
+ continue
+ if users[index0]["name"] == users[index1]["name"]:
+ index_to_delete.append(index1)
+ for key in users[index1].get("key-pairs",()):
+ if "key-pairs" not in users[index0]:
+ users[index0]["key-pairs"] = [key]
+ elif key not in users[index0]["key-pairs"]:
+ users[index0]["key-pairs"].append(key)
+ index_to_delete.sort(reverse=True)
+ for index in index_to_delete:
+ del users[index]
+
def create_instance(mydb, tenant_id, instance_dict):
#print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
logger.debug("Creating instance...")
break
if not found:
raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(descriptor_vnf), HTTP_Bad_Request)
+ #0.1 parse cloud-config parameters
+ cloud_config = scenarioDict.get("cloud-config", {})
+ if instance_dict.get("cloud-config"):
+ cloud_config.update( instance_dict["cloud-config"])
+ if not cloud_config:
+ cloud_config = None
+ else:
+ scenarioDict["cloud-config"] = cloud_config
+ unify_cloud_config(cloud_config)
#1. Creating new nets (sce_nets) in the VIM"
for sce_net in scenarioDict['nets']:
#print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
#print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
vm_id = myvim.new_vminstance(myVMDict['name'],myVMDict['description'],myVMDict.get('start', None),
- myVMDict['imageRef'],myVMDict['flavorRef'],myVMDict['networks'])
+ myVMDict['imageRef'],myVMDict['flavorRef'],myVMDict['networks'], cloud_config = cloud_config)
vm['vim_id'] = vm_id
rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id})
#put interface uuid back to scenario[vnfs][vms[[interfaces]
import db_base
import MySQLdb as mdb
import json
-#import yaml
+import yaml
import time
elif self.cur.rowcount>1:
raise db_base.db_base_Exception("More than one scenario found with this criteria " + where_text, db_base.HTTP_Bad_Request)
scenario_dict = rows[0]
+ if scenario_dict["cloud_config"]:
+ scenario_dict["cloud-config"] = yaml.load(scenario_dict["cloud_config"])
+ del scenario_dict["cloud_config"]
#sce_vnfs
cmd = "SELECT uuid,name,vnf_id,description FROM sce_vnfs WHERE scenario_id='{}' ORDER BY created_at".format(scenario_dict['uuid'])
self.logger.debug(cmd)
'scenario_id' : scenarioDict['uuid'],
'datacenter_id': datacenter_id
}
+ if scenarioDict.get("cloud-config"):
+ INSERT_["cloud_config"] = yaml.safe_dump(scenarioDict["cloud-config"], default_flow_style=True, width=256)
+
instance_uuid = self._new_row_internal('instance_scenarios', INSERT_, add_uuid=True, root_uuid=None, created_time=created_time)
net_scene2instance={}
cmd = "SELECT inst.uuid as uuid,inst.name as name,inst.scenario_id as scenario_id, datacenter_id" +\
" ,datacenter_tenant_id, s.name as scenario_name,inst.tenant_id as tenant_id" + \
" ,inst.description as description,inst.created_at as created_at" +\
+ " ,inst.cloud_config as 'cloud_config'" +\
" FROM instance_scenarios as inst join scenarios as s on inst.scenario_id=s.uuid"+\
" WHERE " + where_text
self.logger.debug(cmd)
elif self.cur.rowcount>1:
raise db_base.db_base_Exception("More than one instance found where " + where_text, db_base.HTTP_Bad_Request)
instance_dict = rows[0]
+ if instance_dict["cloud_config"]:
+ instance_dict["cloud-config"] = yaml.load(instance_dict["cloud_config"])
+ del instance_dict["cloud_config"]
#instance_vnfs
cmd = "SELECT iv.uuid as uuid,sv.vnf_id as vnf_id,sv.name as vnf_name, sce_vnf_id, datacenter_id, datacenter_tenant_id"\
'''
__author__="Alfonso Tierno, Gerardo Garcia"
__date__ ="$09-oct-2014 09:09:48$"
-__version__="0.4.4-r488"
+__version__="0.4.5-r489"
version_date="Aug 2016"
from argcomplete.completers import FilesCompleter
if net_scenario not in myInstance["instance"]["networks"]:
myInstance["instance"]["networks"][net_scenario] = {}
myInstance["instance"]["networks"][net_scenario]["netmap-create"] = net_datacenter
+ if args.keypair:
+ if "cloud-config" not in myInstance["instance"]:
+ myInstance["instance"]["cloud-config"] = {}
+ cloud_config = myInstance["instance"]["cloud-config"]
+ for key in args.keypair:
+ index = key.find(":")
+ if index<0:
+ if "key-pairs" not in cloud_config:
+ cloud_config["key-pairs"] = []
+ cloud_config["key-pairs"].append(key)
+ else:
+ user = key[:index]
+ key_ = key[index+1:]
+ key_list = key_.split(",")
+ if "users" not in cloud_config:
+ cloud_config["users"] = []
+ cloud_config["users"].append({"name": user, "key-pairs": key_list })
+ if args.keypair_auto:
+ try:
+ keys=[]
+ home = os.getenv("HOME")
+ user = os.getenv("USER")
+ files = os.listdir(home+'/.ssh')
+ for file in files:
+ if file[-4:] == ".pub":
+ with open(home+'/.ssh/'+file, 'r') as f:
+ keys.append(f.read())
+ if not keys:
+ print "Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh')
+ return 1
+ except Exception as e:
+ print "Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e))
+ return 1
+
+ if "cloud-config" not in myInstance["instance"]:
+ myInstance["instance"]["cloud-config"] = {}
+ cloud_config = myInstance["instance"]["cloud-config"]
+ if "key-pairs" not in cloud_config:
+ cloud_config["key-pairs"] = []
+ if user:
+ if "users" not in cloud_config:
+ cloud_config["users"] = []
+ cloud_config["users"].append({"name": user, "key-pairs": keys })
payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False, encoding='utf-8', allow_unicode=True)
logger.debug("openmano request: %s", payload_req)
instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
instance_scenario_create_parser.add_argument("--netmap-use", action="append", type=str, dest="netmap_use", help="indicates a datacenter network to map a scenario network 'scenario-network=datacenter-network'. Can be used several times")
instance_scenario_create_parser.add_argument("--netmap-create", action="append", type=str, dest="netmap_create", help="the scenario network must be created at datacenter 'scenario-network[=datacenter-network-name]' . Can be used several times")
+ instance_scenario_create_parser.add_argument("--keypair", action="append", type=str, dest="keypair", help="public key for ssh access. Format '[user:]key1[,key2...]'. Can be used several times")
+ instance_scenario_create_parser.add_argument("--keypair-auto", action="store_true", dest="keypair_auto", help="Inject the user ssh-keys found at $HOME/.ssh directory")
instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
instance_scenario_create_parser.set_defaults(func=instance_create)
'''
__author__="Alfonso Tierno, Gerardo Garcia, Pablo Montes"
__date__ ="$26-aug-2014 11:09:29$"
-__version__="0.4.46-r485"
+__version__="0.4.47-r486"
version_date="Aug 2016"
-database_version="0.12" #expected database schema version
+database_version="0.13" #expected database schema version
import httpserver
import time
- VNF2vms: out
- VNF3: data1
default:
+ external: true
interfaces:
- VNF2vms: control0
- VNF2vms: control1
vnf_name: linux # VNF name as introduced in OPENMANO DB
networks:
default: # provide a name for this net or connection
+ external: true
interfaces:
- linux1: eth0 # Node and its interface
echo "Stopping openmano"
$DIRscript/service-openmano.sh mano stop
echo "Initializing openmano database"
- $DIRmano/database_utils/init_mano_db.sh -u mano -p manopw
+ $DIRmano/database_utils/init_mano_db.sh -u mano -p manopw --createdb
echo "Starting openmano"
$DIRscript/service-openmano.sh mano start
! is_valid_uuid $scenario && echo FAIL && echo " $result" && $_exit 1
echo $scenario
done
+
+ #USER_KEY=""
+ key_param1=""
+ key_param2=""
+ #for file_key in ${HOME}/.ssh/*.pub
+ #do
+ # [[ -n ${USER_KEY} ]] && USER_KEY="${USER_KEY},"
+ # USER_KEY="${USER_KEY}$(cat $file_key)"
+ #done
+ #[[ -n ${USER_KEY} ]] && key_param1="--keypair=${USER}:${USER_KEY}" && key_param2="--keypair=${USER_KEY}"
+ key_param1=--keypair-auto
for sce in simple complex2
do
printf "%-50s" "Deploying scenario '$sce':"
- result=`openmano instance-scenario-create --scenario $sce --name ${sce}-instance`
+ result=`openmano instance-scenario-create --scenario $sce --name ${sce}-instance "$key_param1" "$key_param2"`
instance=`echo $result |gawk '{print $1}'`
! is_valid_uuid $instance && echo FAIL && echo " $result" && $_exit 1
echo $instance
'''
raise vimconnNotImplemented( "Should have implemented this" )
- def new_vminstance(self,name,description,start,image_id,flavor_id,net_list):
+ def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
'''Adds a VM instance to VIM
Params:
start: indicates if VM must start or boot in pause mode. Ignored
use: 'data', 'bridge', 'mgmt'
type: 'virtual', 'PF', 'VF', 'VFnotShared'
vim_id: filled/added by this function
+ cloud_config: can be a text script to be passed directly to cloud-init,
+ or an object to inject users and ssh keys with format:
+ key-pairs: [] list of keys to install to the default user
+ users: [{ name, key-pairs: []}] list of users to add with their key-pair
#TODO ip, security groups
Returns >=0, the instance identifier
<0, error_text
except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError) as e:
self._format_exception(e)
- def new_vminstance(self,name,description,start,image_id,flavor_id,net_list):
+ def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
'''Adds a VM instance to VIM
Params:
start: indicates if VM must start or boot in pause mode. Ignored
security_groups = self.config.get('security_groups')
if type(security_groups) is str:
security_groups = ( security_groups, )
+ if isinstance(cloud_config, dict):
+ userdata="#cloud-config\nusers:\n"
+ #default user
+ if "key-pairs" in cloud_config:
+ userdata += " - default:\n ssh-authorized-keys:\n"
+ for key in cloud_config["key-pairs"]:
+ userdata += " - '{key}'\n".format(key=key)
+ for user in cloud_config.get("users",[]):
+ userdata += " - name: {name}\n sudo: ALL=(ALL) NOPASSWD:ALL\n".format(name=user["name"])
+ if "user-info" in user:
+ userdata += " gecos: {}'\n".format(user["user-info"])
+ if user.get("key-pairs"):
+ userdata += " ssh-authorized-keys:\n"
+ for key in user["key-pairs"]:
+ userdata += " - '{key}'\n".format(key=key)
+ self.logger.debug("userdata: %s", userdata)
+ elif isinstance(cloud_config, str):
+ userdata = cloud_config
+ else:
+ userdata=None
+
server = self.nova.servers.create(name, image_id, flavor_id, nics=net_list_vim, meta=metadata,
security_groups = security_groups,
availability_zone = self.config.get('availability_zone'),
key_name = self.config.get('keypair'),
+ userdata=userdata
) #, description=description)
#print text
return -vim_response.status_code,text
- def new_vminstance(self,name,description,start,image_id,flavor_id,net_list):
+ def new_vminstance(self,name,description,start,image_id,flavor_id,net_list, cloud_config=None):
'''Adds a VM instance to VIM
Params:
start: indicates if VM must start or boot in pause mode. Ignored