/* * Copyright 2017 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.thoughtworks.go.util; import com.rits.cloning.Cloner; import com.thoughtworks.go.config.*; import com.thoughtworks.go.config.exceptions.NoSuchEnvironmentException; import com.thoughtworks.go.config.materials.Filter; import com.thoughtworks.go.config.materials.MaterialConfigs; import com.thoughtworks.go.config.materials.PackageMaterialConfig; import com.thoughtworks.go.config.materials.svn.SvnMaterialConfig; import com.thoughtworks.go.config.registry.ConfigElementImplementationRegistry; import com.thoughtworks.go.config.remote.ConfigRepoConfig; import com.thoughtworks.go.config.remote.ConfigReposConfig; import com.thoughtworks.go.config.server.security.ldap.BaseConfig; import com.thoughtworks.go.config.server.security.ldap.BasesConfig; import com.thoughtworks.go.domain.ServerSiteUrlConfig; import com.thoughtworks.go.domain.config.Admin; import com.thoughtworks.go.domain.materials.MaterialConfig; import com.thoughtworks.go.domain.materials.svn.Subversion; import com.thoughtworks.go.domain.materials.svn.SvnCommand; import com.thoughtworks.go.domain.packagerepository.PackageRepository; import com.thoughtworks.go.domain.scm.SCM; import com.thoughtworks.go.helper.*; import com.thoughtworks.go.security.GoCipher; import com.thoughtworks.go.server.util.ServerVersion; import com.thoughtworks.go.serverhealth.ServerHealthService; import com.thoughtworks.go.service.ConfigRepository; import org.apache.commons.io.FileUtils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.util.List; import static com.thoughtworks.go.config.PipelineConfigs.DEFAULT_GROUP; import static com.thoughtworks.go.util.ExceptionUtils.bomb; /** * @understands how to edit the cruise config file for testing */ public class GoConfigFileHelper { private final File configFile; private final String originalXml; public GoConfigMother goConfigMother = new GoConfigMother(); private File passwordFile = null; private GoConfigDao goConfigDao; private CachedGoConfig cachedGoConfig; private SystemEnvironment sysEnv; private String originalConfigDir; public GoConfigFileHelper() { this(ConfigFileFixture.DEFAULT_XML_WITH_2_AGENTS); } public GoConfigFileHelper(GoPartialConfig partials) { this(ConfigFileFixture.DEFAULT_XML_WITH_2_AGENTS,partials); } public GoConfigFileHelper(GoConfigDao goConfigDao) { this(ConfigFileFixture.DEFAULT_XML_WITH_2_AGENTS, goConfigDao); } private GoConfigFileHelper(String xml, GoConfigDao goConfigDao) { new SystemEnvironment().setProperty(SystemEnvironment.ENFORCE_SERVERID_MUTABILITY, "N"); this.originalXml = xml; assignFileDao(goConfigDao); try { File dir = TestFileUtil.createTempFolder("server-config-dir"); this.configFile = new File(dir, "cruise-config.xml"); configFile.deleteOnExit(); sysEnv = new SystemEnvironment(); sysEnv.setProperty(SystemEnvironment.CONFIG_FILE_PROPERTY, configFile.getAbsolutePath()); initializeConfigFile(); } catch (IOException e) { throw bomb("Error creating config file", e); } } private void assignFileDao(GoConfigDao goConfigDao) { this.goConfigDao = goConfigDao; try { Field field = GoConfigDao.class.getDeclaredField("cachedConfigService"); field.setAccessible(true); this.cachedGoConfig = (CachedGoConfig) field.get(goConfigDao); } catch (Exception e) { bomb(e); } } /** * Creates config dao that accesses single file */ public static GoConfigDao createTestingDao() { SystemEnvironment systemEnvironment = new SystemEnvironment(); try { ServerHealthService serverHealthService = new ServerHealthService(); ConfigRepository configRepository = new ConfigRepository(systemEnvironment); configRepository.initialize(); ConfigCache configCache = new ConfigCache(); ConfigElementImplementationRegistry configElementImplementationRegistry = ConfigElementImplementationRegistryMother.withNoPlugins(); CachedGoPartials cachedGoPartials = new CachedGoPartials(serverHealthService); FullConfigSaveNormalFlow normalFlow = new FullConfigSaveNormalFlow(configCache, configElementImplementationRegistry, systemEnvironment, new ServerVersion(), new TimeProvider(), configRepository, cachedGoPartials); GoFileConfigDataSource dataSource = new GoFileConfigDataSource(new DoNotUpgrade(), configRepository, systemEnvironment, new TimeProvider(), configCache, new ServerVersion(), configElementImplementationRegistry, serverHealthService, cachedGoPartials, null, normalFlow); dataSource.upgradeIfNecessary(); CachedGoConfig cachedConfigService = new CachedGoConfig(serverHealthService, dataSource, cachedGoPartials, null, null); cachedConfigService.loadConfigIfNull(); return new GoConfigDao(cachedConfigService); } catch (IOException e) { throw new RuntimeException(e); } } /** * Creates config dao that has custom remote configuration parts provided by partialConfig argument */ public static GoConfigDao createTestingDao(GoPartialConfig partialConfig) { SystemEnvironment systemEnvironment = new SystemEnvironment(); try { ServerHealthService serverHealthService = new ServerHealthService(); ConfigRepository configRepository = new ConfigRepository(systemEnvironment); configRepository.initialize(); FullConfigSaveNormalFlow normalFlow = new FullConfigSaveNormalFlow(new ConfigCache(), com.thoughtworks.go.util.ConfigElementImplementationRegistryMother.withNoPlugins(), systemEnvironment, new ServerVersion(), new TimeProvider(), configRepository, new CachedGoPartials(serverHealthService)); GoFileConfigDataSource dataSource = new GoFileConfigDataSource(new DoNotUpgrade(), configRepository, systemEnvironment, new TimeProvider(), new ConfigCache(), new ServerVersion(), com.thoughtworks.go.util.ConfigElementImplementationRegistryMother.withNoPlugins(), serverHealthService, new CachedGoPartials(serverHealthService), null, normalFlow); dataSource.upgradeIfNecessary(); CachedGoPartials cachedGoPartials = new CachedGoPartials(serverHealthService); CachedGoConfig cachedConfigService = new CachedGoConfig(serverHealthService, dataSource, cachedGoPartials, null, null); cachedConfigService.loadConfigIfNull(); return new GoConfigDao(cachedConfigService); } catch (IOException e) { throw new RuntimeException(e); } } public GoConfigFileHelper(File configFile) { assignFileDao(createTestingDao()); this.configFile = configFile.getAbsoluteFile(); ConfigMigrator.migrate(this.configFile); try { this.originalXml = FileUtils.readFileToString(this.configFile, "UTF-8"); } catch (IOException e) { throw bomb("Error reading config file", e); } new SystemEnvironment().setProperty(SystemEnvironment.CONFIG_FILE_PROPERTY, this.configFile.getAbsolutePath()); } public GoConfigFileHelper(String xml) { this(xml, createTestingDao()); } public GoConfigFileHelper(String xml,GoPartialConfig partials) { this(xml, createTestingDao(partials)); } public GoConfigDao getGoConfigDao() { return goConfigDao; } public CachedGoConfig getCachedGoConfig() { return cachedGoConfig; } public void setArtifactsDir(String artifactsDir) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.server().setArtifactsDir(artifactsDir); writeConfigFile(cruiseConfig); } public GoConfigFileHelper usingCruiseConfigDao(GoConfigDao goConfigDao) { assignFileDao(goConfigDao); return this; } public void usingEmptyConfigFileWithLicenseAllowsTwoAgents() { writeToFileAndDB(ConfigFileFixture.DEFAULT_XML_WITH_2_AGENTS); } private void writeToFileAndDB(String configContent) { writeXmlToConfigFile(loadAndMigrate(configContent)); writeConfigFile(load()); } public static GoConfigFileHelper usingEmptyConfigFileWithLicenseAllowsUnlimitedAgents() { return new GoConfigFileHelper(ConfigFileFixture.DEFAULT_XML_WITH_UNLIMITED_AGENTS); } public void writeXmlToConfigFile(String xml) { try { FileUtils.writeStringToFile(configFile, xml); goConfigDao.forceReload(); } catch (Exception e) { throw bomb("Error writing config file: " + configFile.getAbsolutePath(), e); } } public void onSetUp() throws IOException { initializeConfigFile(); goConfigDao.forceReload(); writeConfigFile(load()); originalConfigDir = sysEnv.getConfigDir(); File configDir = configFile.getParentFile(); sysEnv.setProperty(SystemEnvironment.CONFIG_DIR_PROPERTY, configDir.getAbsolutePath()); } public void initializeConfigFile() throws IOException { FileUtils.deleteQuietly(passwordFile); writeXmlToConfigFile(ConfigMigrator.migrate(originalXml)); } public void onTearDown() { sysEnv.setProperty(SystemEnvironment.CONFIG_DIR_PROPERTY, originalConfigDir); FileUtils.deleteQuietly(configFile); try { cachedGoConfig.save(originalXml, true); } catch (Exception e) { throw new RuntimeException(e); } } public PipelineConfig addPipeline(String pipelineName, String stageName) { return addPipeline(pipelineName, stageName, "unit", "functional"); } public PipelineConfig addPipeline(String pipelineName, String stageName, Subversion repository) { return addPipeline(pipelineName, stageName, repository, "unit", "functional"); } public PipelineConfig addPipeline(String pipelineName, String stageName, String... buildNames) { return addPipelineWithGroup(BasicPipelineConfigs.DEFAULT_GROUP, pipelineName, stageName, buildNames); } public PipelineTemplateConfig addTemplate(String pipelineName, String stageName) { return addTemplate(pipelineName, new Authorization(), stageName); } public PipelineTemplateConfig addTemplate(String pipelineName, Authorization authorization, String stageName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineTemplateConfig templateConfig = PipelineTemplateConfigMother.createTemplate(pipelineName, authorization, StageConfigMother.manualStage(stageName)); cruiseConfig.getTemplates().add(templateConfig); writeConfigFile(cruiseConfig); return templateConfig; } public PipelineConfig addPipelineWithGroup(String groupName, String pipelineName, String stageName, String... buildNames) { return addPipelineWithGroup(groupName, pipelineName, new SvnCommand(null, "svn:///user:pass@tmp/foo"), stageName, buildNames); } public PipelineConfig addPipelineWithTemplate(String groupName, String pipelineName, String templateName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = new PipelineConfig(new CaseInsensitiveString(pipelineName), MaterialConfigsMother.mockMaterialConfigs("svn:///user:pass@tmp/foo")); pipelineConfig.setTemplateName(new CaseInsensitiveString(templateName)); cruiseConfig.findGroup(groupName).add(pipelineConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipelineWithGroup(String groupName, String pipelineName, SvnCommand svnCommand, String stageName, String... buildNames) { return addPipelineWithGroupAndTimer(groupName, pipelineName, new MaterialConfigs(MaterialConfigsMother.mockMaterialConfigs(svnCommand.getUrlForDisplay())), stageName, null, buildNames); } public PipelineConfig addPipelineWithGroup(String groupName, String pipelineName, MaterialConfigs materialConfigs, String stageName, String... buildNames) { return addPipelineWithGroupAndTimer(groupName, pipelineName, materialConfigs, stageName, null, buildNames); } public PipelineConfig addPipelineWithGroupAndTimer(String groupName, String pipelineName, MaterialConfigs materialConfigs, String stageName, TimerConfig timer, String... buildNames) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipelineWithGroupAndTimer(cruiseConfig, groupName, pipelineName, materialConfigs, stageName, timer, buildNames); writeConfigFile(cruiseConfig); return pipelineConfig; } public void addSecurityAuthConfig(SecurityAuthConfig securityAuthConfig) { CruiseConfig config = loadForEdit(); config.server().security().securityAuthConfigs().add(securityAuthConfig); writeConfigFile(config); } public interface Updater<T>{ void update(T t); } public PipelineConfig updatePipeline(CaseInsensitiveString pipelineName, Updater<PipelineConfig> updater) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.getPipelineConfigByName(pipelineName); updater.update(pipelineConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipeline(PipelineConfig pipelineConfig) { return addPipelineToGroup(pipelineConfig, "quux-group"); } public PipelineConfig addPipelineToGroup(PipelineConfig pipelineConfig, final String groupName) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.addPipeline(groupName, pipelineConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipelineWithGroup(String groupName, String pipelineName, MaterialConfigs materialConfigs, MingleConfig mingleConfig, String stageName, String... buildNames) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipelineWithGroup(cruiseConfig, groupName, pipelineName, materialConfigs, stageName, buildNames); pipelineConfig.setMingleConfig(mingleConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipelineWithGroup(String groupName, String pipelineName, MaterialConfigs materialConfigs, TrackingTool trackingTool, String stageName, String... jobs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipelineWithGroup(cruiseConfig, groupName, pipelineName, materialConfigs, stageName, jobs); pipelineConfig.setTrackingTool(trackingTool); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipeline(String pipelineName, String stageName, Subversion repository, String... buildNames) { return addPipeline(pipelineName, stageName, new SvnMaterialConfig(repository.getUrl().forCommandline(), repository.getUserName(), repository.getPassword(), repository.isCheckExternals()), buildNames); } public void updateArtifactRoot(String path) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.server().updateArtifactRoot(path); writeConfigFile(cruiseConfig); } public PipelineConfig addPipeline(String pipelineName, String stageName, Subversion repository, Filter filter, String... buildNames) throws Exception { return addPipeline(pipelineName, stageName, new SvnMaterialConfig(repository.getUrl().forCommandline(), repository.getUserName(), repository.getPassword(), repository.isCheckExternals()), filter, buildNames); } private PipelineConfig addPipeline(String pipelineName, String stageName, SvnMaterialConfig svnMaterialConfig, Filter filter, String... buildNames) throws Exception { svnMaterialConfig.setFilter(filter); return addPipeline(pipelineName, stageName, svnMaterialConfig, buildNames); } public PipelineConfig addPipeline(String pipelineName, String stageName, MaterialConfig materialConfig, String... buildNames) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, pipelineName, stageName, new MaterialConfigs(materialConfig), buildNames); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipeline(String pipelineName, String stageName, MaterialConfig materialConfig, MingleConfig mingleConfig, String... jobs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, pipelineName, stageName, new MaterialConfigs(materialConfig), jobs); pipelineConfig.setMingleConfig(mingleConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipeline(String pipelineName, String stageName, MaterialConfig materialConfig, TrackingTool trackingTool, String... jobs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, pipelineName, stageName, new MaterialConfigs(materialConfig), jobs); pipelineConfig.setTrackingTool(trackingTool); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addPipeline(String pipelineName, String stageName, MaterialConfigs materialConfigs, String... buildNames) throws Exception { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addPipeline(cruiseConfig, pipelineName, stageName, materialConfigs, buildNames); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addStageToPipeline(String pipelineName, String stageName) throws Exception { return addStageToPipeline(pipelineName, stageName, "unit"); } public PipelineConfig addStageToPipeline(String pipelineName, String stageName, String... buildNames) throws Exception { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addStageToPipeline(cruiseConfig, pipelineName, stageName, buildNames); writeConfigFile(cruiseConfig); return pipelineConfig; } public PipelineConfig addStageToPipeline(String pipelineName, StageConfig stageConfig) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.add(stageConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public void addEnvironmentVariableToPipeline(String pipelineName, EnvironmentVariablesConfig envVars) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.setVariables(envVars); writeConfigFile(cruiseConfig); } public void addEnvironmentVariableToStage(String pipelineName, String stageName, EnvironmentVariablesConfig envVars) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stageConfig = pipelineConfig.findBy(new CaseInsensitiveString(stageName)); stageConfig.setVariables(envVars); writeConfigFile(cruiseConfig); } public void addEnvironmentVariableToJob(String pipelineName, String stageName, String jobName, EnvironmentVariablesConfig envVars) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stageConfig = pipelineConfig.findBy(new CaseInsensitiveString(stageName)); JobConfig jobConfig = stageConfig.jobConfigByConfigName(new CaseInsensitiveString(jobName)); jobConfig.setVariables(envVars); writeConfigFile(cruiseConfig); } public PipelineConfig addStageToPipeline(String pipelineName, String stageName, int stageindex, String... buildNames) throws Exception { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = goConfigMother.addStageToPipeline( cruiseConfig, pipelineName, stageName, stageindex, buildNames); writeConfigFile(cruiseConfig); return pipelineConfig; } public StageConfig removeStage(String pipelineName, String stageName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stageConfig = pipelineConfig.findBy(new CaseInsensitiveString(stageName)); pipelineConfig.remove(stageConfig); writeConfigFile(cruiseConfig); return stageConfig; } public void removePipeline(String pipelineName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfigs groups = removePipeline(pipelineName, cruiseConfig); if (groups.isEmpty()) { cruiseConfig.getGroups().remove(groups); } writeConfigFile(cruiseConfig); } public PipelineConfigs removePipeline(String pipelineName, CruiseConfig cruiseConfig) { String groupName = cruiseConfig.getGroups().findGroupNameByPipeline(new CaseInsensitiveString(pipelineName)); PipelineConfigs groups = cruiseConfig.getGroups().findGroup(groupName); groups.remove(cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName))); return groups; } public StageConfig addJob(String pipelineName, String stageName, String jobName) { JobConfig jobConfig = new JobConfig(new CaseInsensitiveString(jobName), new Resources(), new ArtifactPlans()); return addJobToStage(pipelineName, stageName, jobConfig); } public StageConfig addJobToStage(String pipelineName, String stageName, JobConfig jobConfig) { return pushJobIntoStage(pipelineName, stageName, jobConfig, false); } public void replaceAllJobsInStage(String pipelineName, String stageName, JobConfig jobConfig) { pushJobIntoStage(pipelineName, stageName, jobConfig, true); } private StageConfig pushJobIntoStage(String pipelineName, String stageName, JobConfig jobConfig, boolean clearExistingJobs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stageConfig = pipelineConfig.findBy(new CaseInsensitiveString(stageName)); if (clearExistingJobs) { stageConfig.allBuildPlans().clear(); } stageConfig.allBuildPlans().add(jobConfig); writeConfigFile(cruiseConfig); return stageConfig; } public PipelineConfig addPipelineWithInvalidMaterial(String pipelineName, String stageName) { CruiseConfig cruiseConfig = loadForEdit(); StageConfig stageConfig = StageConfigMother.custom(stageName, defaultBuildPlans("buildName")); PipelineConfig pipelineConfig = new PipelineConfig(new CaseInsensitiveString(pipelineName), invalidRepositoryMaterialConfigs(), stageConfig); cruiseConfig.addPipeline(DEFAULT_GROUP, pipelineConfig); writeConfigFile(cruiseConfig); return pipelineConfig; } public File getConfigFile() { return configFile; } private MaterialConfig invalidSvnMaterialConfig() { return new SvnMaterialConfig("invalid://invalid url", "user", "password", false); } private MaterialConfigs invalidRepositoryMaterialConfigs() { return new MaterialConfigs(invalidSvnMaterialConfig()); } private static JobConfigs defaultBuildPlans(String... planNames) { JobConfigs plans = new JobConfigs(); for (String name : planNames) { plans.add(defaultBuildPlan(name)); } return plans; } private static JobConfig defaultBuildPlan(String name) { return new JobConfig(new CaseInsensitiveString(name), new Resources(), new ArtifactPlans()); } public CruiseConfig load() { try { goConfigDao.forceReload(); return new Cloner().deepClone(goConfigDao.loadForEditing()); } catch (Exception e) { throw new RuntimeException(e); } } public CruiseConfig loadForEdit() { try { goConfigDao.forceReload(); return new Cloner().deepClone(goConfigDao.loadForEditing()); } catch (Exception e) { throw new RuntimeException(e); } } public CruiseConfig currentConfig() { return load(); } public void addConfigRepo(ConfigRepoConfig configRepoConfig) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.getConfigRepos().add(configRepoConfig); writeConfigFile(cruiseConfig); } public void setConfigRepos(ConfigReposConfig configRepos) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.setConfigRepos(configRepos); writeConfigFile(cruiseConfig); } public void addAgent(String hostname, String uuid) { addAgent(new AgentConfig(uuid, hostname, "127.0.0.1")); } public void addAgent(AgentConfig newAgentConfig) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.agents().add(newAgentConfig); writeConfigFile(cruiseConfig); } public void makeJobRunOnAllAgents(String pipeline, String stageName, String jobName) { CruiseConfig cruiseConfig = currentConfig(); cruiseConfig.jobConfigByName(pipeline, stageName, jobName, true).setRunOnAllAgents(true); writeConfigFile(cruiseConfig); } public void addSecurity(SecurityConfig securityConfig) { CruiseConfig config = loadForEdit(); config.server().useSecurity(securityConfig); writeConfigFile(config); } public void turnOffSecurity() { addSecurity(new SecurityConfig()); } public void addLdapSecurity(String uri, String managerDn, String managerPassword, String searchBase, String searchFilter) { LdapConfig ldapConfig = new LdapConfig(uri, managerDn, managerPassword, null, true, new BasesConfig(new BaseConfig(searchBase)), searchFilter); addLdapSecurityWith(ldapConfig, true, new PasswordFileConfig(), new AdminsConfig()); } public void addLdapSecurityWithAdmin(String uri, String managerDn, String managerPassword, String searchBase, String searchFilter, String adminUser) { LdapConfig ldapConfig = new LdapConfig(uri, managerDn, managerPassword, null, true, new BasesConfig(new BaseConfig(searchBase)), searchFilter); addLdapSecurityWith(ldapConfig, true, new PasswordFileConfig(), new AdminsConfig(new AdminUser(new CaseInsensitiveString(adminUser)))); } public void addLdapSecurityWith(LdapConfig ldapConfig, boolean anonymous, PasswordFileConfig passwordFileConfig, AdminsConfig adminsConfig) { SecurityConfig securityConfig = new SecurityConfig(ldapConfig, passwordFileConfig, anonymous, adminsConfig); addSecurity(securityConfig); } public void addSecurityWithBogusLdapConfig(boolean anonymous) { addLdapSecurityWith(new LdapConfig("uri", "dn", "pw", null, true, new BasesConfig(new BaseConfig("sb")), "sf"), anonymous, new PasswordFileConfig(), new AdminsConfig()); } public File addSecurityWithPasswordFile() throws IOException { addLdapSecurityWith(new LdapConfig(new GoCipher()), true, new PasswordFileConfig(addPasswordFile().getAbsolutePath()), new AdminsConfig()); return passwordFile; } public File turnOnSecurity() throws IOException { return addSecurityWithPasswordFile(); } public void addSecurityWithNonExistantPasswordFile() throws IOException { addLdapSecurityWith(new LdapConfig(new GoCipher()), true, new PasswordFileConfig(new File("invalid", "path").getAbsolutePath()), new AdminsConfig()); } public void addSecurityWithAdminConfig() throws Exception { addLdapSecurityWith(new LdapConfig(new GoCipher()), true, new PasswordFileConfig(addPasswordFile().getAbsolutePath()), new AdminsConfig(new AdminUser(new CaseInsensitiveString("admin1")))); } private File addPasswordFile() throws IOException { passwordFile = TestFileUtil.createTempFile("password.properties"); passwordFile.deleteOnExit(); final String nonAdmin = "jez=ThmbShxAtJepX80c2JY1FzOEmUk=\n"; //in plain text: badger final String admin1 = "admin1=W6ph5Mm5Pz8GgiULbPgzG37mj9g=\n"; //in plain text: password FileUtils.writeStringToFile(passwordFile, nonAdmin + admin1); return passwordFile; } public void addMailHost(MailHost mailHost) { CruiseConfig config = loadForEdit(); config.server().updateMailHost(mailHost); writeConfigFile(config); } public void addRole(Role role) { CruiseConfig config = loadForEdit(); config.server().security().addRole(role); writeConfigFile(config); } public void replaceMaterialWithHgRepoForPipeline(String pipelinename, String hgUrl) { replaceMaterialForPipeline(pipelinename, MaterialConfigsMother.hgMaterialConfig(hgUrl)); } public PipelineConfig replaceMaterialForPipeline(String pipelinename, MaterialConfig materialConfig) { return replaceMaterialConfigForPipeline(pipelinename, new MaterialConfigs(materialConfig)); } public PipelineConfig replaceMaterialConfigForPipeline(String pipelinename, MaterialConfig materialConfig) { return replaceMaterialConfigForPipeline(pipelinename, new MaterialConfigs(materialConfig)); } public PipelineConfig setMaterialConfigForPipeline(String pipelinename, MaterialConfig... materialConfigs) { return addMaterialConfigForPipeline(pipelinename, materialConfigs); } private PipelineConfig addMaterialConfigForPipeline(String pipelinename, MaterialConfig... materialConfigs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelinename)); pipelineConfig.setMaterialConfigs(new MaterialConfigs(materialConfigs)); writeConfigFile(cruiseConfig); return pipelineConfig; } private PipelineConfig replaceMaterialConfigForPipeline(String pipelinename, MaterialConfigs materialConfigs) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelinename)); pipelineConfig.setMaterialConfigs(materialConfigs); writeConfigFile(cruiseConfig); return pipelineConfig; } public void requireApproval(String pipelineName, String stageName) { CruiseConfig cruiseConfig = loadForEdit(); cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)).findBy(new CaseInsensitiveString(stageName)).updateApproval(Approval.manualApproval()); writeConfigFile(cruiseConfig); } public void setDependencyOn(PipelineConfig product, String pipelineName, String stageName) { CruiseConfig cruiseConfig = loadForEdit(); goConfigMother.setDependencyOn(cruiseConfig, product, pipelineName, stageName); writeConfigFile(cruiseConfig); } public void writeConfigFile(CruiseConfig cruiseConfig) { try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); getXml(cruiseConfig, buffer); cachedGoConfig.save(new String(buffer.toByteArray()), false); } catch (Exception e) { throw bomb(e); } } public void getXml(CruiseConfig cruiseConfig, ByteArrayOutputStream buffer) throws Exception { new MagicalGoConfigXmlWriter(new ConfigCache(), com.thoughtworks.go.util.ConfigElementImplementationRegistryMother.withNoPlugins()).write(cruiseConfig, buffer, false); } public void configureStageAsAutoApproval(String pipelineName, String stage) { updateApproval(pipelineName, stage, Approval.automaticApproval()); } public void configureStageAsManualApproval(String pipelineName, String stage) { updateApproval(pipelineName, stage, Approval.manualApproval()); } public void addAuthorizedUserForStage(String pipelineName, String stageName, String... users) { configureStageAsManualApproval(pipelineName, stageName); CruiseConfig cruiseConfig = loadForEdit(); StageConfig stageConfig = cruiseConfig.stageConfigByName(new CaseInsensitiveString(pipelineName), new CaseInsensitiveString(stageName)); Approval approval = stageConfig.getApproval(); for (String user : users) { approval.getAuthConfig().add(new AdminUser(new CaseInsensitiveString(user))); } writeConfigFile(cruiseConfig); } public void addAuthorizedUserForPipelineGroup(String user) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfigs group = cruiseConfig.getGroups().first(); group.getAuthorization().getViewConfig().add(new AdminUser(new CaseInsensitiveString(user))); writeConfigFile(cruiseConfig); } public void addAuthorizedUserForPipelineGroup(String user, String groupName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfigs group = cruiseConfig.getGroups().findGroup(groupName); group.getAuthorization().getViewConfig().add(new AdminUser(new CaseInsensitiveString(user))); writeConfigFile(cruiseConfig); } private void updateApproval(String pipelineName, String ftStage, Approval manualApproval) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig config = pipelineConfig.findBy(new CaseInsensitiveString(ftStage)); config.updateApproval(manualApproval); writeConfigFile(cruiseConfig); } public boolean isSecurityEnabled() { CruiseConfig cruiseConfig = loadForEdit(); return cruiseConfig.server().isSecurityEnabled(); } public static CruiseConfig load(String content) { try { return new GoConfigFileHelper(content).currentConfig(); } catch (Exception e) { throw new RuntimeException(e); } } public static String loadAndMigrate(String originalContent) { GoConfigFileHelper helper = new GoConfigFileHelper(originalContent); try { return FileUtils.readFileToString(helper.getConfigFile()); } catch (IOException e) { throw bomb(e); } } public void setAdminPermissionForGroup(String groupName, String user) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfigs group = cruiseConfig.getGroups().findGroup(groupName); group.getAuthorization().getAdminsConfig().add(new AdminUser(new CaseInsensitiveString(user))); writeConfigFile(cruiseConfig); } public void setViewPermissionForGroup(String groupName, String username) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfigs group = cruiseConfig.getGroups().findGroup(groupName); group.getAuthorization().getViewConfig().add(new AdminUser(new CaseInsensitiveString(username))); writeConfigFile(cruiseConfig); } public void setOperatePermissionForGroup(String groupName, String... userNames) { CruiseConfig cruiseConfig = loadForEdit(); Admin[] admins = AdminUserMother.adminUsers(userNames); for (Admin admin : admins) { cruiseConfig.getGroups().findGroup(groupName).getAuthorization().getOperationConfig().add(admin); } writeConfigFile(cruiseConfig); } public void setOperatePermissionForStage(String pipelineName, String stageName, String username) { CruiseConfig cruiseConfig = loadForEdit(); StageConfig stageConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)).findBy(new CaseInsensitiveString(stageName)); stageConfig.updateApproval(new Approval(new AuthConfig(new AdminUser(new CaseInsensitiveString(username))))); writeConfigFile(cruiseConfig); } public void setPipelineLabelTemplate(String pipelineName, String labelTemplate) { CruiseConfig config = loadForEdit(); config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)).setLabelTemplate(labelTemplate); writeConfigFile(config); } public void setupMailHost() { CruiseConfig config = loadForEdit(); config.server().setMailHost( new MailHost("10.18.3.171", 25, "cruise2", "password", true, false, "cruise2@cruise.com", "admin@cruise.com")); writeConfigFile(config); } public void addAgentToEnvironment(String env, String uuid) { CruiseConfig config = loadForEdit(); config.getEnvironments().addAgentsToEnvironment(env, uuid); writeConfigFile(config); } public void addPipelineToEnvironment(String env, String pipelineName) { CruiseConfig config = loadForEdit(); config.getEnvironments().addPipelinesToEnvironment(env, pipelineName); writeConfigFile(config); } public void setRunOnAllAgents(String pipelineName, String stageName, String jobName, boolean runOnAllAgents) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.findBy(new CaseInsensitiveString(stageName)).jobConfigByInstanceName(jobName, true).setRunOnAllAgents(runOnAllAgents); writeConfigFile(config); } public void setRunMultipleInstance(String pipelineName, String stageName, String jobName, Integer runInstanceCount) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.findBy(new CaseInsensitiveString(stageName)).jobConfigByInstanceName(jobName, true).setRunInstanceCount(runInstanceCount); writeConfigFile(config); } public void addResourcesFor(String pipelineName, String stageName, String jobName, String... resources) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); for (String resource : resources) { pipelineConfig.findBy(new CaseInsensitiveString(stageName)).jobConfigByConfigName(new CaseInsensitiveString(jobName)).addResource(resource); } writeConfigFile(config); } public void addAssociatedEntitiesForAJob(String pipelineName, String stageName, String jobName, Resources resources, ArtifactPlans artifactPlans, ArtifactPropertiesGenerators artifactPropertiesGenerators) { CruiseConfig config = loadForEdit(); JobConfig jobConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)).findBy(new CaseInsensitiveString(stageName)).jobConfigByConfigName(new CaseInsensitiveString(jobName)); ReflectionUtil.setField(jobConfig, "resources", resources); ReflectionUtil.setField(jobConfig, "artifactPlans", artifactPlans); ReflectionUtil.setField(jobConfig, "artifactPropertiesGenerators", artifactPropertiesGenerators); writeConfigFile(config); } public PipelineConfig addMaterialToPipeline(String pipelineName, MaterialConfig materialConfig) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); for (MaterialConfig materialConfig1 : new MaterialConfig[]{materialConfig}) { pipelineConfig.addMaterialConfig(materialConfig1); } writeConfigFile(config); return pipelineConfig; } public PipelineConfig removeMaterialFromPipeline(String pipelineName, MaterialConfig materialConfig) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.removeMaterialConfig(materialConfig); writeConfigFile(config); return pipelineConfig; } public PipelineConfig changeStagenameForToPipeline(String pipelineName, String oldStageName, String newStageName) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stage = pipelineConfig.getStage(new CaseInsensitiveString(oldStageName)); int index = pipelineConfig.indexOf(stage); stage = StageConfigMother.custom(newStageName, stage.isFetchMaterials(), stage.isCleanWorkingDir(), stage.getJobs(), stage.getApproval()); pipelineConfig.set(index, stage); writeConfigFile(config); return pipelineConfig; } public void blockPipelineGroupExceptFor(String pipelineGroupName, String roleName) { CruiseConfig config = loadForEdit(); PipelineConfigs configs = config.getGroups().findGroup(pipelineGroupName); Authorization authorization = new Authorization(new OperationConfig(new AdminRole(new CaseInsensitiveString(roleName))), new ViewConfig(new AdminRole(new CaseInsensitiveString(roleName)))); configs.setAuthorization(authorization); writeConfigFile(config); } public void addAdmins(String... adminNames) { CruiseConfig cruiseConfig = loadForEdit(); AdminsConfig adminsConfig = cruiseConfig.server().security().adminsConfig(); for (String adminName : adminNames) { adminsConfig.add(new AdminUser(new CaseInsensitiveString(adminName))); } writeConfigFile(cruiseConfig); } public void addAdminRoles(String... roleNames) { CruiseConfig cruiseConfig = loadForEdit(); AdminsConfig adminsConfig = cruiseConfig.server().security().adminsConfig(); for (String roleName : roleNames) { adminsConfig.add(new AdminRole(new CaseInsensitiveString(roleName))); } writeConfigFile(cruiseConfig); } public void lockPipeline(String name) { CruiseConfig config = loadForEdit(); PipelineConfig pipeline = config.pipelineConfigByName(new CaseInsensitiveString(name)); pipeline.lockExplicitly(); writeConfigFile(config); } public void addEnvironments(String... environmentNames) { CruiseConfig config = loadForEdit(); for (String environmentName : environmentNames) { config.addEnvironment(environmentName); } writeConfigFile(config); } public void addEnvironments(List<String> environmentNames) { addEnvironments(environmentNames.toArray(new String[environmentNames.size()])); } public void addEnvironmentVariablesToEnvironment(String environmentName, String variableName, String variableValue) throws NoSuchEnvironmentException { CruiseConfig config = loadForEdit(); EnvironmentConfig env = config.getEnvironments().named(new CaseInsensitiveString(environmentName)); env.addEnvironmentVariable(variableName, variableValue); writeConfigFile(config); } public void deleteConfigFile() { configFile.delete(); } public static EnvironmentVariablesConfig env(String name, String value) { return EnvironmentVariablesConfigMother.env(name, value); } public static EnvironmentVariablesConfig env(String [] names, String [] values) { return EnvironmentVariablesConfigMother.env(names, values); } public void addMingleConfigToPipeline(String pipelineName, MingleConfig mingleConfig) { CruiseConfig config = loadForEdit(); PipelineConfig pipelineConfig = config.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); pipelineConfig.setMingleConfig(mingleConfig); writeConfigFile(config); } public void setBaseUrls(ServerSiteUrlConfig siteUrl, ServerSiteUrlConfig secureSiteUrl) { CruiseConfig config = loadForEdit(); config.setServerConfig( new ServerConfig(config.server().security(), config.server().mailHost(), siteUrl, secureSiteUrl)); writeConfigFile(config); } public void removeJob(String pipelineName, String stageName, String jobName) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipelineName)); StageConfig stageConfig = pipelineConfig.findBy(new CaseInsensitiveString(stageName)); JobConfig job = stageConfig.getJobs().getJob(new CaseInsensitiveString(jobName)); stageConfig.getJobs().remove(job); writeConfigFile(cruiseConfig); } public void addParamToPipeline(String pipeline, String paramName, String paramValue) { CruiseConfig cruiseConfig = loadForEdit(); PipelineConfig pipelineConfig = cruiseConfig.pipelineConfigByName(new CaseInsensitiveString(pipeline)); pipelineConfig.addParam(new ParamConfig(paramName, paramValue)); writeConfigFile(cruiseConfig); } public void addPackageDefinition(PackageMaterialConfig packageMaterialConfig){ CruiseConfig config = loadForEdit(); PackageRepository repository = packageMaterialConfig.getPackageDefinition().getRepository(); config.getPackageRepositories().add(repository); writeConfigFile(config); } public void addSCMConfig(SCM scmConfig) { CruiseConfig config = loadForEdit(); config.getSCMs().add(scmConfig); writeConfigFile(config); } public NoOverwriteUpdateConfigCommand addPipelineCommand(final String oldMd5, final String pipelineName, final String stageName, final String jobName) { return new NoOverwriteUpdateConfigCommand() { @Override public String unmodifiedMd5() { return oldMd5; } @Override public CruiseConfig update(CruiseConfig cruiseConfig) throws Exception { cruiseConfig.addPipeline("g1", PipelineConfigMother.pipelineConfig(pipelineName, StageConfigMother.custom(stageName, jobName))); return cruiseConfig; } }; } public UpdateConfigCommand changeJobNameCommand(final String md5, final String pipelineName, final String stageName, final String oldJobName, final String newJobName) { return new NoOverwriteUpdateConfigCommand() { @Override public String unmodifiedMd5() { return md5; } @Override public CruiseConfig update(CruiseConfig cruiseConfig) throws Exception { JobConfig job = cruiseConfig.findJob(pipelineName, stageName, oldJobName); ReflectionUtil.setField(job, "jobName", new CaseInsensitiveString(newJobName)); return cruiseConfig; } }; } /*public void addPipelineGroup(String groupName) { CruiseConfig config = loadForEdit(); config.addGroup(groupName); writeConfigFile(config); }*/ public static class AdminUserMother { public static Admin[] adminUsers(String... userNames) { Admin[] result = new Admin[userNames.length]; for (int i = 0; i < userNames.length; i++) { String userName = userNames[i]; result[i] = new AdminUser(new CaseInsensitiveString(userName)); } return result; } } public static void clearConfigVersions() { SystemEnvironment env = new SystemEnvironment(); FileUtils.deleteQuietly(env.getConfigRepoDir()); } public static void withServerIdImmutability(Procedure fn) { try { SystemEnvironment.enforceServerIdImmutability.set(true); fn.call(); } finally { SystemEnvironment.enforceServerIdImmutability.set(false); } } }