pycloudlib 1!9.3.0__tar.gz → 1!9.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {pycloudlib-1!9.3.0/pycloudlib.egg-info → pycloudlib-1!9.3.2}/PKG-INFO +1 -1
  2. pycloudlib-1!9.3.2/VERSION +1 -0
  3. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm/cloud.py +4 -2
  4. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm/instance.py +7 -5
  5. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/instance.py +2 -1
  6. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2/pycloudlib.egg-info}/PKG-INFO +1 -1
  7. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib.egg-info/SOURCES.txt +3 -0
  8. pycloudlib-1!9.3.2/tests/integration_tests/ibm/test_launch.py +70 -0
  9. pycloudlib-1!9.3.2/tests/unit_tests/ec2/__init__.py +0 -0
  10. pycloudlib-1!9.3.2/tests/unit_tests/ibm/test_instance.py +81 -0
  11. pycloudlib-1!9.3.0/VERSION +0 -1
  12. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/LICENSE +0 -0
  13. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/MANIFEST.in +0 -0
  14. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/README.md +0 -0
  15. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/__init__.py +0 -0
  16. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/azure/__init__.py +0 -0
  17. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/azure/cloud.py +0 -0
  18. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/azure/instance.py +0 -0
  19. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/azure/security_types.py +0 -0
  20. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/azure/util.py +0 -0
  21. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/cloud.py +0 -0
  22. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/config.py +0 -0
  23. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/constants.py +0 -0
  24. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ec2/__init__.py +0 -0
  25. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ec2/cloud.py +0 -0
  26. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ec2/instance.py +0 -0
  27. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ec2/util.py +0 -0
  28. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ec2/vpc.py +0 -0
  29. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/errors.py +0 -0
  30. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/gce/__init__.py +0 -0
  31. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/gce/cloud.py +0 -0
  32. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/gce/errors.py +0 -0
  33. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/gce/instance.py +0 -0
  34. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/gce/util.py +0 -0
  35. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm/__init__.py +0 -0
  36. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm/_util.py +0 -0
  37. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm/errors.py +0 -0
  38. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm_classic/__init__.py +0 -0
  39. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm_classic/cloud.py +0 -0
  40. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm_classic/errors.py +0 -0
  41. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/ibm_classic/instance.py +0 -0
  42. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/key.py +0 -0
  43. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/lxd/__init__.py +0 -0
  44. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/lxd/_images.py +0 -0
  45. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/lxd/cloud.py +0 -0
  46. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/lxd/defaults.py +0 -0
  47. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/lxd/instance.py +0 -0
  48. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/oci/__init__.py +0 -0
  49. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/oci/cloud.py +0 -0
  50. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/oci/instance.py +0 -0
  51. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/oci/utils.py +0 -0
  52. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/openstack/__init__.py +0 -0
  53. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/openstack/cloud.py +0 -0
  54. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/openstack/errors.py +0 -0
  55. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/openstack/instance.py +0 -0
  56. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/py.typed +0 -0
  57. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/qemu/__init__.py +0 -0
  58. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/qemu/cloud.py +0 -0
  59. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/qemu/instance.py +0 -0
  60. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/qemu/util.py +0 -0
  61. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/result.py +0 -0
  62. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/util.py +0 -0
  63. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/vmware/__init__.py +0 -0
  64. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/vmware/cloud.py +0 -0
  65. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib/vmware/instance.py +0 -0
  66. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib.egg-info/dependency_links.txt +0 -0
  67. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib.egg-info/requires.txt +0 -0
  68. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib.egg-info/top_level.txt +0 -0
  69. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pycloudlib.egg-info/zip-safe +0 -0
  70. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/pyproject.toml +0 -0
  71. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/requirements.txt +0 -0
  72. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/setup.cfg +0 -0
  73. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/setup.py +0 -0
  74. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/test-requirements.txt +0 -0
  75. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/__init__.py +0 -0
  76. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/conftest.py +0 -0
  77. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/integration_tests/__init__.py +0 -0
  78. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/integration_tests/gce/__init__.py +0 -0
  79. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/integration_tests/gce/test_launch.py +0 -0
  80. {pycloudlib-1!9.3.0/tests/unit_tests/ec2 → pycloudlib-1!9.3.2/tests/integration_tests/ibm}/__init__.py +0 -0
  81. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/integration_tests/test_public_api.py +0 -0
  82. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/integration_tests/test_qemu.py +0 -0
  83. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/__init__.py +0 -0
  84. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/azure/__init__.py +0 -0
  85. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/azure/test_cloud.py +0 -0
  86. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/azure/test_security_types.py +0 -0
  87. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ec2/test_cloud.py +0 -0
  88. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/gce/__init__.py +0 -0
  89. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/gce/test_cloud.py +0 -0
  90. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ibm/__init__.py +0 -0
  91. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ibm/test_cloud.py +0 -0
  92. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ibm/test_util.py +0 -0
  93. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ibm_classic/__init__.py +0 -0
  94. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/ibm_classic/test_cloud.py +0 -0
  95. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/lxd/__init__.py +0 -0
  96. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/lxd/test_cloud.py +0 -0
  97. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/lxd/test_defaults.py +0 -0
  98. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/lxd/test_images.py +0 -0
  99. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/lxd/test_instance.py +0 -0
  100. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/test_cloud.py +0 -0
  101. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/test_config.py +0 -0
  102. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/test_errors.py +0 -0
  103. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tests/unit_tests/test_instance.py +0 -0
  104. {pycloudlib-1!9.3.0 → pycloudlib-1!9.3.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycloudlib
3
- Version: 1!9.3.0
3
+ Version: 1!9.3.2
4
4
  Summary: Python library to launch, interact, and snapshot cloud instances
5
5
  Home-page: https://github.com/canonical/pycloudlib
6
6
  Author: pycloudlib-devs
@@ -0,0 +1 @@
1
+ 1!9.3.2
@@ -86,6 +86,8 @@ class IBM(BaseCloud):
86
86
  authenticator=authenticator
87
87
  )
88
88
 
89
+ self._floating_ip_substring = self.config.get("floating_ip_substring")
90
+
89
91
  @property
90
92
  def resource_group_id(self) -> str:
91
93
  """Resource Group ID used to create new things under."""
@@ -305,8 +307,8 @@ class IBM(BaseCloud):
305
307
  vpc = vpc or self.vpc
306
308
  name = name or f"{self.tag}-vm{next(self.instance_counter)}"
307
309
 
308
- floating_ip_substring = floating_ip_substring or self.config.get(
309
- "floating_ip_substring"
310
+ floating_ip_substring = (
311
+ floating_ip_substring or self._floating_ip_substring
310
312
  )
311
313
 
312
314
  raw_instance = IBMInstance.create_raw_instance(
@@ -652,7 +652,7 @@ class IBMInstance(BaseInstance):
652
652
  Raises:
653
653
  IBMException: If failed to attach floating IP after 10 tries
654
654
  """
655
- attached_floating_ip = None
655
+ floating_ip_is_attached = None
656
656
  self._log.info(
657
657
  "Will attempt to attach floating ip with name containing: %s"
658
658
  "until successful or all floating ips are in use.",
@@ -660,7 +660,7 @@ class IBMInstance(BaseInstance):
660
660
  )
661
661
 
662
662
  tries = 0
663
- while attached_floating_ip is None:
663
+ while not floating_ip_is_attached:
664
664
  tries += 1
665
665
  target_floating_ip = self._choose_from_existing_floating_ips(
666
666
  name_includes=floating_ip_substring,
@@ -669,8 +669,10 @@ class IBMInstance(BaseInstance):
669
669
  "Attempting to attach floating ip: %s",
670
670
  target_floating_ip["name"],
671
671
  )
672
- attached_floating_ip = self._attach_floating_ip(target_floating_ip)
673
- if not attached_floating_ip:
672
+ floating_ip_is_attached = self._attach_floating_ip(
673
+ floating_ip=target_floating_ip
674
+ )
675
+ if not floating_ip_is_attached:
674
676
  self._log.info(
675
677
  "Failed to attach floating ip: %s. Will try again.",
676
678
  target_floating_ip["name"],
@@ -960,7 +962,7 @@ class IBMInstance(BaseInstance):
960
962
 
961
963
  def _wait_for_instance_start(self, **kwargs):
962
964
  """Wait for the cloud instance to be up."""
963
- # if self.b
965
+ self._log.info("Waiting for instance to finish provisioning.")
964
966
  self._wait_for_status(
965
967
  _Status.RUNNING,
966
968
  sleep_seconds=900,
@@ -454,7 +454,8 @@ class BaseInstance(ABC):
454
454
  SSHException,
455
455
  OSError,
456
456
  ) as e:
457
- raise SSHException from e
457
+ error_msg = f"{type(e).__name__}: {str(e)}"
458
+ raise SSHException(error_msg) from e
458
459
  self._ssh_client = client
459
460
  return client
460
461
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycloudlib
3
- Version: 1!9.3.0
3
+ Version: 1!9.3.2
4
4
  Summary: Python library to launch, interact, and snapshot cloud instances
5
5
  Home-page: https://github.com/canonical/pycloudlib
6
6
  Author: pycloudlib-devs
@@ -75,6 +75,8 @@ tests/integration_tests/test_public_api.py
75
75
  tests/integration_tests/test_qemu.py
76
76
  tests/integration_tests/gce/__init__.py
77
77
  tests/integration_tests/gce/test_launch.py
78
+ tests/integration_tests/ibm/__init__.py
79
+ tests/integration_tests/ibm/test_launch.py
78
80
  tests/unit_tests/__init__.py
79
81
  tests/unit_tests/test_cloud.py
80
82
  tests/unit_tests/test_config.py
@@ -89,6 +91,7 @@ tests/unit_tests/gce/__init__.py
89
91
  tests/unit_tests/gce/test_cloud.py
90
92
  tests/unit_tests/ibm/__init__.py
91
93
  tests/unit_tests/ibm/test_cloud.py
94
+ tests/unit_tests/ibm/test_instance.py
92
95
  tests/unit_tests/ibm/test_util.py
93
96
  tests/unit_tests/ibm_classic/__init__.py
94
97
  tests/unit_tests/ibm_classic/test_cloud.py
@@ -0,0 +1,70 @@
1
+ import os
2
+ import pytest
3
+ from pycloudlib.ibm.cloud import IBM
4
+ from pycloudlib.ibm.instance import IBMInstance
5
+ from google.cloud import compute_v1
6
+ import time
7
+
8
+
9
+ @pytest.fixture
10
+ def ibm_cloud():
11
+ with IBM(tag="integration-test-launch") as ibm:
12
+ yield ibm
13
+
14
+
15
+ def manage_ssh_key(ibm: IBM, key_name):
16
+ """Manage ssh keys for ibm instances."""
17
+ if key_name in ibm.list_keys():
18
+ ibm.delete_key(key_name)
19
+
20
+ pub_key_path = "ibm-pubkey"
21
+ priv_key_path = "ibm-privkey"
22
+ pub_key, priv_key = ibm.create_key_pair()
23
+
24
+ with open(pub_key_path, "w", encoding="utf-8") as f:
25
+ f.write(pub_key)
26
+
27
+ with open(priv_key_path, "w", encoding="utf-8") as f:
28
+ f.write(priv_key)
29
+
30
+ os.chmod(pub_key_path, 0o600)
31
+ os.chmod(priv_key_path, 0o600)
32
+
33
+ ibm.use_key(
34
+ public_key_path=pub_key_path,
35
+ private_key_path=priv_key_path,
36
+ name=key_name,
37
+ )
38
+
39
+
40
+ def test_ibm_launch(ibm_cloud: IBM):
41
+ """
42
+ Test launching an IBM instance.
43
+
44
+ This tests the following:
45
+ - The instance is launched successfully
46
+ - The instance is reachable via SSH
47
+ - The instance has a floating IP as expected
48
+ - The instance name was set correctly
49
+ """
50
+ time_id = time.time_ns()
51
+ image_id = ibm_cloud.released_image("noble")
52
+ floating_ip_substring = (
53
+ ibm_cloud._floating_ip_substring or "default-floating-ip"
54
+ )
55
+ unique_instance_name = f"integration-test-launch-instance-{time_id}"
56
+ # create ssh_keys for use
57
+ manage_ssh_key(ibm_cloud, f"integration-test-key-{time_id}")
58
+ with ibm_cloud.launch(
59
+ image_id=image_id,
60
+ floating_ip_substring=floating_ip_substring,
61
+ name=unique_instance_name,
62
+ ) as inst:
63
+ inst: IBMInstance # type hint for IDE
64
+ # wait for instance to come online
65
+ inst.wait()
66
+ # assert hostname is the same as the instance name
67
+ assert inst.execute("hostname").strip() == unique_instance_name
68
+ # assert that the instance has a floating IP as expected
69
+ assert inst._floating_ip is not None
70
+ assert floating_ip_substring in inst._floating_ip["name"]
File without changes
@@ -0,0 +1,81 @@
1
+ """Module for IBM instance tests."""
2
+
3
+ import pytest
4
+ from unittest import mock
5
+
6
+ from pycloudlib.ibm.instance import IBMInstance, _IBMInstanceType
7
+
8
+ SAMPLE_RAW_INSTANCE = {
9
+ "id": "ibm1",
10
+ "primary_network_interface": {"id": "nic1"},
11
+ "profile": {"name": "metal"},
12
+ "zone": {"name": "zone1"},
13
+ }
14
+ M_PATH = "pycloudlib.ibm.instance."
15
+
16
+
17
+ class TestIBMInstance:
18
+ @pytest.mark.parametrize(
19
+ "raw_instance,inst_id,zone_id,inst_type",
20
+ (
21
+ (
22
+ SAMPLE_RAW_INSTANCE,
23
+ "ibm1",
24
+ "zone1",
25
+ _IBMInstanceType.BARE_METAL_SERVER,
26
+ ),
27
+ ),
28
+ )
29
+ @mock.patch(M_PATH + "VpcV1", autospec=True)
30
+ def test_type_from_raw_instance(
31
+ self, client, raw_instance, inst_id, zone_id, inst_type
32
+ ):
33
+ """Factory function inits the appropriate IBMInstanceType."""
34
+ inst = IBMInstance.from_raw_instance(
35
+ key_pair=None,
36
+ client=client,
37
+ instance=raw_instance,
38
+ )
39
+ assert client == inst._client
40
+ assert inst_id == inst.id
41
+ assert zone_id == inst.zone
42
+ assert inst_type == inst._ibm_instance_type
43
+
44
+ @mock.patch(M_PATH + "VpcV1", autospec=True)
45
+ def test_attach_floating_ip(self, client, caplog):
46
+ """
47
+ retry attach_floating_ip until VpcV1 lists non-empty floating_ips."""
48
+
49
+ inst = IBMInstance.from_raw_instance(
50
+ key_pair=None,
51
+ client=client,
52
+ instance=SAMPLE_RAW_INSTANCE,
53
+ )
54
+ metal_floating_ips = mock.Mock(
55
+ get_result=mock.Mock(
56
+ side_effect=[
57
+ {"floating_ips": []},
58
+ {
59
+ "floating_ips": [
60
+ {"id": "floatingid1", "name": "floatingname"}
61
+ ]
62
+ },
63
+ ]
64
+ )
65
+ )
66
+ with mock.patch.object(
67
+ client,
68
+ "list_bare_metal_server_network_interface_floating_ips",
69
+ return_value=metal_floating_ips,
70
+ ), mock.patch.object(
71
+ inst,
72
+ "_choose_from_existing_floating_ips",
73
+ return_value={"name": "ci-ip-match-5", "id": "floatingid1"},
74
+ ):
75
+ inst.attach_floating_ip(floating_ip_substring="ci-ip-match")
76
+ for expected_log in [
77
+ "Failed to attach floating ip: ci-ip-match-5.",
78
+ "Successfully attached floating ip: floatingname",
79
+ ]:
80
+ assert expected_log in caplog.text
81
+ assert 2 == metal_floating_ips.get_result.call_count
@@ -1 +0,0 @@
1
- 1!9.3.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes