From a833cd230e9185251934664b49c62f9c7c06b73f Mon Sep 17 00:00:00 2001 From: Dimitris Aragiorgis Date: Mon, 4 Jun 2012 23:20:09 +0300 Subject: [PATCH 1/1] Rapi support for networks Support: - GetNetwork(s) - CreateNetwork - ConnectNetwork - DisconnectNetwork - RemoveNetwork Signed-off-by: Dimitris Aragiorgis --- lib/rapi/client.py | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/rapi/connector.py | 14 ++++++- lib/rapi/rlib2.py | 107 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 229 insertions(+), 3 deletions(-) diff --git a/lib/rapi/client.py b/lib/rapi/client.py index b5a4df5..5138bb0 100644 --- a/lib/rapi/client.py +++ b/lib/rapi/client.py @@ -1625,6 +1625,117 @@ class GanetiRapiClient(object): # pylint: disable=R0904 ("/%s/nodes/%s/tags" % (GANETI_RAPI_VERSION, node)), query, None) + def GetNetworks(self, bulk=False): + """Gets all networks in the cluster. + + @type bulk: bool + @param bulk: whether to return all information about the networks + + @rtype: list of dict or str + @return: if bulk is true, a list of dictionaries with info about all + networks in the cluster, else a list of names of those networks + + """ + query = [] + _AppendIf(query, bulk, ("bulk", 1)) + + networks = self._SendRequest(HTTP_GET, "/%s/networks" % GANETI_RAPI_VERSION, + query, None) + if bulk: + return networks + else: + return [n["name"] for n in networks] + + def GetNetwork(self, network): + """Gets information about a network. + + @type group: str + @param group: name of the network whose info to return + + @rtype: dict + @return: info about the network + + """ + return self._SendRequest(HTTP_GET, + "/%s/networks/%s" % (GANETI_RAPI_VERSION, network), + None, None) + + def CreateNetwork(self, network_name, network, gateway=None, network6=None, + gateway6=None, mac_prefix=None, network_type=None, + add_reserved_ips=None, dry_run=False): + """Creates a new network. + + @type name: str + @param name: the name of network to create + @type dry_run: bool + @param dry_run: whether to peform a dry run + + @rtype: string + @return: job id + + """ + query = [] + _AppendDryRunIf(query, dry_run) + + body = { + "network_name": network_name, + "gateway": gateway, + "network": network, + "gateway6": gateway6, + "network6": network6, + "mac_prefix": mac_prefix, + "network_type": network_type, + "add_reserved_ips": add_reserved_ips + } + + return self._SendRequest(HTTP_POST, "/%s/networks" % GANETI_RAPI_VERSION, + query, body) + + def ConnectNetwork(self, network_name, group_name, mode, link): + """Connects a Network to a NodeGroup with the given netparams + + """ + body = { + "group_name": group_name, + "network_mode": mode, + "network_link": link + } + + return self._SendRequest(HTTP_PUT, + ("/%s/networks/%s/connect" % + (GANETI_RAPI_VERSION, network_name)), None, body) + + def DisconnectNetwork(self, network_name, group_name): + """Connects a Network to a NodeGroup with the given netparams + + """ + body = { + "group_name": group_name + } + return self._SendRequest(HTTP_PUT, + ("/%s/networks/%s/disconnect" % + (GANETI_RAPI_VERSION, network_name)), None, body) + + + def DeleteNetwork(self, network, dry_run=False): + """Deletes a network. + + @type group: str + @param group: the network to delete + @type dry_run: bool + @param dry_run: whether to peform a dry run + + @rtype: string + @return: job id + + """ + query = [] + _AppendDryRunIf(query, dry_run) + + return self._SendRequest(HTTP_DELETE, + ("/%s/networks/%s" % + (GANETI_RAPI_VERSION, network)), query, None) + def GetGroups(self, bulk=False): """Gets all node groups in the cluster. diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py index b701d71..a833fcf 100644 --- a/lib/rapi/connector.py +++ b/lib/rapi/connector.py @@ -89,7 +89,8 @@ class Mapper: def GetHandlers(node_name_pattern, instance_name_pattern, - group_name_pattern, job_id_pattern, disk_pattern, + group_name_pattern, network_name_pattern, + job_id_pattern, disk_pattern, query_res_pattern): """Returns all supported resources and their handlers. @@ -167,6 +168,14 @@ def GetHandlers(node_name_pattern, instance_name_pattern, re.compile(r"^/2/instances/(%s)/console$" % instance_name_pattern): rlib2.R_2_instances_name_console, + "/2/networks": rlib2.R_2_networks, + re.compile(r"^/2/networks/(%s)$" % network_name_pattern): + rlib2.R_2_networks_name, + re.compile(r"^/2/networks/(%s)/connect$" % network_name_pattern): + rlib2.R_2_networks_name_connect, + re.compile(r"^/2/networks/(%s)/disconnect$" % network_name_pattern): + rlib2.R_2_networks_name_disconnect, + "/2/groups": rlib2.R_2_groups, re.compile(r"^/2/groups/(%s)$" % group_name_pattern): rlib2.R_2_groups_name, @@ -197,6 +206,7 @@ def GetHandlers(node_name_pattern, instance_name_pattern, } -CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN, +CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, + _NAME_PATTERN, _NAME_PATTERN, constants.JOB_ID_TEMPLATE, _DISK_PATTERN, _NAME_PATTERN)) diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py index e434340..9201a82 100644 --- a/lib/rapi/rlib2.py +++ b/lib/rapi/rlib2.py @@ -70,7 +70,8 @@ _COMMON_FIELDS = ["ctime", "mtime", "uuid", "serial_no", "tags"] I_FIELDS = ["name", "admin_state", "os", "pnode", "snodes", "disk_template", - "nic.ips", "nic.macs", "nic.modes", "nic.links", "nic.bridges", + "nic.ips", "nic.macs", "nic.modes", + "nic.links", "nic.networks", "nic.bridges", "network_port", "disk.sizes", "disk_usage", "beparams", "hvparams", @@ -90,6 +91,14 @@ N_FIELDS = ["name", "offline", "master_candidate", "drained", "group.uuid", ] + _COMMON_FIELDS +NET_FIELDS = ["name", "network", "gateway", + "network6", "gateway6", + "mac_prefix", "network_type", + "free_count", "reserved_count", + "map", "group_list", "inst_list", + "external_reservations", + ] + G_FIELDS = [ "alloc_policy", "name", @@ -642,6 +651,101 @@ class R_2_nodes_name_storage_repair(baserlib.OpcodeResource): }) +class R_2_networks(baserlib.OpcodeResource): + """/2/networks resource. + + """ + GET_OPCODE = opcodes.OpNetworkQuery + POST_OPCODE = opcodes.OpNetworkAdd + POST_RENAME = { + "name": "network_name", + } + + def GetPostOpInput(self): + """Create a network. + + """ + assert not self.items + return (self.request_body, { + "dry_run": self.dryRun(), + }) + + def GET(self): + """Returns a list of all networks. + + """ + client = self.GetClient() + + if self.useBulk(): + bulkdata = client.QueryNetworks([], NET_FIELDS, False) + return baserlib.MapBulkFields(bulkdata, NET_FIELDS) + else: + data = client.QueryNetworks([], ["name"], False) + networknames = [row[0] for row in data] + return baserlib.BuildUriList(networknames, "/2/networks/%s", + uri_fields=("name", "uri")) + + +class R_2_networks_name(baserlib.OpcodeResource): + """/2/network/[network_name] resource. + + """ + DELETE_OPCODE = opcodes.OpNetworkRemove + + def GET(self): + """Send information about a network. + + """ + network_name = self.items[0] + client = self.GetClient() + + result = baserlib.HandleItemQueryErrors(client.QueryNetworks, + names=[network_name], + fields=NET_FIELDS, + use_locking=self.useLocking()) + + return baserlib.MapFields(NET_FIELDS, result[0]) + + def GetDeleteOpInput(self): + """Delete a network. + + """ + assert len(self.items) == 1 + return (self.request_body, { + "network_name": self.items[0], + "dry_run": self.dryRun(), + }) + +class R_2_networks_name_connect(baserlib.OpcodeResource): + """/2/network/[network_name]/connect. + + """ + PUT_OPCODE = opcodes.OpNetworkConnect + + def GetPutOpInput(self): + """Changes some parameters of node group. + + """ + assert self.items + return (self.request_body, { + "network_name": self.items[0], + }) + +class R_2_networks_name_disconnect(baserlib.OpcodeResource): + """/2/network/[network_name]/disconnect. + + """ + PUT_OPCODE = opcodes.OpNetworkDisconnect + + def GetPutOpInput(self): + """Changes some parameters of node group. + + """ + assert self.items + return (self.request_body, { + "network_name": self.items[0], + }) + class R_2_groups(baserlib.OpcodeResource): """/2/groups resource. @@ -655,6 +759,7 @@ class R_2_groups(baserlib.OpcodeResource): def GetPostOpInput(self): """Create a node group. + """ assert not self.items return (self.request_body, { -- 1.7.10.4