Skip to content

Commit

Permalink
Added ReplicaSetService to handle ReplicaSet k8s objects.
Browse files Browse the repository at this point in the history
When provisioning the adapter will set on all kubernetes descriptions
custom label which will be used to discover kubernetes objects from same
composite component.

After the kubernetes descritpions are being deployed the adapter will
discover all new kubernetes object created by kubernetes itself and
create states for them.

When removing application the adapter will follow specific order based
on the objects type to prevent unexpected object recreations and leaving
leftovers.

Change-Id: I05b3fa106911c56473e56cb26541565422e988a8
Reviewed-on: http://bellevue-ci.eng.vmware.com:8080/7612
Reviewed-by: Tony Georgiev <[email protected]>
Compute-Verified: jenkins <[email protected]>
Upgrade-Verified: jenkins <[email protected]>
Bellevue-Verified: jenkins <[email protected]>
CS-Verified: jenkins <[email protected]>
  • Loading branch information
angel-ivanov committed Mar 9, 2017
1 parent a9cb5ee commit 47dcb83
Show file tree
Hide file tree
Showing 25 changed files with 1,404 additions and 490 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import static com.vmware.admiral.adapter.kubernetes.ApiUtil.API_PREFIX_V1;
import static com.vmware.admiral.common.util.AssertUtil.assertNotNull;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.KUBERNETES_LABEL_APP;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.KUBERNETES_LABEL_APP_ID;

import java.io.IOException;
import java.net.URI;
Expand Down Expand Up @@ -298,9 +299,16 @@ public void createNamespaceIfMissing(KubernetesContext context,
});
}

public void getPods(KubernetesContext context, CompletionHandler completionHandler) {
public void getPods(KubernetesContext context, String appId, CompletionHandler
completionHandler) {
URI uri = UriUtils
.buildUri(ApiUtil.namespacePrefix(context, ApiUtil.API_PREFIX_V1) + "/pods");

if (appId != null) {
uri = UriUtils.extendUriWithQuery(uri, LABEL_SELECTOR_QUERY, String
.format("%s=%s", KUBERNETES_LABEL_APP_ID, appId));
}

sendRequest(Action.GET, uri, null, context, completionHandler);
}

Expand Down Expand Up @@ -329,42 +337,56 @@ public void createDeployment(Deployment deployment, KubernetesContext context,
sendRequest(Action.POST, uri, deployment, context, completionHandler);
}

public void getServices(String appName, KubernetesContext context, CompletionHandler
public void getServices(KubernetesContext context, String appId, CompletionHandler
completionHandler) {
URI uri = UriUtils.buildUri(ApiUtil.namespacePrefix(context, ApiUtil.API_PREFIX_V1) +
"/services");

if (appName != null) {
if (appId != null) {
uri = UriUtils.extendUriWithQuery(uri, LABEL_SELECTOR_QUERY, String
.format("%s=%s", KUBERNETES_LABEL_APP, appName));
.format("%s=%s", KUBERNETES_LABEL_APP_ID, appId));
}

sendRequest(Action.GET, uri, null, context, completionHandler);
}

public void getDeployments(String appName, KubernetesContext context, CompletionHandler
public void getDeployments(KubernetesContext context, String appId, CompletionHandler
completionHandler) {
URI uri = UriUtils.buildUri(
ApiUtil.namespacePrefix(context, API_PREFIX_EXTENSIONS_V1BETA)
+ "/deployments");

if (appName != null) {
if (appId != null) {
uri = UriUtils.extendUriWithQuery(uri, LABEL_SELECTOR_QUERY, String
.format("%s=%s", KUBERNETES_LABEL_APP_ID, appId));
}

sendRequest(Action.GET, uri, null, context, completionHandler);
}

public void getReplicaSets(KubernetesContext context, String appId, CompletionHandler
completionHandler) {
URI uri = UriUtils.buildUri(
ApiUtil.namespacePrefix(context, API_PREFIX_EXTENSIONS_V1BETA)
+ "/replicasets");

if (appId != null) {
uri = UriUtils.extendUriWithQuery(uri, LABEL_SELECTOR_QUERY, String
.format("%s=%s", KUBERNETES_LABEL_APP, appName));
.format("%s=%s", KUBERNETES_LABEL_APP_ID, appId));
}

sendRequest(Action.GET, uri, null, context, completionHandler);
}

public void getReplicationControllers(String appName, KubernetesContext context,
public void getReplicationControllers(KubernetesContext context, String appId,
CompletionHandler completionHandler) {
URI uri = UriUtils.buildUri(
ApiUtil.namespacePrefix(context, API_PREFIX_V1)
+ "/replicationcontrollers");

if (appName != null) {
if (appId != null) {
uri = UriUtils.extendUriWithQuery(uri, LABEL_SELECTOR_QUERY, String
.format("%s=%s", KUBERNETES_LABEL_APP, appName));
.format("%s=%s", KUBERNETES_LABEL_APP, appId));
}

sendRequest(Action.GET, uri, null, context, completionHandler);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import com.vmware.admiral.compute.kubernetes.entities.deployments.DeploymentList;
import com.vmware.admiral.compute.kubernetes.entities.pods.Pod;
import com.vmware.admiral.compute.kubernetes.entities.pods.PodList;
import com.vmware.admiral.compute.kubernetes.entities.replicaset.ReplicaSet;
import com.vmware.admiral.compute.kubernetes.entities.replicaset.ReplicaSetList;
import com.vmware.admiral.compute.kubernetes.entities.replicationcontrollers.ReplicationController;
import com.vmware.admiral.compute.kubernetes.entities.replicationcontrollers.ReplicationControllerList;
import com.vmware.admiral.compute.kubernetes.entities.services.Service;
Expand Down Expand Up @@ -295,7 +297,8 @@ private void listEntities(AdapterRequest request, KubernetesContext context, Ope

callbackResponse.computeHostLink = context.host.documentSelfLink;
KubernetesRemoteApiClient client = getApiClient();
client.getPods(context, resultHandler.appendResult(o -> {

client.getPods(context, null, resultHandler.appendResult((o) -> {
PodList podList = o.getBody(PodList.class);
if (podList.items != null) {
synchronized (callbackResponse) {
Expand All @@ -310,7 +313,7 @@ private void listEntities(AdapterRequest request, KubernetesContext context, Ope
}
}
}));
client.getServices(null, context, resultHandler.appendResult(o -> {
client.getServices(context, null, resultHandler.appendResult(o -> {
ServiceList serviceList = o.getBody(ServiceList.class);
if (serviceList.items != null) {
synchronized (callbackResponse) {
Expand All @@ -325,7 +328,7 @@ private void listEntities(AdapterRequest request, KubernetesContext context, Ope
}
}
}));
client.getDeployments(null, context, resultHandler.appendResult(o -> {
client.getDeployments(context, null, resultHandler.appendResult(o -> {
DeploymentList deploymentList = o.getBody(DeploymentList.class);
if (deploymentList.items != null) {
synchronized (callbackResponse) {
Expand All @@ -340,7 +343,7 @@ private void listEntities(AdapterRequest request, KubernetesContext context, Ope
}
}
}));
client.getReplicationControllers(null, context, resultHandler.appendResult(o -> {
client.getReplicationControllers(context, null, resultHandler.appendResult(o -> {
ReplicationControllerList rcList = o.getBody(ReplicationControllerList.class);
if (rcList.items != null) {
synchronized (callbackResponse) {
Expand All @@ -355,6 +358,21 @@ private void listEntities(AdapterRequest request, KubernetesContext context, Ope
}
}
}));
client.getReplicaSets(context, null, resultHandler.appendResult(o -> {
ReplicaSetList rsList = o.getBody(ReplicaSetList.class);
if (rsList.items != null) {
synchronized (callbackResponse) {
for (ReplicaSet rc : rsList.items) {
if (rc != null && rc.metadata != null) {
callbackResponse.entityIdsAndNames.put(
rc.metadata.uid, rc.metadata.name);
callbackResponse.entityIdsAndTypes.put(
rc.metadata.uid, KubernetesUtil.REPLICA_SET_TYPE);
}
}
}
}
}));
allStarted.set(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.vmware.admiral.compute.kubernetes.KubernetesHostConstants;
import com.vmware.admiral.compute.kubernetes.service.DeploymentService;
import com.vmware.admiral.compute.kubernetes.service.PodService;
import com.vmware.admiral.compute.kubernetes.service.ReplicaSetService;
import com.vmware.admiral.compute.kubernetes.service.ReplicationControllerService;
import com.vmware.admiral.compute.kubernetes.service.ServiceEntityHandler;
import com.vmware.admiral.host.CompositeComponentNotificationProcessingChain;
Expand Down Expand Up @@ -197,6 +198,8 @@ protected void customizeChains(
chains.put(ServiceEntityHandler.class, CompositeComponentNotificationProcessingChain.class);
chains.put(ReplicationControllerService.class,
CompositeComponentNotificationProcessingChain.class);
chains.put(ReplicaSetService.class,
CompositeComponentNotificationProcessingChain.class);
}

protected static AuthCredentialsServiceState getKubernetesCredentials() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public interface KubernetesPathConstants {
String SERVICES = "/services";
String DEPLOYMENTS = "/deployments";
String REPLICATION_CONTROLLERS = "/replicationcontrollers";
String REPLICA_SETS = "/replicasets";

String DASHBOARD_PROXY_FOR_STATS = API_V1 +
"/proxy/namespaces/kube-system/services/kubernetes-dashboard/api/v1/node/";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,35 @@

package com.vmware.admiral.adapter.kubernetes.mock;

import java.io.IOException;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.DEPLOYMENT_TYPE;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.POD_TYPE;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.REPLICATION_CONTROLLER_TYPE;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.REPLICA_SET_TYPE;
import static com.vmware.admiral.compute.content.kubernetes.KubernetesUtil.SERVICE_TYPE;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.vmware.admiral.common.util.YamlMapper;
import com.vmware.admiral.compute.kubernetes.entities.common.BaseKubernetesObject;
import com.vmware.admiral.compute.kubernetes.entities.deployments.Deployment;
import com.vmware.admiral.compute.kubernetes.entities.services.Service;
import com.vmware.xenon.common.Operation;
import com.vmware.xenon.common.ServiceDocument;
import com.vmware.xenon.common.StatelessService;
import com.vmware.xenon.common.UriUtils;
import com.vmware.xenon.common.Utils;

public class MockKubernetesHost extends StatelessService {

public List<Object> deployedElements;
public List<BaseKubernetesObject> deployedElements;

public Map<String, Object> deployedElementsMap;

Expand All @@ -53,6 +62,16 @@ public void handleGet(Operation get) {
String uri = get.getUri().toString();
if (uri.contains("/log?container=")) {
handleFetchLog(get);
} else if (uri.contains("/pods?labelSelector=")) {
getEntitiesMatchingLabel(get, POD_TYPE);
} else if (uri.contains("/replicasets?labelSelector=")) {
getEntitiesMatchingLabel(get, REPLICA_SET_TYPE);
} else if (uri.contains("/deployments?labelSelector=")) {
getEntitiesMatchingLabel(get, DEPLOYMENT_TYPE);
} else if (uri.contains("/services?labelSelector=")) {
getEntitiesMatchingLabel(get, SERVICE_TYPE);
} else if (uri.contains("/replicationcontrollers?labelSelector=")) {
getEntitiesMatchingLabel(get, REPLICATION_CONTROLLER_TYPE);
} else {
handleGetResource(get);
}
Expand All @@ -62,8 +81,12 @@ public void handleGet(Operation get) {
public void handlePost(Operation post) {
String uri = post.getUri().toString();
if (uri.endsWith("/services")) {
Service service = post.getBody(Service.class);
service.metadata.uid = UUID.randomUUID().toString();
callbackRandomly(post, post.getBody(Service.class));
} else if (uri.endsWith("/deployments")) {
Deployment deployment = post.getBody(Deployment.class);
deployment.metadata.uid = UUID.randomUUID().toString();
callbackRandomly(post, post.getBody(Deployment.class));
} else {
post.fail(new IllegalArgumentException("Unknown uri " + uri));
Expand All @@ -84,14 +107,9 @@ public void handleDelete(Operation delete) {
}
}

private void callbackRandomly(Operation post, Object element) {
String responseBody;
try {
responseBody = YamlMapper.fromYamlToJson(post.getBody(String.class));
} catch (IOException e) {
post.fail(e);
return;
}
private void callbackRandomly(Operation post, BaseKubernetesObject element) {
String responseBody = Utils.toJson(element);

if (Math.random() > 0.5) {
deployedElements.add(element);
deployedElementsMap.put(post.getBody(BaseKubernetesObject.class).metadata.name,
Expand Down Expand Up @@ -127,6 +145,25 @@ private void handleGetResource(Operation get) {
get.fail(404);
}

private void getEntitiesMatchingLabel(Operation get, String objectType) {
Map<String, String> queryParams = UriUtils.parseUriQueryParams(get.getUri());
String labelSelectorKey = queryParams.get("labelSelector").split("=")[0];
String labelSelectorValue = queryParams.get("labelSelector").split("=")[1];
List<BaseKubernetesObject> items = deployedElements.stream()
.filter(e -> e.kind.equals(objectType))
.filter(e -> {
if (e.metadata.labels.containsKey(labelSelectorKey) && e.metadata.labels.get
(labelSelectorKey).equals(labelSelectorValue)) {
return true;
}
return false;
}).collect(Collectors.toList());

HashMap<String, Object> response = new HashMap<>();
response.put("items", items);
get.setBody(response).complete();
}

private String extractName(Operation op) {
String[] elements = op.getUri().getPath().split("/");
return elements[elements.length - 1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import static com.vmware.admiral.adapter.kubernetes.mock.KubernetesPathConstants.BASE_PATH;

import java.net.URI;
import java.util.ArrayList;

import com.vmware.admiral.compute.kubernetes.entities.replicaset.ReplicaSetList;
import com.vmware.xenon.common.Operation;
import com.vmware.xenon.common.ServiceDocument;
import com.vmware.xenon.common.StatefulService;
Expand Down Expand Up @@ -53,6 +55,12 @@ public void handleGet(Operation get) {
} else if (uri.getPath().contains(KubernetesPathConstants.DASHBOARD_PROXY_FOR_STATS)) {
get.setBody(statsProxyStub());
get.complete();
} else if (uri.getPath().contains(KubernetesPathConstants.REPLICA_SETS)) {
ReplicaSetList emptyList = new ReplicaSetList();
emptyList.items = new ArrayList<>();
emptyList.kind = "ReplicaSetList";
get.setBody(emptyList);
get.complete();
} else {
get.fail(new IllegalStateException("Operation path not supported."));
}
Expand Down
Loading

0 comments on commit 47dcb83

Please sign in to comment.