r1.8 adding documentation
[sfa.git] / sfa / bonfire / bonfire.py
index cdaf089..0818e21 100644 (file)
@@ -4,39 +4,62 @@
 #pip install requests
 import requests
 import xml.etree.ElementTree as ET
+# parsing a xml content
 import subprocess
+# using for calling sfa code
+
 import time
+#import ldap
+# will be use to authentice against bonfire's ldap
 
 # module for bonfire to connect with sfa (following the Rspec)
-# inspired by the following documenation :
+# inspired by the following documenation:
 # https://svn.planet-lab.org/wiki/SfaDeveloperDummyTutorial#RunningSFAinDummyflavour
 
-# 1) list all the resources  of bonfire from sfa's point of view
+# does not forget to launching this code:
+#python /usr/lib/python2.7/site-packages/sfa/dummy/dummy_testbed_api.py   
+
+# documentation
+# http://wiki.bonfire-project.eu/index.php/FED4FIRE_sfa
+
+#1 - list resources
+#2 - allocate
+#3 - provisioning
+#4 - create compute VM for fr-inria/uk-epcc
+
+# 1) list all the resources of bonfire from sfa's point of view
 # python -c 'import bonfire; print bonfire.bonsources()'
 
-# 2) retrieve the url, the name and the key that will currently use by sfa for a compute N°3656 located at fr-inria
+# 2) allocate: create an experiment bonfire with slice information (parameters : user_name, groups, description, walltime, slice_name)
+# python -c 'import bonfire; print bonfire.allocate("nlebreto", "nlebreto", "tdes", "125", "topdomain.dummy.nicolas")'
+
+# 3) provisioning: changing the status to running status for the experiment 2911
+# python -c 'import bonfire; print bonfire.provisioning("2911")'
+
+# 4) bonfire create virtual machine with these specific features 1) fr-inria storages n°1805 network 2 ip public 2) uk-epcc storages n°1364 network 0 bonfire wan
+# python -c 'import bonfire; print bonfire.create_vm("fr-inria", "56910", "rester", "nlebreto")'
+# python -c 'import bonfire; print bonfire.create_vm("uk-epcc",  "56910", "rester", "nlebreto")'
+
+# 5) retrieve the url, the name and the key for a compute N°3656 located at fr-inria
 # python -c 'import bonfire; print bonfire.rsa_user_bonfire("fr-inria", "3656")'
 
-# 3) create a new user and slice for sfa wrap
+# 6) create a new user and slice for sfa wrap
 # python -c 'import bonfire; print bonfire.new_user_slice()'
 
-# 4) changing the status to running status for the experiment 2911
-# python -c 'import bonfire; print bonfire.provisioning("2911")'
-
-# 5) stop virtual machine n°3756  at fr-inira testbed
+# 7) stop virtual machine in bonfire testbed (ex n°3756 at fr-inira testbed)
 # python -c 'import bonfire; print bonfire.stop_vm("fr-inria", "3756")'
 
-# 6) allocation : create an experiment bonfire with slice information
-# python -c 'import bonfire; print bonfire.allocate("nlebreto", "nlebreto", "tdes", "125", "topdomain.dummy.nicolasi", "https://api.integration.bonfire.grid5000.fr/experiments")'
-
-# 7) remove slice or key 
+# 8) remove slice or key 
 # python -c 'import bonfire; print bonfire.remove_slice("topdomain.dummy.alice_slice")'
 
-# 8) attach slice to a user (did not work)
+# 9) attach slice to a user
 # python -c 'import bonfire; print bonfire.create_slice_attach_user("topdomain.dummy.alice")'
 
-# 9) verify bonfire authentication 
-# # python -c 'import bonfire; print bonfire.callcurl("https://api.bonfire-project.eu/")'
+# 10) verify bonfire authentication 
+# python -c 'import bonfire; print bonfire.callcurl("https://api.bonfire-project.eu/")'
+
+# 11) bonfire ldap authentification
+# python -c 'import bonfire; print bonfire.bonldap("nicolas.lebreton@inria.fr")'
 
 # ########################################################## #
 # ########################################################## #
@@ -45,10 +68,28 @@ import time
 def bonfire_authenticate():
     h = {}
     h["user"]      = "nlebreto"
+    h["mail"]      = "nicolas.lebreton@inria.fr"
     h["user_pass"] = "GDRU_23tc$"
     h["location"]  = "https://api.integration.bonfire.grid5000.fr"
     return h  
 
+# authentification against bonfire's ldap using a virtual machine
+#def bonldap(mail):
+#    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, '/Fed4FIRE-SFA-Backend/puppet/modules/ca/ca.crt')
+    # using a certificate (client)
+#    ldap.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
+#    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
+#    ld = ldap.initialize('ldaps://127.0.0.1:2636')
+    # connection with ldaps
+#    basedn = "ou=People,dc=bonfire-project,dc=eu"
+#    filter_test = "mail=" + mail
+#    filter = filter_test
+    # search email in the ldap 
+#    results = ld.search_s(basedn, ldap.SCOPE_SUBTREE, filter)
+#    if not results:
+#       print ("error 401, you need to be register to the portal f4f")
+#    return results
+
 # create a slice and attach a specific user to it
 def create_slice_attach_user(user_slice):
     call = "sfa.py add -x {0}_slice -t slice -r {0}@dummy.net".format(user_slice)
@@ -59,13 +100,14 @@ def remove_slice(name):
     cmdremove    = "sfaadmin.py reg remove {0}".format(name)
     removeaction = subprocess.Popen(cmdremove, shell=True)
 
-# show specific credential of a slice    
+# show specific credential of a slice (see the content of a specific file  /root/.sfi/*.slice.cred)  
 def show_slice_credential(slice_name):
     path = "/root/.sfi/{0}.slice.cred".format(slice_name)
     tree = ET.parse(path)
     root = tree.getroot()
     hash = {}
     hash["slice_native"] = root.findall(".//signatures//{http://www.w3.org/2000/09/xmldsig#}Signature//{http://www.w3.org/2000/09/xmldsig#}KeyInfo//{http://www.w3.org/2000/09/xmldsig#}X509Data//{http://www.w3.org/2000/09/xmldsig#}X509SubjectName")[0].text
+    hash["X509IssuerName"] = root.findall(".//signatures//{http://www.w3.org/2000/09/xmldsig#}Signature//{http://www.w3.org/2000/09/xmldsig#}KeyInfo//{http://www.w3.org/2000/09/xmldsig#}X509Data//{http://www.w3.org/2000/09/xmldsig#}X509IssuerName")[0].text
     for target in root.findall('credential'):
         hash["slice_user_urn"] = target.find('owner_urn').text
         hash["slice_urn"] = target.find('target_urn').text
@@ -76,25 +118,8 @@ def show_slice_credential(slice_name):
 def allocate(user_name, groups, description, walltime, slice_name):
     hash ={}
     hash = show_slice_credential(slice_name)
-    create_fed4fire_exp(user_name, groups, description, walltime, hash["slice_urn"], hash["slice_user_urn"], hash["slice_native"])
+    create_fed4fire_exp(user_name, groups, description, walltime, hash["slice_urn"], hash["slice_user_urn"], hash["slice_native"], "https://api.integration.bonfire.grid5000.fr/experiments")
     
-
-
-# retrieve the url, the name and the key that will currently use by sfa
-def rsa_user_bonfire(testbed, num_compute):
-    url = "https://api.integration.bonfire.grid5000.fr/" + "locations/" + testbed + "/computes/" + num_compute
-    pagebonfirecompute = callcurl(url)
-    xmlreduit = ET.fromstring(pagebonfirecompute)
-    hash = {}
-    hash["url"] = url
-    for name in xmlreduit:
-        if name.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}groups":
-           hash["name"] = name.text
-        for context in name:
-            if context.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}authorized_keys":
-               hash["keys"] = context.text
-    return hash 
-
 # create a new user and slice for sfa wrap
 def new_user_slice():
     n = rsa_user_bonfire("fr-inria", "3656")
@@ -113,6 +138,15 @@ def create_fed4fire_exp(name, groups, description, walltime, slice_urn, slice_us
     xmldescription='<experiment xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>' + name +'</name><groups>' + groups + '</groups><description>' + description + '</description><walltime>' + walltime + '</walltime><status>ready</status><slice_urn>' + slice_urn + '</slice_urn><slice_usr_urn>' + slice_user_urn + '<slice_usr_urn><slice_native>' + slice_native + '</slice_native></experiment>'
     postexp(url_experiment_bonfire, xmldescription)
 
+# create a virtual machine with these specific features 1) fr-inria storages n°1805 network 2 ip public 2) uk-epcc storages n°1364 network 0 bonfire wan
+def create_vm(testbed, nb_experiment, name_compute, groups):
+    url = 'https://api.integration.bonfire.grid5000.fr/experiments/' + num_experiment + '/computes' 
+    if testbed == "fr-inria":
+       xmldescription='<compute xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>' + name_compute + '</name><groups>' + groups + '</groups><instance_type>lite</instance_type><disk><storage href="/locations/fr-inria/storages/1805"/><type>OS</type><target>hda</target></disk><nic><network href="/locations/fr-inria/networks/2"/></nic><link href="/locations/fr-inria" rel="location"/></compute>'
+    if testbed == "uk-epcc": 
+       xmldescription='<compute xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>' + name_compute + '</name><groups>' + groups + '</groups><instance_type>lite</instance_type><disk><storage href="/locations/uk-epcc/storages/1364"/><type>OS</type><target>hda</target></disk><nic><network href="/locations/uk-epcc/networks/0"/></nic><link href="/locations/uk-epcc" rel="location"/></compute>'
+    postexp(url, xmldescription)    
+
 # simple post method for request
 def postexp(url, xmldescription):
     headers = {'content-type': 'application/vnd.bonfire+xml'}
@@ -148,18 +182,19 @@ def rsa_user_bonfire(testbed, num_compute):
         if name.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}groups":
            hash["name"] = name.text
         for context in name:
-            if context.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}authorized_keys":
-               hash["keys"] = context.text
+           if context.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}authorized_keys":
+              hash["keys"] = context.text
     return hash 
 
 # do a curl request  
 def callcurl(url):
     h = bonfire_authenticate()
     r = requests.get(url, verify=False, auth=(h["user"], h["user_pass"]))
+    # with the authentication against the ldap, peuhaps these two ligns below is not necessary  
     if r.status_code == 401:
-        return "error 401, you need to be register to the portal f4f"
+       return "error 401, you need to be register to the portal f4f"
     if r.status_code == 200:
-        return r.text
+       return r.text
         
 # create the url page 
 def buildpagehttp(part1, part2, locations):
@@ -211,7 +246,7 @@ def remove_needless_txt(txt):
     txt=txt.replace("<?xml version='1.0' encoding='UTF-8'?>\n","\n")
     return txt
 
-# list all bonfire resources following the sfa specification
+# list all bonfire resources following the sfa specification in a rspec way
 def bonsources():
        # parameters
     locations = ["fr-inria", "be-ibbt", "uk-epcc"]
@@ -233,12 +268,15 @@ def bonsources():
     jfedfeat(bonfires, "http://bonfire.psnc.pl/one-status.xml")
     jfedfeat(bonfires, "http://nebulosus.rus.uni-stuttgart.de/one-status.xml")
     bonfires.append("</machines><networks>")
+    # adding networks information 
     for xmlnetworks in urlnetworks:
         bonfires.append(remove_needless_txt(callcurl(xmlnetworks)))
     bonfires.append("</networks><storages>")
+    # adding storages information 
     for xmlstorages in urlstorages:
         bonfires.append(remove_needless_txt(callcurl(xmlstorages)))
     bonfires.append("</storages><instance_types><computes>")
+    # adding computes information 
     for xmlcomputes in urlcomputes:
         bonfires.append(remove_needless_txt(callcurl(xmlcomputes)))
     bonfires.append("</computes></instance_types></sites><experiments>")
@@ -246,6 +284,7 @@ def bonsources():
     rexp = remove_needless_txt(exp)
     bonfires.append(rexp)
     bonfires.append("</experiments><reservations>")
+    # adding reservation information 
     reserv = callcurl("https://api.integration.bonfire.grid5000.fr/locations/fr-inria/reservations")
     rreserv = remove_needless_txt(reserv)
     bonfires.append(rreserv)