Skip to content

Commit 39c9fe5

Browse files
authored
feature(v3) add stack manager (#287)
See #280
1 parent 2ca8f60 commit 39c9fe5

File tree

9 files changed

+406
-1
lines changed

9 files changed

+406
-1
lines changed

cloudfoundry_client/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from cloudfoundry_client.v3.service_offerings import ServiceOfferingsManager
4747
from cloudfoundry_client.v3.service_plans import ServicePlanManager
4848
from cloudfoundry_client.v3.spaces import SpaceManager
49+
from cloudfoundry_client.v3.stacks import StackMananager
4950
from cloudfoundry_client.v3.tasks import TaskManager
5051
from cloudfoundry_client.v3.jobs import JobManager
5152
from cloudfoundry_client.v3.users import UserManager
@@ -137,6 +138,7 @@ def __init__(self, cloud_controller_v3_url: str, credential_manager: "CloudFound
137138
self.service_offerings = ServiceOfferingsManager(target_endpoint, credential_manager)
138139
self.service_plans = ServicePlanManager(target_endpoint, credential_manager)
139140
self.spaces = SpaceManager(target_endpoint, credential_manager)
141+
self.stacks = StackMananager(target_endpoint, credential_manager)
140142
self.tasks = TaskManager(target_endpoint, credential_manager)
141143
self.users = UserManager(target_endpoint, credential_manager)
142144

cloudfoundry_client/v3/stacks.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from typing import TYPE_CHECKING
2+
3+
from cloudfoundry_client.common_objects import Pagination
4+
from cloudfoundry_client.v3.entities import EntityManager, Entity
5+
6+
if TYPE_CHECKING:
7+
from cloudfoundry_client.client import CloudFoundryClient
8+
9+
10+
class StackMananager(EntityManager[Entity]):
11+
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
12+
super(StackMananager, self).__init__(target_endpoint, client, "/v3/stacks")
13+
14+
def create(
15+
self,
16+
name: str,
17+
description: str | None = None,
18+
meta_labels: dict | None = None,
19+
meta_annotations: dict | None = None,
20+
) -> Entity:
21+
data = {"name": name}
22+
if description is not None:
23+
data["description"] = description
24+
self._metadata(data, meta_labels, meta_annotations)
25+
return super(StackMananager, self)._create(data)
26+
27+
def update(
28+
self,
29+
stack_guid: str,
30+
meta_labels: dict | None = None,
31+
meta_annotations: dict | None = None,
32+
) -> Entity:
33+
data = {}
34+
self._metadata(data, meta_labels, meta_annotations)
35+
return super(StackMananager, self)._update(stack_guid, data)
36+
37+
def list_apps(self, stack_guid: str, **kwargs) -> Pagination[Entity]:
38+
uri: str = "%s/%s/apps" % (self.entity_uri, stack_guid)
39+
return super(StackMananager, self)._list(requested_path=uri, **kwargs)
40+
41+
def remove(self, stack_guid: str):
42+
super(StackMananager, self)._remove(stack_guid)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"pagination": {
3+
"total_results": 3,
4+
"total_pages": 2,
5+
"first": {
6+
"href": "https://api.example.org/v3/stacks?page=1&per_page=2"
7+
},
8+
"last": {
9+
"href": "https://api.example.org/v3/stacks?page=2&per_page=2"
10+
},
11+
"next": null,
12+
"previous": null
13+
},
14+
"resources": [
15+
{
16+
"guid": "11c916c9-c2f9-440e-8e73-102e79c4704d",
17+
"created_at": "2018-11-09T22:43:28Z",
18+
"updated_at": "2018-11-09T22:43:28Z",
19+
"name": "my-stack-1",
20+
"build_rootfs_image": "my-stack-1-build",
21+
"run_rootfs_image": "my-stack-1-run",
22+
"description": "This is my first stack!",
23+
"default": true,
24+
"metadata": {
25+
"labels": {},
26+
"annotations": {}
27+
},
28+
"links": {
29+
"self": {
30+
"href": "https://api.example.org/v3/stacks/11c916c9-c2f9-440e-8e73-102e79c4704d"
31+
}
32+
}
33+
},
34+
{
35+
"guid": "81c916c9-c2f9-440e-8e73-102e79c4704h",
36+
"created_at": "2018-11-09T22:43:29Z",
37+
"updated_at": "2018-11-09T22:43:29Z",
38+
"name": "my-stack-2",
39+
"description": "This is my second stack!",
40+
"build_rootfs_image": "my-stack-2-build",
41+
"run_rootfs_image": "my-stack-2-run",
42+
"default": false,
43+
"metadata": {
44+
"labels": {},
45+
"annotations": {}
46+
},
47+
"links": {
48+
"self": {
49+
"href": "https://api.example.org/v3/stacks/81c916c9-c2f9-440e-8e73-102e79c4704h"
50+
}
51+
}
52+
}
53+
]
54+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
{
2+
"pagination": {
3+
"total_results": 3,
4+
"total_pages": 2,
5+
"first": {
6+
"href": "https://api.example.org/v3/stacks/[guid]/apps?page=1&per_page=2"
7+
},
8+
"last": {
9+
"href": "https://api.example.org/v3/stacks/[guid]/apps?page=2&per_page=2"
10+
},
11+
"next": null,
12+
"previous": null
13+
},
14+
"resources": [
15+
{
16+
"guid": "1cb006ee-fb05-47e1-b541-c34179ddc446",
17+
"name": "my_app",
18+
"state": "STARTED",
19+
"created_at": "2016-03-17T21:41:30Z",
20+
"updated_at": "2016-03-18T11:32:30Z",
21+
"lifecycle": {
22+
"type": "buildpack",
23+
"data": {
24+
"buildpacks": ["java_buildpack"],
25+
"stack": "cflinuxfs4"
26+
}
27+
},
28+
"relationships": {
29+
"space": {
30+
"data": {
31+
"guid": "2f35885d-0c9d-4423-83ad-fd05066f8576"
32+
}
33+
},
34+
"current_droplet": {
35+
"data": {
36+
"guid": "585bc3c1-3743-497d-88b0-403ad6b56d16"
37+
}
38+
}
39+
},
40+
"links": {
41+
"self": {
42+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446"
43+
},
44+
"space": {
45+
"href": "https://api.example.org/v3/spaces/2f35885d-0c9d-4423-83ad-fd05066f8576"
46+
},
47+
"processes": {
48+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/processes"
49+
},
50+
"packages": {
51+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/packages"
52+
},
53+
"environment_variables": {
54+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/environment_variables"
55+
},
56+
"current_droplet": {
57+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/droplets/current"
58+
},
59+
"droplets": {
60+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/droplets"
61+
},
62+
"tasks": {
63+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/tasks"
64+
},
65+
"start": {
66+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/actions/start",
67+
"method": "POST"
68+
},
69+
"stop": {
70+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/actions/stop",
71+
"method": "POST"
72+
},
73+
"revisions": {
74+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions"
75+
},
76+
"deployed_revisions": {
77+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/revisions/deployed"
78+
},
79+
"features": {
80+
"href": "https://api.example.org/v3/apps/1cb006ee-fb05-47e1-b541-c34179ddc446/features"
81+
}
82+
},
83+
"metadata": {
84+
"labels": {},
85+
"annotations": {}
86+
}
87+
},
88+
{
89+
"guid": "02b4ec9b-94c7-4468-9c23-4e906191a0f8",
90+
"name": "my_app2",
91+
"state": "STOPPED",
92+
"created_at": "1970-01-01T00:00:02Z",
93+
"updated_at": "2016-06-08T16:41:26Z",
94+
"lifecycle": {
95+
"type": "buildpack",
96+
"data": {
97+
"buildpacks": ["ruby_buildpack"],
98+
"stack": "cflinuxfs4"
99+
}
100+
},
101+
"relationships": {
102+
"space": {
103+
"data": {
104+
"guid": "2f35885d-0c9d-4423-83ad-fd05066f8576"
105+
}
106+
},
107+
"droplet": {
108+
"data": {
109+
"guid": "585bc3c1-3743-497d-88b0-403ad6b56d16"
110+
}
111+
}
112+
},
113+
"links": {
114+
"self": {
115+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8"
116+
},
117+
"space": {
118+
"href": "https://api.example.org/v3/spaces/2f35885d-0c9d-4423-83ad-fd05066f8576"
119+
},
120+
"processes": {
121+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/processes"
122+
},
123+
"packages": {
124+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/packages"
125+
},
126+
"environment_variables": {
127+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/environment_variables"
128+
},
129+
"current_droplet": {
130+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/droplets/current"
131+
},
132+
"droplets": {
133+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/droplets"
134+
},
135+
"tasks": {
136+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/tasks"
137+
},
138+
"start": {
139+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/actions/start",
140+
"method": "POST"
141+
},
142+
"stop": {
143+
"href": "https://api.example.org/v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/actions/stop",
144+
"method": "POST"
145+
},
146+
"revisions": {
147+
"href": "https://api.example.org//v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/revisions"
148+
},
149+
"deployed_revisions": {
150+
"href": "https://api.example.org//v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/revisions/deployed"
151+
},
152+
"features": {
153+
"href": "https://api.example.org//v3/stacks/[guid]/apps/02b4ec9b-94c7-4468-9c23-4e906191a0f8/features"
154+
}
155+
},
156+
"metadata": {
157+
"labels": {},
158+
"annotations": {}
159+
}
160+
}
161+
]
162+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"guid": "11c916c9-c2f9-440e-8e73-102e79c4704d",
3+
"created_at": "2018-11-09T22:43:28Z",
4+
"updated_at": "2018-11-09T22:43:28Z",
5+
"name": "my-stack",
6+
"description": "Here is my stack!",
7+
"build_rootfs_image": "my-stack",
8+
"run_rootfs_image": "my-stack",
9+
"default": true,
10+
"metadata": {
11+
"labels": {},
12+
"annotations": {}
13+
},
14+
"links": {
15+
"self": {
16+
"href": "https://api.example.com/v3/stacks/11c916c9-c2f9-440e-8e73-102e79c4704d"
17+
}
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"guid": "11c916c9-c2f9-440e-8e73-102e79c4704d",
3+
"created_at": "2018-11-09T22:43:28Z",
4+
"updated_at": "2018-11-09T22:43:28Z",
5+
"name": "my-stack",
6+
"description": "Here is my stack!",
7+
"build_rootfs_image": "my-stack",
8+
"run_rootfs_image": "my-stack",
9+
"default": true,
10+
"metadata": {
11+
"labels": {"key":"value"},
12+
"annotations": {"note":"detailed information"}
13+
},
14+
"links": {
15+
"self": {
16+
"href": "https://api.example.com/v3/stacks/11c916c9-c2f9-440e-8e73-102e79c4704d"
17+
}
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"guid": "11c916c9-c2f9-440e-8e73-102e79c4704d",
3+
"created_at": "2018-11-09T22:43:28Z",
4+
"updated_at": "2018-11-09T22:43:28Z",
5+
"name": "my-stack",
6+
"description": "Here is my stack!",
7+
"build_rootfs_image": "my-stack",
8+
"run_rootfs_image": "my-stack",
9+
"default": true,
10+
"metadata": {
11+
"labels": {},
12+
"annotations": {}
13+
},
14+
"links": {
15+
"self": {
16+
"href": "https://api.example.com/v3/stacks/11c916c9-c2f9-440e-8e73-102e79c4704d"
17+
}
18+
}
19+
}

tests/v3/test_security_groups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def test_list(self):
4242
self.client.get.return_value = self.mock_response(
4343
"/v3/security_groups", HTTPStatus.OK, None, "v3", "security_groups", "GET_response.json"
4444
)
45-
all_security_groups = [service_broker for service_broker in self.client.v3.security_groups.list()]
45+
all_security_groups = [security_group for security_group in self.client.v3.security_groups.list()]
4646
self.client.get.assert_called_with(self.client.get.return_value.url)
4747
self.assertEqual(2, len(all_security_groups))
4848
self.assertEqual(all_security_groups[0]["name"], "my-group0")

0 commit comments

Comments
 (0)