[DeploymentManager] Multi-env configuration support

User can put several configurations for different
types of Murano-environment. Object model for
each environment placed to a separate file.

Minor code reformatting.

Change-Id: Ibf011caa7d9dd36857391acd05ce3bfc4fd5582c
This commit is contained in:
Alexey Khivin 2016-10-05 21:36:08 +03:00
parent 2110eec0e8
commit a40f7fb476
13 changed files with 235 additions and 114 deletions

View File

@ -5,13 +5,8 @@ import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.*;
import hudson.security.ACL;
@ -19,19 +14,17 @@ import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrapperDescriptor;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import org.apache.http.impl.client.SystemDefaultCredentialsProvider;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.export.Exported;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.credentials.OpenstackCredentials;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.repository.RepositoryTemplatedDeployment;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigInteger;
import java.net.URL;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -74,7 +67,7 @@ public class MuranoManagerBuildWrapper extends BuildWrapper implements Serializa
credentials.getPassword().getPlainText(),
credentials.getTenant()
);
if (env.containsKey("BUILD_ENVIRONMENT_TIMEOUT")) {
if (env.containsKey("BUILD_ENVIRONMENT_TIMEOUT")){
int timeout = Integer.parseInt(env.get("BUILD_ENVIRONMENT_TIMEOUT"));
helper.setTimeout(timeout);
}
@ -82,7 +75,8 @@ public class MuranoManagerBuildWrapper extends BuildWrapper implements Serializa
//TODO: Remove
try {
((RepositoryTemplatedDeployment) deployment).readObjectModel(build.getWorkspace());
} catch (Exception io) {
} catch (Exception io){
io.printStackTrace();
}
String name = generateEnvName();
@ -91,7 +85,7 @@ public class MuranoManagerBuildWrapper extends BuildWrapper implements Serializa
name, deployment.getObjectModel());
boolean result = helper.waitDeploymentResult(envId);
if (!result) {
if (!result){
build.setResult(Result.FAILURE);
}
} catch (Exception e) {
@ -122,7 +116,7 @@ public class MuranoManagerBuildWrapper extends BuildWrapper implements Serializa
return openstackCredentials;
}
@Exported
public MuranoDeployment getDeployment() {
return deployment;

View File

@ -1,6 +1,5 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;

View File

@ -1,101 +0,0 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import hudson.Extension;
import hudson.FilePath;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RepositoryTemplatedDeployment extends MuranoDeployment {
/**
* The file in the repository that contains muranoci configuration.
*/
public static final String CI_CONFG_FILENAME = ".murano.yml";
/**
*
*/
private final String environment;
/**
* The specific Implemenation of <code>MuranoDeployment</code> that
* gets object model from the file within the repo.
*
* @param environment The name of the environment within the .murano.yml config
*/
@DataBoundConstructor
public RepositoryTemplatedDeployment(
String environment) {
this.environment = environment;
}
public String getEnvironment() {
return environment;
}
/**
* Denotes that this is a cloud deployment plugin.
*/
@Extension
public static class DescriptorImpl extends AbstractMuranoDeploymentDescriptor {
public DescriptorImpl() {
this(RepositoryTemplatedDeployment.class);
}
public DescriptorImpl(Class<? extends RepositoryTemplatedDeployment> clazz) {
super(clazz);
}
/**
* {@inheritDoc}
*/
@Override
public String getDisplayName() {
return Messages.RepositoryTemplatedMuranoDeployment_DisplayName();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isApplicable(Descriptor descriptor) {
return true;
}
}
public void readObjectModel(FilePath workspace) throws IOException {
String config = null;
try {
config = new FilePath(workspace, ".murano.yml").readToString();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
YAMLFactory factory = new YAMLFactory();
ObjectMapper mapper = new ObjectMapper(factory);
HashMap<String, Object> map = mapper.readValue(config, HashMap.class);
Object model = ((Map<String,Object>)((Map<String,Object>)map).get("environments")).get(this.environment);
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper mapperModel = new ObjectMapper(jsonFactory);
String string = mapperModel.writeValueAsString(model);
System.out.println(string);
this.setObjectModel(string);
}
}

View File

@ -0,0 +1,20 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy.model;
public class EnvironmentDescription {
private String modelFile = null;
public EnvironmentDescription() {
}
public EnvironmentDescription(String modelPath) {
this.modelFile = modelPath;
}
public String getModelFile() {
return modelFile;
}
public void setModelFile(String modelFile) {
this.modelFile = modelFile;
}
}

View File

@ -0,0 +1,28 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.HashMap;
import java.util.Map;
public class MuranoYaml {
@JsonProperty
private Map<String, EnvironmentDescription> environments = null;
public MuranoYaml() {
}
public MuranoYaml(Map<String, EnvironmentDescription> environments) {
this.environments = environments;
}
public Map<String, EnvironmentDescription> getEnvironments() {
return environments;
}
public void setEnvironments(HashMap<String, EnvironmentDescription> environments) {
this.environments = environments;
}
}

View File

@ -0,0 +1,45 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy.repository;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import hudson.FilePath;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.model.MuranoYaml;
import java.io.IOException;
/**
* Class for getting information from a CI-config.
*/
public class MuranoCiConfig {
/**
* The file in the repository that contains muranoci configuration.
*/
public static final String CI_CONFG_FILENAME = ".murano.yml";
private final MuranoYaml data;
public MuranoCiConfig(MuranoYaml data) {
this.data = data;
}
public MuranoYaml getData() {
return data;
}
public static MuranoCiConfig read(FilePath workspace) throws IOException {
String configYaml = null;
try {
configYaml = new FilePath(workspace, CI_CONFG_FILENAME).readToString();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
final YAMLFactory factory = new YAMLFactory();
ObjectMapper mapper = new ObjectMapper(factory);
MuranoYaml data = mapper.readValue(configYaml, MuranoYaml.class);
return new MuranoCiConfig(data);
}
}

View File

@ -0,0 +1,86 @@
package org.openstack.murano.jenkins_plugins.muranoci.deploy.repository;
import hudson.Extension;
import hudson.FilePath;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.AbstractMuranoDeploymentDescriptor;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.Messages;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.MuranoDeployment;
import org.openstack.murano.jenkins_plugins.muranoci.deploy.model.EnvironmentDescription;
import java.io.IOException;
public class RepositoryTemplatedDeployment extends MuranoDeployment {
/**
* An environment description name in a config
*/
private final String environment;
/**
* The specific Implemenation of <code>MuranoDeployment</code> that
* gets object model from the file within the repo.
*
* @param environment The name of the environment within the .murano.yml config
*/
@DataBoundConstructor
public RepositoryTemplatedDeployment(String environment) {
this.environment = environment;
}
public String getEnvironment() {
return environment;
}
/**
* Denotes that this is a cloud deployment plugin.
*/
@Extension
public static class DescriptorImpl extends AbstractMuranoDeploymentDescriptor {
public DescriptorImpl() {
this(RepositoryTemplatedDeployment.class);
}
public DescriptorImpl(Class<? extends RepositoryTemplatedDeployment> clazz) {
super(clazz);
}
/**
* {@inheritDoc}
*/
@Override
public String getDisplayName() {
return Messages.RepositoryTemplatedMuranoDeployment_DisplayName();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isApplicable(Descriptor descriptor) {
return true;
}
}
/**
* Read object model from a file pointed at current job param.
* The file should be placed at the repo and th3e repo should be
* fetched before this stage
*
* @param workspace working dir for a current Jenkins-job
* @throws IOException file reading error
* @throws InterruptedException file reading error
*/
public void readObjectModel(FilePath workspace) throws IOException, InterruptedException {
MuranoCiConfig config = MuranoCiConfig.read(workspace);
EnvironmentDescription description = config.getData().getEnvironments().get(this.environment);
String modelPath = description.getModelFile();
String objectModel = new FilePath(workspace, modelPath).readToString();
this.setObjectModel( objectModel);
}
}

View File

@ -0,0 +1,5 @@
<div>
<p>
<a href="http://docs.openstack.org/developer/murano/draft/appdev-guide/murano_pl.html#object-model">Object Model</a> for your environment
</p>
</div>

View File

@ -0,0 +1 @@
CertificateCredentialsImpl.DisplayName=Openstack Cloud

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
<f:entry title="Name" field="name">
<f:textbox/>
</f:entry>
<f:entry title="Description" field="description">
<f:textbox/>
</f:entry>
<f:entry title="${%Identity service endpoint}" field="identityServiceEndpoint">
<f:textbox/>
</f:entry>
<f:entry title="${%Tenant}" field="tenant">
<f:textbox/>
</f:entry>
<f:entry title="${%Username}" field="username">
<f:textbox/>
</f:entry>
<f:entry title="${%Password}" field="password">
<f:password/>
</f:entry>
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection" with="identityServiceEndpoint,tenant,username,password"/>
</j:jelly>

View File

@ -0,0 +1,8 @@
<div>
<p>
Keystone is an OpenStack service that provides API client authentication,
service discovery, and distributed multi-tenant authorization by
implementing OpenStacks Identity API.
<a href="http://docs.openstack.org/developer/keystone/"/>
</p>
</div>

View File

@ -0,0 +1,5 @@
<div>
<p>
Choose one from environments described in .murano.yml file at the root of your repository.
</p>
</div>