automating contrail cloud solution - j-net … · 12/9/2016 · automating contrail cloud solution...

16
AUTOMATING CONTRAIL CLOUD SOLUTION Sethuraman Ramanathan - System test

Upload: lynhi

Post on 18-Jun-2018

234 views

Category:

Documents


0 download

TRANSCRIPT

AUTOMATING CONTRAIL CLOUD SOLUTION Sethuraman Ramanathan - System test

Writing Style – Solution Brief

Executivesummary:ContrailCloudsolutionisanopencloudnetworkautomationproductthatusessoftware-definednetworking(SDN)technologytoorchestratethecreationofvirtualnetworkswithhighscalability.ItexposesasetofRESTAPIsfornorthboundinteractionwithcloudorchestrationtools,aswellasotherapplications.ContrailCloudsolutionhasmultiplecomponentslikecontrailcontroller,Openstackcontrollerandvrouters.ThisproductcreatesVirtualMachinesonthecomputenodes,attachVirtualMachinetothevirtualnetworkandconnecttheVirtualMachinetothestorage.ThisDocumentgivesdetailsonRESTAPIstoautomatethefollowing,

• Verifyinghypervisorstatus,• CreateVirtualMachineordeleteVirtualMachine,• CreatevirtualNetworks,• AttachVirtualMachinetovirtualnetwork,• VerifyingVirtualMachinestatus,• GetinformationaboutexistingVirtualMachines

Description:

Writing Style – Solution Brief

IncontrailcloudsolutionOpenstackserverisresponsibleforcreationofVirtualMachines.OpenstackserverhasinventoryofalltheHypervisors.WhenaVMcreationisrequestedthroughopenstackHorizonGUIorthroughRESTAPIcommands,NOVAcomponentinopenstackcontrollerwillconnecttotheHypervisor(whichhassufficientresourcestocreateVM)andrequestforVMcreation.AfterVMiscreated,NEUTRONcomponentinOpenstackcontrollerwillconnecttotheContrailcontrollerandrequestforattachingtheVMtothespeceficVirtualNetwork.ContrailcontrollerwillthenconnecttothevrouterintheHypervisor(throughXMPPprotocol)andrequestforroutinginstancecreationforthespeceficvirtualnetwork.ThesamesequenceoperationrepeatedforeachVMcreation.WhentheVMsarecreatedonmultiplehypervisors.Theyexchangeroutesbetweenthem.ThenMPLSOVERGRE/MPLSOVERUDPTunnelscreatedbetweenthem.RESTAPIscanbeusedforautomatingVMcreation,VMdeletionandotheroperationsdescribed.

ThispictureshowstheimplementationdetailsofContrailcloudsolution.InthistopologyPE2&PE3willbeactingaslocalDatacentergateway.PE1willbetheremoteDatacentergateway.

Writing Style – Solution Brief

Allcomputenodes,controllersareattachedtoIPfabric.TheIPFabricisnotawareofthevirtualNetworkstowhichthevirtualmachinesareattached.ThereisnoneedfortheIPfabrictoknowvirtualnetworkdetails.BetweenPE2(&PE3)andcomputenodesandbetweenthecomputenodesTUNNELoverlaysisimplemented.SoalltrafficbetweencomputenodestoPE2/PE3orbetweencomputenodeswillbeencapsulatedwithTUNNELheader.IPfabricisawareoftheIPaddresespresentintheTunnelheader(astheseIPaddressesarepartofunderlay/IPfabricnetwork.Contrailcontrollerswillbemanagingthecomputenodes(vrouters)usingXMPP.PE2&PE3willtalktoContrailcontrollerswithBGP.ThevroutersincontrailcloudwillactsimilartoPErouterinL3VPNenvironment.WhenaVMinavrouterneedtosendtraffictoVMinanothervrouterinthesamedatacenter,thesourcevrouterwillencapsulatethepacketswithTunnelheaderandthenforwardittotheIPfabric.AfterthedestinationvrouterreceivesthepacketitwilldecapsulatethepacketsandforwardittotheVM.WhenvrouterneedtosendtraffictovroutersinanotherdatacenteritwillencapulatepacketswithTunnelheaderandforwardittoPE2orPE3.PE2orPE3willdecapsulatetheMPLSOVERUDPheaderandthenencapsulateitwithMPLSheadersandforwardittoPE1.PE1decapsulateMPLSheaderandforwardthepacketstothenodeinremoteDatacenter.

AutomatingContrail/OpenstackController: ThissectiongivesdetailsonContrail/OpenstackcontrollerAutomation.AsampleperlcodewithRESTAPIdetailsgivenforeachoperationslikevirtualnetworkcreation,VMcreation,VMdeletionetc..PerlmoduleLWP::UserAgentanduseJSONqw(decode_jsonencode_json)shouldbesourcedforthis. VirtualMachinecreation: OpenstackToken-idandTenantid: ThissectiongivesdetailsonautomatingVMcreation.BeforestartingVMcreationweneedtogetthetoken-idandtenantidfromtheopenstackcontroller.Thistokenidisrequiredtoexecuteanyoperationalcommandsintheopenstackcontroller.Tenantidisrequiredtofindtherightopenstackproject.Thesamplecodegivenbelowgivesdetailsonthis.TheOpenstackcomponentkeystoneprovidesthistoken-id.KeystoneistheidentityserviceusedbyOpenStackforauthentication(authN)andhigh-levelauthorization(authZ).Itcurrentlysupportstoken-basedauthNanduser-serviceauthorization.Inthissamplecode“$OS_tenant_name”istheprojectname.ThisnamecanbefoundonopenstackHorizonGUI(identity->Projects).Projectnameisrequiredtofindthecorrecttenantid.The“$CMDpath”showsthesyntaxofRESTAPIcommandtogettoken-idfromopenstackcontroller.Thetenantidandtokenidcollectedherewillbeusedinnextsteps.

Writing Style – Solution Brief

myopenstack_ip=‘1.1.1.1’;

my$KEYSTONEport="5000"; my$OS_tenant_name="PROJECTNAME"; my$OS_user="admin"; my$OS_password=‘xxxxxx’; my$CMDpath="/v2.0/tokens";

my$APIport=$KEYSTONEport; my$url="http://".$openstack_ip.":".$APIport.$CMDpath;my$body= {"auth"=> { "tenantName"=>"$OS_tenant_name","passwordCredentials"=>{ "username"=>"$OS_user", "password"=>"$OS_password"}}}; my$request=HTTP::Request->new(POST=>$url); my$bjson=encode_json$body; $request->content_type("application/json"); $request->authorization_basic("$OS_user","$OS_password"); $request->content($bjson); my$http=LWP::UserAgent->new->request($request); my@y=$http->{_content}; my$mes=JSON::decode_json($y[0]); my$token_id=$mes->{'access'}{'token'}{'id'}; my$token_exp=$mes->{'access'}{'token'}{'expires'}; my$tenant_id=$mes->{'access'}{'token'}{'tenant'}{'id'}; print("\n\n*******token_idis$token_idandtoken_expis$token_expandtenant_idis$tenant_id*******

\n\n");

VerifyingHypervisorstatus: Beforegoingtonextstepweneedtoverifythestatusofcomputenodes(Hypervisors).BeforecreatingtheVM,theHypervisorsshouldbeUpandrunning.TheRESTAPIcommand"/v1.1/".$tenant_id."/os-services"providesthestatusofthehypervisors.Thisisequivalentto“novaservice-listcommand(theoutputgivenbelow).my$NOVAport="8774"; $CMDpath="/v1.1/".$tenant_id."/os-services";$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};printDumper($http);$mes=JSON::decode_json($y[0]);

Writing Style – Solution Brief

my$len=@{$mes->{"services"}};my%server_to_netaddr_hash;my%test;my$servername;my$state;my$status;my$hostcount=0;for(my$x=0;$x<$len;++$x){$servername=$mes->{"services"}[$x]{"host"};if(($servername=~/vmg\d+/)||($servername=~/vm\d+/)){ $state=$mes->{"services"}[$x]{"state"};my$status=$mes->{"services"}[$x]{"status"};if($statene"up"||$statusne"enabled"){print("\n\n*******statusorstateofhost$servernameisnotcorrect.Thestateis$stateandstatusis$status*******\n\n");returnJT::FALSE;}print("\n\n*******statusorstateofthecomputenode$servernameiscorrectThestateis$stateandstatusis$status*******\n\n");$hostcount++;} }root@server01:~#novaservice-list+----+------------------+--------------+----------+---------+-------+----------------------------+-----------------+|Id|Binary|Host|Zone|Status|State|Updated_at|DisabledReason|+----+------------------+--------------+----------+---------+-------+----------------------------+-----------------+|1|nova-scheduler|server1|internal|enabled|up|2016-12-09T21:32:39.000000|-||2|nova-console|server1|internal|enabled|up|2016-12-09T21:32:42.000000|-||3|nova-consoleauth|server1|internal|enabled|up|2016-12-09T21:32:42.000000|-||4|nova-conductor|server1|internal|enabled|up|2016-12-09T21:32:38.000000|-||6|nova-compute|vm6|nova|enabled|up|2016-12-09T21:32:38.000000|-||7|nova-compute|vm7|nova|enabled|up|2016-12-09T21:32:35.000000|-||8|nova-compute|vm8|nova|enabled|up|2016-12-09T21:32:38.000000|-||9|nova-compute|vm9|nova|enabled|up|2016-12-09T21:32:33.000000|-||10|nova-compute|vm10|nova|enabled|up|2016-12-09T21:32:41.000000|-||11|nova-compute|vm11|nova|enabled|up|2016-12-09T21:32:41.000000|-||12|nova-compute|vm12|nova|enabled|up|2016-12-09T21:32:33.000000|-||13|nova-compute|vm13|nova|enabled|up|2016-12-09T21:32:37.000000|-||14|nova-compute|vm14|nova|enabled|up|2016-12-09T21:32:41.000000|-||15|nova-compute|vm15|nova|enabled|up|2016-12-09T21:32:39.000000|-||16|nova-compute|vm16|nova|enabled|up|2016-12-09T21:32:42.000000|-||17|nova-compute|vm17|nova|enabled|up|2016-12-09T21:32:33.000000|-||18|nova-compute|vm18|nova|enabled|up|2016-12-09T21:32:40.000000|-|+----+------------------+--------------+----------+---------+-------+----------------------------+-----------------+root@server01:~#

CreatingVirtualNetwork:ThenextstepistocreatevirtualNetwork.VirtualnetworkhastobecreatedbeforecreatingVM.TocreatevirtualNetworkthefollowinginformationisrequired.

• Networksegmentaddressandnetmask• Gatewayaddress

Writing Style – Solution Brief

• Networkname• Route-targetattachedtothisnetwork• Projectname(collectedfromopenstackhorizonGUI)• Token-id(asexplainedinpreviousstep)

Tocreatevirtualnetwork,theRESAPIcommand"/virtual-networks"isexecutedonthecontrailcontroller.Portnumber8082isusedforthis.Thecorrectprojectnameshouldbeaddedherewhereitsays"PROJECTNAME".”novanet-list”showsthenetworkcreatedasshownbelow. $netname="net$i"; $cont_ip=”1.1.1.1”; $target="target:64512:$value"; $gateway="100.$n.$m.1"; $pool = "100.$n.$m.0"; $CMDpath = "/virtual-networks"; $APIport="8082"; $url= "http://".$cont_ip.":".$APIport.$CMDpath; $body = { "virtual-network"=> { "parent_type"=> "project", "fq_name"=> [ "default-domain", "PROJECTNAME", $netname ], "route_target_list"=> { "route_target"=> [ $target ] }, "network_ipam_refs"=> [{ "attr"=> { "ipam_subnets"=> [{ "subnet"=> { "gateway_ip" => $gateway, "ip_prefix"=> $pool, "ip_prefix_len"=> 24}}]}, "to"=> [ "default-domain", "default-project", "default-network-ipam"]}]} }; $request = HTTP::Request->new( POST => $url ); $bjson = encode_json $body; $request->content_type("application/json"); $request->header('x-auth-token' => $token_id); $request->content($bjson); $http = LWP::UserAgent->new->request($request); root@server1:~#novanet-list+--------------------------------------+-------------------------+------+|ID|Label|CIDR|+--------------------------------------+-------------------------+------+

Writing Style – Solution Brief

|363b4323-69d3-404a-b7b2-6587b4507479|net6|None||274b0b81-52be-48f9-8888-0c6be1d910c2|net9|None||72f26b86-f0bf-44c0-aadb-5f94c34b5eeb|net4|None||72be70e4-c0d8-46ce-be8c-33d80f095c5a|default-virtual-network|None||aa0f528e-f276-4d5a-a02f-bb02f7289c9c|net10|None||ce1e9035-9c4d-49de-a867-2f4a27bd5691|net13|None||b8599366-f1c0-4c2f-bab2-34533902466d|net12|None||b8543c48-872d-4e25-9de7-658f304c032a|net7|None||34168c65-a4c8-439a-beda-3c7a1f380176|net3|None||7a244326-fc1e-416c-98fb-cc073f8762a0|test|None||e7b4e0b9-6fc9-497f-9899-4e2aa344a97b|net11|None||d669a490-53f4-4fac-bed2-b79fe8538eae|__link_local__|None||f5307953-9490-4da6-b365-7173035d69d3|net5|None||a9eac604-a634-43df-8b9f-ea7258941313|net8|None||a8363373-548d-4f78-8366-bd0277be8b80|net1|None||c4d757cb-d2ab-4334-8e80-029cb0c31610|ip-fabric|None||fac53b08-59e7-45c6-9ef6-6007160979bb|net2|None|+--------------------------------------+-------------------------+------+root@server1:~# VMFlavorid/VMImageid/virtualNetworkidDetails: BeforecreatingtheVMweneedthefollowinginformation.ThereareseparateRESTAPIcommandsavailabletocollecteachofthisinformation.

• VMname• VMflavorid• VMimageid• Virtualnetworkid• VMsecuritygroup• Tenantname(orprojectname)

VMFlavorID: TogettheVMflavoridthefollowingcodeisused.TheRESTAPIcommand"/v1.1/".$tenant_id."/flavors"returnstheVMflavorid.ThisRESTAPIcommandishandledbyNOVAcomponentofopenstackcontroller. My$NOVAport="8774";My$openstack_ip=”1.1.1.1”; my$headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-Auth-Token':$token_id}";$CMDpath="/v1.1/".$tenant_id."/flavors";$APIport=$NOVAport;$url="http://".$openstack_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};$mes=JSON::decode_json($y[0]);

Writing Style – Solution Brief

my$len=@{$mes->{'flavors'}};my$flavor_id;for(my$x=0;$x<$len;++$x){if($mes->{'flavors'}[$x]{'name'}eq$add_vm_flavor){$flavor_id=$mes->{'flavors'}[$x]{'id'};last;}}print("\n\n*******imageidfor$add_vm_flavoris$flavor_id*******\n\n");

VMimageid:Togettheimageidthiscodeisused.TheRESTAPIcommand"/v1.1/".$tenant_id."/images"returnstheimageid.ThisRESTAPIcommandishandledbyNOVAcomponentofopenstackcontroller. my$headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-Auth-Token':$token_id}";$CMDpath="/v1.1/".$tenant_id."/images";$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};$mes=JSON::decode_json($y[0]);my$len=@{$mes->{'images'}};my$image_id;for(my$x=0;$x<$len;++$x){if($mes->{'images'}[$x]{'name'}eq$add_vm_image){$image_id=$mes->{'images'}[$x]{'id'};last;}}print("\n\n*******imageidfor$add_vm_imageis$image_id*******\n\n"); VirtualNetworkID: TheRESTAPIcommand"/v1.1/".$tenant_id."/os-tenant-networks"returnsthevirtualnetworkid.ThisRESTAPIcommandishandledbyNOVAcomponentofopenstackcontroller.Thenetworkidofthenetworkname“$add_vm_net”canbeidentifiedbythiscode. my$headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-Auth-Token':$token_id}";$CMDpath="/v1.1/".$tenant_id."/os-tenant-networks";$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};

Writing Style – Solution Brief

$mes=JSON::decode_json($y[0]);my$len=@{$mes->{'networks'}};my$network_id;for(my$x=0;$x<$len;++$x){if($mes->{'networks'}[$x]{'label'}eq$add_vm_net){$network_id=$mes->{'networks'}[$x]{'id'};last;}}print("\n\n*******networksidfor$add_vm_netis$network_id*******\n\n");

VMcreation:NowwereachedthefinalsteptocreateVM.TheRESTAPI"/v1.1/".$tenant_id."/servers"createstheVM.TheVMname,imageid,flavoridandsecuritygroupnamearerequiredtorunthisRESTAPIcommand. $headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-OpenStack-Nova-API-Version':'2.11','X-Auth-Token':$token_id}";$CMDpath="/v1.1/".$tenant_id."/servers";$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$body={"server"=>{"name"=>"$add_vm_name","imageRef"=>"$image_id","flavorRef"=>"$flavor_id","max_count"=>1,"min_count"=>1,"networks"=>[{"uuid"=>"$network_id"}],"security_groups"=>[{"name"=>"$add_vm_secgroup"}]}};$request=HTTP::Request->new(POST=>$url);$bjson=encode_json$body;$request->content_type("application/json");$request->header('x-auth-token'=>$token_id);$request->content($bjson);$http=LWP::UserAgent->new->request($request);

VMstatusverification:AftercreatingVMthestatusoftheVMcanbeverifiedbytheRESTAPIcommand"/v1.1/".$tenant_id."/servers/detail".ThissamplecodegivesdetailsonhowtoverifystatusofaVM.Itchecksforvm_statetobeactiveandpower_statetobe1.ThisRESTAPIcommandisequivalenttonovalistcommandshownbelow. $CMDpath="/v1.1/".$tenant_id."/servers/detail";

Writing Style – Solution Brief

$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};printDumper($http);$mes=JSON::decode_json($y[0]);my$len=@{$mes->{"servers"}};my%server_to_netaddr_hash;my%test;my$servername;my$state;my$status;my$test;my$vmcount=0; $status=$mes->{"servers"}[$x]{"OS-EXT-STS:vm_state"};$state=$mes->{"servers"}[$x]{"OS-EXT-STS:power_state"};if($statusne"active"||$state!=1){print("\n\n*******status/stateofthevm$testisnotcorrect.Thecurrentstatusis$statusandstateis$state*******\n\n");returnJT::FALSE;}print("\n\n*******statusandstateofthevm$testiscorrectThecurrentstatusis$statusandstateis$state*******\n\n");} root@server1:~#novalist+--------------------------------------+--------+--------+------------+-------------+--------------------+|ID|Name|Status|TaskState|PowerState|Networks|+--------------------------------------+--------+--------+------------+-------------+--------------------+|935bb371-9fb6-4d1e-92b6-239db2d28a2a|nvmg1|ACTIVE|-|Running|net1=100.0.4.252||69b9dca5-a4e0-4168-8363-b87caa65e741|nvmg10|ACTIVE|-|Running|net10=100.0.13.252||176f9b62-1561-41e9-9c2f-de86f76afffd|nvmg11|ACTIVE|-|Running|net11=100.0.14.252||15eff465-7251-4de8-b371-cc85790ca9a6|nvmg12|ACTIVE|-|Running|net12=100.0.15.252||c1be1e20-4969-4911-8fdf-81e09c0023e9|nvmg13|ACTIVE|-|Running|net13=100.0.16.252||449becae-69b7-4f57-947a-74d78875ef39|nvmg2|ACTIVE|-|Running|net2=100.0.5.252||db8c1d5b-5990-458f-bfcb-13a7d2bdbbda|nvmg3|ACTIVE|-|Running|net3=100.0.6.252||a7ceee7e-539a-4398-a768-209db065a71c|nvmg4|ACTIVE|-|Running|net4=100.0.7.252||43713c5b-c262-4e56-9a77-ffde968f448e|nvmg5|ACTIVE|-|Running|net5=100.0.8.252||8010f8a0-56d8-4904-a747-8e5dfa1f8ac8|nvmg6|ACTIVE|-|Running|net6=100.0.9.252||0c57cb78-922b-4f76-98d5-f962f08a85a6|nvmg7|ACTIVE|-|Running|net7=100.0.10.252||47ca6427-c898-4d71-9c2d-61ffa533e31e|nvmg8|ACTIVE|-|Running|net8=100.0.11.252||a08bbaac-3ed9-4cf6-ad6c-def7484a35e4|nvmg9|ACTIVE|-|Running|net9=100.0.12.252|+--------------------------------------+--------+--------+------------+-------------+--------------------+ ThestatusoftheVMscanalsobecheckedinOPENSTACKhorizonGUIasshownbelow.

Writing Style – Solution Brief

VMDeletion: BeforestartdeletingtheVMsweneedtogetthetoken-idfromtheOpenstackserverusingtheproceduregivenearlier.InadditiontothisweneedtoknowtheVMid.TogettheVMidwecanusetheRESTAPI"/v2/".$tenant_id."/servers?name=".$del_vm_nameasshownbelow.my$headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-Auth-Token':$token_id}";$CMDpath="/v2/".$tenant_id."/servers?name=".$del_vm_name;$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);@y=$http->{_content};$mes=JSON::decode_json($y[0]);#print"\n\n\n\n\n\---------------\n\n\n\n";#printDumper($mes);my$del_vm_id=$mes->{'servers'}[0]{'id'};print("\n\n*******deltevminstanceidis$del_vm_id*******\n\n");AftergettingtheVMIDwecanusetheRESTAPI"/v1.1/".$tenant_id."/servers/".$del_vm_id."/action"todeletetheVM.Thisisequivlantto“novadelete<vmname/vmid>”command.$headers="{'Content-Type':'application/json','Accept':'application/json','ser-Agent':'python-novaclient','X-Auth-Token':

Writing Style – Solution Brief

$token_id}";$CMDpath="/v1.1/".$tenant_id."/servers/".$del_vm_id."/action";$APIport=$NOVAport;$url="http://".$cont_ip.":".$APIport.$CMDpath;$body={"forceDelete"=>"null"};$request=HTTP::Request->new(POST=>$url);$bjson=encode_json$body;$request->content_type("application/json");$request->header('x-auth-token'=>$token_id);$request->content($bjson);$http=LWP::UserAgent->new->request($request);

Conclusion ThisdocumentgivesdetailsonCONTRAILcloudsolutionimplementation.ItalsoexplainstheRESTAPIdetailsforVMcreation,VMdeletionetc..

Writing Style – Solution Brief

APPENDIX The section give details on other RESTAPI commands.

Deletingvirtualnetwork: This command is executed on the contrail controller. To run this command we need virtual network id. $CMDpath="/virtual-network/";$APIport="8082";$url="http://".$cont_ip.":".$APIport.$CMDpath.$netid;$request=HTTP::Request->new(DELETE=>$url);$request->header('content-type'=>'application/json');$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request); To get the virtual network id this RESTAPI is used.The “uuid” returns the network id. $CMDpath="/virtual-networks";$APIport="8082";$url="http://".$cont_ip.":".$APIport.$CMDpath;$request=HTTP::Request->new(GET=>$url);$request->content_type("application/json");$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request);printDumper$http;@y=$http->{_content};$mes=JSON::decode_json($y[0]);$len=@{$mes->{"virtual-networks"}};my@network_list;my$i=1;for(my$x=0;$x<$len;++$x){if($mes->{"virtual-networks"}[$x]{"fq_name"}[2]=~/net\d+/){push(@network_list,$mes->{"virtual-networks"}[$x]{"uuid"});$i++;}} TodeletetheportswhichmapvirtualnetworkwiththeVMweneedtousetheRESTAPIgivenbelow.Weneedportidtorunthiscommand. My$NEUTRONport="9696";$CMDpath="/v2.0/ports/";$APIport=$NEUTRONport;$url="http://".$cont_ip.":".$APIport.$CMDpath.$portid.".json";$request=HTTP::Request->new(DELETE=>$url);$request->header('content-type'=>'application/json');

Writing Style – Solution Brief

$request->header('x-auth-token'=>$token_id);$http=LWP::UserAgent->new->request($request); The port id can be found from, $CMDpath= "/v2.0/ports.json"; $APIport=$NEUTRONport; $url= "http://".$cont_ip.":".$APIport.$CMDpath; $request = HTTP::Request->new( GET => $url ); $request->header('content-type' => 'application/json'); $request->header('x-auth-token' => $token_id); $http = LWP::UserAgent->new->request($request); @y = $http->{_content}; $mes = JSON::decode_json($y[0]); my $len = @{$mes->{"ports"}}; my @port_list; for (my $x = 0; $x< $len ; ++$x) { push (@port_list, $mes->{"ports"}[$x]{"id"}); }

Writing Style – Solution Brief