Skip to content

Commit be4f2b8

Browse files
committed
Sort network for have it in dclared order
1 parent 4830e31 commit be4f2b8

4 files changed

Lines changed: 161 additions & 1 deletion

File tree

plugin/src/main/java/jenkins/plugins/openstack/compute/JCloudsSlaveTemplate.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class JCloudsSlaveTemplate implements Describable<JCloudsSlaveTemplate>,
5757
public static final String OPENSTACK_CLOUD_NAME_KEY = "jenkins-cloud-name";
5858
// To be attached on all servers provisioned from configured templates
5959
public static final String OPENSTACK_TEMPLATE_NAME_KEY = "jenkins-template-name";
60+
// To be attached on all servers provisioned from configured templates
61+
public static final String OPENSTACK_NETWORK_ORDER = "jenkins-network-order";
6062

6163
private static final Logger LOGGER = Logger.getLogger(JCloudsSlaveTemplate.class.getName());
6264

@@ -304,6 +306,7 @@ public boolean canProvision(final Label label) {
304306
List<String> networks = selectNetworkIds(openstack, nid);
305307
LOGGER.fine("Setting networks to " + networks);
306308
builder.networks(networks);
309+
builder.addMetadataItem(OPENSTACK_NETWORK_ORDER, String.join(",", selectNetworkOrder(openstack, nid)));
307310
}
308311

309312
String securityGroups = opts.getSecurityGroups();
@@ -477,6 +480,30 @@ private String getServerName() {
477480

478481
return ret.stream().map(Network::getId).collect(Collectors.toList());
479482
}
483+
@VisibleForTesting
484+
/*package*/ static @Nonnull List<String> selectNetworkOrder(@Nonnull Openstack openstack, @Nonnull String spec) {
485+
if (spec == null || spec.isEmpty()) throw new IllegalArgumentException();
486+
487+
List<List<String>> declared = TokenGroup.from(spec, ',', '|');
488+
489+
List<String> allDeclaredNetworks = declared.stream().flatMap(Collection::stream).collect(Collectors.toList());
490+
491+
if (declared.isEmpty() || declared.contains(Collections.emptyList()) || allDeclaredNetworks.contains("")) {
492+
throw new IllegalArgumentException("Networks declaration contains blank '" + declared + "'");
493+
}
494+
495+
Map<String, Network> osNetworksById = openstack.getNetworks(allDeclaredNetworks);
496+
Map<String, Network> osNetworksByName = osNetworksById.values().stream().collect(Collectors.toMap(Network::getName, n -> n));
497+
498+
final Function<String, String> RESOLVE_IDS_TO_NAME = n -> {
499+
if (osNetworksByName.containsKey(n)) return n;
500+
Network network = osNetworksById.getOrDefault(n, null);
501+
if (network != null) return network.getName();
502+
throw new IllegalArgumentException("No network name '" + n + "' found for " + spec);
503+
};
504+
505+
return allDeclaredNetworks.stream().map(RESOLVE_IDS_TO_NAME).distinct().collect(Collectors.toList());
506+
}
480507

481508
/*package for testing*/ @CheckForNull String getUserData() {
482509
return UserDataConfig.resolve(getEffectiveSlaveOptions().getUserDataId());

plugin/src/main/java/jenkins/plugins/openstack/compute/internal/Openstack.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import hudson.Util;
3535
import hudson.util.FormValidation;
3636
import jenkins.model.Jenkins;
37+
import jenkins.plugins.openstack.compute.JCloudsSlaveTemplate;
3738
import jenkins.plugins.openstack.compute.auth.OpenstackCredential;
3839
import org.apache.commons.codec.binary.Base64;
3940
import org.apache.commons.codec.digest.DigestUtils;
@@ -72,6 +73,7 @@
7273
import javax.annotation.Nonnull;
7374
import javax.annotation.concurrent.ThreadSafe;
7475
import java.util.ArrayList;
76+
import java.util.Arrays;
7577
import java.util.Collection;
7678
import java.util.Collections;
7779
import java.util.Comparator;
@@ -735,7 +737,18 @@ public static Address getAccessIpAddressObject(@Nonnull Server server) {
735737
Address fixedIPv4 = null;
736738
Address fixedIPv6 = null;
737739
Address floatingIPv6 = null;
738-
Collection<List<? extends Address>> addressMap = server.getAddresses().getAddresses().values();
740+
String order= server.getMetadata().get(JCloudsSlaveTemplate.OPENSTACK_NETWORK_ORDER);
741+
Collection<List<? extends Address>> addressMap;
742+
if (order != null && !order.isEmpty()) {
743+
final List<String> listOrder = Arrays.asList(order.split(","));
744+
745+
TreeMap<String, List<? extends Address>> sortedAddress = new TreeMap<>(Comparator.comparingInt(listOrder::indexOf));
746+
sortedAddress.putAll(server.getAddresses().getAddresses());
747+
addressMap = sortedAddress.values();
748+
} else {
749+
addressMap = server.getAddresses().getAddresses().values();
750+
}
751+
739752
for (List<? extends Address> addresses: addressMap) {
740753
for (Address addr: addresses) {
741754
String type = addr.getType();

plugin/src/test/java/jenkins/plugins/openstack/compute/JCloudsSlaveTemplateTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
import static jenkins.plugins.openstack.compute.JCloudsSlaveTemplate.parseSecurityGroups;
3838
import static jenkins.plugins.openstack.compute.JCloudsSlaveTemplate.selectNetworkIds;
39+
import static jenkins.plugins.openstack.compute.JCloudsSlaveTemplate.selectNetworkOrder;
3940
import static org.hamcrest.Matchers.*;
4041
import static org.junit.Assert.*;
4142
import static org.junit.Assert.assertEquals;
@@ -515,4 +516,66 @@ public void selectNetworksWhenUtilizationApiDisabled() {
515516
// If we have not utilization info, result will likely be suboptimal
516517
assertEquals(Arrays.asList("uuid-empty", "uuid-full", "uuid-loaded", "uuid-empty"), selectNetworkIds(os, "empty|full,full,loaded|empty,empty"));
517518
}
519+
520+
@Test
521+
public void selectNetworkOrderTest() {
522+
JCloudsSlaveTemplate t = j.dummySlaveTemplate("foo");
523+
JCloudsCloud c = j.dummyCloud(t);
524+
j.configureSlaveProvisioning(c, Collections.emptyList());
525+
526+
Network fullNet = mockNetwork("full");
527+
Network emptyNet = mockNetwork("empty");
528+
Network loadedNet = mockNetwork("loaded");
529+
Map<String, Network> networkMap = new HashMap<>();
530+
Stream.of(fullNet, emptyNet, loadedNet).forEach(n -> {
531+
networkMap.put(n.getId(), n );
532+
networkMap.put(n.getName(), n);
533+
});
534+
535+
Openstack os = c.getOpenstack();
536+
doAnswer(i -> {
537+
Map<String, Network> ret = new HashMap<>();
538+
539+
for (String netSpec : ((List<String>) i.getArguments()[0])) {
540+
Network n = networkMap.get(netSpec);
541+
ret.put(n.getId(), n);
542+
}
543+
return ret;
544+
}).when(os).getNetworks(any());
545+
doAnswer(i -> {
546+
Map<String, Network> requestedNets = (Map<String, Network>) i.getArguments()[0];
547+
548+
Map<Network, Integer> ret = new HashMap<>();
549+
if (requestedNets.containsKey(fullNet.getId())) {
550+
ret.put(fullNet, 0);
551+
}
552+
if (requestedNets.containsKey(emptyNet.getId())) {
553+
ret.put(emptyNet, 10);
554+
}
555+
if (requestedNets.containsKey(loadedNet.getId())) {
556+
ret.put(loadedNet, 5);
557+
}
558+
return ret;
559+
}).when(os).getNetworksCapacity(any());
560+
561+
assertEquals(singletonList("empty"), selectNetworkOrder(os, "empty"));
562+
assertEquals(singletonList("loaded"), selectNetworkOrder(os, "loaded"));
563+
assertEquals(singletonList("full"), selectNetworkOrder(os, "full"));
564+
assertEquals(singletonList("empty"), selectNetworkOrder(os, "uuid-empty"));
565+
assertEquals(singletonList("loaded"), selectNetworkOrder(os, "uuid-loaded"));
566+
assertEquals(singletonList("full"), selectNetworkOrder(os, "uuid-full"));
567+
assertEquals(Arrays.asList("empty", "full", "loaded"), selectNetworkOrder(os, "empty,uuid-full,loaded"));
568+
assertEquals(Arrays.asList("empty"), selectNetworkOrder(os, "empty,uuid-empty,empty"));
569+
570+
assertEquals(Arrays.asList("empty","full"), selectNetworkOrder(os, "empty|full"));
571+
assertEquals(Arrays.asList("empty","loaded"), selectNetworkOrder(os, "empty|loaded"));
572+
assertEquals(Arrays.asList("loaded","full"), selectNetworkOrder(os, "loaded|full"));
573+
assertEquals(Arrays.asList("empty", "loaded", "full"), selectNetworkOrder(os, "empty|loaded|full"));
574+
assertEquals(Arrays.asList("full", "loaded", "empty"), selectNetworkOrder(os, "full|loaded|empty"));
575+
576+
assertEquals(Arrays.asList("empty", "full", "loaded"), selectNetworkOrder(os, "empty|full,full,loaded|empty,empty"));
577+
assertEquals(Arrays.asList("empty", "loaded"), selectNetworkOrder(os, "empty|empty,loaded|loaded,empty|empty"));
578+
}
579+
580+
518581
}

plugin/src/test/java/jenkins/plugins/openstack/compute/internal/OpenstackTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static org.mockito.Matchers.argThat;
1010
import static org.mockito.Mockito.*;
1111

12+
import jenkins.plugins.openstack.compute.JCloudsSlaveTemplate;
1213
import org.junit.Before;
1314
import org.junit.Test;
1415
import org.mockito.invocation.InvocationOnMock;
@@ -22,6 +23,8 @@
2223
import org.openstack4j.api.networking.ext.NetworkIPAvailabilityService;
2324
import org.openstack4j.api.storage.BlockVolumeSnapshotService;
2425
import org.openstack4j.model.common.ActionResponse;
26+
import org.openstack4j.model.compute.Address;
27+
import org.openstack4j.model.compute.Addresses;
2528
import org.openstack4j.model.compute.Fault;
2629
import org.openstack4j.model.compute.Server;
2730
import org.openstack4j.model.compute.builder.ServerCreateBuilder;
@@ -488,6 +491,60 @@ public void deleteFloatingIpsWhenDeletingMachine() {
488491
verify(fips, never()).delete("keep-me");
489492
}
490493

494+
495+
@Test
496+
public void getAccessIpAddress() {
497+
getAccesIpAdressTest(getAddressesOneAddress(), Collections.singletonList("default_network"),"DEFAULT_IP");
498+
499+
getAccesIpAdressTest(getAddressesTwoAddress(), Arrays.asList("first_network", "second_network"),"FIRST_IP");
500+
getAccesIpAdressTest(getAddressesTwoAddress(), Arrays.asList("second_network", "first_network"),"SECOND_IP");
501+
}
502+
503+
private Addresses getAddressesOneAddress() {
504+
Address address = getAddress("DEFAULT_IP", "fixed", 4);
505+
Addresses addresses = mock(Addresses.class);
506+
Map<String, List<? extends Address>> mapAdresses = new HashMap<String, List<? extends Address>>() {{
507+
put("default_network", Collections.singletonList(address));
508+
}};
509+
when(addresses.getAddresses()).thenReturn(mapAdresses);
510+
when(addresses.getAddresses(any()))
511+
.thenAnswer((Answer<List<? extends Address>>) invocationOnMock -> mapAdresses.get(invocationOnMock.getArguments()[0]));
512+
return addresses;
513+
}
514+
private Addresses getAddressesTwoAddress() {
515+
Address firstIp = getAddress("FIRST_IP", "fixed", 4);
516+
Address secondIp = getAddress("SECOND_IP", "fixed", 4);
517+
Addresses addresses = mock(Addresses.class);
518+
Map<String, List<? extends Address>> mapAdresses = new HashMap<String, List<? extends Address>>() {{
519+
put("first_network", Collections.singletonList(firstIp));
520+
put("second_network", Collections.singletonList(secondIp));
521+
}};
522+
when(addresses.getAddresses()).thenReturn(mapAdresses);
523+
when(addresses.getAddresses(any()))
524+
.thenAnswer((Answer<List<? extends Address>>) invocationOnMock -> mapAdresses.get(invocationOnMock.getArguments()[0]));
525+
return addresses;
526+
}
527+
528+
private Address getAddress(String ip, String type, int version) {
529+
Address address = mock(Address.class);
530+
when(address.getAddr()).thenReturn(ip);
531+
when(address.getVersion()).thenReturn(version);
532+
when(address.getType()).thenReturn(type);
533+
return address;
534+
}
535+
536+
private void getAccesIpAdressTest(Addresses addresses,List<String> networkOrder, String result) {
537+
Server server = mock(Server.class);
538+
when(server.getAddresses()).thenReturn(addresses);
539+
Map<String,String> metadata = new HashMap<>();
540+
metadata.put(JCloudsSlaveTemplate.OPENSTACK_NETWORK_ORDER, String.join(",", networkOrder));
541+
when(server.getMetadata()).thenReturn(metadata);
542+
543+
String ipAdresse = Openstack.getAccessIpAddress(server);
544+
545+
assertThat(ipAdresse, equalTo(result));
546+
}
547+
491548
/**
492549
* Track the state of the openstack to be manifested by different client calls;
493550
*/

0 commit comments

Comments
 (0)