Revision 6e8091f9
b/doc/hooks.rst | ||
---|---|---|
214 | 214 |
:pre-execution: master node and all nodes in the group |
215 | 215 |
:post-execution: master node and all nodes in the group |
216 | 216 |
|
217 |
Network operations |
|
218 |
~~~~~~~~~~~~~~~~~~ |
|
219 |
|
|
220 |
OP_NETWORK_ADD |
|
221 |
++++++++++++++ |
|
222 |
|
|
223 |
Adds a network to the cluster. |
|
224 |
|
|
225 |
:directory: network-add |
|
226 |
:env. vars: NETWORK_NAME, NETWORK_SUBNET, NETWORK_GATEWAY, NETWORK_SUBNET6, |
|
227 |
NETWORK_GATEWAY6, NETWORK_TYPE, NETWORK_MAC_PREFIX, NETWORK_TAGS |
|
228 |
:pre-execution: master node |
|
229 |
:post-execution: master node |
|
230 |
|
|
231 |
OP_NETWORK_REMOVE |
|
232 |
+++++++++++++++++ |
|
233 |
|
|
234 |
Removes a network from the cluster. |
|
235 |
|
|
236 |
:directory: network-remove |
|
237 |
:env. vars: NETWORK_NAME |
|
238 |
:pre-execution: master node |
|
239 |
:post-execution: master node |
|
240 |
|
|
241 |
OP_NETWORK_CONNECT |
|
242 |
++++++++++++++++++ |
|
243 |
|
|
244 |
Connects a network to a nodegroup. |
|
245 |
|
|
246 |
:directory: network-connect |
|
247 |
:env. vars: GROUP_NAME, NETWORK_NAME, |
|
248 |
GROUP_NETWORK_MODE, GROUP_NETWORK_LINK, |
|
249 |
NETWORK_SUBNET, NETWORK_GATEWAY, NETWORK_SUBNET6, |
|
250 |
NETWORK_GATEWAY6, NETWORK_TYPE, NETWORK_MAC_PREFIX, NETWORK_TAGS |
|
251 |
:pre-execution: nodegroup nodes |
|
252 |
:post-execution: nodegroup nodes |
|
253 |
|
|
254 |
|
|
255 |
OP_NETWORK_DISCONNECT |
|
256 |
+++++++++++++++++++++ |
|
257 |
|
|
258 |
Disconnects a network from a nodegroup. |
|
259 |
|
|
260 |
:directory: network-disconnect |
|
261 |
:env. vars: GROUP_NAME, NETWORK_NAME, |
|
262 |
GROUP_NETWORK_MODE, GROUP_NETWORK_LINK, |
|
263 |
NETWORK_SUBNET, NETWORK_GATEWAY, NETWORK_SUBNET6, |
|
264 |
NETWORK_GATEWAY6, NETWORK_TYPE, NETWORK_MAC_PREFIX, NETWORK_TAGS |
|
265 |
:pre-execution: nodegroup nodes |
|
266 |
:post-execution: nodegroup nodes |
|
267 |
|
|
268 |
|
|
269 |
OP_NETWORK_SET_PARAMS |
|
270 |
+++++++++++++++++++++ |
|
271 |
|
|
272 |
Modifies a network. |
|
273 |
|
|
274 |
:directory: network-modify |
|
275 |
:env. vars: NETWORK_NAME, NETWORK_SUBNET, NETWORK_GATEWAY, NETWORK_SUBNET6, |
|
276 |
NETWORK_GATEWAY6, NETWORK_TYPE, NETWORK_MAC_PREFIX, NETWORK_TAGS |
|
277 |
:pre-execution: master node |
|
278 |
:post-execution: master node |
|
279 |
|
|
217 | 280 |
|
218 | 281 |
Instance operations |
219 | 282 |
~~~~~~~~~~~~~~~~~~~ |
b/doc/rapi.rst | ||
---|---|---|
646 | 646 |
It supports the ``dry-run`` argument. |
647 | 647 |
|
648 | 648 |
|
649 |
``/2/networks`` |
|
650 |
+++++++++++++++ |
|
651 |
|
|
652 |
The networks resource. |
|
653 |
|
|
654 |
It supports the following commands: ``GET``, ``POST``. |
|
655 |
|
|
656 |
``GET`` |
|
657 |
~~~~~~~ |
|
658 |
|
|
659 |
Returns a list of all existing networks. |
|
660 |
|
|
661 |
Example:: |
|
662 |
|
|
663 |
[ |
|
664 |
{ |
|
665 |
"name": "network1", |
|
666 |
"uri": "\/2\/networks\/network1" |
|
667 |
}, |
|
668 |
{ |
|
669 |
"name": "network2", |
|
670 |
"uri": "\/2\/networks\/network2" |
|
671 |
} |
|
672 |
] |
|
673 |
|
|
674 |
If the optional bool *bulk* argument is provided and set to a true value |
|
675 |
(i.e ``?bulk=1``), the output contains detailed information about networks |
|
676 |
as a list. |
|
677 |
|
|
678 |
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`. |
|
679 |
|
|
680 |
Example:: |
|
681 |
|
|
682 |
[ |
|
683 |
{ |
|
684 |
'external_reservations': '10.0.0.0, 10.0.0.1, 10.0.0.15', |
|
685 |
'free_count': 13, |
|
686 |
'gateway': '10.0.0.1', |
|
687 |
'gateway6': None, |
|
688 |
'group_list': ['default(bridged, prv0)'], |
|
689 |
'inst_list': [], |
|
690 |
'mac_prefix': None, |
|
691 |
'map': 'XX.............X', |
|
692 |
'name': 'nat', |
|
693 |
'network': '10.0.0.0/28', |
|
694 |
'network6': None, |
|
695 |
'network_type': 'private', |
|
696 |
'reserved_count': 3, |
|
697 |
'tags': ['nfdhcpd'] |
|
698 |
}, |
|
699 |
] |
|
700 |
|
|
701 |
``POST`` |
|
702 |
~~~~~~~~ |
|
703 |
|
|
704 |
Creates a network. |
|
705 |
|
|
706 |
If the optional bool *dry-run* argument is provided, the job will not be |
|
707 |
actually executed, only the pre-execution checks will be done. |
|
708 |
|
|
709 |
Returns: a job ID that can be used later for polling. |
|
710 |
|
|
711 |
Body parameters: |
|
712 |
|
|
713 |
.. opcode_params:: OP_NETWORK_ADD |
|
714 |
|
|
715 |
Job result: |
|
716 |
|
|
717 |
.. opcode_result:: OP_NETWORK_ADD |
|
718 |
|
|
719 |
|
|
720 |
``/2/networks/[network_name]`` |
|
721 |
++++++++++++++++++++++++++++++ |
|
722 |
|
|
723 |
Returns information about a network. |
|
724 |
|
|
725 |
It supports the following commands: ``GET``, ``DELETE``. |
|
726 |
|
|
727 |
``GET`` |
|
728 |
~~~~~~~ |
|
729 |
|
|
730 |
Returns information about a network, similar to the bulk output from |
|
731 |
the network list. |
|
732 |
|
|
733 |
Returned fields: :pyeval:`utils.CommaJoin(sorted(rlib2.NET_FIELDS))`. |
|
734 |
|
|
735 |
``DELETE`` |
|
736 |
~~~~~~~~~~ |
|
737 |
|
|
738 |
Deletes a network. |
|
739 |
|
|
740 |
It supports the ``dry-run`` argument. |
|
741 |
|
|
742 |
Job result: |
|
743 |
|
|
744 |
.. opcode_result:: OP_NETWORK_REMOVE |
|
745 |
|
|
746 |
|
|
747 |
``/2/networks/[network_name]/modify`` |
|
748 |
+++++++++++++++++++++++++++++++++++++ |
|
749 |
|
|
750 |
Modifies the parameters of a network. |
|
751 |
|
|
752 |
Supports the following commands: ``PUT``. |
|
753 |
|
|
754 |
``PUT`` |
|
755 |
~~~~~~~ |
|
756 |
|
|
757 |
Returns a job ID. |
|
758 |
|
|
759 |
Body parameters: |
|
760 |
|
|
761 |
.. opcode_params:: OP_NETWORK_SET_PARAMS |
|
762 |
|
|
763 |
Job result: |
|
764 |
|
|
765 |
.. opcode_result:: OP_NETWORK_SET_PARAMS |
|
766 |
|
|
767 |
|
|
768 |
``/2/networks/[network_name]/connect`` |
|
769 |
++++++++++++++++++++++++++++++++++++++ |
|
770 |
|
|
771 |
Connects a network to a nodegroup. |
|
772 |
|
|
773 |
Supports the following commands: ``PUT``. |
|
774 |
|
|
775 |
``PUT`` |
|
776 |
~~~~~~~ |
|
777 |
|
|
778 |
Returns a job ID. It supports the ``dry-run`` arguments. |
|
779 |
|
|
780 |
Body parameters: |
|
781 |
|
|
782 |
.. opcode_params:: OP_NETWORK_CONNECT |
|
783 |
|
|
784 |
Job result: |
|
785 |
|
|
786 |
.. opcode_result:: OP_NETWORK_CONNECT |
|
787 |
|
|
788 |
|
|
789 |
``/2/networks/[network_name]/disconnect`` |
|
790 |
+++++++++++++++++++++++++++++++++++++++++ |
|
791 |
|
|
792 |
Disonnects a network from a nodegroup. |
|
793 |
|
|
794 |
Supports the following commands: ``PUT``. |
|
795 |
|
|
796 |
``PUT`` |
|
797 |
~~~~~~~ |
|
798 |
|
|
799 |
Returns a job ID. It supports the ``dry-run`` arguments. |
|
800 |
|
|
801 |
Body parameters: |
|
802 |
|
|
803 |
.. opcode_params:: OP_NETWORK_DISCONNECT |
|
804 |
|
|
805 |
Job result: |
|
806 |
|
|
807 |
.. opcode_result:: OP_NETWORK_DISCONNECT |
|
808 |
|
|
809 |
|
|
810 |
``/2/networks/[network_name]/tags`` |
|
811 |
+++++++++++++++++++++++++++++++++++ |
|
812 |
|
|
813 |
Manages per-network tags. |
|
814 |
|
|
815 |
Supports the following commands: ``GET``, ``PUT``, ``DELETE``. |
|
816 |
|
|
817 |
``GET`` |
|
818 |
~~~~~~~ |
|
819 |
|
|
820 |
Returns a list of tags. |
|
821 |
|
|
822 |
Example:: |
|
823 |
|
|
824 |
["tag1", "tag2", "tag3"] |
|
825 |
|
|
826 |
``PUT`` |
|
827 |
~~~~~~~ |
|
828 |
|
|
829 |
Add a set of tags. |
|
830 |
|
|
831 |
The request as a list of strings should be ``PUT`` to this URI. The |
|
832 |
result will be a job id. |
|
833 |
|
|
834 |
It supports the ``dry-run`` argument. |
|
835 |
|
|
836 |
|
|
837 |
``DELETE`` |
|
838 |
~~~~~~~~~~ |
|
839 |
|
|
840 |
Delete a tag. |
|
841 |
|
|
842 |
In order to delete a set of tags, the DELETE request should be addressed |
|
843 |
to URI like:: |
|
844 |
|
|
845 |
/tags?tag=[tag]&tag=[tag] |
|
846 |
|
|
847 |
It supports the ``dry-run`` argument. |
|
848 |
|
|
849 |
|
|
649 | 850 |
``/2/instances-multi-alloc`` |
650 | 851 |
++++++++++++++++++++++++++++ |
651 | 852 |
|
b/lib/network.py | ||
---|---|---|
115 | 115 |
assert self.net.family == 4 |
116 | 116 |
assert len(self.reservations) == self._GetSize() |
117 | 117 |
assert len(self.ext_reservations) == self._GetSize() |
118 |
assert not (self.reservations & self.ext_reservations).any() |
|
118 |
all_res = self.reservations & self.ext_reservations |
|
119 |
assert not all_res.any() |
|
119 | 120 |
|
120 | 121 |
if self.gateway is not None: |
121 | 122 |
assert self.net.family == self.gateway.version |
b/lib/opcodes.py | ||
---|---|---|
2011 | 2011 |
OP_PARAMS = [ |
2012 | 2012 |
_PNetworkName, |
2013 | 2013 |
_PNetworkType, |
2014 |
("network", None, ht.TAnd(ht.TString ,_CheckCIDRNetNotation), None), |
|
2015 |
("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None), |
|
2016 |
("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None), |
|
2017 |
("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None), |
|
2018 |
("mac_prefix", None, ht.TMaybeString, None), |
|
2014 |
("network", None, ht.TAnd(ht.TString ,_CheckCIDRNetNotation), |
|
2015 |
"IPv4 Subnet"), |
|
2016 |
("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), |
|
2017 |
"IPv4 Gateway"), |
|
2018 |
("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), |
|
2019 |
"IPv6 Subnet"), |
|
2020 |
("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), |
|
2021 |
"IPv6 Gateway"), |
|
2022 |
("mac_prefix", None, ht.TMaybeString, |
|
2023 |
"Mac prefix that overrides cluster one"), |
|
2019 | 2024 |
("add_reserved_ips", None, |
2020 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None), |
|
2025 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), |
|
2026 |
"Which IPs to reserve"), |
|
2021 | 2027 |
("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), "Network tags"), |
2022 | 2028 |
] |
2029 |
OP_RESULT = ht.TNone |
|
2023 | 2030 |
|
2024 | 2031 |
class OpNetworkRemove(OpCode): |
2025 | 2032 |
"""Remove an existing network from the cluster. |
... | ... | |
2031 | 2038 |
_PNetworkName, |
2032 | 2039 |
_PForce, |
2033 | 2040 |
] |
2041 |
OP_RESULT = ht.TNone |
|
2034 | 2042 |
|
2035 | 2043 |
class OpNetworkSetParams(OpCode): |
2036 | 2044 |
"""Modify Network's parameters except for IPv4 subnet""" |
... | ... | |
2038 | 2046 |
OP_PARAMS = [ |
2039 | 2047 |
_PNetworkName, |
2040 | 2048 |
_PNetworkType, |
2041 |
("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), None), |
|
2042 |
("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), None), |
|
2043 |
("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), None), |
|
2044 |
("mac_prefix", None, ht.TMaybeString, None), |
|
2049 |
("gateway", None, ht.TOr(ht.TNone, _CheckCIDRAddrNotation), |
|
2050 |
"IPv4 Gateway"), |
|
2051 |
("network6", None, ht.TOr(ht.TNone, _CheckCIDR6NetNotation), |
|
2052 |
"IPv6 Subnet"), |
|
2053 |
("gateway6", None, ht.TOr(ht.TNone, _CheckCIDR6AddrNotation), |
|
2054 |
"IPv6 Gateway"), |
|
2055 |
("mac_prefix", None, ht.TMaybeString, |
|
2056 |
"Mac prefix that overrides cluster one"), |
|
2045 | 2057 |
("add_reserved_ips", None, |
2046 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None), |
|
2058 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), |
|
2059 |
"Which external IPs to reserve"), |
|
2047 | 2060 |
("remove_reserved_ips", None, |
2048 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), None), |
|
2061 |
ht.TOr(ht.TNone, ht.TListOf(_CheckCIDRAddrNotation)), |
|
2062 |
"Which external IPs to release"), |
|
2049 | 2063 |
] |
2064 |
OP_RESULT = ht.TNone |
|
2050 | 2065 |
|
2051 | 2066 |
class OpNetworkConnect(OpCode): |
2052 | 2067 |
"""Connect a Network to a specific Nodegroup with the defined netparams |
... | ... | |
2060 | 2075 |
OP_PARAMS = [ |
2061 | 2076 |
_PGroupName, |
2062 | 2077 |
_PNetworkName, |
2063 |
("network_mode", None, ht.TString, None),
|
|
2064 |
("network_link", None, ht.TString, None),
|
|
2065 |
("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
|
|
2078 |
("network_mode", None, ht.TString, "Connectivity mode"),
|
|
2079 |
("network_link", None, ht.TString, "Connectivity link"),
|
|
2080 |
("conflicts_check", True, ht.TBool, "Whether to check for conflicting IPs"),
|
|
2066 | 2081 |
] |
2082 |
OP_RESULT = ht.TNone |
|
2067 | 2083 |
|
2068 | 2084 |
class OpNetworkDisconnect(OpCode): |
2069 | 2085 |
"""Disconnect a Network from a Nodegroup. Produce errors if NICs are |
... | ... | |
2074 | 2090 |
OP_PARAMS = [ |
2075 | 2091 |
_PGroupName, |
2076 | 2092 |
_PNetworkName, |
2077 |
("conflicts_check", True, ht.TBool, "Check for conflicting IPs"),
|
|
2093 |
("conflicts_check", True, ht.TBool, "Whether to check for conflicting IPs"),
|
|
2078 | 2094 |
] |
2095 |
OP_RESULT = ht.TNone |
|
2079 | 2096 |
|
2080 | 2097 |
class OpNetworkQuery(OpCode): |
2081 | 2098 |
"""Compute the list of networks.""" |
... | ... | |
2084 | 2101 |
("names", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), |
2085 | 2102 |
"Empty list to query all groups, group names otherwise"), |
2086 | 2103 |
] |
2104 |
OP_RESULT = ht.TNone |
|
2087 | 2105 |
|
2088 | 2106 |
|
2089 | 2107 |
def _GetOpList(): |
b/lib/ovf.py | ||
---|---|---|
760 | 760 |
SubElementText(nic, "gnt:MACAddress", network["mac"]) |
761 | 761 |
SubElementText(nic, "gnt:IPAddress", network["ip"]) |
762 | 762 |
SubElementText(nic, "gnt:Link", network["link"]) |
763 |
SubElementText(nic, "gnt:Network", network["network"])
|
|
763 |
SubElementText(nic, "gnt:Net", network["network"]) |
|
764 | 764 |
|
765 | 765 |
def SaveVirtualSystemData(self, name, vcpus, memory): |
766 | 766 |
"""Convert virtual system information to OVF sections. |
... | ... | |
1665 | 1665 |
counter = 0 |
1666 | 1666 |
while True: |
1667 | 1667 |
data_link = \ |
1668 |
self.config_parser.get(constants.INISECT_INS, "nic%s_network" % counter) |
|
1668 |
self.config_parser.get(constants.INISECT_INS, |
|
1669 |
"nic%s_link" % counter) |
|
1669 | 1670 |
if data_link is None: |
1670 | 1671 |
break |
1671 | 1672 |
results.append({ |
... | ... | |
1675 | 1676 |
"nic%s_mac" % counter), |
1676 | 1677 |
"ip": self.config_parser.get(constants.INISECT_INS, |
1677 | 1678 |
"nic%s_ip" % counter), |
1678 |
"link": self.config_parser.get(constants.INISECT_INS,
|
|
1679 |
"nic%s_link" % counter),
|
|
1680 |
"network": data_link,
|
|
1679 |
"network": self.config_parser.get(constants.INISECT_INS,
|
|
1680 |
"nic%s_network" % counter),
|
|
1681 |
"link": data_link,
|
|
1681 | 1682 |
}) |
1682 | 1683 |
if results[counter]["mode"] not in constants.NIC_VALID_MODES: |
1683 | 1684 |
raise errors.OpPrereqError("Network mode %s not recognized" |
b/lib/rapi/client.py | ||
---|---|---|
1761 | 1761 |
return self._SendRequest(HTTP_POST, "/%s/networks" % GANETI_RAPI_VERSION, |
1762 | 1762 |
query, body) |
1763 | 1763 |
|
1764 |
def ConnectNetwork(self, network_name, group_name, mode, link): |
|
1764 |
def ConnectNetwork(self, network_name, group_name, mode, link, dry_run=False):
|
|
1765 | 1765 |
"""Connects a Network to a NodeGroup with the given netparams |
1766 | 1766 |
|
1767 | 1767 |
""" |
... | ... | |
1771 | 1771 |
"network_link": link |
1772 | 1772 |
} |
1773 | 1773 |
|
1774 |
query = [] |
|
1775 |
_AppendDryRunIf(query, dry_run) |
|
1776 |
|
|
1774 | 1777 |
return self._SendRequest(HTTP_PUT, |
1775 | 1778 |
("/%s/networks/%s/connect" % |
1776 |
(GANETI_RAPI_VERSION, network_name)), None, body)
|
|
1779 |
(GANETI_RAPI_VERSION, network_name)), query, body)
|
|
1777 | 1780 |
|
1778 |
def DisconnectNetwork(self, network_name, group_name): |
|
1781 |
def DisconnectNetwork(self, network_name, group_name, dry_run=False):
|
|
1779 | 1782 |
"""Connects a Network to a NodeGroup with the given netparams |
1780 | 1783 |
|
1781 | 1784 |
""" |
1782 | 1785 |
body = { |
1783 | 1786 |
"group_name": group_name |
1784 | 1787 |
} |
1788 |
|
|
1789 |
query = [] |
|
1790 |
_AppendDryRunIf(query, dry_run) |
|
1791 |
|
|
1785 | 1792 |
return self._SendRequest(HTTP_PUT, |
1786 | 1793 |
("/%s/networks/%s/disconnect" % |
1787 |
(GANETI_RAPI_VERSION, network_name)), None, body)
|
|
1794 |
(GANETI_RAPI_VERSION, network_name)), query, body)
|
|
1788 | 1795 |
|
1789 | 1796 |
|
1797 |
def ModifyNetwork(self, network, **kwargs): |
|
1798 |
"""Modifies a network. |
|
1799 |
|
|
1800 |
More details for parameters can be found in the RAPI documentation. |
|
1801 |
|
|
1802 |
@type network: string |
|
1803 |
@param network: Network name |
|
1804 |
@rtype: string |
|
1805 |
@return: job id |
|
1806 |
|
|
1807 |
""" |
|
1808 |
return self._SendRequest(HTTP_PUT, |
|
1809 |
("/%s/networks/%s/modify" % |
|
1810 |
(GANETI_RAPI_VERSION, network)), None, kwargs) |
|
1811 |
|
|
1790 | 1812 |
def DeleteNetwork(self, network, dry_run=False): |
1791 | 1813 |
"""Deletes a network. |
1792 | 1814 |
|
... | ... | |
1806 | 1828 |
("/%s/networks/%s" % |
1807 | 1829 |
(GANETI_RAPI_VERSION, network)), query, None) |
1808 | 1830 |
|
1831 |
def GetNetworkTags(self, network): |
|
1832 |
"""Gets tags for a network. |
|
1833 |
|
|
1834 |
@type network: string |
|
1835 |
@param network: Node group whose tags to return |
|
1836 |
|
|
1837 |
@rtype: list of strings |
|
1838 |
@return: tags for the network |
|
1839 |
|
|
1840 |
""" |
|
1841 |
return self._SendRequest(HTTP_GET, |
|
1842 |
("/%s/networks/%s/tags" % |
|
1843 |
(GANETI_RAPI_VERSION, network)), None, None) |
|
1844 |
|
|
1845 |
def AddNetworkTags(self, network, tags, dry_run=False): |
|
1846 |
"""Adds tags to a network. |
|
1847 |
|
|
1848 |
@type network: str |
|
1849 |
@param network: network to add tags to |
|
1850 |
@type tags: list of string |
|
1851 |
@param tags: tags to add to the network |
|
1852 |
@type dry_run: bool |
|
1853 |
@param dry_run: whether to perform a dry run |
|
1854 |
|
|
1855 |
@rtype: string |
|
1856 |
@return: job id |
|
1857 |
|
|
1858 |
""" |
|
1859 |
query = [("tag", t) for t in tags] |
|
1860 |
_AppendDryRunIf(query, dry_run) |
|
1861 |
|
|
1862 |
return self._SendRequest(HTTP_PUT, |
|
1863 |
("/%s/networks/%s/tags" % |
|
1864 |
(GANETI_RAPI_VERSION, network)), query, None) |
|
1865 |
|
|
1866 |
def DeleteNetworkTags(self, network, tags, dry_run=False): |
|
1867 |
"""Deletes tags from a network. |
|
1868 |
|
|
1869 |
@type network: str |
|
1870 |
@param network: network to delete tags from |
|
1871 |
@type tags: list of string |
|
1872 |
@param tags: tags to delete |
|
1873 |
@type dry_run: bool |
|
1874 |
@param dry_run: whether to perform a dry run |
|
1875 |
@rtype: string |
|
1876 |
@return: job id |
|
1877 |
|
|
1878 |
""" |
|
1879 |
query = [("tag", t) for t in tags] |
|
1880 |
_AppendDryRunIf(query, dry_run) |
|
1881 |
|
|
1882 |
return self._SendRequest(HTTP_DELETE, |
|
1883 |
("/%s/networks/%s/tags" % |
|
1884 |
(GANETI_RAPI_VERSION, network)), query, None) |
|
1885 |
|
|
1886 |
|
|
1809 | 1887 |
def GetGroups(self, bulk=False): |
1810 | 1888 |
"""Gets all node groups in the cluster. |
1811 | 1889 |
|
b/lib/rapi/connector.py | ||
---|---|---|
175 | 175 |
rlib2.R_2_networks_name_connect, |
176 | 176 |
re.compile(r"^/2/networks/(%s)/disconnect$" % network_name_pattern): |
177 | 177 |
rlib2.R_2_networks_name_disconnect, |
178 |
re.compile(r"^/2/networks/(%s)/modify$" % network_name_pattern): |
|
179 |
rlib2.R_2_networks_name_modify, |
|
180 |
re.compile(r"^/2/networks/(%s)/tags$" % network_name_pattern): |
|
181 |
rlib2.R_2_networks_name_tags, |
|
178 | 182 |
|
179 | 183 |
"/2/groups": rlib2.R_2_groups, |
180 | 184 |
re.compile(r"^/2/groups/(%s)$" % group_name_pattern): |
b/lib/rapi/rlib2.py | ||
---|---|---|
688 | 688 |
|
689 | 689 |
|
690 | 690 |
class R_2_networks_name(baserlib.OpcodeResource): |
691 |
"""/2/network/[network_name] resource. |
|
691 |
"""/2/networks/[network_name] resource.
|
|
692 | 692 |
|
693 | 693 |
""" |
694 | 694 |
DELETE_OPCODE = opcodes.OpNetworkRemove |
... | ... | |
718 | 718 |
}) |
719 | 719 |
|
720 | 720 |
class R_2_networks_name_connect(baserlib.OpcodeResource): |
721 |
"""/2/network/[network_name]/connect.
|
|
721 |
"""/2/networks/[network_name]/connect resource.
|
|
722 | 722 |
|
723 | 723 |
""" |
724 | 724 |
PUT_OPCODE = opcodes.OpNetworkConnect |
... | ... | |
730 | 730 |
assert self.items |
731 | 731 |
return (self.request_body, { |
732 | 732 |
"network_name": self.items[0], |
733 |
"dry_run": self.dryRun(), |
|
733 | 734 |
}) |
734 | 735 |
|
735 | 736 |
class R_2_networks_name_disconnect(baserlib.OpcodeResource): |
736 |
"""/2/network/[network_name]/disconnect.
|
|
737 |
"""/2/networks/[network_name]/disconnect resource.
|
|
737 | 738 |
|
738 | 739 |
""" |
739 | 740 |
PUT_OPCODE = opcodes.OpNetworkDisconnect |
... | ... | |
745 | 746 |
assert self.items |
746 | 747 |
return (self.request_body, { |
747 | 748 |
"network_name": self.items[0], |
749 |
"dry_run": self.dryRun(), |
|
750 |
}) |
|
751 |
|
|
752 |
class R_2_networks_name_modify(baserlib.OpcodeResource): |
|
753 |
"""/2/networks/[network_name]/modify resource. |
|
754 |
|
|
755 |
""" |
|
756 |
PUT_OPCODE = opcodes.OpNetworkSetParams |
|
757 |
|
|
758 |
def GetPutOpInput(self): |
|
759 |
"""Changes some parameters of network. |
|
760 |
|
|
761 |
""" |
|
762 |
assert self.items |
|
763 |
return (self.request_body, { |
|
764 |
"network_name": self.items[0], |
|
748 | 765 |
}) |
749 | 766 |
|
767 |
|
|
750 | 768 |
class R_2_groups(baserlib.OpcodeResource): |
751 | 769 |
"""/2/groups resource. |
752 | 770 |
|
... | ... | |
1546 | 1564 |
""" |
1547 | 1565 |
TAG_LEVEL = constants.TAG_NODEGROUP |
1548 | 1566 |
|
1567 |
class R_2_networks_name_tags(_R_Tags): |
|
1568 |
""" /2/networks/[network_name]/tags resource. |
|
1569 |
|
|
1570 |
Manages per-network tags. |
|
1571 |
|
|
1572 |
""" |
|
1573 |
TAG_LEVEL = constants.TAG_NETWORK |
|
1574 |
|
|
1549 | 1575 |
|
1550 | 1576 |
class R_2_tags(_R_Tags): |
1551 | 1577 |
""" /2/tags resource. |
b/man/gnt-network.rst | ||
---|---|---|
158 | 158 |
|
159 | 159 |
Renames a given network from *oldname* to *newname*. NOT implemeted yet |
160 | 160 |
|
161 |
TAGS |
|
162 |
~~~ |
|
163 |
|
|
164 |
ADD-TAGS |
|
165 |
^^^^^^^^ |
|
166 |
|
|
167 |
**add-tags** [\--from *file*] {*networkname*} {*tag*...} |
|
168 |
|
|
169 |
Add tags to the given network. If any of the tags contains invalid |
|
170 |
characters, the entire operation will abort. |
|
171 |
|
|
172 |
If the ``--from`` option is given, the list of tags will be extended |
|
173 |
with the contents of that file (each line becomes a tag). In this case, |
|
174 |
there is not need to pass tags on the command line (if you do, both |
|
175 |
sources will be used). A file name of ``-`` will be interpreted as |
|
176 |
stdin. |
|
177 |
|
|
178 |
LIST-TAGS |
|
179 |
^^^^^^^^^ |
|
180 |
|
|
181 |
**list-tags** {*networkname*} |
|
182 |
|
|
183 |
List the tags of the given network. |
|
184 |
|
|
185 |
REMOVE-TAGS |
|
186 |
^^^^^^^^^^^ |
|
187 |
|
|
188 |
**remove-tags** [\--from *file*] {*networkname*} {*tag*...} |
|
189 |
|
|
190 |
Remove tags from the given network. If any of the tags are not |
|
191 |
existing on the network, the entire operation will abort. |
|
192 |
|
|
193 |
If the ``--from`` option is given, the list of tags to be removed will |
|
194 |
be extended with the contents of that file (each line becomes a tag). In |
|
195 |
this case, there is not need to pass tags on the command line (if you |
|
196 |
do, tags from both sources will be removed). A file name of ``-`` will |
|
197 |
be interpreted as stdin. |
|
198 |
|
|
199 |
|
|
161 | 200 |
INFO |
162 | 201 |
~~~~ |
163 | 202 |
|
b/test/cfgupgrade_unittest.py | ||
---|---|---|
93 | 93 |
"version": constants.CONFIG_VERSION, |
94 | 94 |
"cluster": {}, |
95 | 95 |
"instances": {}, |
96 |
"nodegroups": {}, |
|
96 | 97 |
})) |
97 | 98 |
|
98 | 99 |
hostname = netutils.GetHostname().name |
... | ... | |
108 | 109 |
"version": constants.CONFIG_VERSION, |
109 | 110 |
"cluster": {}, |
110 | 111 |
"instances": {}, |
112 |
"nodegroups": {}, |
|
111 | 113 |
})) |
112 | 114 |
|
113 | 115 |
utils.WriteFile(self.ss_master_node_path, |
... | ... | |
124 | 126 |
"config_version": 0, |
125 | 127 |
}, |
126 | 128 |
"instances": {}, |
129 |
"nodegroups": {}, |
|
127 | 130 |
} |
128 | 131 |
utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg)) |
129 | 132 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True) |
... | ... | |
148 | 151 |
"version": from_version, |
149 | 152 |
"cluster": cluster, |
150 | 153 |
"instances": {}, |
154 |
"nodegroups": {}, |
|
151 | 155 |
} |
152 | 156 |
self._CreateValidConfigDir() |
153 | 157 |
utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg)) |
b/test/data/ovfdata/config.ini | ||
---|---|---|
8 | 8 |
nic_count = 1 |
9 | 9 |
nic0_link = br0 |
10 | 10 |
nic0_ip = None |
11 |
nic0_network = test |
|
11 | 12 |
disk0_ivname = disk/0 |
12 | 13 |
disk0_size = 0 |
13 | 14 |
|
b/test/docs_unittest.py | ||
---|---|---|
186 | 186 |
node_name = re.escape("[node_name]") |
187 | 187 |
instance_name = re.escape("[instance_name]") |
188 | 188 |
group_name = re.escape("[group_name]") |
189 |
network_name = re.escape("[network_name]") |
|
189 | 190 |
job_id = re.escape("[job_id]") |
190 | 191 |
disk_index = re.escape("[disk_index]") |
191 | 192 |
query_res = re.escape("[resource]") |
192 | 193 |
|
193 |
resources = connector.GetHandlers(node_name, instance_name, group_name, |
|
194 |
resources = connector.GetHandlers(node_name, instance_name, |
|
195 |
group_name, network_name, |
|
194 | 196 |
job_id, disk_index, query_res) |
195 | 197 |
|
196 | 198 |
handler_dups = utils.FindDuplicates(resources.values()) |
... | ... | |
202 | 204 |
re.compile(node_name): "node1examplecom", |
203 | 205 |
re.compile(instance_name): "inst1examplecom", |
204 | 206 |
re.compile(group_name): "group4440", |
207 |
re.compile(network_name): "network5550", |
|
205 | 208 |
re.compile(job_id): "9409", |
206 | 209 |
re.compile(disk_index): "123", |
207 | 210 |
re.compile(query_res): "lock", |
b/test/ganeti.locking_unittest.py | ||
---|---|---|
1762 | 1762 |
self.nodes=['n1', 'n2'] |
1763 | 1763 |
self.nodegroups=['g1', 'g2'] |
1764 | 1764 |
self.instances=['i1', 'i2', 'i3'] |
1765 |
self.networks=['net1', 'net2', 'net3'] |
|
1765 | 1766 |
self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, |
1766 |
self.instances) |
|
1767 |
self.instances, self.networks)
|
|
1767 | 1768 |
|
1768 | 1769 |
def tearDown(self): |
1769 | 1770 |
# Don't try this at home... |
... | ... | |
1778 | 1779 |
self.assertEqual(i, locking.LEVELS[i]) |
1779 | 1780 |
|
1780 | 1781 |
def testDoubleGLFails(self): |
1781 |
self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], []) |
|
1782 |
self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [], [])
|
|
1782 | 1783 |
|
1783 | 1784 |
def testLockNames(self): |
1784 | 1785 |
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL'])) |
... | ... | |
1787 | 1788 |
set(self.nodegroups)) |
1788 | 1789 |
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), |
1789 | 1790 |
set(self.instances)) |
1791 |
self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), |
|
1792 |
set(self.networks)) |
|
1790 | 1793 |
|
1791 | 1794 |
def testInitAndResources(self): |
1792 | 1795 |
locking.GanetiLockManager._instance = None |
1793 |
self.GL = locking.GanetiLockManager([], [], []) |
|
1796 |
self.GL = locking.GanetiLockManager([], [], [], [])
|
|
1794 | 1797 |
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL'])) |
1795 | 1798 |
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set()) |
1796 | 1799 |
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set()) |
1797 | 1800 |
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set()) |
1801 |
self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set()) |
|
1798 | 1802 |
|
1799 | 1803 |
locking.GanetiLockManager._instance = None |
1800 |
self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, []) |
|
1804 |
self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [], [])
|
|
1801 | 1805 |
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL'])) |
1802 | 1806 |
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes)) |
1803 | 1807 |
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), |
1804 | 1808 |
set(self.nodegroups)) |
1805 | 1809 |
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set()) |
1810 |
self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set()) |
|
1806 | 1811 |
|
1807 | 1812 |
locking.GanetiLockManager._instance = None |
1808 |
self.GL = locking.GanetiLockManager([], [], self.instances) |
|
1813 |
self.GL = locking.GanetiLockManager([], [], self.instances, [])
|
|
1809 | 1814 |
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL'])) |
1810 | 1815 |
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set()) |
1811 | 1816 |
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set()) |
1812 | 1817 |
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), |
1813 | 1818 |
set(self.instances)) |
1814 | 1819 |
|
1820 |
locking.GanetiLockManager._instance = None |
|
1821 |
self.GL = locking.GanetiLockManager([], [], [], self.networks) |
|
1822 |
self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL'])) |
|
1823 |
self.assertEqual(self.GL._names(locking.LEVEL_NODE), set()) |
|
1824 |
self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set()) |
|
1825 |
self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set()) |
|
1826 |
self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), |
|
1827 |
set(self.networks)) |
|
1828 |
|
|
1815 | 1829 |
def testAcquireRelease(self): |
1816 | 1830 |
self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1) |
1817 | 1831 |
self.assertEquals(self.GL.list_owned(locking.LEVEL_CLUSTER), set(['BGL'])) |
b/test/ganeti.ovf_unittest.py | ||
---|---|---|
1 | 1 |
#!/usr/bin/python |
2 | 2 |
# |
3 | 3 |
|
4 |
# Copyright (C) 2011 Google Inc. |
|
4 |
# Copyright (C) 2011, 2012 Google Inc.
|
|
5 | 5 |
# |
6 | 6 |
# This program is free software; you can redistribute it and/or modify |
7 | 7 |
# it under the terms of the GNU General Public License as published by |
... | ... | |
59 | 59 |
"nic0_ip": "none", |
60 | 60 |
"nic0_mac": "aa:00:00:d8:2c:1e", |
61 | 61 |
"nic0_link": "xen-br0", |
62 |
"nic0_network": "auto", |
|
62 | 63 |
} |
63 | 64 |
GANETI_HYPERVISOR = { |
64 | 65 |
"hypervisor_name": "xen-pvm", |
... | ... | |
91 | 92 |
"nic0_ip": "none", |
92 | 93 |
"nic0_link": "auto", |
93 | 94 |
"nic0_mac": "auto", |
95 |
"nic0_network": "auto", |
|
94 | 96 |
} |
95 | 97 |
VIRTUALBOX_HYPERVISOR = {"hypervisor_name": "auto"} |
96 | 98 |
VIRTUALBOX_OS = {"os_name": None} |
... | ... | |
130 | 132 |
"nic0_ip": "none", |
131 | 133 |
"nic0_mac": "auto", |
132 | 134 |
"nic_count": "1", |
135 |
"nic0_network": "auto", |
|
133 | 136 |
} |
134 | 137 |
CMDARGS_HYPERVISOR = { |
135 | 138 |
"hypervisor_name": "xen-pvm" |
... | ... | |
207 | 210 |
}, |
208 | 211 |
] |
209 | 212 |
EXP_NETWORKS_LIST = [ |
210 |
{"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0","mode":"routed"}, |
|
213 |
{"mac": "aa:00:00:d8:2c:1e", "ip":"None", "link":"br0", |
|
214 |
"mode":"routed", "network": "test"}, |
|
211 | 215 |
] |
212 | 216 |
EXP_PARTIAL_GANETI_DICT = { |
213 | 217 |
"hypervisor": {"name": "xen-kvm"}, |
... | ... | |
263 | 267 |
"Nic ovf:name=\"routed0\"><gnt:Mode>routed</gnt:" |
264 | 268 |
"Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:" |
265 | 269 |
"MACAddress><gnt:IPAddress>None</gnt:IPAddress>" |
266 |
"<gnt:Link>br0</gnt:Link></gnt:Nic></gnt:Network>"
|
|
267 |
"</gnt:GanetiSection>") |
|
270 |
"<gnt:Link>br0</gnt:Link><gnt:Net>test</gnt:Net>"
|
|
271 |
"</gnt:Nic></gnt:Network></gnt:GanetiSection>")
|
|
268 | 272 |
EXPORT_GANETI = ("<gnt:GanetiSection><gnt:Version>0</gnt:Version><gnt:" |
269 | 273 |
"AutoBalance>False</gnt:AutoBalance><gnt:OperatingSystem>" |
270 | 274 |
"<gnt:Name>lenny-image</gnt:Name><gnt:Parameters /></gnt:" |
... | ... | |
274 | 278 |
"Hypervisor><gnt:Network><gnt:Nic ovf:name=\"routed0\"><gnt:" |
275 | 279 |
"Mode>routed</gnt:Mode><gnt:MACAddress>aa:00:00:d8:2c:1e</gnt:" |
276 | 280 |
"MACAddress><gnt:IPAddress>None</gnt:IPAddress><gnt:Link>br0" |
277 |
"</gnt:Link></gnt:Nic></gnt:Network></gnt:GanetiSection>") |
|
281 |
"</gnt:Link><gnt:Net>test</gnt:Net></gnt:Nic></gnt:Network>" |
|
282 |
"</gnt:GanetiSection>") |
|
278 | 283 |
EXPORT_SYSTEM = ("<References><File ovf:compression=\"gzip\" ovf:href=\"new_" |
279 | 284 |
"disk.cow.gz\" ovf:id=\"file0\" ovf:size=\"203\" /><File ovf:" |
280 | 285 |
"href=\"new_disk.cow\" ovf:id=\"file1\" ovf:size=\"15\" />" |
b/test/ganeti.rapi.client_unittest.py | ||
---|---|---|
1115 | 1115 |
self.assertDryRun() |
1116 | 1116 |
self.assertUseForce() |
1117 | 1117 |
|
1118 |
def testGetNetworksBulk(self): |
|
1119 |
networks = [{"name": "network1", |
|
1120 |
"uri": "/2/networks/network1", |
|
1121 |
"network": "192.168.0.0/24", |
|
1122 |
}, |
|
1123 |
{"name": "network2", |
|
1124 |
"uri": "/2/networks/network2", |
|
1125 |
"network": "192.168.0.0/24", |
|
1126 |
}, |
|
1127 |
] |
|
1128 |
self.rapi.AddResponse(serializer.DumpJson(networks)) |
|
1129 |
|
|
1130 |
self.assertEqual(networks, self.client.GetNetworks(bulk=True)) |
|
1131 |
self.assertHandler(rlib2.R_2_networks) |
|
1132 |
self.assertBulk() |
|
1133 |
|
|
1134 |
def testGetNetwork(self): |
|
1135 |
network = {"ctime": None, |
|
1136 |
"name": "network1", |
|
1137 |
} |
|
1138 |
self.rapi.AddResponse(serializer.DumpJson(network)) |
|
1139 |
self.assertEqual({"ctime": None, "name": "network1"}, |
|
1140 |
self.client.GetNetwork("network1")) |
|
1141 |
self.assertHandler(rlib2.R_2_networks_name) |
|
1142 |
self.assertItems(["network1"]) |
|
1143 |
|
|
1144 |
def testCreateNetwork(self): |
|
1145 |
self.rapi.AddResponse("12345") |
|
1146 |
job_id = self.client.CreateNetwork("newnetwork", network="192.168.0.0/24", |
|
1147 |
dry_run=True) |
|
1148 |
self.assertEqual(job_id, 12345) |
|
1149 |
self.assertHandler(rlib2.R_2_networks) |
|
1150 |
self.assertDryRun() |
|
1151 |
|
|
1152 |
def testModifyNetwork(self): |
|
1153 |
self.rapi.AddResponse("12346") |
|
1154 |
job_id = self.client.ModifyNetwork("mynetwork", gateway="192.168.0.10", |
|
1155 |
dry_run=True) |
|
1156 |
self.assertEqual(job_id, 12346) |
|
1157 |
self.assertHandler(rlib2.R_2_networks_name_modify) |
|
1158 |
|
|
1159 |
def testDeleteNetwork(self): |
|
1160 |
self.rapi.AddResponse("12347") |
|
1161 |
job_id = self.client.DeleteNetwork("newnetwork", dry_run=True) |
|
1162 |
self.assertEqual(job_id, 12347) |
|
1163 |
self.assertHandler(rlib2.R_2_networks_name) |
|
1164 |
self.assertDryRun() |
|
1165 |
|
|
1166 |
def testConnectNetwork(self): |
|
1167 |
self.rapi.AddResponse("12348") |
|
1168 |
job_id = self.client.ConnectNetwork("mynetwork", "default", |
|
1169 |
"bridged", "br0", dry_run=True) |
|
1170 |
self.assertEqual(job_id, 12348) |
|
1171 |
self.assertHandler(rlib2.R_2_networks_name_connect) |
|
1172 |
self.assertDryRun() |
|
1173 |
|
|
1174 |
def testDisconnectNetwork(self): |
|
1175 |
self.rapi.AddResponse("12349") |
|
1176 |
job_id = self.client.DisconnectNetwork("mynetwork", "default", dry_run=True) |
|
1177 |
self.assertEqual(job_id, 12349) |
|
1178 |
self.assertHandler(rlib2.R_2_networks_name_disconnect) |
|
1179 |
self.assertDryRun() |
|
1180 |
|
|
1181 |
def testGetNetworkTags(self): |
|
1182 |
self.rapi.AddResponse("[]") |
|
1183 |
self.assertEqual([], self.client.GetNetworkTags("fooNetwork")) |
|
1184 |
self.assertHandler(rlib2.R_2_networks_name_tags) |
|
1185 |
self.assertItems(["fooNetwork"]) |
|
1186 |
|
|
1187 |
def testAddNetworkTags(self): |
|
1188 |
self.rapi.AddResponse("1234") |
|
1189 |
self.assertEqual(1234, |
|
1190 |
self.client.AddNetworkTags("fooNetwork", ["awesome"], dry_run=True)) |
|
1191 |
self.assertHandler(rlib2.R_2_networks_name_tags) |
|
1192 |
self.assertItems(["fooNetwork"]) |
|
1193 |
self.assertDryRun() |
|
1194 |
self.assertQuery("tag", ["awesome"]) |
|
1195 |
|
|
1196 |
def testDeleteNetworkTags(self): |
|
1197 |
self.rapi.AddResponse("25826") |
|
1198 |
self.assertEqual(25826, self.client.DeleteNetworkTags("foo", ["awesome"], |
|
1199 |
dry_run=True)) |
|
1200 |
self.assertHandler(rlib2.R_2_networks_name_tags) |
|
1201 |
self.assertItems(["foo"]) |
|
1202 |
self.assertDryRun() |
|
1203 |
self.assertQuery("tag", ["awesome"]) |
|
1204 |
|
|
1118 | 1205 |
def testModifyInstance(self): |
1119 | 1206 |
self.rapi.AddResponse("23681") |
1120 | 1207 |
job_id = self.client.ModifyInstance("inst7210", os_name="linux") |
b/tools/cfgupgrade | ||
---|---|---|
104 | 104 |
|
105 | 105 |
|
106 | 106 |
def UpgradeGroups(config_data): |
107 |
nicparams = config_data["cluster"]["nicparams"]["default"] |
|
108 | 107 |
for group in config_data["nodegroups"].values(): |
109 | 108 |
networks = group.get("networks", None) |
110 | 109 |
if not networks: |
Also available in: Unified diff