Skip to content

Commit

Permalink
Added KubernetesDescriptionService & KubernetesDescriptionContentServ…
Browse files Browse the repository at this point in the history
…ice.

KubernetesDescriptionContentService will handle creation of a single
yaml file with multiple k8s definitions.

Added tests for KubernetesDescriptionContentService and tests for
KubernetesDescriptionService

Exported isApplicationYamlContent() method in OperationUtils.

Added 2 util methods fromJsonToYaml() and fromYamlToJson() which convert
strings, added test for them.

Added hidden flag "--k8s" for admiral template import command. Currently
to be used for easier testing of KubernetesDescriptionService.

Change-Id: I145e2e844e8128f972e3e5d4fcc79e6b7c77b7e8
Reviewed-on: http://bellevue-ci.eng.vmware.com:8080/6497
Upgrade-Verified: jenkins <[email protected]>
Bellevue-Verified: jenkins <[email protected]>
CS-Verified: jenkins <[email protected]>
Reviewed-by: Tony Georgiev <[email protected]>
  • Loading branch information
angel-ivanov committed Feb 9, 2017
1 parent f18ad50 commit 607ffda
Show file tree
Hide file tree
Showing 13 changed files with 647 additions and 26 deletions.
16 changes: 12 additions & 4 deletions cli/src/admiral/cmd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,28 @@ var templateImportCmd = &cobra.Command{
},
}

var importKubernetes bool

func initTemplateImport() {
templateImportCmd.Flags().BoolVar(&importKubernetes, "k8s", false, "Import k8s object.")
templateImportCmd.Flags().MarkHidden("k8s")
TemplatesRootCmd.AddCommand(templateImportCmd)
}

func RunTemplateImport(args []string) (string, error) {
var (
filePath string
ok bool
filePath, id string
ok bool
err error
)
if filePath, ok = ValidateArgsCount(args); !ok {
return "", MissingPathToFileError
}
id, err := templates.Import(filePath)

if importKubernetes {
id, err = templates.ImportKubernetes(filePath)
} else {
id, err = templates.Import(filePath)
}
if err != nil {
return "", err
} else {
Expand Down
18 changes: 18 additions & 0 deletions cli/src/admiral/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,24 @@ func Export(id, dirF, format string) (string, error) {
return fullId, nil
}

func ImportKubernetes(dirF string) (string, error) {
importFile, err := ioutil.ReadFile(dirF)

if err != nil {
return "", err
}

url := config.URL + "/resources/kubernetes-templates"

req, _ := http.NewRequest("POST", url, bytes.NewBuffer(importFile))
_, respBody, respErr := client.ProcessRequest(req)
if respErr != nil {
return "", respErr
}

return string(respBody), nil
}

//Function to verify if file can be created.
//Returns the file and result of verification
func verifyFile(dirF string) (*os.File, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ protected boolean getPeerSynchronizationEnabled() {

/**
* Returns maintenance interval millis to be set to the host
*
* @return milliseconds
*/
protected long getMaintenanceIntervalMillis() {
Expand Down Expand Up @@ -362,7 +363,7 @@ protected void verifyService(URI factoryUri, FactoryService factoryInstance,
assertTrue(childTemplate.documentDescription != null);
assertTrue(childTemplate.documentDescription.propertyDescriptions != null
&& childTemplate.documentDescription.propertyDescriptions
.size() > 0);
.size() > 0);

if (!TaskServiceDocument.class.isAssignableFrom(childTemplate.getClass())) {
Field[] allFields = childTemplate.getClass().getDeclaredFields();
Expand Down Expand Up @@ -542,7 +543,7 @@ protected <T> T waitForPropertyValue(String documentSelfLink, Class<T> type, Str

/**
* Waits until the given task succeeds and returns its final state.
*
* <p>
* Note: will stop polling if the task transitions to any final state.
*/
protected <T extends TaskServiceDocument<E>, E extends Enum<E>> T waitForTaskSuccess(
Expand All @@ -555,7 +556,7 @@ protected <T extends TaskServiceDocument<E>, E extends Enum<E>> T waitForTaskSuc

/**
* Waits until the given task fails and returns its final state.
*
* <p>
* Note: will stop polling if the task transitions to any final state.
*/
protected <T extends TaskServiceDocument<E>, E extends Enum<E>> T waitForTaskError(
Expand Down Expand Up @@ -727,7 +728,7 @@ protected <T extends ServiceDocument> T searchForDocument(Class<T> type, String
* Tries to retrieve the given document and creates it (through a POST request), if not found.
* Assuming the {@code documentSelfLink} in the given document does not contain the full path
* but only the relative path from the given {@code factoryLink}.
*
* <p>
* Returns the document state as retrieved from the server.
*/
protected <T extends ServiceDocument> T getOrCreateDocument(T inState, String factoryLink)
Expand Down Expand Up @@ -887,17 +888,40 @@ public List<String> findResourceLinks(Class<? extends ServiceDocument> type,
List<String> result = new LinkedList<>();
new ServiceDocumentQuery<>(
host, type).query(query,
(r) -> {
if (r.hasException()) {
ctx.failIteration(r.getException());
return;
}
if (r.hasResult()) {
result.add(r.getDocumentSelfLink());
return;
}
(r) -> {
if (r.hasException()) {
ctx.failIteration(r.getException());
return;
}
if (r.hasResult()) {
result.add(r.getDocumentSelfLink());
return;
}
ctx.completeIteration();
});
ctx.await();

return result;
}

public List<String> getDocumentLinksOfType(Class<? extends ServiceDocument> type)
throws Throwable {
TestContext ctx = testCreate(1);
QueryTask query = QueryUtil.buildQuery(type, true);

List<String> result = new LinkedList<>();
new ServiceDocumentQuery<>(
host, type).query(query,
(r) -> {
if (r.hasException()) {
ctx.failIteration(r.getException());
return;
} else if (r.hasResult()) {
result.add(r.getDocumentSelfLink());
} else {
ctx.completeIteration();
});
}
});
ctx.await();

return result;
Expand Down Expand Up @@ -939,7 +963,8 @@ protected static void setPrivateField(Field field, Object instance, Object newVa
field.set(instance, newValue);
}

protected void validateLocalizableException(LocalizableExceptionHandler handler, String expectation)
protected void validateLocalizableException(LocalizableExceptionHandler handler,
String expectation)
throws Throwable {
try {
handler.call();
Expand All @@ -952,7 +977,7 @@ protected void validateLocalizableException(LocalizableExceptionHandler handler,
protected void waitForInitialBootServiceToBeSelfStopped(String bootServiceSelfLink)
throws Throwable {
waitFor("Failed waiting for " + bootServiceSelfLink
+ " to self stop itself after all instances created.",
+ " to self stop itself after all instances created.",
() -> {
TestContext ctx = testCreate(1);
URI uri = UriUtils.buildUri(host, bootServiceSelfLink);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public interface ManagementUriParts {
String COMPUTE_NETWORKS = RESOURCES + "/compute-networks";
String COMPUTE_NETWORK_DESC = RESOURCES + "/compute-network" + DESCRIPTION_SUFFIX;

String KUBERNETES_DESC = RESOURCES + "/kubernetes" + DESCRIPTION_SUFFIX;
String KUBERNETES_DESC_CONTENT = RESOURCES + "/kubernetes-templates";

// Request tasks:
String REQUEST = "/request";
String REQUESTS = "/requests";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

package com.vmware.admiral.common.util;

import static com.vmware.admiral.common.util.UriUtilsExtended.MEDIA_TYPE_APPLICATION_YAML;

import java.net.URI;
import java.util.function.Consumer;
import java.util.logging.Level;
Expand Down Expand Up @@ -83,4 +85,16 @@ public static <T extends ServiceDocument> void getDocumentState(Service service,
);
}

public static boolean isApplicationYamlContent(String contentType) {
return (contentType != null)
&& MEDIA_TYPE_APPLICATION_YAML.equals(contentType.split(";")[0]);
}

public static boolean isApplicationYamlAccpetHeader(Operation op) {
String acceptHeader = op.getRequestHeader("Accept");
if (acceptHeader == null || acceptHeader.trim().equals("")) {
return false;
}
return MEDIA_TYPE_APPLICATION_YAML.equals(acceptHeader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

package com.vmware.admiral.common.util;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
Expand All @@ -26,6 +28,7 @@
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import com.vmware.xenon.common.ServiceDocument;
import com.vmware.xenon.common.Utils;

/**
* YAML mapping functions
Expand Down Expand Up @@ -63,4 +66,14 @@ public static Set<String> getBuiltinFieldNames() {
.filter(ServiceDocument::isBuiltInDocumentField)
.collect(Collectors.toSet());
}

public static String fromYamlToJson(String yaml) throws IOException {
Object obj = objectMapper().readValue(yaml, Object.class);
return Utils.toJson(obj);
}

public static String fromJsonToYaml(String json) throws IOException {
JsonNode jsonNode = objectMapper().readTree(json);
return objectMapper().writeValueAsString(jsonNode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2017 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with separate copyright notices
* and license terms. Your use of these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*/

package com.vmware.admiral.service.common.util;

import static org.junit.Assert.assertEquals;

import java.io.IOException;

import org.junit.Test;

import com.vmware.admiral.common.util.YamlMapper;

public class YamlMapperTest {

@Test
public void testConvertFromYamlToJson() throws IOException {
String yamlInput = "---\n"
+ "person:\n"
+ " name: test-name\n"
+ " age: 14\n";

String expectedJsonOutput = "{\"person\":{\"name\":\"test-name\",\"age\":14}}";

String actualJsonOutput = YamlMapper.fromYamlToJson(yamlInput);

assertEquals(expectedJsonOutput, actualJsonOutput);
}

@Test
public void testConvertFromJsonToYaml() throws IOException {
String jsonInput = "{\"person\":{\"name\":\"test-name\",\"age\":14}}";

String expectedYamlOutput = "---\n"
+ "person:\n"
+ " name: \"test-name\"\n"
+ " age: 14\n";

String actualYamlOutput = YamlMapper.fromJsonToYaml(jsonInput);

assertEquals(expectedYamlOutput, actualYamlOutput);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
package com.vmware.admiral.compute.content;

import static com.vmware.admiral.common.util.AssertUtil.assertNotEmpty;
import static com.vmware.admiral.common.util.OperationUtil.isApplicationYamlContent;
import static com.vmware.admiral.common.util.UriUtilsExtended.MEDIA_TYPE_APPLICATION_YAML;
import static com.vmware.admiral.common.util.ValidationUtils.handleValidationException;
import static com.vmware.admiral.compute.content.CompositeTemplateUtil.assertContainersComponentsOnly;
Expand Down Expand Up @@ -228,8 +229,5 @@ private DeferredResult<Operation> persistComponent(ComponentTemplate<?> componen
return nestedState.sendRequest(this, Action.POST);
}

private boolean isApplicationYamlContent(String contentType) {
return (contentType != null)
&& MEDIA_TYPE_APPLICATION_YAML.equals(contentType.split(";")[0]);
}

}
Loading

0 comments on commit 607ffda

Please sign in to comment.