Skip to content

Commit

Permalink
Add XML Migration to support clusterProfileId attribute on profile tag (
Browse files Browse the repository at this point in the history
gocd#5538)

* Add clusterProfileId attribute on 'profile' tag
* Define a default clusterProfile under elastic/clusterProfiles
  • Loading branch information
GaneshSPatil committed Mar 13, 2019
1 parent 8cea20a commit 7a9918b
Show file tree
Hide file tree
Showing 19 changed files with 1,262 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public static void toJSON(OutputWriter outputWriter, ElasticProfile elasticProfi
public static ElasticProfile fromJSON(JsonReader jsonReader) {
ElasticProfile elasticProfile = new ElasticProfile(
jsonReader.getString("id"),
jsonReader.getString("plugin_id"));
jsonReader.getString("plugin_id"),
null);
elasticProfile.addConfigurations(ConfigurationPropertyRepresenter.fromJSONArray(jsonReader, "properties"));
return elasticProfile;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class GoConstants {

public static final String PRODUCT_NAME = "go";

public static final int CONFIG_SCHEMA_VERSION = 117;
public static final int CONFIG_SCHEMA_VERSION = 118;

public static final String APPROVAL_SUCCESS = "success";
public static final String APPROVAL_MANUAL = "manual";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ public void shouldNotMatchJobPlanIfJobRequiresElasticAgent_MatchingIsManagedByBu
agentConfig.setElasticPluginId(elasticPluginId);
AgentInstance agentInstance = new AgentInstance(agentConfig, REMOTE, mock(SystemEnvironment.class), null);
DefaultJobPlan jobPlan1 = new DefaultJobPlan();
jobPlan1.setElasticProfile(new ElasticProfile("foo", elasticPluginId));
jobPlan1.setElasticProfile(new ElasticProfile("foo", elasticPluginId, "prod-cluster"));
List<JobPlan> jobPlans = asList(jobPlan1, new DefaultJobPlan());

assertThat(agentInstance.firstMatching(jobPlans), is(nullValue()));
Expand All @@ -666,7 +666,7 @@ public void shouldNotMatchJobPlanIfTheAgentWasLaunchedByADifferentPluginFromThat
agentConfig.setElasticPluginId(elasticPluginId);
AgentInstance agentInstance = new AgentInstance(agentConfig, REMOTE, mock(SystemEnvironment.class), null);
DefaultJobPlan jobPlan1 = new DefaultJobPlan();
jobPlan1.setElasticProfile(new ElasticProfile("foo", "elastic-plugin-id-2"));
jobPlan1.setElasticProfile(new ElasticProfile("foo", "elastic-plugin-id-2", "prod-cluster"));
List<JobPlan> jobPlans = asList(jobPlan1, new DefaultJobPlan());

assertThat(agentInstance.firstMatching(jobPlans), is(nullValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,39 @@

package com.thoughtworks.go.config.elastic;

import com.thoughtworks.go.config.ConfigAttribute;
import com.thoughtworks.go.config.ConfigCollection;
import com.thoughtworks.go.config.ConfigTag;
import com.thoughtworks.go.config.PluginProfile;
import com.thoughtworks.go.domain.config.ConfigurationProperty;
import com.thoughtworks.go.plugin.access.elastic.ElasticAgentMetadataStore;
import com.thoughtworks.go.plugin.domain.elastic.ElasticAgentPluginInfo;
import org.apache.commons.lang3.StringUtils;

import java.util.Collection;

@ConfigTag("profile")
@ConfigCollection(value = ConfigurationProperty.class)
public class ElasticProfile extends PluginProfile {

@ConfigAttribute(value = "clusterProfileId", allowNull = false)
protected String clusterProfileId;

public ElasticProfile() {
super();
}

public ElasticProfile(String id, String pluginId, ConfigurationProperty... props) {
public ElasticProfile(String id, String pluginId, String clusterProfileId, ConfigurationProperty... props) {
super(id, pluginId, props);
this.clusterProfileId = StringUtils.isBlank(clusterProfileId) ? "default" : clusterProfileId;
}

public ElasticProfile(String id, String pluginId, String clusterProfileId, Collection<ConfigurationProperty> configProperties) {
this(id, pluginId, clusterProfileId, configProperties.toArray(new ConfigurationProperty[0]));
}

public ElasticProfile(String id, String pluginId, Collection<ConfigurationProperty> configProperties) {
this(id, pluginId, configProperties.toArray(new ConfigurationProperty[0]));
public String getClusterProfileId() {
return clusterProfileId;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public void shouldCheckForExistenceOfPackage() throws Exception {
public void isValidProfileIdShouldBeValidInPresenceOfElasticProfile() {
BasicCruiseConfig cruiseConfig = new BasicCruiseConfig();
ElasticConfig elasticConfig = new ElasticConfig();
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker")));
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker", "prod-cluster")));
cruiseConfig.setElasticConfig(elasticConfig);
ValidationContext context = ConfigSaveValidationContext.forChain(cruiseConfig);

Expand All @@ -153,7 +153,7 @@ public void isValidProfileIdShouldBeValidInPresenceOfElasticProfile() {
public void isValidProfileIdShouldBeInValidInAbsenceOfElasticProfileForTheGivenId() {
BasicCruiseConfig cruiseConfig = new BasicCruiseConfig();
ElasticConfig elasticConfig = new ElasticConfig();
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker")));
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker", "prod-cluster")));
cruiseConfig.setElasticConfig(elasticConfig);
ValidationContext context = ConfigSaveValidationContext.forChain(cruiseConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public void shouldCheckForExistenceOfPackage() throws Exception {
public void isValidProfileIdShouldBeValidInPresenceOfElasticProfile() {
BasicCruiseConfig cruiseConfig = new BasicCruiseConfig();
ElasticConfig elasticConfig = new ElasticConfig();
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker")));
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker", "prod-cluster")));
cruiseConfig.setElasticConfig(elasticConfig);
ValidationContext context = PipelineConfigSaveValidationContext.forChain(true, "group", cruiseConfig, new PipelineConfig());

Expand All @@ -205,7 +205,7 @@ public void isValidProfileIdShouldBeValidInPresenceOfElasticProfile() {
public void isValidProfileIdShouldBeInValidInAbsenceOfElasticProfileForTheGivenId() {
BasicCruiseConfig cruiseConfig = new BasicCruiseConfig();
ElasticConfig elasticConfig = new ElasticConfig();
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker")));
elasticConfig.setProfiles(new ElasticProfiles(new ElasticProfile("docker.unit-test", "docker", "prod-cluster")));
cruiseConfig.setElasticConfig(elasticConfig);
ValidationContext context = PipelineConfigSaveValidationContext.forChain(true, "group", cruiseConfig, new PipelineConfig());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void shouldNotAllowNullPluginIdOrProfileId() throws Exception {

@Test
public void shouldValidateElasticPluginIdPattern() throws Exception {
ElasticProfile profile = new ElasticProfile("!123", "docker");
ElasticProfile profile = new ElasticProfile("!123", "docker", "prod-cluster");
profile.validate(null);
assertThat(profile.errors().size(), is(1));
assertThat(profile.errors().on(ElasticProfile.ID), is("Invalid id '!123'. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters."));
Expand All @@ -68,7 +68,7 @@ public void shouldValidateElasticPluginIdPattern() throws Exception {
public void shouldValidateConfigPropertyNameUniqueness() throws Exception {
ConfigurationProperty prop1 = ConfigurationPropertyMother.create("USERNAME");
ConfigurationProperty prop2 = ConfigurationPropertyMother.create("USERNAME");
ElasticProfile profile = new ElasticProfile("docker.unit-test", "cd.go.elastic-agent.docker", prop1, prop2);
ElasticProfile profile = new ElasticProfile("docker.unit-test", "cd.go.elastic-agent.docker", "prod-cluster", prop1, prop2);

profile.validate(null);

Expand All @@ -85,7 +85,7 @@ public void shouldValidateConfigPropertyNameUniqueness() throws Exception {
public void addConfigurations_shouldAddConfigurationsWithValue() throws Exception {
ConfigurationProperty property = new ConfigurationProperty(new ConfigurationKey("username"), new ConfigurationValue("some_name"));

ElasticProfile profile = new ElasticProfile("id", "plugin_id");
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster");
profile.addConfigurations(Arrays.asList(property));

assertThat(profile.size(), is(1));
Expand All @@ -96,7 +96,7 @@ public void addConfigurations_shouldAddConfigurationsWithValue() throws Exceptio
public void addConfigurations_shouldAddConfigurationsWithEncryptedValue() throws Exception {
ConfigurationProperty property = new ConfigurationProperty(new ConfigurationKey("username"), new EncryptedConfigurationValue("some_name"));

ElasticProfile profile = new ElasticProfile("id", "plugin_id");
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster");
profile.addConfigurations(Arrays.asList(property));

assertThat(profile.size(), is(1));
Expand All @@ -109,7 +109,7 @@ public void addConfiguration_shouldEncryptASecureVariable() throws Exception {
ElasticAgentPluginInfo pluginInfo = new ElasticAgentPluginInfo(pluginDescriptor("plugin_id"), profileSettings, null, null, null);

store.setPluginInfo(pluginInfo);
ElasticProfile profile = new ElasticProfile("id", "plugin_id");
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster");
profile.addConfigurations(Arrays.asList(new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass"))));

assertThat(profile.size(), is(1));
Expand All @@ -121,7 +121,7 @@ public void addConfiguration_shouldIgnoreEncryptionInAbsenceOfCorrespondingConfi
ElasticAgentPluginInfo pluginInfo = new ElasticAgentPluginInfo(pluginDescriptor("plugin_id"), new PluggableInstanceSettings(new ArrayList<>()), null, null, null);

store.setPluginInfo(pluginInfo);
ElasticProfile profile = new ElasticProfile("id", "plugin_id");
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster");
profile.addConfigurations(Arrays.asList(new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass"))));

assertThat(profile.size(), is(1));
Expand All @@ -135,7 +135,7 @@ public void postConstruct_shouldEncryptSecureConfigurations() {
ElasticAgentPluginInfo pluginInfo = new ElasticAgentPluginInfo(pluginDescriptor("plugin_id"), profileSettings, null, null, null);

store.setPluginInfo(pluginInfo);
ElasticProfile profile = new ElasticProfile("id", "plugin_id", new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass")));
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster", new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass")));

profile.encryptSecureConfigurations();

Expand All @@ -145,7 +145,7 @@ public void postConstruct_shouldEncryptSecureConfigurations() {

@Test
public void postConstruct_shouldIgnoreEncryptionIfPluginInfoIsNotDefined() {
ElasticProfile profile = new ElasticProfile("id", "plugin_id", new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass")));
ElasticProfile profile = new ElasticProfile("id", "plugin_id", "prod-cluster", new ConfigurationProperty(new ConfigurationKey("password"), new ConfigurationValue("pass")));

profile.encryptSecureConfigurations();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ public class ElasticProfilesTest {
@Test
public void shouldFindProfileById() throws Exception {
assertThat(new ElasticProfiles().find("foo"), is(nullValue()));
ElasticProfile profile = new ElasticProfile("foo", "docker");
ElasticProfile profile = new ElasticProfile("foo", "docker", "prod-cluster");
assertThat(new ElasticProfiles(profile).find("foo"), is(profile));
}

@Test
public void shouldNotAllowMultipleProfilesWithSameId() throws Exception {
ElasticProfile profile1 = new ElasticProfile("foo", null);
ElasticProfile profile2 = new ElasticProfile("foo", null);
ElasticProfile profile1 = new ElasticProfile("foo", null, "prod-cluster");
ElasticProfile profile2 = new ElasticProfile("foo", null, "prod-cluster");
ElasticProfiles profiles = new ElasticProfiles(profile1, profile2);
profiles.validate(null);

Expand Down
16 changes: 12 additions & 4 deletions config/config-server/src/main/resources/cruise-config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
</xsd:unique>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="schemaVersion" type="xsd:int" use="required" fixed="117"/>
<xsd:attribute name="schemaVersion" type="xsd:int" use="required" fixed="118"/>
</xsd:complexType>
<xsd:unique name="uniquePipelines">
<xsd:selector xpath="pipelines"/>
Expand Down Expand Up @@ -310,7 +310,7 @@
<xsd:attribute name="emailOnFailure" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="elasticConfigType">
<xsd:sequence>
<xsd:all>
<xsd:element name="clusterProfiles" type="elasticAgentClusterProfilesType" minOccurs="0" maxOccurs="1">
<xsd:unique name="uniqueClusterProfileId">
<xsd:selector xpath="clusterProfile"/>
Expand All @@ -325,12 +325,12 @@
<!-- Unique profile id -->
</xsd:unique>
</xsd:element>
</xsd:sequence>
</xsd:all>
<xsd:attribute name="jobStarvationTimeout" type="xsd:long"/>
</xsd:complexType>
<xsd:complexType name="elasticAgentProfilesType">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="profile" type="pluginProfile"/>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="profile" type="elasticAgentProfile"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="elasticAgentClusterProfilesType">
Expand All @@ -348,6 +348,14 @@
<xsd:element minOccurs="0" maxOccurs="unbounded" name="authConfig" type="pluginProfile"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="elasticAgentProfile">
<xsd:sequence>
<xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="pluginPropertyType"/>
</xsd:sequence>
<xsd:attribute type="nameType" name="clusterProfileId" use="required"/>
<xsd:attribute type="nameType" name="pluginId" use="required"/>
<xsd:attribute type="nameType" name="id" use="required"/>
</xsd:complexType>
<xsd:complexType name="pluginProfile">
<xsd:sequence>
<xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="pluginPropertyType"/>
Expand Down
Loading

0 comments on commit 7a9918b

Please sign in to comment.