Skip to content

Commit 92df1ee

Browse files
committed
Add Integration Tests for Security Groups
This commit adds some integration tests for security groups. Some tests remain ignored, pending further implementation work. It also adds an enum for security group rules protocol, and adds a missing 'description' field to rules.
1 parent dc576ea commit 92df1ee

File tree

8 files changed

+252
-28
lines changed

8 files changed

+252
-28
lines changed

cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v2/securitygroups/ReactorSecurityGroupsTest.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
import static io.netty.handler.codec.http.HttpResponseStatus.ACCEPTED;
5656
import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT;
5757
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
58+
import static org.cloudfoundry.client.v2.securitygroups.Protocol.ALL;
59+
import static org.cloudfoundry.client.v2.securitygroups.Protocol.ICMP;
60+
import static org.cloudfoundry.client.v2.securitygroups.Protocol.TCP;
61+
import static org.cloudfoundry.client.v2.securitygroups.Protocol.UDP;
5862

5963
public final class ReactorSecurityGroupsTest extends AbstractClientApiTest {
6064

@@ -77,24 +81,24 @@ public void create() {
7781
.create(CreateSecurityGroupRequest.builder()
7882
.name("my_super_sec_group")
7983
.rule(RuleEntity.builder()
80-
.protocol("icmp")
84+
.protocol(ICMP)
8185
.destination("0.0.0.0/0")
8286
.type(0)
8387
.code(1)
8488
.build())
8589
.rule(RuleEntity.builder()
86-
.protocol("tcp")
90+
.protocol(TCP)
8791
.destination("0.0.0.0/0")
8892
.ports("2048-3000")
8993
.log(true)
9094
.build())
9195
.rule(RuleEntity.builder()
92-
.protocol("udp")
96+
.protocol(UDP)
9397
.destination("0.0.0.0/0")
9498
.ports("53, 5353")
9599
.build())
96100
.rule(RuleEntity.builder()
97-
.protocol("all")
101+
.protocol(ALL)
98102
.destination("0.0.0.0/0")
99103
.build())
100104
.build())
@@ -108,24 +112,24 @@ public void create() {
108112
.entity(SecurityGroupEntity.builder()
109113
.name("my_super_sec_group")
110114
.rule(RuleEntity.builder()
111-
.protocol("icmp")
115+
.protocol(ICMP)
112116
.destination("0.0.0.0/0")
113117
.type(0)
114118
.code(1)
115119
.build())
116120
.rule(RuleEntity.builder()
117-
.protocol("tcp")
121+
.protocol(TCP)
118122
.destination("0.0.0.0/0")
119123
.ports("2048-3000")
120124
.log(true)
121125
.build())
122126
.rule(RuleEntity.builder()
123-
.protocol("udp")
127+
.protocol(UDP)
124128
.destination("0.0.0.0/0")
125129
.ports("53, 5353")
126130
.build())
127131
.rule(RuleEntity.builder()
128-
.protocol("all")
132+
.protocol(ALL)
129133
.destination("0.0.0.0/0")
130134
.build())
131135
.runningDefault(false)
@@ -286,7 +290,7 @@ public void list() {
286290
.entity(SecurityGroupEntity.builder()
287291
.name("name-67")
288292
.rule(RuleEntity.builder()
289-
.protocol("udp")
293+
.protocol(UDP)
290294
.ports("8080")
291295
.destination("198.41.191.47/1")
292296
.build())
@@ -304,7 +308,7 @@ public void list() {
304308
.entity(SecurityGroupEntity.builder()
305309
.name("name-68")
306310
.rule(RuleEntity.builder()
307-
.protocol("udp")
311+
.protocol(UDP)
308312
.ports("8080")
309313
.destination("198.41.191.47/1")
310314
.build())
@@ -322,7 +326,7 @@ public void list() {
322326
.entity(SecurityGroupEntity.builder()
323327
.name("name-69")
324328
.rule(RuleEntity.builder()
325-
.protocol("udp")
329+
.protocol(UDP)
326330
.ports("8080")
327331
.destination("198.41.191.47/1")
328332
.build())
@@ -366,7 +370,7 @@ public void listRunning() {
366370
.rule(RuleEntity.builder()
367371
.destination("198.41.191.47/1")
368372
.ports("8080")
369-
.protocol("udp")
373+
.protocol(UDP)
370374
.build())
371375
.runningDefault(true)
372376
.stagingDefault(false)
@@ -407,7 +411,7 @@ public void listStaging() {
407411
.rule(RuleEntity.builder()
408412
.destination("198.41.191.47/1")
409413
.ports("8080")
410-
.protocol("udp")
414+
.protocol(UDP)
411415
.build())
412416
.runningDefault(false)
413417
.stagingDefault(true)
@@ -447,7 +451,7 @@ public void setRunning() {
447451
.rule(RuleEntity.builder()
448452
.destination("198.41.191.47/1")
449453
.ports("8080")
450-
.protocol("udp")
454+
.protocol(UDP)
451455
.build())
452456
.runningDefault(true)
453457
.stagingDefault(false)
@@ -486,7 +490,7 @@ public void setStaging() {
486490
.rule(RuleEntity.builder()
487491
.destination("198.41.191.47/1")
488492
.ports("8080")
489-
.protocol("udp")
493+
.protocol(UDP)
490494
.build())
491495
.runningDefault(false)
492496
.stagingDefault(true)

cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v2/spaces/ReactorSpacesTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
import static io.netty.handler.codec.http.HttpResponseStatus.ACCEPTED;
123123
import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT;
124124
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
125+
import static org.cloudfoundry.client.v2.securitygroups.Protocol.UDP;
125126
import static org.cloudfoundry.client.v2.serviceinstances.ServiceInstance.builder;
126127

127128
public final class ReactorSpacesTest extends AbstractClientApiTest {
@@ -1088,7 +1089,7 @@ public void listSecurityGroups() {
10881089
.rule(RuleEntity.builder()
10891090
.destination("198.41.191.47/1")
10901091
.ports("8080")
1091-
.protocol("udp")
1092+
.protocol(UDP)
10921093
.build())
10931094
.runningDefault(false)
10941095
.spacesUrl("/v2/security_groups/a3728437-fe41-42c1-875c-b59cffc7498c/spaces")
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.client.v2.securitygroups;
18+
19+
import com.fasterxml.jackson.annotation.JsonCreator;
20+
import com.fasterxml.jackson.annotation.JsonValue;
21+
22+
/**
23+
* The protocol of a {@link RuleEntity}
24+
*/
25+
public enum Protocol {
26+
27+
/**
28+
* All protocols
29+
*/
30+
ALL("all"),
31+
32+
/**
33+
* ICMP protocol
34+
*/
35+
ICMP("icmp"),
36+
37+
/**
38+
* TCP protocol
39+
*/
40+
TCP("tcp"),
41+
42+
/**
43+
* UDP protocol
44+
*/
45+
UDP("udp");
46+
47+
private final String value;
48+
49+
Protocol(String value) {
50+
this.value = value;
51+
}
52+
53+
@JsonCreator
54+
public static Protocol from(String s) {
55+
switch (s.toLowerCase()) {
56+
case "all":
57+
return ALL;
58+
case "icmp":
59+
return ICMP;
60+
case "tcp":
61+
return TCP;
62+
case "udp":
63+
return UDP;
64+
default:
65+
throw new IllegalArgumentException(String.format("Unknown protocol: %s", s));
66+
}
67+
}
68+
69+
@JsonValue
70+
public String getValue() {
71+
return this.value;
72+
}
73+
74+
@Override
75+
public String toString() {
76+
return getValue();
77+
}
78+
}

cloudfoundry-client/src/main/java/org/cloudfoundry/client/v2/securitygroups/_RuleEntity.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,19 @@
2929
abstract class _RuleEntity {
3030

3131
/**
32-
* The control signal for icmp
32+
* The code control signal for icmp
3333
*/
3434
@JsonProperty("code")
3535
@Nullable
3636
abstract Integer getCode();
3737

38+
/**
39+
* The description of the rule
40+
*/
41+
@JsonProperty("description")
42+
@Nullable
43+
abstract String getDescription();
44+
3845
/**
3946
* The destination
4047
*/
@@ -61,10 +68,10 @@ abstract class _RuleEntity {
6168
*/
6269
@JsonProperty("protocol")
6370
@Nullable
64-
abstract String getProtocol();
71+
abstract Protocol getProtocol();
6572

6673
/**
67-
* The control signal for icmp
74+
* The type control signal for icmp
6875
*/
6976
@JsonProperty("type")
7077
@Nullable

cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/spaces/_Rule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.cloudfoundry.operations.spaces;
1818

19+
import org.cloudfoundry.client.v2.securitygroups.Protocol;
1920
import org.immutables.value.Value;
2021

2122
@Value.Immutable
@@ -34,6 +35,6 @@ abstract class _Rule {
3435
/**
3536
* The protocol
3637
*/
37-
abstract String getProtocol();
38+
abstract Protocol getProtocol();
3839

3940
}

integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.cloudfoundry.client.v2.routes.DeleteRouteRequest;
3737
import org.cloudfoundry.client.v2.routes.ListRoutesRequest;
3838
import org.cloudfoundry.client.v2.routes.RouteEntity;
39+
import org.cloudfoundry.client.v2.securitygroups.DeleteSecurityGroupRequest;
40+
import org.cloudfoundry.client.v2.securitygroups.ListSecurityGroupsRequest;
3941
import org.cloudfoundry.client.v2.serviceinstances.DeleteServiceInstanceRequest;
4042
import org.cloudfoundry.client.v2.serviceinstances.ListServiceInstancesRequest;
4143
import org.cloudfoundry.client.v2.shareddomains.DeleteSharedDomainRequest;
@@ -112,6 +114,7 @@ void clean() {
112114
.thenMany(cleanApplicationsV2(this.cloudFoundryClient, this.nameFactory))
113115
.thenMany(cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory))
114116
.thenMany(cleanPackages(this.cloudFoundryClient))
117+
.thenMany(cleanSecurityGroups(this.cloudFoundryClient, this.nameFactory))
115118
.thenMany(cleanServiceInstances(this.cloudFoundryClient, this.nameFactory))
116119
.thenMany(cleanUserProvidedServiceInstances(this.cloudFoundryClient, this.nameFactory))
117120
.thenMany(cleanSharedDomains(this.cloudFoundryClient, this.nameFactory))
@@ -337,6 +340,21 @@ private static Flux<Void> cleanRoutes(CloudFoundryClient cloudFoundryClient, Nam
337340
})));
338341
}
339342

343+
private static Flux<Void> cleanSecurityGroups(CloudFoundryClient cloudFoundryClient, NameFactory nameFactory) {
344+
return PaginationUtils
345+
.requestClientV2Resources(page -> cloudFoundryClient.securityGroups()
346+
.list(ListSecurityGroupsRequest.builder()
347+
.page(page)
348+
.build()))
349+
.filter(securityGroup -> nameFactory.isSecurityGroupName(ResourceUtils.getEntity(securityGroup).getName()))
350+
.flatMap(securityGroup -> cloudFoundryClient.securityGroups()
351+
.delete(DeleteSecurityGroupRequest.builder()
352+
.securityGroupId(ResourceUtils.getId(securityGroup))
353+
.build())
354+
.doOnError(t -> LOGGER.error("Unable to delete security group {}", ResourceUtils.getEntity(securityGroup).getName(), t))
355+
.then());
356+
}
357+
340358
private static Flux<Void> cleanServiceInstances(CloudFoundryClient cloudFoundryClient, NameFactory nameFactory) {
341359
return PaginationUtils
342360
.requestClientV2Resources(page -> cloudFoundryClient.serviceInstances()

integration-test/src/test/java/org/cloudfoundry/NameFactory.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public interface NameFactory {
4747

4848
String QUOTA_DEFINITION_PREFIX = "test-quota-definition-";
4949

50+
String SECURITY_GROUP_PREFIX = "test-security-group-";
51+
5052
String SERVICE_INSTANCE_PREFIX = "test-service-instance-";
5153

5254
String SPACE_PREFIX = "test-space-";
@@ -196,6 +198,15 @@ default String getQuotaDefinitionName() {
196198
return getName(QUOTA_DEFINITION_PREFIX);
197199
}
198200

201+
/**
202+
* Creates a security group name
203+
*
204+
* @return the security group name
205+
*/
206+
default String getSecurityGroupName() {
207+
return getName(SECURITY_GROUP_PREFIX);
208+
}
209+
199210
/**
200211
* Creates a service instance name
201212
*
@@ -396,6 +407,16 @@ default boolean isQuotaDefinitionName(String candidate) {
396407
return isName(QUOTA_DEFINITION_PREFIX, candidate);
397408
}
398409

410+
/**
411+
* Tests a name to determine if it is a security group name
412+
*
413+
* @param candidate the candidate name
414+
* @return {@code true} if the name is a security group name, {@code false} otherwise
415+
*/
416+
default boolean isSecurityGroupName(String candidate) {
417+
return isName(SECURITY_GROUP_PREFIX, candidate);
418+
}
419+
399420
/**
400421
* Tests a name to determine if it is a service instance name
401422
*

0 commit comments

Comments
 (0)