├── .dockerignore ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── 1-report-bug.yml │ ├── 2-feature-request.yml │ ├── 3-documentation.yml │ ├── 4-plugin-compatibility.yml │ ├── 5-question.md │ └── config.yml ├── pull_request_template.md ├── release-drafter.yml ├── renovate.json ├── settings.yml ├── stale.yml └── workflows │ ├── cd.yaml │ └── jenkins-security-scan.yml ├── .gitignore ├── .idea └── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── .mvn ├── checkstyle-suppressions.xml ├── checkstyle.xml ├── extensions.xml └── maven.config ├── .run └── start jenkins.run.xml ├── Jenkinsfile ├── LICENSE ├── README.md ├── codecov.yml ├── demos ├── README.adoc ├── active-directory │ └── README.md ├── alauda-devops-sync │ └── README.md ├── artifact-manager-s3 │ └── README.md ├── artifactory │ └── README.md ├── build_agents │ └── README.md ├── config-file-provider │ └── README.md ├── credentials │ └── README.md ├── docker-workflow │ └── README.md ├── docker │ └── README.md ├── ec2 │ └── README.md ├── embedded-userdatabase │ └── README.md ├── external-workspace-manager │ └── README.md ├── git-client │ └── README.md ├── git │ └── README.md ├── gitea │ └── README.md ├── github-oauth │ └── README.md ├── github │ └── README.md ├── gitlab │ └── README.md ├── global-matrix-auth │ └── README.md ├── golang │ └── README.md ├── google-login │ ├── README.md │ └── config.yaml ├── graphite │ └── README.md ├── jdk │ └── README.md ├── jenkins │ ├── README.md │ └── jenkins.yaml ├── jira │ └── README.md ├── jobs │ ├── README.md │ ├── bitbucket.yaml │ ├── gitea.yaml │ ├── multibranch-github.yaml │ └── pipeline.yaml ├── kubernetes-helm │ ├── README.md │ └── values.yaml ├── kubernetes-secrets │ └── README.md ├── kubernetes │ ├── README.md │ ├── adv_config.yml │ ├── config.yml │ ├── jenkins.yml │ └── service-account.yml ├── ldap │ └── README.md ├── log-recorder │ └── README.md ├── mailer │ └── README.md ├── matrix-auth │ └── README.md ├── maven │ └── README.md ├── mercurial │ └── README.md ├── msbuild │ └── README.md ├── mstestrunner │ └── README.md ├── node-monitors │ └── README.md ├── nodejs │ └── README.md ├── pipeline-groovy-lib │ └── README.md ├── pipeline-maven │ └── README.md ├── proxy │ ├── README.md │ ├── proxy.yaml │ └── proxyMinimal.yaml ├── role-strategy-auth │ └── README.md ├── saml │ └── README.md ├── sbt │ └── README.md ├── simple-theme-plugin │ └── README.md ├── slack │ └── README.md ├── sonarqube │ └── README.md ├── statistics-gatherer │ └── README.md ├── terraform │ └── README.md ├── tfs │ └── README.md └── view-job-filters │ └── README.md ├── docs ├── COMPATIBILITY.md ├── CONTRIBUTING.md ├── DEVELOPER.md ├── IMPLEMENTATION.md ├── PLUGINS.md ├── REQUIREMENTS.md ├── VAULT.md ├── benchmarks │ └── jmh-benchmarks.md ├── features │ ├── configExport.md │ ├── configurationReload.md │ ├── jsonSchema.md │ ├── mergeStrategy.md │ └── secrets.adoc ├── migrate.md ├── seed-jobs.md ├── usageScenarios.md └── vault │ └── setup-vault-using-docker.md ├── images ├── BraceYourselves.jpg ├── CasC_new-03.png ├── logo-head.svg ├── reference.png ├── sample_form.png └── unclassified.png ├── integrations ├── pom.xml └── src │ └── test │ ├── java │ └── io │ │ └── jenkins │ │ └── plugins │ │ └── casc │ │ ├── ActiveDirectoryTest.java │ │ ├── ArtifactManagerS3Test.java │ │ ├── ArtifactoryTest.java │ │ ├── AzureKeyVaultTest.java │ │ ├── BuildAgentsTest.java │ │ ├── ConfigFileProviderTest.java │ │ ├── CredentialsReadmeTest.java │ │ ├── CredentialsTest.java │ │ ├── CustomToolsTest.java │ │ ├── DockerCloudTest.java │ │ ├── DockerWorkflowSymbolTest.java │ │ ├── DockerWorkflowTest.java │ │ ├── EC2CloudTest.java │ │ ├── EssentialsTest.java │ │ ├── ExternalWorkspaceManagerTest.java │ │ ├── GitHostKeyVerificationTest.java │ │ ├── GitHubTest.java │ │ ├── GitLabConfigurationTest.java │ │ ├── GitTest.java │ │ ├── GitToolInstallationTest.java │ │ ├── GiteaOrganisationFolderTest.java │ │ ├── GiteaServerTest.java │ │ ├── GithubOAuthTest.java │ │ ├── GithubOrganisationFolderTest.java │ │ ├── GitscmTest.java │ │ ├── GlobalLibrariesTest.java │ │ ├── GlobalMatrixAuthorizationTest.java │ │ ├── GlobalNodePropertiesTest.java │ │ ├── GlobalNodePropertiesWithEnvVarsTest.java │ │ ├── JdkConfiguratorTest.java │ │ ├── JenkinsDemoTest.java │ │ ├── JenkinsReadmeDemoTest.java │ │ ├── JiraTest.java │ │ ├── JobDslGlobalSecurityConfigurationTest.java │ │ ├── KubernetesCloudTest.java │ │ ├── LDAPSecurityRealmTest.java │ │ ├── LDAPTest.java │ │ ├── LogRecorderTest.java │ │ ├── MSBuildTest.java │ │ ├── MSTestRunnerTest.java │ │ ├── MailExtTest.java │ │ ├── MailerTest.java │ │ ├── MavenConfiguratorTest.java │ │ ├── MercurialTest.java │ │ ├── NodeJSTest.java │ │ ├── PermissionAssert.java │ │ ├── ProjectMatrixAuthorizationTest.java │ │ ├── PropertiesSecretSourceTest.java │ │ ├── ProxyTest.java │ │ ├── RoleStrategyTest.java │ │ ├── RoundTripMailerTest.java │ │ ├── SSHCredentialsTest.java │ │ ├── SbtTest.java │ │ ├── Security1446Test.java │ │ ├── SeedJobTest.java │ │ ├── SimpleThemeTest.java │ │ ├── SlackTest.java │ │ ├── SonarQubeTest.java │ │ ├── StatisticsGathererTest.java │ │ ├── SystemCredentialsTest.java │ │ ├── TerraformTest.java │ │ ├── ToolDefaultPropertiesExportIgnoreListTest.java │ │ ├── TopReadmeTest.java │ │ ├── ViewJobFiltersTest.java │ │ ├── WorkflowCpsGlobalLibTest.java │ │ └── core │ │ ├── HudsonPrivateSecurityRealmConfiguratorTest.java │ │ └── NodeMonitorsConfiguratorTest.java │ └── resources │ └── io │ └── jenkins │ └── plugins │ └── casc │ ├── CredentialsWithDomain.yml │ ├── CustomToolsTest.yml │ ├── DockerCloudTest2.yml │ ├── DockerWorkflowSymbol.yml │ ├── DockerWorkflowSymbolExpected.yml │ ├── EssentialsTest.yml │ ├── GitTest.yml │ ├── GitToolInstallationTestExpected.yml │ ├── GithubOrganisationFolderTest.yml │ ├── GlobalCredentials.yml │ ├── GlobalLibrariesGitHubTest.yml │ ├── GlobalNodePropertiesTest.yml │ ├── GlobalNodePropertiesTestExpected.yml │ ├── GlobalNodePropertiesWithEnvVarsTest.yml │ ├── GlobalNodePropertiesWithEnvVarsTestExpected.yml │ ├── JdkConfiguratorTestExpected.yml │ ├── JobDslGlobalSecurityConfigurationTest.yml │ ├── LDAPSecurityRealmTestNoSecret.yml │ ├── LDAPSecurityRealmTestNoSecretExpected.yml │ ├── LogRecorderTestExpected.yaml │ ├── MailExtTest.yml │ ├── MailerTest.yml │ ├── MavenConfiguratorTestExpected.yml │ ├── MavenConfiguratorTestGlobalConfigExpected.yml │ ├── MavenConfiguratorTestGlobalConfigSpecificFilesExpected.yml │ ├── MercurialTest.yaml │ ├── ProjectMatrixStrategy.yml │ ├── PropertiesSecretSourceTest.yaml │ ├── RoleStrategy1.yml │ ├── RoleStrategy1Expected.yml │ ├── RoleStrategy2.yml │ ├── SSHCredentialsTest.yml │ ├── SSHCredentialsTest_Multiline_Key.yml │ ├── SSHCredentialsTest_Singleline_Key.yml │ ├── SbtTestExpected.yml │ ├── Security1446Test.yml │ ├── SeedJobTest.yml │ ├── SeedJobTest_withEnvVars.yml │ ├── SeedJobTest_withGiteaOrganisation.yml │ ├── SeedJobTest_withSecrets.yml │ ├── SeedJobTest_withSecurityConfig.yml │ ├── SystemCredentialsTest.yml │ ├── TerraformConfiguratorTestExpected.yml │ ├── ToolDefaultPropertiesExportIgnoreList.yml │ ├── ToolDefaultPropertiesExportIgnoreListExpected.yml │ ├── alias1.yml │ ├── azureKeyVault.yml │ ├── init.yml │ ├── mysecretfile.txt │ ├── private-key.pem │ ├── secrets.properties │ ├── slackSchema.yml │ ├── sonarSchema.yml │ ├── sonarSchemaFull.yml │ ├── test.p12 │ └── testJob2.groovy ├── plugin ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── jenkins │ │ │ └── plugins │ │ │ └── casc │ │ │ ├── Attribute.java │ │ │ ├── BaseConfigurator.java │ │ │ ├── CasCGlobalConfig.java │ │ │ ├── Configurable.java │ │ │ ├── ConfigurationAsCode.java │ │ │ ├── ConfigurationAsCodeBootFailure.java │ │ │ ├── ConfigurationContext.java │ │ │ ├── Configurator.java │ │ │ ├── ConfiguratorConflictException.java │ │ │ ├── ConfiguratorException.java │ │ │ ├── ConfiguratorRegistry.java │ │ │ ├── FixedInterpolatorStringLookup.java │ │ │ ├── IgnoreList.java │ │ │ ├── ObsoleteConfigurationMonitor.java │ │ │ ├── RootElementConfigurator.java │ │ │ ├── SchemaGeneration.java │ │ │ ├── SecretSource.java │ │ │ ├── SecretSourceResolver.java │ │ │ ├── TokenReloadAction.java │ │ │ ├── TokenReloadCrumbExclusion.java │ │ │ ├── UnknownAttributesException.java │ │ │ ├── UnknownConfiguratorException.java │ │ │ ├── VersionConverter.java │ │ │ ├── cli │ │ │ ├── ApplyConfigurationCommand.java │ │ │ ├── CheckConfigurationCommand.java │ │ │ ├── ExportConfigurationCommand.java │ │ │ └── ReloadJCascConfigurationCommand.java │ │ │ ├── core │ │ │ ├── AdminWhitelistRuleConfigurator.java │ │ │ ├── GlobalNodePropertiesConfigurator.java │ │ │ ├── HudsonPrivateSecurityRealmConfigurator.java │ │ │ ├── JNLPLauncherConfigurator.java │ │ │ ├── JenkinsConfigurator.java │ │ │ ├── LabelAtomConfigurator.java │ │ │ ├── LabelAtomPropertyConfigurator.java │ │ │ ├── MavenConfigurator.java │ │ │ ├── NoneSecurityRealmConfigurator.java │ │ │ ├── UnsecuredAuthorizationStrategyConfigurator.java │ │ │ ├── UpdateCenterConfigurator.java │ │ │ └── UpdateSiteConfigurator.java │ │ │ ├── impl │ │ │ ├── DefaultConfiguratorRegistry.java │ │ │ ├── attributes │ │ │ │ ├── DescribableAttribute.java │ │ │ │ ├── DescribableListAttribute.java │ │ │ │ ├── MultivaluedAttribute.java │ │ │ │ └── PersistedListAttribute.java │ │ │ ├── configurators │ │ │ │ ├── ConfigurableConfigurator.java │ │ │ │ ├── DataBoundConfigurator.java │ │ │ │ ├── DescriptorConfigurator.java │ │ │ │ ├── EnumConfigurator.java │ │ │ │ ├── ExtensionConfigurator.java │ │ │ │ ├── GlobalConfigurationCategoryConfigurator.java │ │ │ │ ├── HeteroDescribableConfigurator.java │ │ │ │ ├── PrimitiveConfigurator.java │ │ │ │ └── SelfConfigurator.java │ │ │ └── secrets │ │ │ │ ├── DockerSecretSource.java │ │ │ │ ├── EnvSecretSource.java │ │ │ │ └── PropertiesSecretSource.java │ │ │ ├── model │ │ │ ├── CNode.java │ │ │ ├── Mapping.java │ │ │ ├── Scalar.java │ │ │ ├── Sequence.java │ │ │ └── Source.java │ │ │ ├── util │ │ │ └── ExtraFieldUtils.java │ │ │ └── yaml │ │ │ ├── ErrorOnConflictMergeStrategy.java │ │ │ ├── MergeStrategy.java │ │ │ ├── MergeStrategyAction.java │ │ │ ├── MergeStrategyFactory.java │ │ │ ├── ModelConstructor.java │ │ │ ├── OverrideMergeStrategy.java │ │ │ ├── StreamReaderWithSource.java │ │ │ ├── YamlSource.java │ │ │ └── YamlUtils.java │ ├── resources │ │ ├── images │ │ │ └── symbols │ │ │ │ └── logo.svg │ │ ├── index.jelly │ │ └── io │ │ │ └── jenkins │ │ │ └── plugins │ │ │ └── casc │ │ │ ├── BaseConfigurator │ │ │ ├── documentation.jelly │ │ │ └── documentation_zh_CN.properties │ │ │ ├── CasCGlobalConfig │ │ │ └── config.jelly │ │ │ ├── ConfigurationAsCode │ │ │ ├── error.jelly │ │ │ ├── index.jelly │ │ │ ├── index.properties │ │ │ ├── reference.jelly │ │ │ └── viewExport.jelly │ │ │ ├── ObsoleteConfigurationMonitor │ │ │ ├── message.jelly │ │ │ └── message_zh_CN.properties │ │ │ └── assets │ │ │ ├── index.css │ │ │ └── viewExport.css │ └── webapp │ │ └── css │ │ └── reference.css │ └── test │ ├── java │ └── io │ │ └── jenkins │ │ └── plugins │ │ └── casc │ │ ├── AttributeTest.java │ │ ├── DocumentationGenerationTest.java │ │ ├── ErrorPageTest.java │ │ ├── IgnoreAliasEntryTest.java │ │ ├── MockHttpServletRequest.java │ │ ├── SecretSourceResolverTest.java │ │ ├── TestCrumbIssuerConfigurator.java │ │ ├── TokenReloadCrumbExclusionTest.java │ │ ├── UnknownRootElementTest.java │ │ ├── impl │ │ └── configurators │ │ │ └── PrimitiveConfiguratorTest.java │ │ ├── jmh │ │ ├── BenchmarkRunner.java │ │ └── benchmarks │ │ │ ├── ConfigureBenchmark.java │ │ │ └── SecretSourceResolverBenchmark.java │ │ ├── model │ │ └── MappingTest.java │ │ ├── permissions │ │ ├── Action.java │ │ └── PermissionsTest.java │ │ └── yaml │ │ ├── CustomMergeStrategyTest.java │ │ ├── ErrorOnConflictMergeStrategyTest.java │ │ ├── ExportTest.java │ │ ├── MergeStrategyActionTest.java │ │ ├── MergeStrategyTest.java │ │ ├── OverrideMergeStrategyTest.java │ │ ├── YamlExportTest.java │ │ └── YamlSourceTest.java │ └── resources │ └── io │ └── jenkins │ └── plugins │ └── casc │ ├── known.yml │ ├── secret.json │ ├── secret.key │ ├── some secret.json │ ├── unknown1.yml │ ├── unknown2.yml │ └── yaml │ ├── conflicts.yml │ ├── incompatible.yml │ ├── multiple-keys-a.yml │ ├── multiple-keys-b.yml │ ├── normal.yml │ ├── overwrite.yml │ ├── sequence-a.yml │ ├── sequence-b.yml │ ├── systemMessage-a.yml │ ├── systemMessage-b.yml │ └── unknown.yml ├── pom.xml └── test-harness ├── pom.xml └── src ├── main └── java │ └── io │ └── jenkins │ └── plugins │ └── casc │ └── misc │ ├── ConfiguredWithCode.java │ ├── ConfiguredWithReadme.java │ ├── Env.java │ ├── EnvVarsRule.java │ ├── Envs.java │ ├── EnvsFromFile.java │ ├── JenkinsConfiguredRule.java │ ├── JenkinsConfiguredWithCodeRule.java │ ├── JenkinsConfiguredWithReadmeRule.java │ ├── RoundTripAbstractTest.java │ ├── Util.java │ ├── jmh │ └── CascJmhBenchmarkState.java │ └── junit │ └── jupiter │ ├── AbstractRoundTripTest.java │ ├── JUnit5JenkinsConfiguredWithCodeRule.java │ ├── JenkinsConfiguredWithCodeExtension.java │ └── WithJenkinsConfiguredWithCode.java └── test ├── java └── io │ └── jenkins │ └── plugins │ └── casc │ ├── BackwardCompatibilityTest.java │ ├── CascJmhBenchmarkStateTest.java │ ├── ConfigurationAsCodeTest.java │ ├── DetectMissingVaultPluginTest.java │ ├── JenkinsConfigTest.java │ ├── JenkinsConfiguredWithCodeRuleClassRuleTest.java │ ├── MockHttpServletRequest.java │ ├── MockHttpServletResponse.java │ ├── SampleBenchmark.java │ ├── SchemaGenerationSanitisationTest.java │ ├── SchemaGenerationTest.java │ ├── Security1290Test.java │ ├── TokenReloadActionTest.java │ ├── YamlCodePointLimitTest.java │ ├── YamlMaxAliasesCollectionTest.java │ ├── YamlReaderTest.java │ ├── YamlValidationTest.java │ ├── core │ ├── JenkinsConfiguratorCloudSupportTest.java │ ├── JenkinsConfiguratorTest.java │ ├── MavenConfiguratorTest.java │ ├── ProxyConfiguratorTest.java │ ├── UnsecuredAuthorizationStrategyConfiguratorTest.java │ └── UpdateCenterConfiguratorTest.java │ ├── impl │ └── configurators │ │ ├── DataBoundConfiguratorTest.java │ │ ├── DescriptorConfiguratorTest.java │ │ ├── DuplicateKeyDescribableConfiguratorTest.java │ │ ├── MissingConfiguratorTest.java │ │ ├── SelfConfiguratorTest.java │ │ └── nonnull │ │ ├── ClassParametersAreNonnullByDefault.java │ │ ├── NonnullParameterConstructor.java │ │ ├── nonnullparampackage │ │ ├── PackageParametersAreNonnullByDefault.java │ │ ├── PackageParametersNonNullCheckForNull.java │ │ └── package-info.java │ │ └── package-info.java │ └── junit │ └── jupiter │ ├── JenkinsConfiguredWithCodeMethodRuleTest.java │ ├── JenkinsConfiguredWithCodeRuleClassRuleTest.java │ └── JenkinsConfiguredWithCodeRulePermissionTest.java └── resources └── io └── jenkins └── plugins └── casc ├── ArtifactoryBuilderTest.yml ├── BackwardCompatibilityTest.yml ├── GetConfiguratorsTest.yml ├── GlobalSecurityConfiguration.yml ├── JenkinsConfigTest.yml ├── aNonEmpty.yml ├── admin.yml ├── attributesNotFlattenedToTop.yml ├── benchmarks.yml ├── core ├── ConfigureLabels.yml ├── ExpectedLabelsConfiguration.yml ├── HeteroDescribable.yml ├── JenkinsConfiguratorCloudSupportTest.yml ├── MavenConfiguratorTest.yml ├── Primitives.yml ├── Proxy.yml ├── ProxyMinimal.yml ├── ProxyWithSecrets.yml ├── SetEnvironmentVariable.yml ├── UnsecuredAuthorizationStrategyConfiguratorTest.yml └── UpdateCenter.yml ├── empty.yml ├── folder ├── jenkins.yml └── jenkins2.yml ├── impl └── configurators │ ├── DataBoundDescriptorNonNull.yml │ ├── DescriptorConfiguratorTest_camelCase.yml │ ├── DescriptorConfiguratorTest_lowerCase.yml │ ├── DuplicateKeyDescribableConfigure.yml │ ├── MissingConfiguratorTest.yml │ ├── SelfConfiguratorRestrictedTest.yml │ └── SelfConfiguratorTest.yml ├── invalidBaseConfig.yml ├── invalidSchemaConfig.yml ├── invalidToolBaseConfig.yml ├── junit └── jupiter │ └── admin.yml ├── maxAliasesLimit.yml ├── merge1.yml ├── merge2.yml ├── merge3.yml ├── multi-line1.yml ├── multi-line2.yml ├── validJenkinsBaseConfig.yml ├── validJenkinsBaseConfigWithSymbol.yml ├── validSchemaConfig.yml └── validSelfConfig.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | target 3 | !target/configuration-as-code.hpi 4 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Enable spotless 2 | b273e7be3888cd5279f5d328d119348e107669fb 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.jks binary 3 | *.p12 binary 4 | *.jpi binary 5 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/configuration-as-code-plugin-developers 2 | .github/settings.yml @jetersen @timja 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ### Your checklist for this issue 6 | 7 | 🚨 Please review the [guidelines for contributing](../blob/master/docs/CONTRIBUTING.md) to this repository. 8 | 9 | - [ ] Jenkins version 10 | 11 | - [ ] Plugin version 12 | 13 | - [ ] OS 14 | 15 | 19 | 20 | ### Description 21 | 22 | Please describe your issue here. 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature-request.yml: -------------------------------------------------------------------------------- 1 | name: '🚀 Feature request' 2 | labels: 'enhancement' 3 | description: I have a suggestion 4 | 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: What feature do you want to see added? 9 | description: A clear and concise description of your feature request. 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: Upstream changes 16 | description: Link here any upstream changes that might be relevant to this request 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-documentation.yml: -------------------------------------------------------------------------------- 1 | name: '📝 Documentation' 2 | labels: 'documentation' 3 | description: 'Let us know if any documentation is missing or could be improved' 4 | 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Describe your use-case which is not covered by existing documentation. 9 | description: If it is easier to submit a documentation patch instead of writing an issue, just do it! 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: Reference any relevant documentation, other materials or issues/pull requests that can be used for inspiration. 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/5-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❓ Need help" 3 | labels: question 4 | about: Please ask in our Gitter channel first 5 | --- 6 | 7 | 10 | 11 | ### Your checklist for this issue 12 | 13 | 🚨 Please review the [Support Policy](https://github.com/jenkinsci/.github/blob/master/SUPPORT.md) 14 | 15 | - [ ] The question was asked in the project's [Gitter chat](https://gitter.im/jenkinsci/configuration-as-code-plugin) 16 | - [ ] Jenkins version 17 | - [ ] Plugin version 18 | - [ ] OS 19 | - [ ] Reproduction steps 20 | 21 | 25 | 26 | ### Description 27 | 28 | Please describe your issue here, and explain what you have already tried to resolve it. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: "❓ Gitter chat" 4 | url: https://gitter.im/jenkinsci/configuration-as-code-plugin 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Your checklist for this pull request 4 | 5 | 🚨 Please review the [guidelines for contributing](../blob/master/docs/CONTRIBUTING.md) to this repository. 6 | 7 | - [ ] Make sure you are requesting to **pull a topic/feature/bugfix branch** (right side) and not your master branch! 8 | - [ ] Ensure that the pull request title represents the desired changelog entry 9 | - [ ] Please describe what you did 10 | - [ ] Link to relevant issues in GitHub or in [Jenkins JIRA](https://issues.jenkins-ci.org) 11 | - [ ] Link to relevant pull requests, esp. upstream and downstream changes 12 | - [ ] Did you provide a test-case? That demonstrates feature works or fixes the issue. 13 | 14 | 17 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | ":semanticCommitsDisabled", 6 | "schedule:earlyMondays" 7 | ], 8 | "automerge": true, 9 | "labels": [ 10 | "dependencies" 11 | ], 12 | "packageRules": [ 13 | { 14 | "allowedVersions": "/^[0-9]+\\.[0-9]+\\.[0-9]+$/", 15 | "registryUrls": [ 16 | "https://repo.jenkins-ci.org/public/" 17 | ], 18 | "matchPackageNames": [ 19 | "/org.jenkins-ci.main:jenkins-war/" 20 | ] 21 | } 22 | ], 23 | "customManagers": [ 24 | { 25 | "customType": "regex", 26 | "fileMatch": [ 27 | "integrations/pom.xml" 28 | ], 29 | "matchStrings": [ 30 | "(?.*?)" 31 | ], 32 | "depNameTemplate": "org.jenkins-ci.main:jenkins-war", 33 | "datasourceTemplate": "maven" 34 | } 35 | ], 36 | "rebaseWhen": "conflicted" 37 | } 38 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 7 9 | 10 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 11 | exemptLabels: 12 | - pinned 13 | - feature 14 | 15 | # Label to use when marking as stale 16 | staleLabel: stale 17 | 18 | # Comment to post when marking as stale. Set to `false` to disable 19 | markComment: > 20 | This issue has been automatically marked as stale because it has not had 21 | recent activity. It will be closed if no further activity occurs. Thank you 22 | for your contributions. 23 | 24 | pulls: 25 | markComment: > 26 | This pull request has been automatically marked as stale because it has not had 27 | recent activity. It will be closed if no further activity occurs. Thank you 28 | for your contributions. 29 | 30 | # Comment to post when closing a stale issue. Set to `false` to disable 31 | closeComment: false 32 | -------------------------------------------------------------------------------- /.github/workflows/cd.yaml: -------------------------------------------------------------------------------- 1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins 2 | 3 | name: cd 4 | on: 5 | workflow_dispatch: 6 | check_run: 7 | types: 8 | - completed 9 | 10 | jobs: 11 | maven-cd: 12 | uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1 13 | secrets: 14 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 15 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [ opened, synchronize, reopened ] 9 | workflow_dispatch: 10 | 11 | permissions: 12 | security-events: write 13 | contents: read 14 | actions: read 15 | 16 | jobs: 17 | security-scan: 18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 19 | with: 20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | work/ 3 | .idea/* 4 | !.idea/codeStyles/ 5 | *.iml 6 | 7 | # ignore jenkins.yaml from root and plugin folder (used by many for testing) 8 | /jenkins.yaml 9 | /plugin/jenkins.yaml 10 | plugins.txt 11 | 12 | # Ignore generated files. 13 | .project 14 | .settings 15 | */.classpath 16 | */.factorypath 17 | */.project 18 | */.settings 19 | 20 | # Ignore DS_Store (Mac) 21 | .DS_Store 22 | 23 | # Ignore benchmark reports 24 | jmh-report*.json 25 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /.mvn/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.mvn/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.8 6 | 7 | 8 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -Dchangelist.format=%d.v%s 4 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | // Windows controller tests crash with unexpected errors 2 | buildPlugin(useContainerAgent: true, forkCount: '0.5C', timeout: 360, configurations: [ 3 | [platform: 'linux', jdk: 21], 4 | [platform: 'windows', jdk: 17], 5 | ]) 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "header, diff, tree, changes" 3 | -------------------------------------------------------------------------------- /demos/active-directory/README.md: -------------------------------------------------------------------------------- 1 | # Configure activeDirectory Security Realm 2 | 3 | Basic configuration of the [Active Directory plugin](https://plugins.jenkins.io/active-directory) 4 | 5 | For plugin version 2.12 and up: 6 | 7 | ## sample configuration 8 | 9 | ```yaml 10 | jenkins: 11 | securityRealm: 12 | activeDirectory: 13 | domains: 14 | - name: "acme" 15 | servers: "ad1.acme.com:123,ad2.acme.com:456" 16 | site: "site" 17 | bindName: "admin" 18 | bindPassword: "${BIND_PASSWORD}" 19 | tlsConfiguration: JDK_TRUSTSTORE 20 | groupLookupStrategy: "RECURSIVE" 21 | removeIrrelevantGroups: true 22 | customDomain: true 23 | cache: 24 | size: 500 25 | ttl: 600 26 | startTls: true 27 | requireTLS: true 28 | internalUsersDatabase: 29 | jenkinsInternalUser: "jenkins" 30 | ``` 31 | -------------------------------------------------------------------------------- /demos/alauda-devops-sync/README.md: -------------------------------------------------------------------------------- 1 | # Alauda DevOps Sync plugin 2 | 3 | Alauda DevOps Sync plugin configuration belongs under `unclassified` root element 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | alaudaSync: 10 | enabled: true 11 | jenkinsService: jenkins 12 | ``` 13 | -------------------------------------------------------------------------------- /demos/artifact-manager-s3/README.md: -------------------------------------------------------------------------------- 1 | # Configure artifact manager s3 2 | 3 | Basic configuration of the [Artifact Manager on S3 plugin](https://plugins.jenkins.io/artifact-manager-s3) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | artifactManager: 10 | artifactManagerFactories: 11 | - jclouds: 12 | provider: s3 13 | 14 | aws: 15 | awsCredentials: 16 | region: "us-east-1" 17 | s3: 18 | container: "${ARTIFACT_MANAGER_S3_BUCKET_NAME}" 19 | prefix: "jenkins_data/" 20 | ``` 21 | -------------------------------------------------------------------------------- /demos/artifactory/README.md: -------------------------------------------------------------------------------- 1 | # artifactory plugin 2 | 3 | Artifactory plugin configuration belongs under `unclassified` root element 4 | 5 | ## sample configuration 6 | 7 | Since 3.11.0: 8 | 9 | ```yaml 10 | unclassified: 11 | artifactorybuilder: 12 | useCredentialsPlugin: true 13 | jfrogInstances: 14 | - instanceId: artifactory 15 | platformUrl: http://acme.com/artifactory 16 | artifactoryUrl: http://acme.com/artifactory 17 | distributionUrl: http://acme.com/distribution 18 | deployerCredentialsConfig: 19 | credentialsId: "artifactory" 20 | resolverCredentialsConfig: 21 | username: artifactory_user 22 | password: "${ARTIFACTORY_PASSWORD}" 23 | ``` 24 | 25 | Before 3.11.0: 26 | 27 | ```yaml 28 | unclassified: 29 | artifactorybuilder: 30 | useCredentialsPlugin: true 31 | artifactoryServers: 32 | - serverId: artifactory 33 | artifactoryUrl: http://acme.com/artifactory 34 | deployerCredentialsConfig: 35 | credentialsId: "artifactory" 36 | resolverCredentialsConfig: 37 | username: artifactory_user 38 | password: "${ARTIFACTORY_PASSWORD}" 39 | ``` 40 | 41 | ## implementation note 42 | 43 | Currently setting credentials causes ERROR & `Enable Push to Bintray` is not supported (always enabled). 44 | 45 | see [jfrog/HAP-1018](https://www.jfrog.com/jira/browse/HAP-1018) 46 | -------------------------------------------------------------------------------- /demos/build_agents/README.md: -------------------------------------------------------------------------------- 1 | # build agents 2 | 3 | Build agents configuration belongs (currently) under `jenkins` root element 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | jenkins: 9 | nodes: 10 | - permanent: 11 | labelString: "linux docker test" 12 | mode: NORMAL 13 | name: "utility-node" 14 | remoteFS: "/home/user1" 15 | launcher: 16 | inbound: 17 | webSocket: true 18 | tunnel: some.proxy 19 | workDirSettings: 20 | disabled: true 21 | failIfWorkDirIsMissing: false 22 | internalDir: "remoting2" 23 | workDirPath: "/tmp" 24 | 25 | - permanent: 26 | labelString: "linux docker test" 27 | mode: NORMAL 28 | name: "utility-node-2" 29 | numExecutors: 4 30 | remoteFS: "/home/user2" 31 | launcher: 32 | SSHLauncher: 33 | host: "192.168.1.1" 34 | port: 22 35 | credentialsId: test 36 | launchTimeoutSeconds: 60 37 | maxNumRetries: 3 38 | retryWaitTime: 30 39 | sshHostKeyVerificationStrategy: 40 | manuallyTrustedKeyVerificationStrategy: 41 | requireInitialManualTrust: false 42 | ``` 43 | -------------------------------------------------------------------------------- /demos/docker-workflow/README.md: -------------------------------------------------------------------------------- 1 | # Configure Declarative agent settings for Docker Pipeline 2 | 3 | Global configuration for Docker Workflow plugin belongs under `unclassified` root element 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | pipeline-model-docker: 10 | dockerLabel: "label-casc" 11 | registry: 12 | url: "my.docker.endpoint" 13 | credentialsId: "credId" 14 | ``` 15 | -------------------------------------------------------------------------------- /demos/docker/README.md: -------------------------------------------------------------------------------- 1 | # Configure docker plugin 2 | 3 | Basic configuration of the [Docker plugin](https://plugins.jenkins.io/docker-plugin) 4 | 5 | For plugin version 1.1.2 and up: 6 | 7 | ## sample configuration 8 | 9 | ```yaml 10 | jenkins: 11 | clouds: 12 | - docker: 13 | name: "docker" 14 | dockerApi: 15 | dockerHost: 16 | uri: "unix:///var/run/docker.sock" 17 | templates: 18 | - labelString: "docker-agent" 19 | dockerTemplateBase: 20 | # TODO: pin sha256 or versions when using in production 21 | image: "jenkins/agent" 22 | mounts: 23 | - "type=tmpfs,destination=/run" 24 | - "type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock" 25 | - "type=volume,src=hello,dst=/world" 26 | environmentsString: | 27 | hello=world 28 | foo=bar 29 | remoteFs: "/home/jenkins/agent" 30 | connector: 31 | attach: 32 | user: "jenkins" 33 | instanceCapStr: "10" 34 | retentionStrategy: 35 | idleMinutes: 1 36 | ``` 37 | 38 | ## implementation note 39 | 40 | Jenkins singleton doesn't offer any `setClouds` method. So here we rely on a pseudo-property implemented by a dedicated 41 | `Attribute` to add the configured clouds to `Jenkins.clouds`. The current implementation only adds the configured cloud 42 | if it doesn't exists yet. 43 | -------------------------------------------------------------------------------- /demos/embedded-userdatabase/README.md: -------------------------------------------------------------------------------- 1 | # configure Jenkins’ own user database 2 | 3 | _Note: You can disable exporting of users by setting the following system property:_ 4 | 5 | `-Dio.jenkins.plugins.casc.core.HudsonPrivateSecurityRealmConfigurator.exportUsers=false` 6 | 7 | ## sample configuration 8 | 9 | ```yaml 10 | jenkins: 11 | securityRealm: 12 | local: 13 | allowsSignup: false 14 | users: 15 | - id: "admin" 16 | password: "somethingsecret" 17 | authorizationStrategy: loggedInUsersCanDoAnything 18 | ``` 19 | 20 | ### Additional attributes 21 | 22 | ```yaml 23 | jenkins: 24 | securityRealm: 25 | local: 26 | allowsSignup: false 27 | users: 28 | - id: "hashedadmin" 29 | # password is 'password' 30 | password: "#jbcrypt:$2a$10$LP4bMhwyCPnsDm.XRcTZSuBqWYKGAiDAsQXrSrJGYcEd9padaPgsC" 31 | - id: "admin" 32 | name: "Admin" 33 | description: "Superwoman" 34 | password: "somethingsecret" 35 | properties: 36 | - mailer: 37 | emailAddress: "admin3@example.com" 38 | - preferredProvider: 39 | providerId: "default" 40 | - slack: 41 | userId: "ABCDEFGH" 42 | - timezone: 43 | timeZoneName: "Europe/London" 44 | - sshPublicKey: 45 | authorizedKeys: | 46 | ssh-rsa some-key 47 | authorizationStrategy: loggedInUsersCanDoAnything 48 | ``` 49 | -------------------------------------------------------------------------------- /demos/git/README.md: -------------------------------------------------------------------------------- 1 | # Configure Git plugin 2 | 3 | Basic global configuration of the [Git plugin](https://plugins.jenkins.io/git). 4 | Detailed descriptions of each option are available in the [git plugin documentation](https://plugins.jenkins.io/git/#plugin-content-global-configuration). 5 | 6 | ## sample configuration 7 | 8 | ```yaml 9 | unclassified: 10 | scmGit: 11 | addGitTagAction: false 12 | allowSecondFetch: false 13 | createAccountBasedOnEmail: true 14 | disableGitToolChooser: false 15 | globalConfigEmail: jenkins@domain.local 16 | globalConfigName: jenkins 17 | hideCredentials: false 18 | showEntireCommitSummaryInChanges: true 19 | useExistingAccountWithSameEmail: false 20 | ``` 21 | -------------------------------------------------------------------------------- /demos/gitea/README.md: -------------------------------------------------------------------------------- 1 | # Configure Gitea plugin 2 | 3 | Basic configuration of the [Gitea plugin](https://plugins.jenkins.io/gitea/) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | giteaServers: 10 | servers: 11 | - credentialsId: 12 | displayName: scm 13 | manageHooks: true 14 | serverUrl: https://my-scm-url 15 | ``` 16 | -------------------------------------------------------------------------------- /demos/github-oauth/README.md: -------------------------------------------------------------------------------- 1 | # Configure github-oauth-plugin 2 | 3 | Basic configuration of the [GitHub Authentication plugin](https://plugins.jenkins.io/github-oauth) 4 | 5 | ## sample-configuration 6 | 7 | ```yaml 8 | jenkins: 9 | securityRealm: 10 | github: 11 | githubWebUri: "https://github.com" 12 | githubApiUri: "https://api.github.com" 13 | clientID: "someId" 14 | clientSecret: "${GITHUB_SECRET}" 15 | oauthScopes: "read:org,user:email" 16 | ``` 17 | -------------------------------------------------------------------------------- /demos/github/README.md: -------------------------------------------------------------------------------- 1 | # Configure GitHub 2 | 3 | Basic configuration of the [GitHub plugin](https://plugins.jenkins.io/github) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | githubpluginconfig: 10 | configs: 11 | - name: "InHouse GitHub EE" 12 | apiUrl: "https://github.domain.local/api/v3" 13 | credentialsId: "[GitHubEEUser]" 14 | manageHooks: true 15 | ``` 16 | 17 | Please note that the _credentialsId_ takes the id of a set of credentials created as a "Secret Text Credential", i.e. a token from a GitHub user. 18 | -------------------------------------------------------------------------------- /demos/gitlab/README.md: -------------------------------------------------------------------------------- 1 | # Configure gitlab plugin 2 | 3 | Basic configuration of the [Gitlab plugin](https://plugins.jenkins.io/gitlab-plugin) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | credentials: 9 | system: 10 | domainCredentials: 11 | - credentials: 12 | - gitLabApiTokenImpl: 13 | scope: SYSTEM 14 | id: gitlab_token 15 | apiToken: "${BIND_TOKEN}" 16 | description: "Gitlab Token" 17 | unclassified: 18 | gitlabconnectionconfig: 19 | connections: 20 | - apiTokenId: gitlab_token 21 | clientBuilderId: "autodetect" 22 | connectionTimeout: 20 23 | ignoreCertificateErrors: true 24 | name: "my_gitlab_server" 25 | readTimeout: 10 26 | url: "https://gitlab.com/" 27 | ``` 28 | -------------------------------------------------------------------------------- /demos/golang/README.md: -------------------------------------------------------------------------------- 1 | # Configure GoLang 2 | 3 | Basic configuration of [Golang](https://plugins.jenkins.io/golang/) 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | tool: 9 | go: 10 | installations: 11 | - name: "go_lang" 12 | properties: 13 | - installSource: 14 | installers: 15 | - golangInstaller: 16 | id: "1.18.3" 17 | ``` 18 | -------------------------------------------------------------------------------- /demos/google-login/README.md: -------------------------------------------------------------------------------- 1 | # google-login-plugin 2 | 3 | Example configuration of the [Google Login plugin](https://plugins.jenkins.io/google-login), 4 | providing oauth authorization to Jenkins. 5 | 6 | For more info on what values to use, follow the instructions in the [README](https://github.com/jenkinsci/google-login-plugin) of the plugin. 7 | 8 | ## sample-configuration 9 | 10 | ```yaml 11 | jenkins: 12 | securityRealm: 13 | googleOAuth2: 14 | clientId: "___.apps.googleusercontent.com" 15 | clientSecret: "${GOOGLE_OAUTH_SECRET}" 16 | ``` 17 | -------------------------------------------------------------------------------- /demos/google-login/config.yaml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Example of configuring of google login plugin in Jenkins" 3 | 4 | securityRealm: 5 | googleOAuth2: 6 | # The Client ID from the Google Developer Console 7 | clientId: "${GOOGLE_OAUTH_CLIENT_ID}" 8 | # The Client Secret from the Google Developer Console. 9 | clientSecret: "${GOOGLE_OAUTH_CLIENT_SECRET}" 10 | # Optional. If present, access to Jenkins will be restricted to users in the provided Google Apps Domain. 11 | # A comma separated list can be used to specify multiple domains. 12 | domain: "" 13 | -------------------------------------------------------------------------------- /demos/graphite/README.md: -------------------------------------------------------------------------------- 1 | # configure Metrics Graphite plugin 2 | 3 | ## sample configuration 4 | 5 | ```yaml 6 | unclassified: 7 | graphiteserver: 8 | servers: 9 | - hostname: "1.2.3.4" 10 | port: 2003 11 | prefix: jenkins.controller. 12 | ``` 13 | -------------------------------------------------------------------------------- /demos/jdk/README.md: -------------------------------------------------------------------------------- 1 | # Configure JDK 2 | 3 | Basic configuration of the [JDK](https://plugins.jenkins.io/jdk-tool), using [AdoptOpenJDK installer](https://plugins.jenkins.io/adoptopenjdk/) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | tool: 9 | jdk: 10 | installations: 11 | - name: jdk11 12 | home: "/jdk" 13 | properties: 14 | - installSource: 15 | installers: 16 | - adoptOpenJdkInstaller: 17 | id: "jdk-11.0.14+9" 18 | ``` 19 | -------------------------------------------------------------------------------- /demos/jira/README.md: -------------------------------------------------------------------------------- 1 | # Configure Jira 2 | 3 | Basic configuration of the [Jira plugin](https://plugins.jenkins.io/jira) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | jiraGlobalConfiguration: 10 | sites: 11 | - url: "http://jira.codehaus.org/" 12 | - url: "http://issues.jenkins.io/" 13 | ``` 14 | -------------------------------------------------------------------------------- /demos/jobs/multibranch-github.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | multibranchPipelineJob('image-jenkins') { 4 | branchSources { 5 | github { 6 | // The id option in the Git and GitHub branch source contexts is now mandatory (JENKINS-43693). 7 | id('12312313') // IMPORTANT: use a constant and unique identifier 8 | scanCredentialsId('github') 9 | repoOwner('my-org') 10 | repository('my-repository') 11 | apiUri('http://my-github-server/api/v3') // Optional, needed for private github enterprise servers 12 | } 13 | } 14 | orphanedItemStrategy { 15 | discardOldItems { 16 | numToKeep(1) 17 | } 18 | } 19 | triggers { 20 | periodic(5) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demos/jobs/pipeline.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | folder('testjobs') 4 | - script: > 5 | pipelineJob('testjobs/default-agent') { 6 | definition { 7 | cps { 8 | script("""\ 9 | pipeline { 10 | agent any 11 | stages { 12 | stage ('test') { 13 | steps { 14 | echo "hello" 15 | } 16 | } 17 | } 18 | }""".stripIndent()) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /demos/kubernetes/config.yml: -------------------------------------------------------------------------------- 1 | # A Kubernetes ConfigMap providing the configuration-as-code 2 | # default config for Kubernetes plugin and an example job 3 | --- 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: jenkins-configuration-as-code 8 | data: 9 | configuration-as-code.yaml: | 10 | jenkins: 11 | clouds: 12 | - kubernetes: 13 | name: kubernetes 14 | containerCapStr: 100 15 | templates: 16 | - name: maven 17 | label: mavenpodtemplate 18 | containers: 19 | - name: maven 20 | image: maven:3.3.9-jdk-8-alpine 21 | ttyEnabled: true 22 | command: cat 23 | args: "" 24 | unclassified: 25 | location: 26 | url: http://jenkins/ 27 | jobs: 28 | - script: > 29 | pipelineJob('configuration-as-code') { 30 | definition { 31 | cps { 32 | sandbox() 33 | script(""" 34 | podTemplate(label: 'mypod') { 35 | node('mypod') { 36 | sh "hostname" 37 | } 38 | } 39 | """.stripIndent()) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /demos/kubernetes/service-account.yml: -------------------------------------------------------------------------------- 1 | # In GKE need to get RBAC permissions first with 2 | # kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin [--user=|--group=] 3 | 4 | --- 5 | apiVersion: v1 6 | kind: ServiceAccount 7 | metadata: 8 | name: jenkins 9 | 10 | --- 11 | kind: Role 12 | apiVersion: rbac.authorization.k8s.io/v1beta1 13 | metadata: 14 | name: jenkins 15 | rules: 16 | - apiGroups: [""] 17 | resources: ["pods"] 18 | verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] 19 | - apiGroups: [""] 20 | resources: ["pods/exec"] 21 | verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] 22 | - apiGroups: [""] 23 | resources: ["pods/log"] 24 | verbs: ["get", "list", "watch"] 25 | - apiGroups: [""] 26 | resources: ["secrets"] 27 | verbs: ["get"] 28 | 29 | --- 30 | apiVersion: rbac.authorization.k8s.io/v1beta1 31 | kind: RoleBinding 32 | metadata: 33 | name: jenkins 34 | roleRef: 35 | apiGroup: rbac.authorization.k8s.io 36 | kind: Role 37 | name: jenkins 38 | subjects: 39 | - kind: ServiceAccount 40 | name: jenkins 41 | -------------------------------------------------------------------------------- /demos/ldap/README.md: -------------------------------------------------------------------------------- 1 | # configure ldap plugin 2 | 3 | ## sample configuration 4 | 5 | ```yaml 6 | jenkins: 7 | securityRealm: 8 | ldap: 9 | configurations: 10 | - server: ldap.acme.com 11 | rootDN: dc=acme,dc=fr 12 | managerDN: "manager" 13 | managerPasswordSecret: "${LDAP_PASSWORD}" 14 | userSearch: "(&(objectCategory=User)(sAMAccountName={0}))" 15 | groupSearchFilter: "(&(cn={0})(objectclass=group))" 16 | groupMembershipStrategy: 17 | fromGroupSearch: 18 | filter: "(&(objectClass=group)(|(cn=GROUP_1)(cn=GROUP_2)))" 19 | cache: 20 | size: 100 21 | ttl: 10 22 | userIdStrategy: CaseInsensitive 23 | groupIdStrategy: CaseSensitive 24 | ``` 25 | 26 | ## implementation note 27 | 28 | `hudson.security.LDAPSecurityRealm` can be configured using its `@DataBoundConstructor` parameters without any dedicated 29 | adapter code. 30 | It is identified as `ldap` as it implements the `SecurityRealm` extension point, so we can define a "natural" symbol name 31 | for it. 32 | -------------------------------------------------------------------------------- /demos/log-recorder/README.md: -------------------------------------------------------------------------------- 1 | # Configure log recorders 2 | 3 | Requires jenkins >= 2.224 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | jenkins: 9 | log: 10 | recorders: 11 | - name: "JCasC" 12 | loggers: 13 | - level: "WARNING" 14 | name: "io.jenkins.plugins.casc" 15 | ``` 16 | -------------------------------------------------------------------------------- /demos/mailer/README.md: -------------------------------------------------------------------------------- 1 | # mailer plugin 2 | 3 | Requires `mailer-plugin` >= 1.25 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | mailer: 10 | replyToAddress: do-not-reply@acme.org 11 | smtpHost: smtp.acme.org 12 | smtpPort: 4441 13 | ``` 14 | -------------------------------------------------------------------------------- /demos/matrix-auth/README.md: -------------------------------------------------------------------------------- 1 | # Configure Matrix Authorization Strategy 2 | 3 | Basic configuration of the [Matrix Authorization Strategy plugin](https://plugins.jenkins.io/matrix-auth) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | jenkins: 9 | securityRealm: 10 | local: 11 | allowsSignup: false 12 | users: 13 | - id: test 14 | password: test 15 | 16 | authorizationStrategy: 17 | globalMatrix: 18 | permissions: 19 | - "Overall/Read:anonymous" 20 | - "Overall/Administer:authenticated" 21 | ``` 22 | -------------------------------------------------------------------------------- /demos/mercurial/README.md: -------------------------------------------------------------------------------- 1 | # Configure mercurial 2 | 3 | Basic configuration of the [Mercurial](https://plugins.jenkins.io/mercurial) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | tool: 9 | mercurialinstallation: 10 | installations: 11 | - name: "Mercurial 3" 12 | home: "/mercurial" 13 | config: | 14 | [defaults] 15 | clone = --uncompressed 16 | bundle = --type none 17 | executable: "INSTALLATION/bin/hg" 18 | useCaches: true 19 | debug: false 20 | masterCacheRoot: "/cache/root" 21 | useSharing: false 22 | properties: 23 | - installSource: 24 | installers: 25 | - command: 26 | toolHome: "mercurial" 27 | label: "SomeLabel" 28 | command: "[ -d mercurial ] || wget -q -O - http://www.archlinux.org/packages/extra/x86_64/mercurial/download/ | xzcat | tar xvf -" 29 | ``` 30 | -------------------------------------------------------------------------------- /demos/msbuild/README.md: -------------------------------------------------------------------------------- 1 | # Configure MSBuild 2 | 3 | Basic configuration of [MSBuild](https://plugins.jenkins.io/msbuild) plugin. 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | tool: 9 | msbuild: 10 | installations: 11 | - name: "MSBuild Latest" 12 | home: "C:\\WINDOWS\\Microsoft.NET\\Framework\\14.0\\Bin\\MSBuild.exe" 13 | defaultArgs: "/p:Configuration=Debug" 14 | ``` 15 | -------------------------------------------------------------------------------- /demos/mstestrunner/README.md: -------------------------------------------------------------------------------- 1 | # Configure MSBuild 2 | 3 | Basic configuration of [MSTestRunner](https://plugins.jenkins.io/mstestrunner/) plugin. 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | tool: 9 | msTestInstallation: 10 | installations: 11 | - defaultArgs: "/category:SmokeTests" 12 | home: "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\MSTest.exe" 13 | name: "MSTest test" 14 | omitNoIsolation: true 15 | ``` 16 | -------------------------------------------------------------------------------- /demos/node-monitors/README.md: -------------------------------------------------------------------------------- 1 | # Configuring Node Monitors 2 | 3 | Node monitor configuration belongs under `jenkins` root element. 4 | Requires at least Jenkins `2.433`.
5 | 6 | Any monitor that is available but is not configured will be treated as ignored. 7 | Some monitors are capable to take agents offline when they are not ignored. Ignored 8 | monitors will still run and report data. 9 | 10 | ## sample configuration 11 | 12 | ```yaml 13 | jenkins: 14 | nodeMonitors: 15 | - "architecture" 16 | - diskSpace: 17 | freeSpaceThreshold: "3GB" 18 | - "swapSpace" 19 | - tmpSpace: 20 | freeSpaceThreshold: "3GB" 21 | - responseTime: 22 | ignored: true 23 | ``` -------------------------------------------------------------------------------- /demos/nodejs/README.md: -------------------------------------------------------------------------------- 1 | # Configure NodeJS 2 | 3 | Basic configuration of [NodeJS](https://plugins.jenkins.io/nodejs) 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | tool: 9 | nodejs: 10 | installations: 11 | - name: "NodeJS Latest" 12 | home: "" #required until nodejs-1.3.4 release (JENKINS-57508) 13 | properties: 14 | - installSource: 15 | installers: 16 | - nodeJSInstaller: 17 | id: "12.11.1" 18 | npmPackagesRefreshHours: 48 #default is 72 19 | ``` 20 | -------------------------------------------------------------------------------- /demos/pipeline-groovy-lib/README.md: -------------------------------------------------------------------------------- 1 | # Configure global libraries plugin 2 | 3 | Global Pipeline Libraries plugin configuration belongs under `unclassified` root element 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | globalLibraries: 10 | libraries: 11 | - name: "awesome-lib" 12 | retriever: 13 | modernSCM: 14 | scm: 15 | git: 16 | remote: "https://github.com/jenkins-infra/pipeline-library.git" 17 | ``` 18 | 19 | ## Using credentials 20 | 21 | ```yaml 22 | unclassified: 23 | globalLibraries: 24 | libraries: 25 | - name: "internal-pipeline-library" 26 | retriever: 27 | modernSCM: 28 | scm: 29 | git: 30 | remote: "git@github.com:furry-octo-lamp-inc/pipeline-library.git" 31 | credentialsId: "reimagined-parakeet-ssh" 32 | ``` 33 | -------------------------------------------------------------------------------- /demos/proxy/README.md: -------------------------------------------------------------------------------- 1 | # Configure proxy 2 | 3 | ## Sample configuration 4 | 5 | ```yaml 6 | jenkins: 7 | proxy: 8 | name: "proxyhost" 9 | port: 80 10 | userName: "login" 11 | secretPassword: "password" 12 | noProxyHost: "externalhost" 13 | testUrl: "http://google.com" 14 | ``` 15 | -------------------------------------------------------------------------------- /demos/proxy/proxy.yaml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | proxy: 3 | name: "proxyhost" 4 | port: 80 5 | userName: "login" 6 | secretPassword: "password" 7 | noProxyHost: "externalhost" 8 | testUrl: "http://google.com" 9 | -------------------------------------------------------------------------------- /demos/proxy/proxyMinimal.yaml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | proxy: 3 | name: "proxyhost" 4 | port: 80 5 | -------------------------------------------------------------------------------- /demos/saml/README.md: -------------------------------------------------------------------------------- 1 | # configure saml2.0 plugin 2 | 3 | ## sample configuration 4 | 5 | ```yaml 6 | jenkins: 7 | securityRealm: 8 | saml: 9 | binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 10 | displayNameAttributeName: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" 11 | emailAttributeName: "Email" 12 | groupsAttributeName: "http://schemas.xmlsoap.org/claims/Group" 13 | idpMetadataConfiguration: 14 | period: 0 15 | url: "https://abc.com" 16 | 17 | maximumAuthenticationLifetime: 86400 18 | usernameAttributeName: "NameID" 19 | usernameCaseConversion: "none" 20 | ``` -------------------------------------------------------------------------------- /demos/sbt/README.md: -------------------------------------------------------------------------------- 1 | # Configure sbt plugin 2 | 3 | Basic configuration of the [Sbt plugin](https://plugins.jenkins.io/sbt) 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | tool: 9 | sbt: 10 | installations: 11 | - name: sbt 12 | home: "/usr/bin/sbt" 13 | properties: 14 | - installSource: 15 | installers: 16 | - sbtInstaller: 17 | id: "1.2.8" 18 | ``` 19 | -------------------------------------------------------------------------------- /demos/simple-theme-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Configure simple-theme-plugin plugin 2 | 3 | Basic configuration of the [Simple Theme plugin](https://plugins.jenkins.io/simple-theme-plugin) 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | appearance: 9 | simpleTheme: 10 | elements: 11 | - cssUrl: 12 | url: "https://example.bogus/test.css" 13 | - cssText: 14 | text: ".testcss { color: red }" 15 | - jsUrl: 16 | url: "https://example.bogus/test.js" 17 | - faviconUrl: 18 | url: "https://vignette.wikia.nocookie.net/deadpool/images/6/64/Favicon.ico" 19 | ``` 20 | -------------------------------------------------------------------------------- /demos/slack/README.md: -------------------------------------------------------------------------------- 1 | # Configure Slack 2 | 3 | Basic configuration of the [Slack plugin](https://plugins.jenkins.io/slack) 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | credentials: 9 | system: 10 | domainCredentials: 11 | - credentials: 12 | - string: 13 | scope: GLOBAL 14 | id: slack-token 15 | secret: "${SLACK_TOKEN}" 16 | description: Slack token 17 | 18 | unclassified: 19 | slackNotifier: 20 | teamDomain: # i.e. your-company (just the workspace name not the full url) 21 | tokenCredentialId: slack-token 22 | ``` 23 | -------------------------------------------------------------------------------- /demos/sonarqube/README.md: -------------------------------------------------------------------------------- 1 | # configure sonar plugin 2 | 3 | ## sample configuration 4 | 5 | Sample configuration for the [SonarQube plugin](https://plugins.jenkins.io/sonar). 6 | 7 | *Below sample configuration willingly set all attributes values because of current issues with Sonar plugin 2.9 version. (cf. #982)* 8 | 9 | ```yaml 10 | credentials: 11 | system: 12 | domainCredentials: 13 | - credentials: 14 | - string: 15 | scope: GLOBAL 16 | id: "token" 17 | secret: "secret value" 18 | description: "Sonar token" 19 | 20 | unclassified: 21 | sonarglobalconfiguration: # mandatory 22 | buildWrapperEnabled: true 23 | installations: # mandatory 24 | - name: "TEST" # id of the SonarQube configuration - to be used in jobs 25 | serverUrl: "http://url:9000" 26 | credentialsId: token # id of the credentials containing sonar auth token (since 2.9 version) 27 | #serverAuthenticationToken: "token" # for retrocompatibility with versions < 2.9 28 | mojoVersion: "mojoVersion" 29 | additionalProperties: "blah=blah" 30 | additionalAnalysisProperties: "additionalAnalysisProperties" 31 | triggers: 32 | skipScmCause: true 33 | skipUpstreamCause: true 34 | envVar: "envVar" 35 | ``` 36 | 37 | ## notes 38 | 39 | You can add multiple installations. 40 | -------------------------------------------------------------------------------- /demos/statistics-gatherer/README.md: -------------------------------------------------------------------------------- 1 | # Configure statistics-gatherer plugin 2 | 3 | Sample configuration for the [Statistics Gatherer plugin](https://plugins.jenkins.io/statistics-gatherer). 4 | 5 | ## sample configuration 6 | 7 | Sample configuration for the Statistics Gatherer plugin. 8 | 9 | ```yaml 10 | unclassified: 11 | statisticsconfiguration: 12 | buildUrl: "http://elasticsearch:9200/jenkins-stats/builds" 13 | shouldSendApiHttpRequests: true 14 | buildInfo: true 15 | queueInfo: false 16 | projectInfo: false 17 | buildStepInfo: false 18 | scmCheckoutInfo: true 19 | ``` 20 | -------------------------------------------------------------------------------- /demos/terraform/README.md: -------------------------------------------------------------------------------- 1 | # Configure terraform plugin 2 | 3 | Requires `terrorform-plugin` >= 1.0.10 4 | 5 | Sample configuration for the [Terraform plugin](https://plugins.jenkins.io/terraform). 6 | 7 | ## Sample configuration 8 | 9 | ```yaml 10 | tool: 11 | terraform: 12 | installations: 13 | - name: "terraform" 14 | home: "/terraform-0.11" 15 | properties: 16 | - installSource: 17 | installers: 18 | - terraformInstaller: 19 | id: "0.11.9-linux-amd64" 20 | ``` 21 | 22 | An example of the job definition, with the JobDSL, that uses the terraform wrapper. 23 | 24 | ```yaml 25 | jobs: 26 | - script: > 27 | job("terraform-job") { 28 | description() 29 | keepDependencies(false) 30 | disabled(false) 31 | concurrentBuild(false) 32 | wrappers { 33 | terraformBuildWrapper { 34 | variables("") 35 | terraformInstallation("terraform") 36 | doGetUpdate(true) 37 | doNotApply(false) 38 | doDestroy(false) 39 | config { 40 | value("inline") 41 | inlineConfig("") 42 | fileConfig("") 43 | } 44 | } 45 | } 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /demos/tfs/README.md: -------------------------------------------------------------------------------- 1 | # TFS/Team Services plugin 2 | 3 | TFS plugin configuration belongs under `unclassified` root element 4 | 5 | ## sample configuration 6 | 7 | ```yaml 8 | unclassified: 9 | teampluginglobalconfig: 10 | collectionConfigurations: 11 | - collectionUrl: http://test.com 12 | credentialsId: tfsCredentials 13 | enableTeamPushTriggerForAllJobs: true 14 | enableTeamStatusForAllJobs: true 15 | #userAccountMapper: 16 | configFolderPerNode: true 17 | ``` 18 | 19 | ## implementation note 20 | 21 | User account name mapping strategy is not yet supported. 22 | -------------------------------------------------------------------------------- /demos/view-job-filters/README.md: -------------------------------------------------------------------------------- 1 | # Configure View Job Filters 2 | 3 | Basic configuration of the [View Job Filters plugin](https://plugins.jenkins.io/view-job-filters/) 4 | 5 | ## Sample configuration 6 | 7 | ```yaml 8 | jenkins: 9 | views: 10 | - list: 11 | columns: 12 | - "status" 13 | - "weather" 14 | - "jobName" 15 | - "lastSuccess" 16 | - "lastFailure" 17 | - "lastDuration" 18 | - "buildButton" 19 | jobFilters: 20 | - buildDurationFilter: 21 | amount: "60.0" 22 | amountTypeString: "Days" 23 | buildCountTypeString: "Latest" 24 | buildDurationMinutes: "5" 25 | includeExcludeTypeString: "includeMatched" 26 | lessThan: true 27 | - buildStatusFilter: 28 | building: false 29 | inBuildQueue: true 30 | includeExcludeTypeString: "includeMatched" 31 | neverBuilt: true 32 | - securityFilter: 33 | build: false 34 | configure: true 35 | includeExcludeTypeString: "includeMatched" 36 | permissionCheckType: "MustMatchAll" 37 | workspace: false 38 | name: "MyFirstView" 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/COMPATIBILITY.md: -------------------------------------------------------------------------------- 1 | # Plugin Compatibility issues with Configuration as Code plugin 2 | 3 | Often JCasC is not the one having issues with configuring a plugin. 4 | Because of how the JCasC was designed, plugins _should_ be expected to work out of the box if they followed the main patterns in place. 5 | We rely heavily on data bindings so if a plugin is not setup according to expected design pattern for data binding. 6 | 7 | JCasC cannot communicate properly with the plugin without fixing their data binding issues or writing a special configurator. 8 | The path of least resistance is fixing the data binding, since other plugins in the Jenkins eco-system rely heavily on data binding. 9 | 10 | The list of already known issues in the Jenkins issue tracker, are tracked through using the label `jcasc-compatibility` [see dashboard][dashboard]. 11 | 12 | ## Reporting Plugin Compatibility issue 13 | 14 | Create an issue at [issues.jenkins.io](https://issues.jenkins.io) with the label `jcasc-compatibility` and fill out the details. 15 | [Link to create issue][new-jira-issue] 16 | Create a Github issue for crosslink purposes on this repository. 17 | 18 | If you prefer the [new issue for plugin compatibility][new-github-issue] should take you through the entire workflow. 19 | 20 | [dashboard]: https://issues.jenkins.io/secure/Dashboard.jspa?selectPageId=18341 21 | [new-jira-issue]: https://issues.jenkins.io/secure/CreateIssueDetails!init.jspa?pid=10172&issuetype=1&summary=Cannot+configure+X+plugin+with+JCasC&labels=jcasc-compatibility 22 | [new-github-issue]: https://github.com/jenkinsci/configuration-as-code-plugin/issues/new?assignees=&labels=plugin-compatibility&template=4-plugin-compatibility.yml 23 | -------------------------------------------------------------------------------- /docs/benchmarks/jmh-benchmarks.md: -------------------------------------------------------------------------------- 1 | # JMH benchmarks with Configuration-as-Code 2 | 3 | You can configure the instance that is started for benchmarks using Configuration as Code by extending 4 | `CascJmhBenchmarkState` in your benchmarks instead of `JmhBenchmarkState` and overriding the `getResourcePath()` and 5 | `getEnclosingClass()` methods. 6 | 7 | `getResourcePath()` should returning the path to where your YAML configuration is located. 8 | `getEnclosingClass()` should return the class containing the state for the benchmark (`MyBenchmark` in the example below). 9 | 10 | ## Example 11 | 12 | Just like regular JMH benchmarks using `JmhBenchmarkState`, you need to have a `public static` inner class: 13 | 14 | ```java 15 | @JmhBenchmark 16 | public class MyBenchmark { 17 | public static class MyState extends CascJmhBenchmarkState { 18 | @Nonnull 19 | @Override 20 | protected String getResourcePath() { 21 | return "config.yaml"; 22 | } 23 | 24 | @Nonnull 25 | @Override 26 | protected Class getEnclosingClass() { 27 | return MyBenchmark.class; 28 | } 29 | } 30 | 31 | // ... 32 | } 33 | ``` 34 | 35 | If you override the `setup()` method of `CascJmhBenchmarkState`, make sure to call `super.setup()` so 36 | that configuration as code works as intended. 37 | 38 | You can find more examples in the [Role Strategy Plugin](https://github.com/jenkinsci/role-strategy-plugin/tree/master/src/test/java/jmh). 39 | -------------------------------------------------------------------------------- /docs/features/mergeStrategy.md: -------------------------------------------------------------------------------- 1 | # Merge Strategy 2 | 3 | It's possible to load multiple config files. CasC can load YAML files from a directory. 4 | And it's convenient to maintain if we split different parts of Jenkins into multiple files. 5 | 6 | ## Supported strategies 7 | 8 | * [ErrorOnConflictMergeStrategy](../../plugin/src/main/java/io/jenkins/plugins/casc/yaml/ErrorOnConflictMergeStrategy.java) (default) 9 | * The strategy name is `errorOnConflict`. 10 | * Throws an exception if there's a conflict in multiple YAML files. 11 | * [OverrideMergeStrategy](../../plugin/src/main/java/io/jenkins/plugins/casc/yaml/OverrideMergeStrategy.java) 12 | * The strategy name is `override` 13 | * Override the config files according to the loading order. 14 | 15 | ## Use cases 16 | 17 | You can provide two YAML config files. They can be system and user config files. Then allow users to change their file and override the system configuration. 18 | 19 | ## How to 20 | 21 | There are two ways to configure the strategy name. 22 | 23 | * set the environment `CASC_MERGE_STRATEGY` 24 | * set the system property `casc.merge.strategy` 25 | 26 | The strategy name could be `errorOnConflict` or `override`. 27 | -------------------------------------------------------------------------------- /docs/migrate.md: -------------------------------------------------------------------------------- 1 | # How to migrate your traditionally configured Jenkins 2 | 3 | So you're tired of manually configuring Jenkins each time you want to introduce a plugin or change existing setup? 4 | Or maybe you're not feeling confident enough with the change you have in mind? 5 | 6 | Jenkins Configuration as Code solves both problems - you don't need to access Jenkins to implement a change and you can always revert to previous version of configuration (if you keep your configuration under version control) 7 | 8 | ## Create jenkins.yaml from scratch 9 | 10 | We've decided to use the YAML format so writing the configuration "by hand" should be easy. Your existing Jenkins can be also used as a documentation - the YAML file tries to mimic the UI you're used to as much as possible. 11 | 12 | Plugin provides documentation generated for your specific Jenkins instance - after you install it, and it is available at: 13 | `http://[your_jenkins_url]/configuration-as-code/` 14 | 15 | Various samples of plugins' configuration can be found in [demos](../demos) folder 16 | 17 | ## Export existing configuration 18 | 19 | To be able to do that, you need to install the plugin manually on your working Jenkins instance and use the [export function](/docs/features/configExport.md). 20 | This step will produce an initial configuration you can use to create configuration YAMLs for your Jenkins instance. 21 | -------------------------------------------------------------------------------- /images/BraceYourselves.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/images/BraceYourselves.jpg -------------------------------------------------------------------------------- /images/CasC_new-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/images/CasC_new-03.png -------------------------------------------------------------------------------- /images/reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/images/reference.png -------------------------------------------------------------------------------- /images/sample_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/images/sample_form.png -------------------------------------------------------------------------------- /images/unclassified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/images/unclassified.png -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/ArtifactManagerS3Test.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.CoreMatchers.is; 5 | import static org.hamcrest.MatcherAssert.assertThat; 6 | import static org.hamcrest.collection.IsCollectionWithSize.hasSize; 7 | 8 | import hudson.DescriptorExtensionList; 9 | import io.jenkins.plugins.artifact_manager_jclouds.s3.S3BlobStoreConfig; 10 | import io.jenkins.plugins.aws.global_configuration.CredentialsAwsGlobalConfiguration; 11 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 12 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 13 | import jenkins.model.ArtifactManagerFactory; 14 | import jenkins.model.ArtifactManagerFactoryDescriptor; 15 | import org.junit.Rule; 16 | import org.junit.Test; 17 | 18 | public class ArtifactManagerS3Test { 19 | 20 | @Rule 21 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 22 | 23 | @Test 24 | @ConfiguredWithReadme(value = "artifact-manager-s3/README.md") 25 | public void configure_artifact_manager() { 26 | assertThat(CredentialsAwsGlobalConfiguration.get().getRegion(), is(equalTo("us-east-1"))); 27 | assertThat(S3BlobStoreConfig.get().getPrefix(), is(equalTo("jenkins_data/"))); 28 | 29 | final DescriptorExtensionList artifactManagers = 30 | ArtifactManagerFactoryDescriptor.all(); 31 | assertThat(artifactManagers, hasSize(1)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/AzureKeyVaultTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.convertYamlFileToJson; 4 | import static io.jenkins.plugins.casc.misc.Util.validateSchema; 5 | import static org.hamcrest.MatcherAssert.assertThat; 6 | import static org.hamcrest.Matchers.empty; 7 | 8 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | 12 | public class AzureKeyVaultTest { 13 | 14 | @Rule 15 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 16 | 17 | @Test 18 | public void validJsonSchema() throws Exception { 19 | assertThat(validateSchema(convertYamlFileToJson(this, "azureKeyVault.yml")), empty()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/DockerWorkflowTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 8 | import org.jenkinsci.plugins.docker.workflow.declarative.GlobalConfig; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | 12 | public class DockerWorkflowTest { 13 | 14 | @Rule 15 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 16 | 17 | @Test 18 | @ConfiguredWithReadme("docker-workflow/README.md") 19 | public void configure_global_definition() { 20 | GlobalConfig config = GlobalConfig.get(); 21 | 22 | assertNotNull(config); 23 | assertEquals("label-casc", config.getDockerLabel()); 24 | assertEquals("my.docker.endpoint", config.getRegistry().getUrl()); 25 | assertEquals("credId", config.getRegistry().getCredentialsId()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/ExternalWorkspaceManagerTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.collection.IsCollectionWithSize.hasSize; 5 | 6 | import hudson.ExtensionList; 7 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 8 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 9 | import org.jenkinsci.plugins.ewm.steps.ExwsAllocateStep; 10 | import org.jenkinsci.plugins.ewm.steps.ExwsStep; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Victor Martinez 16 | */ 17 | public class ExternalWorkspaceManagerTest { 18 | 19 | @Rule 20 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 21 | 22 | @Test 23 | @ConfiguredWithReadme("external-workspace-manager/README.md") 24 | public void configure_external_workspace_manager() { 25 | // Already validated in the plugin itself: 26 | // https://github.com/jenkinsci/external-workspace-manager-plugin/pull/68 27 | 28 | // Let's run some basic validations 29 | ExwsAllocateStep.DescriptorImpl descriptor = 30 | ExtensionList.lookupSingleton(ExwsAllocateStep.DescriptorImpl.class); 31 | assertThat(descriptor.getDiskPools(), hasSize(1)); 32 | 33 | ExwsStep.DescriptorImpl globalTemplateDescriptor = ExtensionList.lookupSingleton(ExwsStep.DescriptorImpl.class); 34 | assertThat(globalTemplateDescriptor.getTemplates(), hasSize(5)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/GitHostKeyVerificationTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.CoreMatchers.instanceOf; 4 | import static org.hamcrest.CoreMatchers.startsWith; 5 | import static org.hamcrest.MatcherAssert.assertThat; 6 | 7 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 8 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 9 | import jenkins.model.GlobalConfiguration; 10 | import org.jenkinsci.plugins.gitclient.GitHostKeyVerificationConfiguration; 11 | import org.jenkinsci.plugins.gitclient.verifier.ManuallyProvidedKeyVerificationStrategy; 12 | import org.jenkinsci.plugins.gitclient.verifier.SshHostKeyVerificationStrategy; 13 | import org.junit.ClassRule; 14 | import org.junit.Test; 15 | 16 | /** 17 | * @author Mark Waite 18 | */ 19 | public class GitHostKeyVerificationTest { 20 | 21 | @ClassRule 22 | @ConfiguredWithReadme("git-client/README.md#2") 23 | public static JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 24 | 25 | @Test 26 | public void git_client_host_key_verifier() { 27 | final GitHostKeyVerificationConfiguration config = 28 | GlobalConfiguration.all().get(GitHostKeyVerificationConfiguration.class); 29 | SshHostKeyVerificationStrategy strategy = config.getSshHostKeyVerificationStrategy(); 30 | assertThat(strategy, instanceOf(ManuallyProvidedKeyVerificationStrategy.class)); 31 | ManuallyProvidedKeyVerificationStrategy manually = (ManuallyProvidedKeyVerificationStrategy) strategy; 32 | assertThat(manually.getApprovedHostKeys(), startsWith("bitbucket.org ssh-ed25519 ")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/GitHubTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.hamcrest.collection.IsCollectionWithSize.hasSize; 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 9 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 10 | import jenkins.model.GlobalConfiguration; 11 | import org.jenkinsci.plugins.github.config.GitHubPluginConfig; 12 | import org.jenkinsci.plugins.github.config.GitHubServerConfig; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | 16 | /** 17 | * @author v1v (Victor Martinez) 18 | */ 19 | public class GitHubTest { 20 | 21 | @Rule 22 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 23 | 24 | @Test 25 | @ConfiguredWithReadme("github/README.md") 26 | public void configure_github() { 27 | 28 | final GitHubPluginConfig configuration = GlobalConfiguration.all().get(GitHubPluginConfig.class); 29 | assertThat(configuration.getConfigs(), hasSize(1)); 30 | 31 | GitHubServerConfig config = configuration.getConfigs().get(0); 32 | assertThat(config.getApiUrl(), is("https://github.domain.local/api/v3")); 33 | assertThat(config.getCredentialsId(), is("[GitHubEEUser]")); 34 | assertThat(config.getName(), is("InHouse GitHub EE")); 35 | assertTrue(config.isManageHooks()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/GiteaServerTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 8 | import jenkins.model.GlobalConfiguration; 9 | import org.jenkinsci.plugin.gitea.servers.GiteaServer; 10 | import org.jenkinsci.plugin.gitea.servers.GiteaServers; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | public class GiteaServerTest { 15 | 16 | @Rule 17 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 18 | 19 | @Test 20 | @ConfiguredWithReadme("gitea/README.md") 21 | public void configure_gitea() { 22 | final GiteaServers configuration = GlobalConfiguration.all().get(GiteaServers.class); 23 | assertEquals(configuration.getServers().size(), 1); 24 | 25 | GiteaServer config = configuration.getServers().get(0); 26 | assertEquals("https://my-scm-url", config.getServerUrl()); 27 | assertEquals("", config.getCredentialsId()); 28 | assertEquals("scm", config.getDisplayName()); 29 | assertTrue(config.isManageHooks()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/GitscmTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import hudson.ExtensionList; 8 | import hudson.plugins.git.GitSCM; 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author v1v (Victor Martinez) 16 | */ 17 | public class GitscmTest { 18 | 19 | @Rule 20 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 21 | 22 | @Test 23 | @ConfiguredWithReadme("git/README.md") 24 | public void configure_git() { 25 | final GitSCM.DescriptorImpl descriptor = ExtensionList.lookupSingleton(GitSCM.DescriptorImpl.class); 26 | assertNotNull(descriptor); 27 | assertEquals("jenkins", descriptor.getGlobalConfigName()); 28 | assertEquals("jenkins@domain.local", descriptor.getGlobalConfigEmail()); 29 | assertTrue(descriptor.isCreateAccountBasedOnEmail()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/GlobalMatrixAuthorizationTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import hudson.security.GlobalMatrixAuthorizationStrategy; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import jenkins.model.Jenkins; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Mads Nielsen 16 | * @since 1.0 17 | */ 18 | public class GlobalMatrixAuthorizationTest { 19 | 20 | @Rule 21 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 22 | 23 | @Test 24 | @ConfiguredWithReadme("matrix-auth/README.md") 25 | public void checkCorrectlyConfiguredPermissions() { 26 | assertEquals( 27 | "The configured instance must use the Global Matrix Authentication Strategy", 28 | GlobalMatrixAuthorizationStrategy.class, 29 | Jenkins.get().getAuthorizationStrategy().getClass()); 30 | GlobalMatrixAuthorizationStrategy gms = 31 | (GlobalMatrixAuthorizationStrategy) Jenkins.get().getAuthorizationStrategy(); 32 | 33 | List adminPermission = 34 | new ArrayList<>(gms.getGrantedPermissions().get(Jenkins.ADMINISTER)); 35 | assertEquals("authenticated", adminPermission.get(0)); 36 | 37 | List readPermission = 38 | new ArrayList<>(gms.getGrantedPermissions().get(Jenkins.READ)); 39 | assertEquals("anonymous", readPermission.get(0)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/JenkinsReadmeDemoTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.CoreMatchers.containsString; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import hudson.model.Node.Mode; 8 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 9 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 10 | import jenkins.model.Jenkins; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author v1v (Victor Martinez) 16 | */ 17 | public class JenkinsReadmeDemoTest { 18 | 19 | @Rule 20 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 21 | 22 | @Test 23 | @ConfiguredWithReadme("jenkins/README.md#0") 24 | public void configure_demo_first_code_block() { 25 | final Jenkins jenkins = Jenkins.get(); 26 | assertEquals( 27 | "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n", 28 | jenkins.getSystemMessage()); 29 | assertEquals(5, jenkins.getNumExecutors()); 30 | assertEquals(2, jenkins.getScmCheckoutRetryCount()); 31 | assertEquals(Mode.NORMAL, jenkins.getMode()); 32 | } 33 | 34 | @Test 35 | @ConfiguredWithReadme("jenkins/README.md#1") 36 | public void configure_demo_second_code_block() { 37 | final Jenkins jenkins = Jenkins.get(); 38 | assertThat(jenkins.getSystemMessage(), containsString("Welcome to our build server.")); 39 | assertEquals(1, jenkins.getNumExecutors()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/JiraTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.hasSize; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import hudson.plugins.jira.JiraGlobalConfiguration; 8 | import hudson.plugins.jira.JiraSite; 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 11 | import java.util.List; 12 | import org.junit.Rule; 13 | import org.junit.Test; 14 | import org.jvnet.hudson.test.Issue; 15 | 16 | /** 17 | * @author Nicolas De Loof 18 | */ 19 | public class JiraTest { 20 | 21 | @Rule 22 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 23 | 24 | @Test 25 | @ConfiguredWithReadme("jira/README.md") 26 | @Issue("JENKINS-52906") 27 | public void configure_jira_project_globalconfig() { 28 | 29 | List sites = JiraGlobalConfiguration.get().getSites(); 30 | // Was failing due to JENKINS-52906 31 | assertThat(sites, hasSize(2)); 32 | assertEquals("http://jira.codehaus.org/", sites.get(0).getUrl().toString()); 33 | assertEquals("http://issues.jenkins.io/", sites.get(1).getUrl().toString()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/LDAPSecurityRealmTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.getJenkinsRoot; 4 | import static io.jenkins.plugins.casc.misc.Util.toStringFromYamlFile; 5 | import static io.jenkins.plugins.casc.misc.Util.toYamlString; 6 | import static org.hamcrest.MatcherAssert.assertThat; 7 | import static org.hamcrest.core.Is.is; 8 | 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 11 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 12 | import io.jenkins.plugins.casc.model.CNode; 13 | import org.junit.jupiter.api.Test; 14 | 15 | /** 16 | * @author Nicolas De Loof 17 | */ 18 | @WithJenkinsConfiguredWithCode 19 | class LDAPSecurityRealmTest { 20 | 21 | @Test 22 | @ConfiguredWithCode("LDAPSecurityRealmTestNoSecret.yml") 23 | void export_ldap_no_secret(JenkinsConfiguredWithCodeRule j) throws Exception { 24 | ConfiguratorRegistry registry = ConfiguratorRegistry.get(); 25 | ConfigurationContext context = new ConfigurationContext(registry); 26 | CNode yourAttribute = 27 | getJenkinsRoot(context).get("securityRealm").asMapping().get("ldap"); 28 | 29 | String exported = toYamlString(yourAttribute); 30 | 31 | String expected = toStringFromYamlFile(this, "LDAPSecurityRealmTestNoSecretExpected.yml"); 32 | 33 | assertThat(exported, is(expected)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/MSBuildTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import hudson.ExtensionList; 7 | import hudson.plugins.msbuild.MsBuildInstallation; 8 | import hudson.plugins.msbuild.MsBuildInstallation.DescriptorImpl; 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | public class MSBuildTest { 15 | @Rule 16 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 17 | 18 | @Test 19 | @ConfiguredWithReadme("msbuild/README.md") 20 | public void configure_msbuild() { 21 | final DescriptorImpl msBuildDescriptor = ExtensionList.lookupSingleton(DescriptorImpl.class); 22 | assertNotNull(msBuildDescriptor); 23 | assertEquals(1, msBuildDescriptor.getInstallations().length); 24 | 25 | final MsBuildInstallation msBuildInstallation = msBuildDescriptor.getInstallations()[0]; 26 | assertEquals("MSBuild Latest", msBuildInstallation.getName()); 27 | assertEquals("C:\\WINDOWS\\Microsoft.NET\\Framework\\14.0\\Bin\\MSBuild.exe", msBuildInstallation.getHome()); 28 | assertEquals("/p:Configuration=Debug", msBuildInstallation.getDefaultArgs()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/MSTestRunnerTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import hudson.ExtensionList; 8 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 9 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 10 | import org.jenkinsci.plugins.MsTestInstallation; 11 | import org.jenkinsci.plugins.MsTestInstallation.DescriptorImpl; 12 | import org.junit.Rule; 13 | import org.junit.Test; 14 | 15 | public class MSTestRunnerTest { 16 | @Rule 17 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 18 | 19 | @Test 20 | @ConfiguredWithReadme("mstestrunner/README.md") 21 | public void configure_mstestrunner() { 22 | final DescriptorImpl msTestRunnerDescriptor = ExtensionList.lookupSingleton(DescriptorImpl.class); 23 | assertNotNull(msTestRunnerDescriptor); 24 | assertEquals(1, msTestRunnerDescriptor.getInstallations().length); 25 | 26 | final MsTestInstallation msTestRunnerInstallation = 27 | msTestRunnerDescriptor.getInstallations()[0]; 28 | assertEquals("MSTest test", msTestRunnerInstallation.getName()); 29 | assertEquals( 30 | "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\MSTest.exe", 31 | msTestRunnerInstallation.getHome()); 32 | assertEquals("/category:SmokeTests", msTestRunnerInstallation.getDefaultArgs()); 33 | assertTrue(msTestRunnerInstallation.getOmitNoIsolation()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/MailerTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import hudson.tasks.Mailer; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 8 | import jenkins.model.Jenkins; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | 12 | /** 13 | * @author Nicolas De Loof 14 | */ 15 | public class MailerTest { 16 | 17 | @Rule 18 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 19 | 20 | @Test 21 | @ConfiguredWithReadme("mailer/README.md") 22 | public void configure_mailer() { 23 | final Jenkins jenkins = Jenkins.get(); 24 | final Mailer.DescriptorImpl descriptor = (Mailer.DescriptorImpl) jenkins.getDescriptor(Mailer.class); 25 | assertEquals("4441", descriptor.getSmtpPort()); 26 | assertEquals("do-not-reply@acme.org", descriptor.getReplyToAddress()); 27 | assertEquals("smtp.acme.org", descriptor.getSmtpHost()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/NodeJSTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import hudson.ExtensionList; 6 | import hudson.tools.InstallSourceProperty; 7 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 8 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 9 | import jenkins.plugins.nodejs.tools.NodeJSInstallation; 10 | import jenkins.plugins.nodejs.tools.NodeJSInstaller; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | public class NodeJSTest { 15 | 16 | @Rule 17 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 18 | 19 | @Test 20 | @ConfiguredWithReadme("nodejs/README.md") 21 | public void configure_nodejs() { 22 | final NodeJSInstallation.DescriptorImpl descriptor = 23 | ExtensionList.lookupSingleton(NodeJSInstallation.DescriptorImpl.class); 24 | assertEquals(1, descriptor.getInstallations().length); 25 | 26 | final NodeJSInstallation nodejs = descriptor.getInstallations()[0]; 27 | final InstallSourceProperty installSourceProperty = 28 | nodejs.getProperties().get(InstallSourceProperty.class); 29 | final NodeJSInstaller nodeJSInstaller = installSourceProperty.installers.get(NodeJSInstaller.class); 30 | assertEquals("12.11.1", nodeJSInstaller.id); 31 | assertEquals(48, nodeJSInstaller.getNpmPackagesRefreshHours().longValue()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/ProxyTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.junit.Assert.assertNotNull; 6 | import static org.jvnet.hudson.test.JenkinsMatchers.hasPlainText; 7 | 8 | import hudson.ProxyConfiguration; 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 11 | import jenkins.model.Jenkins; 12 | import org.junit.Rule; 13 | import org.junit.Test; 14 | 15 | /** 16 | * @author v1v (Victor Martinez) 17 | */ 18 | public class ProxyTest { 19 | 20 | @Rule 21 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 22 | 23 | @Test 24 | @ConfiguredWithReadme("proxy/README.md") 25 | public void configure_proxy() { 26 | final ProxyConfiguration proxy = Jenkins.get().proxy; 27 | assertNotNull(proxy); 28 | assertThat(proxy.getSecretPassword(), hasPlainText("password")); 29 | assertThat(proxy.getTestUrl(), is("http://google.com")); 30 | assertThat(proxy.getUserName(), is("login")); 31 | assertThat(proxy.name, is("proxyhost")); 32 | assertThat(proxy.noProxyHost, is("externalhost")); 33 | assertThat(proxy.port, is(80)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/RoundTripMailerTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import hudson.tasks.Mailer; 6 | import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest; 7 | import jenkins.model.Jenkins; 8 | import org.jvnet.hudson.test.JenkinsRule; 9 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 10 | 11 | @WithJenkins 12 | class RoundTripMailerTest extends AbstractRoundTripTest { 13 | @Override 14 | protected void assertConfiguredAsExpected(JenkinsRule j, String configContent) { 15 | final Jenkins jenkins = Jenkins.get(); 16 | final Mailer.DescriptorImpl descriptor = (Mailer.DescriptorImpl) jenkins.getDescriptor(Mailer.class); 17 | assertEquals("4441", descriptor.getSmtpPort()); 18 | assertEquals("do-not-reply@acme.org", descriptor.getReplyToAddress()); 19 | } 20 | 21 | @Override 22 | protected String configResource() { 23 | return "MailerTest.yml"; 24 | } 25 | 26 | @Override 27 | protected String stringInLogExpected() { 28 | return "do-not-reply@acme.org"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/SimpleThemeTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | 5 | import hudson.ExtensionList; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 8 | import org.codefirst.SimpleThemeDecorator; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | 12 | /** 13 | * @author v1v (Victor Martinez) 14 | */ 15 | public class SimpleThemeTest { 16 | 17 | @Rule 18 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 19 | 20 | @Test 21 | @ConfiguredWithReadme("simple-theme-plugin/README.md") 22 | public void configure_simple_theme() { 23 | // Already tested within the plugin itself, let's run some basic tests. 24 | // https://github.com/jenkinsci/simple-theme-plugin/blob/master/src/test/java/org/jenkinsci/plugins/simpletheme/ConfigurationAsCodeTest.java 25 | SimpleThemeDecorator decorator = ExtensionList.lookupSingleton(SimpleThemeDecorator.class); 26 | assertNotNull(decorator); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/SlackTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.convertYamlFileToJson; 4 | import static io.jenkins.plugins.casc.misc.Util.validateSchema; 5 | import static org.hamcrest.MatcherAssert.assertThat; 6 | import static org.hamcrest.Matchers.empty; 7 | import static org.junit.Assert.assertNotNull; 8 | 9 | import hudson.ExtensionList; 10 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 11 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 12 | import jenkins.plugins.slack.SlackNotifier; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.junit.contrib.java.lang.system.EnvironmentVariables; 16 | import org.junit.rules.RuleChain; 17 | 18 | /** 19 | * @author v1v (Victor Martinez) 20 | */ 21 | public class SlackTest { 22 | 23 | @Rule 24 | public RuleChain chain = RuleChain.outerRule(new EnvironmentVariables().set("SLACK_TOKEN", "ADMIN123")) 25 | .around(new JenkinsConfiguredWithReadmeRule()); 26 | 27 | @Test 28 | @ConfiguredWithReadme("slack/README.md") 29 | public void configure_slack() { 30 | // Already validated within the plugin itself, so let's run some simple validations 31 | // https://github.com/jenkinsci/slack-plugin/pull/582 32 | SlackNotifier.DescriptorImpl slackNotifier = ExtensionList.lookupSingleton(SlackNotifier.DescriptorImpl.class); 33 | assertNotNull(slackNotifier); 34 | } 35 | 36 | @Test 37 | public void validJsonSchema() throws Exception { 38 | assertThat(validateSchema(convertYamlFileToJson(this, "slackSchema.yml")), empty()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/StatisticsGathererTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static junit.framework.TestCase.assertFalse; 4 | import static junit.framework.TestCase.assertNotNull; 5 | import static junit.framework.TestCase.assertTrue; 6 | import static org.hamcrest.CoreMatchers.containsString; 7 | import static org.hamcrest.MatcherAssert.assertThat; 8 | 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 11 | import org.jenkins.plugins.statistics.gatherer.StatisticsConfiguration; 12 | import org.junit.Rule; 13 | import org.junit.Test; 14 | 15 | public class StatisticsGathererTest { 16 | 17 | @Rule 18 | public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule(); 19 | 20 | @Test 21 | @ConfiguredWithReadme("statistics-gatherer/README.md") 22 | public void configure_statistics() { 23 | StatisticsConfiguration config = StatisticsConfiguration.get(); 24 | assertNotNull(config); 25 | 26 | assertThat(config.getBuildUrl(), containsString("http://elasticsearch:9200/jenkins-stats/builds")); 27 | assertTrue(config.getShouldSendApiHttpRequests()); 28 | assertTrue(config.getBuildInfo()); 29 | assertFalse(config.getQueueInfo()); 30 | assertFalse(config.getProjectInfo()); 31 | assertFalse(config.getBuildStepInfo()); 32 | assertTrue(config.getScmCheckoutInfo()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/ToolDefaultPropertiesExportIgnoreListTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.getToolRoot; 4 | import static io.jenkins.plugins.casc.misc.Util.toStringFromYamlFile; 5 | import static io.jenkins.plugins.casc.misc.Util.toYamlString; 6 | import static org.hamcrest.MatcherAssert.assertThat; 7 | import static org.hamcrest.core.Is.is; 8 | 9 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 10 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 11 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 12 | import io.jenkins.plugins.casc.model.CNode; 13 | import org.junit.jupiter.api.Test; 14 | import org.jvnet.hudson.test.Issue; 15 | 16 | @WithJenkinsConfiguredWithCode 17 | class ToolDefaultPropertiesExportIgnoreListTest { 18 | 19 | @Test 20 | @Issue("JENKINS-57122") 21 | @ConfiguredWithCode("ToolDefaultPropertiesExportIgnoreList.yml") 22 | void export_tool_configuration(JenkinsConfiguredWithCodeRule j) throws Exception { 23 | ConfiguratorRegistry registry = ConfiguratorRegistry.get(); 24 | ConfigurationContext context = new ConfigurationContext(registry); 25 | CNode yourAttribute = getToolRoot(context); 26 | 27 | String exported = toYamlString(yourAttribute).replaceAll("git\\.exe", "git"); 28 | 29 | String expected = toStringFromYamlFile(this, "ToolDefaultPropertiesExportIgnoreListExpected.yml"); 30 | 31 | assertThat(exported, is(expected)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/test/java/io/jenkins/plugins/casc/WorkflowCpsGlobalLibTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import io.jenkins.plugins.casc.misc.ConfiguredWithReadme; 6 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule; 7 | import jenkins.plugins.git.GitSCMSource; 8 | import org.jenkinsci.plugins.workflow.libs.GlobalLibraries; 9 | import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration; 10 | import org.jenkinsci.plugins.workflow.libs.SCMSourceRetriever; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Victor Martinez 16 | */ 17 | public class WorkflowCpsGlobalLibTest { 18 | 19 | @Rule 20 | public JenkinsConfiguredWithReadmeRule j2 = new JenkinsConfiguredWithReadmeRule(); 21 | 22 | @Test 23 | @ConfiguredWithReadme("pipeline-groovy-lib/README.md") 24 | public void configure_global_library() { 25 | assertEquals(1, GlobalLibraries.get().getLibraries().size()); 26 | final LibraryConfiguration library = 27 | GlobalLibraries.get().getLibraries().get(0); 28 | assertEquals("awesome-lib", library.getName()); 29 | final SCMSourceRetriever retriever = (SCMSourceRetriever) library.getRetriever(); 30 | final GitSCMSource scm = (GitSCMSource) retriever.getScm(); 31 | assertEquals("https://github.com/jenkins-infra/pipeline-library.git", scm.getRemote()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/CredentialsWithDomain.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: Testing... 3 | credentials: 4 | system: 5 | domainCredentials: 6 | - domain: 7 | name: "test.com" 8 | description: "test.com domain" 9 | specifications: 10 | - hostnameSpecification: 11 | includes: "*.test.com" 12 | credentials: 13 | - usernamePassword: 14 | scope: SYSTEM 15 | id: user1 16 | username: Administrator 17 | password: secret 18 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/CustomToolsTest.yml: -------------------------------------------------------------------------------- 1 | tool: 2 | customtool: 3 | installations: 4 | - name: "my-tool" 5 | home: "" 6 | properties: 7 | - installSource: 8 | - command: 9 | toolHome: "/bin/my-tool" 10 | command: > 11 | curl -o my-tool.tar.bz2 -L https://github.com/my/tool/releases/download/v0.1.0/linux-amd64-my-tool.tar.bz2 12 | tar -xvjf my-tool.tar.bz2 13 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/DockerCloudTest2.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | clouds: 3 | - docker: 4 | name: "docker" 5 | dockerApi: 6 | dockerHost: 7 | uri: "unix:///var/run/docker.sock" 8 | templates: 9 | - labelString: "docker-agent" 10 | dockerTemplateBase: 11 | image: "jenkins/slave" 12 | mounts: 13 | - type=volume,source=hello,destination=/hello 14 | - type=volume,source=world,destination=/world 15 | environmentsString: | 16 | hello=world 17 | foo=bar 18 | remoteFs: "/home/jenkins/agent" 19 | connector: 20 | attach: 21 | user: "jenkins" 22 | instanceCapStr: "10" 23 | 24 | - labelString: "generic" 25 | dockerTemplateBase: 26 | image: "jenkins/slave" 27 | mounts: 28 | - type=volume,source=hello,destination=/hello 29 | - type=volume,source=world,destination=/world 30 | environmentsString: | 31 | hello=world 32 | foo=bar 33 | remoteFs: "/home/jenkins/agent2" 34 | connector: 35 | attach: 36 | user: "jenkins" 37 | instanceCapStr: "5" 38 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/DockerWorkflowSymbol.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | pipeline-model: 3 | dockerLabel: "label-casc" 4 | registry: 5 | url: "my.docker.endpoint" 6 | credentialsId: "credId" 7 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/DockerWorkflowSymbolExpected.yml: -------------------------------------------------------------------------------- 1 | dockerLabel: "label-casc" 2 | registry: 3 | credentialsId: "credId" 4 | url: "my.docker.endpoint" 5 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/EssentialsTest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # NOTE: THIS FILE IS A COPY OF THE ONE USED IN JENKINS ESSENTIALS 3 | # DO NOT JUST ADAPT IF SOMETHING HAS TO CHANGE, PLEASE PING THE ESSENTIALS TEAM 4 | # IF THIS HAPPENS. Thanks! 5 | jenkins: 6 | systemMessage: "Welcome to Jenkins Essentials!" 7 | numExecutors: 0 8 | 9 | unclassified: 10 | metricsaccesskey: 11 | accessKeys: 12 | - key: "evergreen" 13 | description: "Key for evergreen health-check" 14 | canHealthCheck: true 15 | canPing: false 16 | canThreadDump: false 17 | canMetrics: false 18 | origins: "*" 19 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GitTest.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | globalLibraries: 3 | libraries: 4 | - defaultVersion: "1.2.3" 5 | name: "Test Git Lib" 6 | retriever: 7 | legacySCM: 8 | scm: 9 | git: 10 | branches: 11 | - name: "*/myprodbranch" 12 | browser: 13 | # Reproduces JENKINS-57604 14 | assemblaWeb: 15 | repoUrl: "assembla.acmecorp.com" 16 | buildChooser: "default" 17 | gitTool: "Default" 18 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GitToolInstallationTestExpected.yml: -------------------------------------------------------------------------------- 1 | installations: 2 | - home: "/bin/git" 3 | name: "git" 4 | - home: "/usr/local/bin/git" 5 | name: "another_git" 6 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GithubOrganisationFolderTest.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - organizationFolder: 3 | name: "ndeloof" 4 | navigators: 5 | - github: 6 | repoOwner: "ndeloof" 7 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalCredentials.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: Testing 3 | 4 | credentials: 5 | system: 6 | domainCredentials: 7 | - credentials: 8 | - usernamePassword: 9 | scope: SYSTEM 10 | id: user1 11 | username: Administrator 12 | password: secretPassword 13 | - basicSSHUserPrivateKey: 14 | scope: SYSTEM 15 | id: agent-private-key 16 | username: agentuser 17 | passphrase: password 18 | description: "ssh private key used to connect ssh slaves" 19 | privateKeySource: 20 | directEntry: 21 | privateKey: sp0ds9d+skkfjf 22 | - file: 23 | scope: GLOBAL 24 | id: "secret-file" 25 | fileName: "mysecretfile.txt" 26 | secretBytes: "YWJjZGVmZwo=" 27 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalLibrariesGitHubTest.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | globalLibraries: 3 | libraries: 4 | - defaultVersion: "master" 5 | name: "jenkins-pipeline-lib" 6 | retriever: 7 | modernSCM: 8 | scm: 9 | github: 10 | id: "e43d6600-ba0e-46c5-8eae-3989bf654055" 11 | repoOwner: "jenkins-infra" 12 | repository: "pipeline-library" 13 | traits: 14 | - gitHubBranchDiscovery: 15 | strategyId: 1 16 | - originPullRequestDiscoveryTrait: 17 | strategyId: 2 18 | - gitHubForkDiscovery: 19 | strategyId: 3 20 | trust: "gitHubTrustPermissions" 21 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | globalNodeProperties: 3 | - diskSpaceMonitor: 4 | freeDiskSpaceThreshold: "1GiB" 5 | freeDiskSpaceWarningThreshold: "2GiB" 6 | freeTempSpaceThreshold: "1GiB" 7 | freeTempSpaceWarningThreshold: "2GiB" 8 | - envVars: 9 | env: 10 | - key: FOO 11 | value: BAR 12 | - key: FOO2 13 | value: "" 14 | - toolLocation: 15 | locations: 16 | - home: "/home/user/bin/git" 17 | key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesTestExpected.yml: -------------------------------------------------------------------------------- 1 | - diskSpaceMonitor: 2 | freeDiskSpaceThreshold: "1GiB" 3 | freeDiskSpaceWarningThreshold: "2GiB" 4 | freeTempSpaceThreshold: "1GiB" 5 | freeTempSpaceWarningThreshold: "2GiB" 6 | - envVars: 7 | env: 8 | - key: "FOO" 9 | value: "BAR" 10 | - key: "FOO2" 11 | value: "" 12 | - toolLocation: 13 | locations: 14 | - home: "/home/user/bin/git" 15 | key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" 16 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesWithEnvVarsTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | globalNodeProperties: 3 | - envVars: 4 | env: 5 | - key: FOO 6 | value: ${VALUE_1} 7 | - key: FOO2 8 | value: ${VALUE_2} 9 | - toolLocation: 10 | locations: 11 | - home: "${TEST_GIT_HOME}" 12 | key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/GlobalNodePropertiesWithEnvVarsTestExpected.yml: -------------------------------------------------------------------------------- 1 | - envVars: 2 | env: 3 | - key: "FOO" 4 | value: "BAR" 5 | - key: "FOO2" 6 | value: "" 7 | - toolLocation: 8 | locations: 9 | - home: "git-home" 10 | key: "hudson.plugins.git.GitTool$DescriptorImpl@Default" 11 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/JdkConfiguratorTestExpected.yml: -------------------------------------------------------------------------------- 1 | installations: 2 | - home: "/jdk" 3 | name: "jdk11" 4 | properties: 5 | - installSource: 6 | installers: 7 | - adoptOpenJdkInstaller: 8 | id: "jdk-11.0.14+9" 9 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/JobDslGlobalSecurityConfigurationTest.yml: -------------------------------------------------------------------------------- 1 | security: 2 | GlobalJobDslSecurityConfiguration: 3 | useScriptSecurity: false 4 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/LDAPSecurityRealmTestNoSecret.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: 3 | ldap: 4 | configurations: 5 | - server: ldap.acme.com 6 | rootDN: dc=acme,dc=fr 7 | cache: 8 | size: 100 9 | ttl: 10 10 | userIdStrategy: CaseInsensitive 11 | groupIdStrategy: CaseSensitive 12 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/LDAPSecurityRealmTestNoSecretExpected.yml: -------------------------------------------------------------------------------- 1 | cache: 2 | size: 100 3 | ttl: 30 4 | configurations: 5 | - inhibitInferRootDN: false 6 | rootDN: "dc=acme,dc=fr" 7 | server: "ldap.acme.com" 8 | disableMailAddressResolver: false 9 | groupIdStrategy: "caseSensitive" 10 | userIdStrategy: "caseInsensitive" 11 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/LogRecorderTestExpected.yaml: -------------------------------------------------------------------------------- 1 | recorders: 2 | - loggers: 3 | - level: "WARNING" 4 | name: "io.jenkins.plugins.casc" 5 | name: "JCasC" 6 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MailExtTest.yml: -------------------------------------------------------------------------------- 1 | configuration-as-code: 2 | deprecated: "warn" 3 | unclassified: 4 | extendedEmailPublisher: 5 | smtpUsername: email@acmecorp.com 6 | smtpPassword: myPassword 7 | defaultContentType: text/plain 8 | defaultSubject: "Build $BUILD_NUMBER - $BUILD_STATUS" 9 | defaultBody: "Check console output at $BUILD_URL" 10 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MailerTest.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | mailer: 3 | replyToAddress: do-not-reply@acme.org 4 | smtpHost: smtp.acme.org 5 | smtpPort: 4441 6 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MavenConfiguratorTestExpected.yml: -------------------------------------------------------------------------------- 1 | installations: 2 | - home: "/maven3" 3 | name: "maven3" 4 | properties: 5 | - installSource: 6 | installers: 7 | - maven: 8 | id: "3.8.4" 9 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MavenConfiguratorTestGlobalConfigExpected.yml: -------------------------------------------------------------------------------- 1 | globalSettingsProvider: "standard" 2 | settingsProvider: "standard" 3 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MavenConfiguratorTestGlobalConfigSpecificFilesExpected.yml: -------------------------------------------------------------------------------- 1 | globalSettingsProvider: 2 | filePath: 3 | path: "/conf/maven/global-settings.xml" 4 | settingsProvider: 5 | filePath: 6 | path: "/conf/maven/settings.xml" 7 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/MercurialTest.yaml: -------------------------------------------------------------------------------- 1 | tool: 2 | mercurialinstallation: 3 | installations: 4 | - name: "Mercurial 3" 5 | home: "/mercurial" 6 | config: | 7 | [defaults] 8 | clone = --uncompressed 9 | bundle = --type none 10 | executable: "INSTALLATION/bin/hg" 11 | useCaches: true 12 | debug: false 13 | masterCacheRoot: "/cache/root" 14 | useSharing: false 15 | properties: 16 | - installSource: 17 | installers: 18 | - command: 19 | toolHome: "mercurial" 20 | label: "SomeLabel" 21 | command: "[ -d mercurial ] || wget -q -O - http://www.archlinux.org/packages/extra/x86_64/mercurial/download/ | xzcat | tar xvf -" 22 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/ProjectMatrixStrategy.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Welcome!" 3 | numExecutors: 4 4 | mode: NORMAL 5 | scmCheckoutRetryCount: 4 6 | securityRealm: 7 | local: 8 | allowsSignup: false 9 | users: 10 | - id: test 11 | password: test 12 | 13 | authorizationStrategy: 14 | projectMatrix: 15 | permissions: 16 | - "Overall/Read:anonymous" 17 | - "Overall/Administer:authenticated" 18 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/PropertiesSecretSourceTest.yaml: -------------------------------------------------------------------------------- 1 | credentials: 2 | system: 3 | domainCredentials: 4 | - credentials: 5 | - usernamePassword: 6 | scope: SYSTEM 7 | id: test 8 | username: ${testuser} 9 | password: ${testpassword} -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/RoleStrategy1Expected.yml: -------------------------------------------------------------------------------- 1 | roleBased: 2 | roles: 3 | agents: 4 | - description: "Agent 1" 5 | entries: 6 | - user: "user1" 7 | name: "Agent1" 8 | pattern: "agent1" 9 | permissions: 10 | - "Agent/Build" 11 | global: 12 | - description: "Jenkins administrators" 13 | entries: 14 | - user: "admin" 15 | name: "admin" 16 | pattern: ".*" 17 | permissions: 18 | - "Overall/Administer" 19 | - description: "Read-only users" 20 | entries: 21 | - group: "authenticated" 22 | name: "readonly" 23 | pattern: ".*" 24 | permissions: 25 | - "Overall/Read" 26 | - "Job/Read" 27 | items: 28 | - description: "Jobs in Folder A, but not the folder itself" 29 | entries: 30 | - user: "user1" 31 | - user: "user2" 32 | name: "FolderA" 33 | pattern: "A/.*" 34 | permissions: 35 | - "Job/Build" 36 | - "Job/Delete" 37 | - "Job/Configure" 38 | - description: "Jobs in Folder B, but not the folder itself" 39 | entries: 40 | - user: "user2" 41 | name: "FolderB" 42 | pattern: "B.*" 43 | permissions: 44 | - "Job/Build" 45 | - "Job/Configure" 46 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/RoleStrategy2.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | authorizationStrategy: 3 | roleBased: 4 | roles: 5 | global: 6 | - name: "admin" 7 | description: "Jenkins administrators" 8 | permissions: 9 | - "Overall/Administer" 10 | entries: 11 | - user: "admin" 12 | - name: "readonly" 13 | description: "Read-only users" 14 | permissions: 15 | - "Overall/Read" 16 | - "Job/Read" 17 | entries: 18 | - group: "authenticated" 19 | 20 | # System for test 21 | securityRealm: 22 | local: 23 | allowsSignup: false 24 | users: 25 | - id: "admin" 26 | password: "1234" 27 | - id: "user1" 28 | 29 | nodes: 30 | - dumb: 31 | mode: NORMAL 32 | name: "agent1" 33 | remoteFS: "/home/user1" 34 | launcher: jnlp 35 | - dumb: 36 | mode: NORMAL 37 | name: "agent2" 38 | remoteFS: "/home/user1" 39 | launcher: jnlp 40 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SSHCredentialsTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: Jenkins with SSH Credentials for JCasC test 3 | 4 | credentials: 5 | system: 6 | domainCredentials: 7 | - credentials: 8 | - usernamePassword: 9 | scope: SYSTEM 10 | id: "userid" 11 | username: "username-of-userid" 12 | password: "password-of-userid" 13 | - basicSSHUserPrivateKey: 14 | scope: SYSTEM 15 | id: "userid2" 16 | username: "username-of-userid2" 17 | passphrase: "passphrase-of-userid2" 18 | description: "the description of userid2" 19 | privateKeySource: 20 | directEntry: 21 | privateKey: "sp0ds9d+skkfjf" 22 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SSHCredentialsTest_Multiline_Key.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: Jenkins with SSH Credentials for JCasC test 3 | 4 | credentials: 5 | system: 6 | domainCredentials: 7 | - credentials: 8 | - basicSSHUserPrivateKey: 9 | scope: SYSTEM 10 | id: "userid2" 11 | username: "username-of-userid2" 12 | passphrase: "passphrase-of-userid2" 13 | description: "the description of userid2" 14 | privateKeySource: 15 | directEntry: 16 | privateKey: ${MY_PRIVATE_KEY} 17 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SSHCredentialsTest_Singleline_Key.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: Jenkins with SSH Credentials for JCasC test 3 | 4 | credentials: 5 | system: 6 | domainCredentials: 7 | - credentials: 8 | - basicSSHUserPrivateKey: 9 | scope: SYSTEM 10 | id: "userid2" 11 | username: "username-of-userid2" 12 | passphrase: "passphrase-of-userid2" 13 | description: "the description of userid2" 14 | privateKeySource: 15 | directEntry: 16 | privateKey: ${decodeBase64:${SSH_AGENT_PRIVATE_KEY_BASE64}} 17 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SbtTestExpected.yml: -------------------------------------------------------------------------------- 1 | installations: 2 | - home: "/usr/bin/sbt" 3 | name: "sbt" 4 | properties: 5 | - installSource: 6 | installers: 7 | - sbtInstaller: 8 | id: "1.2.8" 9 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/Security1446Test.yml: -------------------------------------------------------------------------------- 1 | credentials: 2 | system: 3 | domainCredentials: 4 | - credentials: 5 | - string: 6 | description: "path = ^${PATH}" 7 | id: "system secret escaped" 8 | scope: SYSTEM 9 | secret: "{AQAAABAAAAAQwDmo12BE6995SezdXe1Y9ewaoYR6KgzX46VjtoPDqE0=}" 10 | - usernamePassword: 11 | description: "path = ^${PATH}" 12 | id: "global user-passw escaped" 13 | password: "{AQAAABAAAAAQpNs2vtahkRGcR5vzanaIb4UJkCyeNGdP23/X3+Tl1Ic=}" 14 | scope: GLOBAL 15 | username: "java-home = ^${JAVA_HOME}" 16 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SeedJobTest.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | job('testJob1') { 4 | scm { 5 | git('git://github.com/quidryan/aws-sdk-test.git') 6 | } 7 | triggers { 8 | scm('H/15 * * * *') 9 | } 10 | steps { 11 | maven('-e clean test') 12 | } 13 | } 14 | 15 | - file: ./src/test/resources/io/jenkins/plugins/casc/testJob2.groovy 16 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SeedJobTest_withEnvVars.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | job('seedJobWithEnvVars') { 4 | scm { 5 | git("$REPO_URL") 6 | } 7 | triggers { 8 | scm('H/15 * * * *') 9 | } 10 | steps { 11 | maven('-e clean test') 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SeedJobTest_withGiteaOrganisation.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - script: > 3 | organizationFolder('Gitea Organization Folder') { 4 | organizations { 5 | gitea { 6 | serverUrl("https://git.example.com") 7 | repoOwner("OWN") 8 | credentialsId("gitea-token") 9 | 10 | traits { 11 | giteaExcludeArchivedRepositories {} 12 | giteaTagDiscovery {} 13 | giteaBranchDiscovery { 14 | strategyId(1) 15 | } 16 | giteaPullRequestDiscovery { 17 | strategyId(2) 18 | } 19 | giteaForkDiscovery { 20 | strategyId(1) 21 | trust { 22 | giteaTrustContributors {} 23 | } 24 | } 25 | giteaWebhookRegistration { 26 | mode('ITEM') 27 | } 28 | giteaSSHCheckout { 29 | credentialsId('ssh-gitea') 30 | } 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SeedJobTest_withSecrets.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - file: ${SEED_JOB_PATH} 3 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SeedJobTest_withSecurityConfig.yml: -------------------------------------------------------------------------------- 1 | security: 2 | GlobalJobDslSecurityConfiguration: 3 | useScriptSecurity: false 4 | 5 | jobs: 6 | - file: ./src/test/resources/io/jenkins/plugins/casc/testJob2.groovy 7 | - script: > 8 | freeStyleJob('seedJobWithSecurityConfig') { 9 | steps { 10 | customWorkspace("$SEED_JOB_FOLDER_FILE_PATH") 11 | dsl(['testJob2.groovy'], 'DISABLE') 12 | } 13 | } 14 | - script: queue("seedJobWithSecurityConfig") 15 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/SystemCredentialsTest.yml: -------------------------------------------------------------------------------- 1 | credentials: 2 | system: 3 | domainCredentials: 4 | - domain: 5 | name: "test.com" 6 | description: "test.com domain" 7 | specifications: 8 | - hostnameSpecification: 9 | includes: "*.test.com" 10 | credentials: 11 | - usernamePassword: 12 | scope: SYSTEM 13 | id: sudo_password 14 | username: root 15 | password: ${SUDO_PASSWORD} 16 | 17 | # global credentials 18 | - credentials: 19 | # - certificate: 20 | # scope: SYSTEM 21 | # id: ssh_private_key 22 | # password: ${SSH_KEY_PASSWORD} 23 | # keyStoreSource: 24 | # secretBytes: 25 | # keyStoreFile: /docker/secret/id_rsa 26 | - basicSSHUserPrivateKey: 27 | scope: SYSTEM 28 | id: ssh_with_passphrase_provided 29 | username: ssh_root 30 | passphrase: ${SSH_KEY_PASSWORD} 31 | description: "SSH passphrase with private key file. Private key provided" 32 | privateKeySource: 33 | directEntry: 34 | privateKey: ${SSH_PRIVATE_KEY} 35 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/TerraformConfiguratorTestExpected.yml: -------------------------------------------------------------------------------- 1 | installations: 2 | - home: "/terraform-0.11" 3 | name: "terraform" 4 | properties: 5 | - installSource: 6 | installers: 7 | - terraformInstaller: 8 | id: "0.11.9-linux-amd64" 9 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/ToolDefaultPropertiesExportIgnoreList.yml: -------------------------------------------------------------------------------- 1 | tool: 2 | jdk: 3 | installations: 4 | - name: default 5 | home: "/jdk" # only needed so that in the export test it has a fixed path, otherwise it uses your actual JDK location 6 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/ToolDefaultPropertiesExportIgnoreListExpected.yml: -------------------------------------------------------------------------------- 1 | git: 2 | installations: 3 | - home: "git" 4 | name: "Default" 5 | jdk: 6 | installations: 7 | - home: "/jdk" 8 | name: "default" 9 | mavenGlobalConfig: 10 | globalSettingsProvider: "standard" 11 | settingsProvider: "standard" 12 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/alias1.yml: -------------------------------------------------------------------------------- 1 | x-ec2_anchor: &ec2_anchor 2 | associatePublicIp: false 3 | connectBySSHProcess: false 4 | connectionStrategy: PRIVATE_IP 5 | deleteRootOnTermination: false 6 | ebsOptimized: false 7 | idleTerminationMinutes: "10" 8 | maxTotalUses: -1 9 | monitoring: false 10 | numExecutors: 1 11 | stopOnTerminate: false 12 | useDedicatedTenancy: false 13 | useEphemeralDevices: false 14 | zone: "us-east-1" 15 | ami: "ami-0c6bb742864ffa3f3" 16 | securityGroups: "some-group" 17 | remoteFS: "/home/ec2-user" 18 | remoteAdmin: "ec2-user" 19 | mode: "NORMAL" 20 | amiType: 21 | unixData: 22 | rootCommandPrefix: "sudo" 23 | slaveCommandPrefix: "sudo -u jenkins" 24 | sshPort: "61120" 25 | 26 | jenkins: 27 | clouds: 28 | - amazonEC2: 29 | name: "ec2" 30 | instanceCapStr: 20 31 | # this shouldn't be needed, since without explicit creds this should already be used 32 | # but let's be explicit to avoid issues. 33 | useInstanceProfileForCredentials: true 34 | # Reminder: the following key has multiple lines 35 | privateKey: "${EC2_PRIVATE_KEY}" 36 | noDelayProvisioning: true 37 | region: "eu-central-1" 38 | templates: 39 | - description: "Auto configured EC2 Agent Small" 40 | type: "t2.small" 41 | labelString: "Small" 42 | <<: *ec2_anchor 43 | - description: "Auto configured EC2 Agent Large" 44 | type: "t2.xlarge" 45 | labelString: "Large" 46 | <<: *ec2_anchor 47 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/azureKeyVault.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | azureKeyVault: 3 | keyVaultURL: https://not-a-real-vault.vault.azure.net 4 | credentialID: service-principal -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/mysecretfile.txt: -------------------------------------------------------------------------------- 1 | SUPER SECRET 2 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/private-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQC2xOoDBS+RQiwYN+rY0YXYQ/WwmC9ICH7BCXfLUBSHAkF2Dvd0 3 | cvM2Ph2nOPiHdntrvD8JkzIv+S1RIqlBrzK6NRQ0ojoCvyawzY3cgzfQ4dfaOqUF 4 | 2bn4PscioLlq+Pbi3KYYwWUFue2iagRIxp0+/3F5WqOWPPy1twW7ddWPLQIDAQAB 5 | AoGBAKOX7DKZ4LLvfRKMcpxyJpCme/L+tUuPtw1IUT7dxhH2deubh+lmvsXtoZM9 6 | jk+KQPz0+aOzanfAXMzD7qZJkGfQ91aG8OiD+YJnRqOc6C6vQBXiZgeHRqWH0VMG 7 | rp9Xqd8MxEYScaJYMwoHiBCG/cb3c4kpEpZ03IzkekZdXlmhAkEA7iFEk5k1BZ1+ 8 | BnKN9LxLR0EOKoSFJjxBihRP6+UD9BF+/1AlKlLW4hSq4458ppV5Wt4glHTcAQi/ 9 | U+wOOz6DyQJBAMR8G0yjtmLjMBy870GaDxmwWjqSeYwPoHbvRTOml8Fz9fP4gBMi 10 | PUEGJaEHMuPECIegZ93kwAGBT51Q7AZcukUCQGGmnNOWISsjUXndYh85U/ltURzY 11 | aS2rygiQmdGXgY6F2jliqUr424ushAN6+9zoMPK1YlDetxVpe+QzSga7dRkCQQCB 12 | +DI6rORdXziZGeUNuPGaJYxZyEA8hK25Xqag9ubVYXZlLpDRl0l7dKx5awCfpzGZ 13 | PWLXZZQYqsfWIQwvXTEdAkEA2bziyReYAb9fi17alcvwZXGzyyMY8WOGns8NZKcq 14 | INF8D3PDpcCyOvQI/TS3qHYmGyWdHiKCWsgBqE6kyjqpNQ== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/secrets.properties: -------------------------------------------------------------------------------- 1 | testuser = ken 2 | testpassword = p/q2-q4! 3 | -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/slackSchema.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | slackNotifier: 3 | teamDomain: workspace 4 | tokenCredentialId: slack-token -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/sonarSchema.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | sonarGlobalConfiguration: 3 | buildWrapperEnabled: false 4 | installations: 5 | - additionalAnalysisProperties: sonar.organization=jenkinsci 6 | name: SonarQube 7 | credentialsId: token 8 | serverUrl: 'https://sonarcloud.io' -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/sonarSchemaFull.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | sonarGlobalConfiguration: # mandatory 3 | buildWrapperEnabled: true 4 | installations: # mandatory 5 | - name: "TEST" # id of the SonarQube configuration - to be used in jobs 6 | serverUrl: "http://url:9000" 7 | #credentialsId: token-sonarqube # id of the credentials containing sonar auth token (since 2.9 version) 8 | serverAuthenticationToken: "token" # for retrocompatibility with versions < 2.9 9 | mojoVersion: "mojoVersion" 10 | additionalProperties: "blah=blah" 11 | additionalAnalysisProperties: "additionalAnalysisProperties" 12 | triggers: 13 | skipScmCause: true 14 | skipUpstreamCause: true 15 | envVar: "envVar" -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/test.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/integrations/src/test/resources/io/jenkins/plugins/casc/test.p12 -------------------------------------------------------------------------------- /integrations/src/test/resources/io/jenkins/plugins/casc/testJob2.groovy: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc 2 | 3 | job('testJob2') { 4 | steps { 5 | maven('-e clean test') 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/CasCGlobalConfig.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import edu.umd.cs.findbugs.annotations.NonNull; 4 | import hudson.Extension; 5 | import jenkins.model.GlobalConfiguration; 6 | import net.sf.json.JSONObject; 7 | import org.kohsuke.stapler.DataBoundConstructor; 8 | import org.kohsuke.stapler.DataBoundSetter; 9 | import org.kohsuke.stapler.StaplerRequest2; 10 | 11 | /** 12 | * 13 | */ 14 | @Extension 15 | public class CasCGlobalConfig extends GlobalConfiguration { 16 | 17 | private String configurationPath; 18 | 19 | @DataBoundConstructor 20 | public CasCGlobalConfig(String configurationPath) { 21 | this.configurationPath = configurationPath; 22 | } 23 | 24 | public CasCGlobalConfig() { 25 | load(); 26 | } 27 | 28 | @NonNull 29 | @Override 30 | public String getDisplayName() { 31 | return "CasC configuration"; 32 | } 33 | 34 | public String getConfigurationPath() { 35 | return configurationPath; 36 | } 37 | 38 | @DataBoundSetter 39 | public void setConfigurationPath(String configurationPath) { 40 | this.configurationPath = configurationPath; 41 | } 42 | 43 | @Override 44 | public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { 45 | req.bindJSON(this, json); 46 | save(); 47 | return super.configure(req, json); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/Configurable.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import io.jenkins.plugins.casc.model.CNode; 4 | 5 | /** 6 | * API for components to directly implement Configuration-as-Code. 7 | * A default constructor is required. 8 | * @author Nicolas De Loof 9 | */ 10 | public interface Configurable { 11 | 12 | void configure(CNode node) throws ConfiguratorException; 13 | 14 | void check(CNode node) throws ConfiguratorException; 15 | 16 | CNode describe() throws Exception; 17 | } 18 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/ConfigurationAsCodeBootFailure.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import hudson.util.BootFailure; 4 | import jakarta.servlet.ServletException; 5 | import java.io.IOException; 6 | import org.kohsuke.stapler.StaplerRequest2; 7 | import org.kohsuke.stapler.StaplerResponse2; 8 | 9 | public class ConfigurationAsCodeBootFailure extends BootFailure { 10 | 11 | public ConfigurationAsCodeBootFailure(ConfiguratorException cause) { 12 | super(cause); 13 | } 14 | 15 | public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { 16 | rsp.setStatus(503); 17 | ConfigurationAsCode.handleExceptionOnReloading(req, rsp, (ConfiguratorException) getCause()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/ConfiguratorConflictException.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | public class ConfiguratorConflictException extends ConfiguratorException { 4 | 5 | public ConfiguratorConflictException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/ConfiguratorRegistry.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import edu.umd.cs.findbugs.annotations.CheckForNull; 4 | import edu.umd.cs.findbugs.annotations.NonNull; 5 | import java.lang.reflect.Type; 6 | import jenkins.model.Jenkins; 7 | 8 | /** 9 | * A Registry to allow {@link Configurator}s retrieval. 10 | * @author Nicolas De Loof 11 | */ 12 | public interface ConfiguratorRegistry { 13 | 14 | /** 15 | * Retrieve a {@link RootElementConfigurator} by it's yaml element (key) name. 16 | * @param name 17 | * @return null if we don't know any {@link RootElementConfigurator} for requested name 18 | */ 19 | @CheckForNull 20 | RootElementConfigurator lookupRootElement(String name); 21 | 22 | /** 23 | * Retrieve a {@link Configurator} for target type. 24 | * @param type 25 | * @return null if we don't know any {@link RootElementConfigurator} for requested type 26 | */ 27 | @CheckForNull 28 | Configurator lookup(Type type); 29 | 30 | /** 31 | * null-safe flavour of {@link #lookup(Type)}. 32 | * @param type 33 | * @throws ConfiguratorException if we don't know any {@link RootElementConfigurator} for requested type 34 | */ 35 | @NonNull 36 | Configurator lookupOrFail(Type type) throws ConfiguratorException; 37 | 38 | /** 39 | * Retrieve default implementation from Jenkins 40 | */ 41 | static ConfiguratorRegistry get() { 42 | return Jenkins.get().getExtensionList(ConfiguratorRegistry.class).get(0); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/IgnoreList.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import java.util.logging.Level; 6 | import java.util.logging.Logger; 7 | import org.kohsuke.accmod.Restricted; 8 | import org.kohsuke.accmod.restrictions.NoExternalUse; 9 | 10 | @Restricted(NoExternalUse.class) 11 | class IgnoreList { 12 | 13 | private static final Logger LOGGER = Logger.getLogger(IgnoreList.class.getName()); 14 | 15 | /** 16 | * Syntax is: attribute-name space attribute-return-type 17 | *

18 | * Enable FINE logging for this class to see all potential candidates 19 | */ 20 | private static final List IGNORE_LIST = 21 | Collections.singletonList("defaultProperties hudson.tools.ToolProperty"); 22 | 23 | /** 24 | * Checks if an attribute should be ignored 25 | * 26 | * @param attribute the attribute to check if it should be ignored 27 | * @return true if the attribute should be ignored 28 | */ 29 | static boolean isIgnored(Attribute attribute) { 30 | String attributeRepresentation = 31 | attribute.getName() + " " + attribute.getType().getName(); 32 | 33 | LOGGER.log(Level.FINE, attributeRepresentation); 34 | return IGNORE_LIST.contains(attributeRepresentation); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/TokenReloadCrumbExclusion.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import hudson.Extension; 4 | import hudson.security.csrf.CrumbExclusion; 5 | import jakarta.servlet.FilterChain; 6 | import jakarta.servlet.ServletException; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | @Extension 12 | public class TokenReloadCrumbExclusion extends CrumbExclusion { 13 | 14 | @Override 15 | public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) 16 | throws IOException, ServletException { 17 | 18 | if (TokenReloadAction.tokenReloadEnabled()) { 19 | String pathInfo = request.getPathInfo(); 20 | if (pathInfo != null && pathInfo.equals("/" + TokenReloadAction.URL_NAME + "/")) { 21 | chain.doFilter(request, response); 22 | return true; 23 | } 24 | } 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/UnknownAttributesException.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import edu.umd.cs.findbugs.annotations.CheckForNull; 4 | import java.util.List; 5 | 6 | public class UnknownAttributesException extends ConfiguratorException { 7 | 8 | private final String errorMessage; 9 | 10 | public UnknownAttributesException( 11 | @CheckForNull Configurator configurator, 12 | String simpleMessage, 13 | @CheckForNull String message, 14 | String invalidAttribute, 15 | List validAttributes) { 16 | super(configurator, message, invalidAttribute, validAttributes, null); 17 | this.errorMessage = simpleMessage; 18 | } 19 | 20 | public String getErrorMessage() { 21 | return errorMessage; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/UnknownConfiguratorException.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import java.util.List; 4 | 5 | public class UnknownConfiguratorException extends ConfiguratorException { 6 | 7 | private final List configuratorNames; 8 | private final String errorMessage; 9 | 10 | public UnknownConfiguratorException(List configuratorNames, String errorMessage) { 11 | super(errorMessage + String.join(", ", configuratorNames)); 12 | this.errorMessage = errorMessage; 13 | this.configuratorNames = configuratorNames; 14 | } 15 | 16 | public String getErrorMessage() { 17 | return errorMessage; 18 | } 19 | 20 | public List getConfiguratorNames() { 21 | return configuratorNames; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/VersionConverter.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import io.jenkins.plugins.casc.ConfigurationContext.Version; 4 | import org.apache.commons.beanutils.Converter; 5 | 6 | public class VersionConverter implements Converter { 7 | 8 | @Override 9 | public Version convert(Class type, Object value) { 10 | return Version.of(value.toString()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/cli/ApplyConfigurationCommand.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.cli; 2 | 3 | import hudson.Extension; 4 | import hudson.cli.CLICommand; 5 | import io.jenkins.plugins.casc.ConfigurationAsCode; 6 | import io.jenkins.plugins.casc.yaml.YamlSource; 7 | import jenkins.model.Jenkins; 8 | import org.kohsuke.accmod.Restricted; 9 | import org.kohsuke.accmod.restrictions.NoExternalUse; 10 | 11 | /** 12 | * @author Nicolas De Loof 13 | */ 14 | @Extension 15 | @Restricted(NoExternalUse.class) 16 | public class ApplyConfigurationCommand extends CLICommand { 17 | 18 | @Override 19 | public String getShortDescription() { 20 | return "Apply YAML configuration to instance"; 21 | } 22 | 23 | @Override 24 | protected int run() throws Exception { 25 | 26 | if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { 27 | return -1; 28 | } 29 | 30 | ConfigurationAsCode.get().configureWith(YamlSource.of(stdin)); 31 | return 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/cli/CheckConfigurationCommand.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.cli; 2 | 3 | import hudson.Extension; 4 | import hudson.cli.CLICommand; 5 | import io.jenkins.plugins.casc.ConfigurationAsCode; 6 | import io.jenkins.plugins.casc.model.Source; 7 | import io.jenkins.plugins.casc.yaml.YamlSource; 8 | import java.util.Map; 9 | import jenkins.model.Jenkins; 10 | import org.kohsuke.accmod.Restricted; 11 | import org.kohsuke.accmod.restrictions.NoExternalUse; 12 | 13 | /** 14 | * @author Nicolas De Loof 15 | */ 16 | @Extension 17 | @Restricted(NoExternalUse.class) 18 | public class CheckConfigurationCommand extends CLICommand { 19 | 20 | @Override 21 | public String getShortDescription() { 22 | return "Check YAML configuration to instance"; 23 | } 24 | 25 | @Override 26 | protected int run() throws Exception { 27 | 28 | if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { 29 | return -1; 30 | } 31 | 32 | final Map issues = ConfigurationAsCode.get().checkWith(YamlSource.of(stdin)); 33 | for (Map.Entry entry : issues.entrySet()) { 34 | stderr.printf("warning: line %d %s", entry.getKey().line, entry.getValue()); 35 | } 36 | return 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/cli/ExportConfigurationCommand.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.cli; 2 | 3 | import hudson.Extension; 4 | import hudson.cli.CLICommand; 5 | import io.jenkins.plugins.casc.ConfigurationAsCode; 6 | import jenkins.model.Jenkins; 7 | import org.kohsuke.accmod.Restricted; 8 | import org.kohsuke.accmod.restrictions.NoExternalUse; 9 | 10 | /** 11 | * @author Nicolas De Loof 12 | */ 13 | @Extension 14 | @Restricted(NoExternalUse.class) 15 | public class ExportConfigurationCommand extends CLICommand { 16 | 17 | @Override 18 | public String getShortDescription() { 19 | return "Export jenkins configuration as YAML"; 20 | } 21 | 22 | @Override 23 | protected int run() throws Exception { 24 | 25 | if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { 26 | return -1; 27 | } 28 | 29 | ConfigurationAsCode.get().export(stdout); 30 | return 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/cli/ReloadJCascConfigurationCommand.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.cli; 2 | 3 | import hudson.Extension; 4 | import hudson.cli.CLICommand; 5 | import io.jenkins.plugins.casc.ConfigurationAsCode; 6 | import jenkins.model.Jenkins; 7 | import org.kohsuke.accmod.Restricted; 8 | import org.kohsuke.accmod.restrictions.NoExternalUse; 9 | 10 | /** 11 | * @author Nicolas De Loof 12 | */ 13 | @Extension 14 | @Restricted(NoExternalUse.class) 15 | public class ReloadJCascConfigurationCommand extends CLICommand { 16 | 17 | @Override 18 | public String getShortDescription() { 19 | return "Reload JCasC YAML configuration"; 20 | } 21 | 22 | @Override 23 | protected int run() throws Exception { 24 | 25 | if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { 26 | return -1; 27 | } 28 | 29 | ConfigurationAsCode.get().configure(); 30 | return 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/core/JNLPLauncherConfigurator.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.core; 2 | 3 | import hudson.Extension; 4 | import hudson.slaves.JNLPLauncher; 5 | import io.jenkins.plugins.casc.ConfigurationContext; 6 | import io.jenkins.plugins.casc.ConfiguratorException; 7 | import io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator; 8 | import io.jenkins.plugins.casc.model.CNode; 9 | import io.jenkins.plugins.casc.model.Mapping; 10 | import org.kohsuke.accmod.Restricted; 11 | import org.kohsuke.accmod.restrictions.NoExternalUse; 12 | 13 | /** 14 | * @author Nicolas De Loof 15 | */ 16 | @Extension 17 | @Restricted(NoExternalUse.class) 18 | public class JNLPLauncherConfigurator extends DataBoundConfigurator { 19 | 20 | public JNLPLauncherConfigurator() { 21 | super(JNLPLauncher.class); 22 | } 23 | 24 | @Override 25 | protected JNLPLauncher instance(Mapping config, ConfigurationContext context) throws ConfiguratorException { 26 | try { 27 | return super.instance(config, context); 28 | } catch (ConfiguratorException e) { 29 | // see https://issues.jenkins.io/browse/JENKINS-51603 30 | final CNode tunnel = config.get("tunnel"); 31 | final CNode vmargs = config.get("vmargs"); 32 | return new JNLPLauncher( 33 | tunnel != null ? tunnel.asScalar().getValue() : null, 34 | vmargs != null ? vmargs.asScalar().getValue() : null); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/core/LabelAtomPropertyConfigurator.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.core; 2 | 3 | import hudson.Extension; 4 | import hudson.model.labels.LabelAtomProperty; 5 | import io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator; 6 | import org.kohsuke.accmod.Restricted; 7 | import org.kohsuke.accmod.restrictions.NoExternalUse; 8 | 9 | @Extension 10 | @Restricted(NoExternalUse.class) 11 | public class LabelAtomPropertyConfigurator extends HeteroDescribableConfigurator { 12 | 13 | public LabelAtomPropertyConfigurator() { 14 | super(LabelAtomProperty.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/impl/attributes/DescribableListAttribute.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.attributes; 2 | 3 | import hudson.util.PersistedList; 4 | import java.util.Collection; 5 | 6 | /** 7 | * @author Nicolas De Loof 8 | */ 9 | public class DescribableListAttribute extends DescribableAttribute> { 10 | 11 | public DescribableListAttribute(String name, Class type) { 12 | super(name, type); 13 | multiple(true); 14 | } 15 | 16 | @Override 17 | public void setValue(Owner target, Collection o) throws Exception { 18 | getValue(target).replaceBy(o); 19 | } 20 | 21 | @Override 22 | public PersistedList getValue(Owner o) throws Exception { 23 | return (PersistedList) super.getValue(o); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/impl/attributes/MultivaluedAttribute.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.attributes; 2 | 3 | import io.jenkins.plugins.casc.Attribute; 4 | import java.util.Collection; 5 | 6 | /** 7 | * @author Nicolas De Loof 8 | */ 9 | public class MultivaluedAttribute extends Attribute> { 10 | 11 | public MultivaluedAttribute(String name, Class type) { 12 | super(name, type); 13 | this.multiple = true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/impl/attributes/PersistedListAttribute.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.attributes; 2 | 3 | import hudson.util.PersistedList; 4 | import io.jenkins.plugins.casc.Attribute; 5 | import java.util.Collection; 6 | 7 | /** 8 | * @author Nicolas De Loof 9 | */ 10 | public class PersistedListAttribute extends Attribute> { 11 | 12 | public PersistedListAttribute(String name, Class type) { 13 | super(name, type); 14 | multiple(true); 15 | } 16 | 17 | @Override 18 | public void setValue(Owner target, Collection o) throws Exception { 19 | getValue(target).replaceBy(o); 20 | } 21 | 22 | @Override 23 | public PersistedList getValue(Owner o) throws Exception { 24 | return (PersistedList) super.getValue(o); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/impl/secrets/EnvSecretSource.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.secrets; 2 | 3 | import hudson.Extension; 4 | import io.jenkins.plugins.casc.SecretSource; 5 | import java.util.Optional; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.kohsuke.accmod.Restricted; 8 | import org.kohsuke.accmod.restrictions.NoExternalUse; 9 | 10 | @Extension 11 | @Restricted(NoExternalUse.class) 12 | public class EnvSecretSource extends SecretSource { 13 | 14 | @Override 15 | public Optional reveal(String secret) { 16 | if (StringUtils.isBlank(secret)) { 17 | return Optional.empty(); 18 | } 19 | return Optional.ofNullable(System.getProperty(secret, System.getenv(secret))); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/model/Sequence.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Objects; 5 | 6 | /** 7 | * @author Nicolas De Loof 8 | */ 9 | public final class Sequence extends ArrayList implements CNode { 10 | 11 | private Source source; 12 | 13 | public Sequence() {} 14 | 15 | public Sequence(int initialCapacity) { 16 | super(initialCapacity); 17 | } 18 | 19 | @Override 20 | public Type getType() { 21 | return Type.SEQUENCE; 22 | } 23 | 24 | @Override 25 | public Sequence asSequence() { 26 | return this; 27 | } 28 | 29 | public void setSource(Source source) { 30 | this.source = source; 31 | } 32 | 33 | @Override 34 | public Source getSource() { 35 | return source; 36 | } 37 | 38 | @Override 39 | public Sequence clone() { 40 | final Sequence clone = new Sequence(); 41 | stream().map(CNode::clone).forEach(clone::add); 42 | return clone; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object o) { 47 | return o instanceof Sequence && Objects.equals(this.source, ((Sequence) o).source) && super.equals(o); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return Objects.hash(super.hashCode(), source); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/model/Source.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author Nicolas De Loof 7 | */ 8 | public class Source implements Serializable { 9 | 10 | static final long serialVersionUID = 1L; 11 | 12 | public final String file; 13 | public final int line; 14 | 15 | public Source(String file, int line) { 16 | this.file = file; 17 | this.line = line; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/yaml/MergeStrategy.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import io.jenkins.plugins.casc.ConfiguratorException; 4 | import org.yaml.snakeyaml.nodes.Node; 5 | 6 | /** 7 | * YAML merge strategy between multiple files 8 | */ 9 | public interface MergeStrategy { 10 | String DEFAULT_STRATEGY = "errorOnConflict"; 11 | 12 | /** 13 | * Merge two nodes which come from two YAML files 14 | * @param firstNode the first node of a node list 15 | * @param secondNode the second node of a node list 16 | * @param source is the source of node 17 | * @throws ConfiguratorException if the merge fails 18 | */ 19 | void merge(Node firstNode, Node secondNode, String source) throws ConfiguratorException; 20 | 21 | /** 22 | * Name of the merge strategy which must be unique. 23 | * @return name of the merge strategy 24 | */ 25 | String getName(); 26 | } 27 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/yaml/MergeStrategyAction.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import hudson.Extension; 4 | import hudson.ExtensionList; 5 | import hudson.model.Api; 6 | import hudson.model.UnprotectedRootAction; 7 | import hudson.util.HttpResponses; 8 | import javax.annotation.CheckForNull; 9 | import jenkins.model.Jenkins; 10 | import net.sf.json.JSONArray; 11 | import org.jenkinsci.Symbol; 12 | import org.kohsuke.accmod.Restricted; 13 | import org.kohsuke.accmod.restrictions.NoExternalUse; 14 | import org.kohsuke.stapler.HttpResponse; 15 | import org.kohsuke.stapler.export.ExportedBean; 16 | 17 | @Extension 18 | @Symbol("cascMergeStrategy") 19 | @ExportedBean 20 | public class MergeStrategyAction implements UnprotectedRootAction { 21 | 22 | public Api getApi() { 23 | return new Api(this); 24 | } 25 | 26 | @CheckForNull 27 | @Override 28 | public String getIconFileName() { 29 | return null; 30 | } 31 | 32 | @CheckForNull 33 | @Override 34 | public String getDisplayName() { 35 | return "cascMergeStrategy"; 36 | } 37 | 38 | @CheckForNull 39 | @Override 40 | public String getUrlName() { 41 | return "cascMergeStrategy"; 42 | } 43 | 44 | @Restricted(NoExternalUse.class) 45 | public HttpResponse doIndex() { 46 | JSONArray array = new JSONArray(); 47 | 48 | ExtensionList mergeStrategyList = Jenkins.get().getExtensionList(MergeStrategy.class); 49 | array.addAll(mergeStrategyList); 50 | 51 | return HttpResponses.okJSON(array); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/yaml/MergeStrategyFactory.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import hudson.ExtensionList; 4 | import java.util.Optional; 5 | import javax.annotation.Nonnull; 6 | import jenkins.model.Jenkins; 7 | import org.apache.commons.lang.StringUtils; 8 | 9 | public class MergeStrategyFactory { 10 | private static MergeStrategy getMergeStrategy(@Nonnull String name) { 11 | ExtensionList mergeStrategyList = Jenkins.get().getExtensionList(MergeStrategy.class); 12 | Optional opt = mergeStrategyList.stream() 13 | .filter(strategy -> strategy.getName().equals(name)) 14 | .findFirst(); 15 | return opt.orElse(null); 16 | } 17 | 18 | /** 19 | * Get strategy from name 20 | * @param strategyName is the name of strategy 21 | * @return MergeStrategy 22 | */ 23 | public static MergeStrategy getMergeStrategyOrDefault(String strategyName) { 24 | return MergeStrategyFactory.getMergeStrategy( 25 | StringUtils.isEmpty(strategyName) ? MergeStrategy.DEFAULT_STRATEGY : strategyName); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/yaml/StreamReaderWithSource.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import java.io.Reader; 4 | import java.lang.reflect.Field; 5 | import org.yaml.snakeyaml.reader.StreamReader; 6 | 7 | /** 8 | * Hack StreamReader to track the source file/url configuration node have been parsed from 9 | * @author Nicolas De Loof 10 | */ 11 | class StreamReaderWithSource extends StreamReader { 12 | 13 | public StreamReaderWithSource(YamlSource source, Reader reader) { 14 | super(reader); 15 | try { 16 | final Field f = StreamReader.class.getDeclaredField("name"); 17 | f.setAccessible(true); 18 | f.set(this, source.source()); 19 | } catch (NoSuchFieldException | IllegalAccessException e) { 20 | // Can't track origin, maybe due to SecurityManager ? 21 | // never mind 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /plugin/src/main/java/io/jenkins/plugins/casc/yaml/YamlSource.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import jakarta.servlet.http.HttpServletRequest; 4 | import java.io.InputStream; 5 | import java.nio.file.Path; 6 | 7 | /** 8 | * @author Nicolas De Loof 9 | */ 10 | public class YamlSource { 11 | 12 | public final T source; 13 | 14 | public YamlSource(T source) { 15 | this.source = source; 16 | } 17 | 18 | public static YamlSource of(InputStream in) { 19 | return new YamlSource<>(in); 20 | } 21 | 22 | public static YamlSource of(String url) { 23 | return new YamlSource<>(url); 24 | } 25 | 26 | public static YamlSource of(HttpServletRequest req) { 27 | return new YamlSource<>(req); 28 | } 29 | 30 | public static YamlSource of(Path path) { 31 | return new YamlSource<>(path); 32 | } 33 | 34 | public String source() { 35 | if (source instanceof HttpServletRequest) { 36 | return ((HttpServletRequest) source).getPathInfo(); 37 | } 38 | return source.toString(); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "YamlSource: " + source(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /plugin/src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 | This plugin allows configuration of Jenkins based on human-readable declarative configuration files. 7 |
8 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/BaseConfigurator/documentation_zh_CN.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2018, Alauda, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | CONFIGURATOR=\u914D\u7F6E 24 | Possible\ values:=\u53EF\u80FD\u7684\u503C 25 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/CasCGlobalConfig/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/ConfigurationAsCode/error.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

${errorMessage}

${target}

8 | 9 | 10 |

Attribute was:

${invalidAttribute}

11 |
12 | 13 | 14 |

Valid attributes are:

15 | 16 |
    17 | 18 |
  • ${attribute}
  • 19 |
    20 |
21 |
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/ConfigurationAsCode/index.properties: -------------------------------------------------------------------------------- 1 | exportWarning=Export is not intended to offer a directly usable jenkins.yaml configuration. \ 2 | It can be used for inspiration writing your own, be aware export can be partial, \ 3 | or fail for some components. 4 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/ConfigurationAsCode/viewExport.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |       ${export}
11 |     
12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/ObsoleteConfigurationMonitor/message.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | ${%Configuration as Code obsolete file format}: 5 |
    6 | 7 |
  • ${error.message}
  • 8 |
    9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/ObsoleteConfigurationMonitor/message_zh_CN.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2018, Alauda, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Configuration\ as\ Code\ obsolete\ file\ format=\u914D\u7F6E\u5373\u4EE3\u7801\u5E9F\u5F03\u7684\u6587\u4EF6\u683C\u5F0F 24 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/assets/index.css: -------------------------------------------------------------------------------- 1 | form[name='replace'] input[name='_.newSource'] { 2 | width: 32em; 3 | } 4 | 5 | form[name='reload'] { 6 | margin-bottom: 10px; 7 | } 8 | 9 | form[name='export'] { 10 | float: left; 11 | margin-right: 20px; 12 | margin-bottom: 10px; 13 | } 14 | 15 | form[name='viewExport'] { 16 | float: left; 17 | } 18 | 19 | td { 20 | vertical-align: middle; 21 | } 22 | 23 | .clear-action-forms { 24 | margin-top: 10px; 25 | clear: both; 26 | } 27 | -------------------------------------------------------------------------------- /plugin/src/main/resources/io/jenkins/plugins/casc/assets/viewExport.css: -------------------------------------------------------------------------------- 1 | /* 2 | Support easy copy with select all keyboard shortcut 3 | */ 4 | 5 | * { 6 | -webkit-user-select: none; 7 | -moz-user-select: none; 8 | -ms-user-select: none; 9 | user-select: none; 10 | } 11 | 12 | code.language-yaml, code.language-yaml > .token { 13 | -webkit-user-select: text; 14 | -moz-user-select: text; 15 | -ms-user-select: text; 16 | user-select: text; 17 | } 18 | -------------------------------------------------------------------------------- /plugin/src/main/webapp/css/reference.css: -------------------------------------------------------------------------------- 1 | .configurator { 2 | margin-top: 30px; 3 | } 4 | 5 | .configurator__name { 6 | font-size: 1.5em; 7 | } 8 | 9 | .configurator-pointer { 10 | font-size: 0.5em; 11 | color: #454545; 12 | font-weight: 100; 13 | } 14 | 15 | .root-configurator-pointer { 16 | font-size: 0.5em; 17 | color: #7f5200; 18 | font-weight: 100; 19 | } 20 | 21 | .configurator-attributes { 22 | display: flex; 23 | flex-direction: column; 24 | } 25 | 26 | .configurator-attribute { 27 | display: flex; 28 | flex-grow: 1; 29 | margin-left: 25px; 30 | border-left: 1px solid #ccc; 31 | line-height: 24px; 32 | } 33 | 34 | .configurator-attribute__name { 35 | display: flex; 36 | flex-direction: column; 37 | flex-basis: 30%; 38 | min-height: 30px; 39 | padding-top: 5px; 40 | } 41 | 42 | .attribute-name { 43 | display:flex; 44 | } 45 | 46 | .attribute-name:before { 47 | content: ''; 48 | display: block; 49 | margin-right: 10px; 50 | border-top: 1px solid #ccc; 51 | width: 10px; 52 | margin-top: 12px; 53 | } 54 | 55 | 56 | .attribute-name:after { 57 | content: ''; 58 | display: block; 59 | margin-left: 10px; 60 | border-top: 1px dashed #ccc; 61 | flex: 1; 62 | margin-top: 12px; 63 | } 64 | 65 | .configurator-attribute__details { 66 | display: flex; 67 | flex-direction: column; 68 | flex: 1; 69 | padding: 5px; 70 | } 71 | 72 | .attribute-type { 73 | color: #454545; 74 | } 75 | 76 | .attribute-type__list { 77 | color: #999; 78 | margin-right: 5px; 79 | } 80 | 81 | .attribute-type__class { 82 | font-family: Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; 83 | font-size: 0.8em; 84 | } 85 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/DocumentationGenerationTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | /** 4 | * @author Nicolas De Loof 5 | */ 6 | public class DocumentationGenerationTest {} 7 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/IgnoreAliasEntryTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | class IgnoreAliasEntryTest { 9 | 10 | @Test 11 | void aliasKeyIsNull() { 12 | assertThat(ConfigurationAsCode.isNotAliasEntry(null), is(false)); 13 | } 14 | 15 | @Test 16 | void aliasKeyStartsWithX() { 17 | assertThat(ConfigurationAsCode.isNotAliasEntry("x-hello"), is(false)); 18 | } 19 | 20 | @Test 21 | void UnknownRootElementShouldReturnTrue() { 22 | assertThat(ConfigurationAsCode.isNotAliasEntry("bob"), is(true)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/TestCrumbIssuerConfigurator.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | /** 4 | * @author Nicolas De Loof 5 | */ 6 | public class TestCrumbIssuerConfigurator {} 7 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/UnknownRootElementTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.junit.jupiter.api.Assertions.assertThrows; 6 | 7 | import org.junit.jupiter.api.Test; 8 | import org.jvnet.hudson.test.JenkinsRule; 9 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 10 | 11 | @WithJenkins 12 | class UnknownRootElementTest { 13 | 14 | @Test 15 | void oneUnknown(JenkinsRule j) { 16 | assertThrows( 17 | ConfiguratorException.class, 18 | () -> ConfigurationAsCode.get() 19 | .configure(getClass().getResource("unknown1.yml").toExternalForm()), 20 | "No configurator for the following root elements alice"); 21 | } 22 | 23 | @Test 24 | void twoUnknown(JenkinsRule j) { 25 | assertThrows( 26 | ConfiguratorException.class, 27 | () -> ConfigurationAsCode.get() 28 | .configure(getClass().getResource("unknown2.yml").toExternalForm()), 29 | "No configurator for the following root elements bob, alice"); 30 | } 31 | 32 | @Test 33 | void ignoreKnownAlias(JenkinsRule j) throws Exception { 34 | ConfigurationAsCode.get().configure(getClass().getResource("known.yml").toExternalForm()); 35 | assertThat(j.jenkins.getSystemMessage(), is("Configured by Configuration as Code plugin")); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/jmh/BenchmarkRunner.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.jmh; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import jenkins.benchmark.jmh.BenchmarkFinder; 5 | import org.junit.jupiter.api.Test; 6 | import org.openjdk.jmh.annotations.Mode; 7 | import org.openjdk.jmh.results.format.ResultFormatType; 8 | import org.openjdk.jmh.runner.Runner; 9 | import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; 10 | import org.openjdk.jmh.runner.options.OptionsBuilder; 11 | 12 | class BenchmarkRunner { 13 | @Test 14 | void runJmhBenchmarks() throws Exception { 15 | ChainedOptionsBuilder options = new OptionsBuilder() 16 | .mode(Mode.AverageTime) 17 | .warmupIterations(2) 18 | .timeUnit(TimeUnit.MICROSECONDS) 19 | .threads(2) 20 | .forks(2) 21 | .shouldFailOnError(true) 22 | .shouldDoGC(true) 23 | .resultFormat(ResultFormatType.JSON) 24 | .result("jmh-report.json"); 25 | 26 | BenchmarkFinder bf = new BenchmarkFinder(getClass()); 27 | bf.findBenchmarks(options); 28 | new Runner(options.build()).run(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/jmh/benchmarks/ConfigureBenchmark.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.jmh.benchmarks; 2 | 3 | public class ConfigureBenchmark {} 4 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/model/MappingTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.model; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotNull; 5 | import static org.junit.jupiter.api.Assertions.assertNull; 6 | 7 | import org.junit.jupiter.api.Test; 8 | 9 | class MappingTest { 10 | 11 | @Test 12 | void empty() { 13 | Mapping mapping = new Mapping(); 14 | String aKey = "aKey"; 15 | mapping.put(aKey, (CNode) null); 16 | Mapping clone = mapping.clone(); 17 | assertNull(clone.get(aKey)); 18 | assertNull(mapping.get(aKey)); 19 | } 20 | 21 | @Test 22 | void notEmpty() throws Exception { 23 | Mapping mapping = new Mapping(); 24 | String aKey = "aKey"; 25 | String aValue = "aValue"; 26 | mapping.put(aKey, aValue); 27 | Mapping clone = mapping.clone(); 28 | assertNotNull(clone.get(aKey)); 29 | assertNotNull(mapping.get(aKey)); 30 | assertEquals(aValue, clone.getScalarValue(aKey)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/permissions/Action.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.permissions; 2 | 3 | public enum Action { 4 | VIEW_CONFIGURATION("View Configuration"), 5 | DOWNLOAD_CONFIGURATION("Download Configuration"), 6 | APPLY_NEW_CONFIGURATION("Apply new configuration"), 7 | RELOAD_EXISTING_CONFIGURATION("Reload existing configuration"), 8 | ; 9 | 10 | String buttonText; 11 | 12 | Action(String buttonText) { 13 | this.buttonText = buttonText; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/yaml/MergeStrategyActionTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import static org.htmlunit.HttpMethod.GET; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | 7 | import java.io.IOException; 8 | import java.net.URL; 9 | import java.text.MessageFormat; 10 | import net.sf.json.JSONObject; 11 | import org.htmlunit.WebRequest; 12 | import org.htmlunit.WebResponse; 13 | import org.junit.jupiter.api.Test; 14 | import org.jvnet.hudson.test.JenkinsRule; 15 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 16 | 17 | @WithJenkins 18 | class MergeStrategyActionTest { 19 | 20 | @Test 21 | void test(JenkinsRule j) throws IOException { 22 | URL apiURL = 23 | new URL(MessageFormat.format("{0}cascMergeStrategy", j.getURL().toString())); 24 | WebRequest request = new WebRequest(apiURL, GET); 25 | 26 | WebResponse response = j.createWebClient().getPage(request).getWebResponse(); 27 | String strategies = response.getContentAsString(); 28 | 29 | JSONObject strategiesJSON = JSONObject.fromObject(strategies); 30 | assertEquals("ok", strategiesJSON.getString("status"), "The request should be ok"); 31 | assertNotNull(strategiesJSON.getJSONArray("data"), "Should have data field"); 32 | for (Object item : strategiesJSON.getJSONArray("data")) { 33 | String name = JSONObject.fromObject(item).getString("name"); 34 | assertEquals( 35 | name, MergeStrategyFactory.getMergeStrategyOrDefault(name).getName()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/yaml/MergeStrategyTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertNotNull; 5 | 6 | import hudson.ExtensionList; 7 | import jenkins.model.Jenkins; 8 | import org.junit.jupiter.api.Test; 9 | import org.jvnet.hudson.test.JenkinsRule; 10 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 11 | 12 | @WithJenkins 13 | class MergeStrategyTest { 14 | 15 | @Test 16 | void haveTheDefaultStrategy(JenkinsRule j) { 17 | ExtensionList strategyExtensionList = Jenkins.get().getExtensionList(MergeStrategy.class); 18 | 19 | assertFalse(strategyExtensionList.isEmpty(), "should have at least one strategy"); 20 | assertNotNull( 21 | MergeStrategyFactory.getMergeStrategyOrDefault(null), "default merge strategy should not be null"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/src/test/java/io/jenkins/plugins/casc/yaml/YamlExportTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.yaml; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import io.jenkins.plugins.casc.Attribute; 8 | import io.jenkins.plugins.casc.AttributeTest; 9 | import io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator; 10 | import java.util.Set; 11 | import org.junit.jupiter.api.Test; 12 | import org.jvnet.hudson.test.Issue; 13 | import org.jvnet.hudson.test.JenkinsRule; 14 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 15 | 16 | /** 17 | * Contains tests for particular export cases. 18 | */ 19 | @WithJenkins 20 | class YamlExportTest { 21 | 22 | @Test 23 | @Issue("SECURITY-1458") 24 | void shouldDiscoverSecretsBasedOnTheAttributeType(JenkinsRule j) { 25 | DataBoundConfigurator c = 26 | new DataBoundConfigurator<>(AttributeTest.SecretRenamedFieldFithSecretConstructor.class); 27 | Set attributes = c.describe(); 28 | assertThat(attributes.size(), equalTo(1)); 29 | Attribute attr = attributes.iterator().next(); 30 | assertTrue(attr.isSecret(null)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/known.yml: -------------------------------------------------------------------------------- 1 | x-alias: 2 | message: &message 3 | systemMessage: "Configured by Configuration as Code plugin" 4 | 5 | jenkins: 6 | <<: *message 7 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "Our secret": "Hello World" 3 | } 4 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/some secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "Our secret": "Hello World" 3 | } 4 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/unknown1.yml: -------------------------------------------------------------------------------- 1 | alice: 2 | hello: echo 3 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/unknown2.yml: -------------------------------------------------------------------------------- 1 | alice: 2 | hello: bob 3 | 4 | bob: 5 | hello: alice 6 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/conflicts.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: overwrite 3 | globalNodeProperties: 4 | - envVars: 5 | env: 6 | - key: VARIABLE2 7 | value: bar 8 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/incompatible.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: 3 | type: text 4 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/multiple-keys-a.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "hello a" 3 | numExecutors: 0 4 | unclassified: 5 | casCGlobalConfig: 6 | configurationPath: "a" 7 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/multiple-keys-b.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "hello b" 3 | numExecutors: 1 4 | unclassified: 5 | casCGlobalConfig: 6 | configurationPath: "b" 7 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/normal.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: normal 3 | globalNodeProperties: 4 | - envVars: 5 | env: 6 | - key: VARIABLE1 7 | value: foo 8 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/overwrite.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | globalNodeProperties: 3 | - envVars: 4 | env: 5 | - key: VARIABLE2 6 | value: bar 7 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/sequence-a.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: normal 3 | globalNodeProperties: 4 | - envVars: 5 | env: 6 | - key: VARIABLE1 7 | value: foo 8 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/sequence-b.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: normal 3 | globalNodeProperties: 4 | - envVars: 5 | env: 6 | - key: VARIABLE1 7 | value: foo 8 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/systemMessage-a.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "hello a" 3 | numExecutors: 0 4 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/systemMessage-b.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "hello b" 3 | numExecutors: 1 4 | -------------------------------------------------------------------------------- /plugin/src/test/resources/io/jenkins/plugins/casc/yaml/unknown.yml: -------------------------------------------------------------------------------- 1 | abc: fake 2 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/ConfiguredWithCode.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | import org.junit.Test; 10 | 11 | /** 12 | * To load specified config with plugin 13 | */ 14 | @Target({METHOD, FIELD}) 15 | @Retention(RUNTIME) 16 | public @interface ConfiguredWithCode { 17 | 18 | /** 19 | * Resource path in classpath 20 | * @return resources to configure the test case with. 21 | */ 22 | String[] value(); 23 | 24 | Class expected() default Test.None.class; 25 | 26 | String message() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/ConfiguredWithReadme.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | import org.junit.Test; 10 | 11 | /** 12 | * To load specified config with plugin from a README file 13 | */ 14 | @Target({METHOD, FIELD}) 15 | @Retention(RUNTIME) 16 | public @interface ConfiguredWithReadme { 17 | 18 | /** 19 | * Resource path in classpath 20 | * @return resources to configure the test case with 21 | */ 22 | String[] value(); 23 | 24 | Class expected() default Test.None.class; 25 | 26 | String message() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/Env.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Repeatable; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(METHOD) 11 | @Retention(RUNTIME) 12 | @Repeatable(value = Envs.class) 13 | public @interface Env { 14 | String name(); 15 | 16 | String value(); 17 | } 18 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/Envs.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | import org.junit.Test; 9 | 10 | @Target(METHOD) 11 | @Retention(RUNTIME) 12 | public @interface Envs { 13 | 14 | Env[] value() default {}; 15 | 16 | Class expected() default Test.None.class; 17 | 18 | String message() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/EnvsFromFile.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | import org.junit.Test; 9 | 10 | @Target(METHOD) 11 | @Retention(RUNTIME) 12 | public @interface EnvsFromFile { 13 | 14 | String[] value() default {}; 15 | 16 | Class expected() default Test.None.class; 17 | 18 | String message() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /test-harness/src/main/java/io/jenkins/plugins/casc/misc/JenkinsConfiguredRule.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.misc; 2 | 3 | import io.jenkins.plugins.casc.ConfigurationAsCode; 4 | import java.io.ByteArrayOutputStream; 5 | import java.nio.charset.StandardCharsets; 6 | import org.jvnet.hudson.test.JenkinsRule; 7 | 8 | public class JenkinsConfiguredRule extends JenkinsRule { 9 | 10 | // TODO: Looks like API defect, exception should be thrown 11 | /** 12 | * Exports the Jenkins configuration to a string. 13 | * @return YAML as string 14 | * @param strict Fail if any export operation returns error 15 | * @throws Exception Export error 16 | * @throws AssertionError Failed to export the configuration 17 | * @since 1.25 18 | */ 19 | public String exportToString(boolean strict) throws Exception { 20 | final ByteArrayOutputStream out = new ByteArrayOutputStream(); 21 | ConfigurationAsCode.get().export(out); 22 | final String s = out.toString(StandardCharsets.UTF_8.name()); 23 | if (strict && s.contains("Failed to export")) { 24 | throw new AssertionError("Failed to export the configuration: " + s); 25 | } 26 | return s; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/DetectMissingVaultPluginTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.assertLogContains; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.hamcrest.Matchers.is; 6 | 7 | import io.jenkins.plugins.casc.misc.Env; 8 | import io.jenkins.plugins.casc.misc.EnvVarsRule; 9 | import io.jenkins.plugins.casc.misc.Envs; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | import org.junit.Rule; 13 | import org.junit.Test; 14 | import org.junit.rules.RuleChain; 15 | import org.jvnet.hudson.test.JenkinsRule; 16 | import org.jvnet.hudson.test.LoggerRule; 17 | 18 | public class DetectMissingVaultPluginTest { 19 | 20 | public LoggerRule loggerRule = new LoggerRule(); 21 | 22 | @Rule 23 | public RuleChain chain = RuleChain.outerRule(loggerRule 24 | .record(Logger.getLogger(ConfigurationAsCode.class.getName()), Level.SEVERE) 25 | .capture(2048)) 26 | .around(new EnvVarsRule()) 27 | .around(new JenkinsRule()); 28 | 29 | @Test 30 | @Envs(@Env(name = "CASC_VAULT_PW", value = "TEST")) 31 | public void missingVaultPluginShouldThrowException() throws ConfiguratorException { 32 | assertThat(System.getenv("CASC_VAULT_PW"), is("TEST")); 33 | ConfigurationAsCode.get().configure(getClass().getResource("admin.yml").toExternalForm()); 34 | assertLogContains( 35 | loggerRule, 36 | "Vault secret resolver is not installed, consider installing hashicorp-vault-plugin v2.4.0 or higher"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/JenkinsConfiguredWithCodeRuleClassRuleTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | 5 | import hudson.model.User; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 8 | import java.util.Collections; 9 | import org.junit.ClassRule; 10 | import org.junit.Test; 11 | 12 | public class JenkinsConfiguredWithCodeRuleClassRuleTest { 13 | @ClassRule 14 | @ConfiguredWithCode("admin.yml") 15 | public static JenkinsConfiguredWithCodeRule j = new JenkinsConfiguredWithCodeRule(); 16 | 17 | @Test 18 | public void user_created() { 19 | User admin = User.get("admin", false, Collections.emptyMap()); 20 | assertNotNull(admin); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/SampleBenchmark.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import edu.umd.cs.findbugs.annotations.NonNull; 6 | import io.jenkins.plugins.casc.misc.jmh.CascJmhBenchmarkState; 7 | import jenkins.benchmark.jmh.JmhBenchmark; 8 | import jenkins.model.Jenkins; 9 | import org.openjdk.jmh.annotations.Benchmark; 10 | 11 | @JmhBenchmark 12 | public class SampleBenchmark { 13 | public static class MyState extends CascJmhBenchmarkState { 14 | @NonNull 15 | @Override 16 | protected String getResourcePath() { 17 | return "benchmarks.yml"; 18 | } 19 | 20 | @NonNull 21 | @Override 22 | protected Class getEnclosingClass() { 23 | return SampleBenchmark.class; 24 | } 25 | } 26 | 27 | @Benchmark 28 | public void benchmark(MyState state) { 29 | Jenkins jenkins = state.getJenkins(); 30 | assertEquals("Benchmark started with Configuration as Code", jenkins.getSystemMessage()); 31 | assertEquals(22, jenkins.getNumExecutors()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/SchemaGenerationSanitisationTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc; 2 | 3 | import static io.jenkins.plugins.casc.SchemaGeneration.removeHtmlTags; 4 | import static io.jenkins.plugins.casc.SchemaGeneration.retrieveDocStringFromAttribute; 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 8 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 9 | import org.junit.jupiter.api.Test; 10 | 11 | @WithJenkinsConfiguredWithCode 12 | class SchemaGenerationSanitisationTest { 13 | 14 | @Test 15 | void testRetrieveDocStringFromAttribute(JenkinsConfiguredWithCodeRule j) { 16 | String expectedDocString = 17 | "If checked, this will allow users who are not authenticated to access Jenkins\n in a read-only mode."; 18 | String actualDocString = retrieveDocStringFromAttribute( 19 | hudson.security.FullControlOnceLoggedInAuthorizationStrategy.class, "allowAnonymousRead"); 20 | assertEquals(expectedDocString, actualDocString); 21 | } 22 | 23 | @Test 24 | void testRemoveHtmlTagRegex(JenkinsConfiguredWithCodeRule j) { 25 | String htmlTagString = 26 | "
If checked, this will allow users who are not authenticated to access Jenkins in a read-only mode.
"; 27 | String expectedString = 28 | "If checked, this will allow users who are not authenticated to access Jenkins in a read-only mode."; 29 | String actualString = removeHtmlTags(htmlTagString); 30 | assertEquals(expectedString, actualString); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/core/UnsecuredAuthorizationStrategyConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.core; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertSame; 4 | 5 | import hudson.security.AuthorizationStrategy; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 8 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 9 | import org.junit.jupiter.api.Test; 10 | 11 | /** 12 | * @author Kohsuke Kawaguchi 13 | */ 14 | @WithJenkinsConfiguredWithCode 15 | class UnsecuredAuthorizationStrategyConfiguratorTest { 16 | 17 | @Test 18 | @ConfiguredWithCode("UnsecuredAuthorizationStrategyConfiguratorTest.yml") 19 | void unsecured(JenkinsConfiguredWithCodeRule j) { 20 | assertSame(AuthorizationStrategy.UNSECURED, j.jenkins.getAuthorizationStrategy()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/MissingConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.is; 5 | import static org.hamcrest.Matchers.nullValue; 6 | import static org.junit.Assume.assumeThat; 7 | 8 | import hudson.model.User; 9 | import io.jenkins.plugins.casc.UnknownAttributesException; 10 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 11 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 12 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 13 | import org.junit.jupiter.api.Test; 14 | 15 | @WithJenkinsConfiguredWithCode 16 | class MissingConfiguratorTest { 17 | 18 | @ConfiguredWithCode( 19 | value = "MissingConfiguratorTest.yml", 20 | expected = UnknownAttributesException.class, 21 | message = "No hudson.security.AuthorizationStrategy implementation found for globalMatrix") 22 | @Test 23 | void testThrowsSuggestion(JenkinsConfiguredWithCodeRule j) { 24 | // The conditions for this test can be false in PCT runs 25 | assumeThat(j.jenkins.getPlugin("matrix-auth"), nullValue()); 26 | // No config check needed, should fail with IllegalArgumentException 27 | // We're purposely trying to configure a plugin for which there is no configurator 28 | // admin user should not be created due to IllegalArgumentException 29 | User user = User.getById("admin", false); 30 | assertThat(user, is(nullValue())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/SelfConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.is; 5 | import static org.hamcrest.Matchers.not; 6 | 7 | import io.jenkins.plugins.casc.ConfiguratorException; 8 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 9 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 10 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 11 | import org.junit.jupiter.api.Test; 12 | 13 | /** 14 | * @author Nicolas De Loof 15 | */ 16 | @WithJenkinsConfiguredWithCode 17 | class SelfConfiguratorTest { 18 | 19 | @Test 20 | @ConfiguredWithCode(value = "SelfConfiguratorTest.yml") 21 | void self_configure(JenkinsConfiguredWithCodeRule j) { 22 | assertThat(j.jenkins.getRawBuildsDir(), is("/tmp")); 23 | } 24 | 25 | @Test 26 | @ConfiguredWithCode(value = "SelfConfiguratorRestrictedTest.yml", expected = ConfiguratorException.class) 27 | void self_configure_restricted(JenkinsConfiguredWithCodeRule j) { 28 | // expected to throw Configurator Exception 29 | assertThat(j.jenkins.getRawBuildsDir(), is(not("/tmp"))); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/ClassParametersAreNonnullByDefault.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators.nonnull; 2 | 3 | import java.util.List; 4 | import javax.annotation.Nonnull; 5 | import javax.annotation.ParametersAreNonnullByDefault; 6 | import org.kohsuke.stapler.DataBoundConstructor; 7 | 8 | /** 9 | * This class checks the behaviour of {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator} 10 | * with {@link Nonnull} {@link List} parameters. 11 | */ 12 | @ParametersAreNonnullByDefault 13 | public class ClassParametersAreNonnullByDefault { 14 | private List strings; 15 | 16 | @DataBoundConstructor 17 | public ClassParametersAreNonnullByDefault(@Nonnull List strings) { 18 | this.strings = strings; 19 | } 20 | 21 | public List getStrings() { 22 | return strings; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/NonnullParameterConstructor.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators.nonnull; 2 | 3 | import java.util.Set; 4 | import javax.annotation.Nonnull; 5 | import org.kohsuke.stapler.DataBoundConstructor; 6 | 7 | /** 8 | * This class checks the behaviour of {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator} 9 | * with {@link Nonnull} {@link Set} parameters 10 | */ 11 | public class NonnullParameterConstructor { 12 | private Set strings; 13 | 14 | @DataBoundConstructor 15 | public NonnullParameterConstructor(@Nonnull Set strings) { 16 | this.strings = strings; 17 | } 18 | 19 | public Set getStrings() { 20 | return strings; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/nonnullparampackage/PackageParametersAreNonnullByDefault.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators.nonnull.nonnullparampackage; 2 | 3 | import org.kohsuke.stapler.DataBoundConstructor; 4 | 5 | /** 6 | * Checks the behaviour of {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator} with non null 7 | * {@link String} when using package-level {@link javax.annotation.ParametersAreNonnullByDefault} annotations. 8 | */ 9 | public class PackageParametersAreNonnullByDefault { 10 | private String string; 11 | 12 | @DataBoundConstructor 13 | public PackageParametersAreNonnullByDefault(String string) { 14 | this.string = string; 15 | } 16 | 17 | public String getString() { 18 | return string; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/nonnullparampackage/PackageParametersNonNullCheckForNull.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.impl.configurators.nonnull.nonnullparampackage; 2 | 3 | import hudson.util.Secret; 4 | import javax.annotation.CheckForNull; 5 | import org.kohsuke.stapler.DataBoundConstructor; 6 | 7 | /** 8 | * Checks the behaviour of {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator} with non null 9 | * {@link Secret} when using package-level {@link javax.annotation.ParametersAreNonnullByDefault} annotations. 10 | */ 11 | public class PackageParametersNonNullCheckForNull { 12 | private Secret secret; 13 | 14 | @DataBoundConstructor 15 | public PackageParametersNonNullCheckForNull(@CheckForNull Secret secret) { 16 | this.secret = secret; 17 | } 18 | 19 | public Secret getSecret() { 20 | return secret; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/nonnullparampackage/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package tests {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator}'s behaviour with 3 | * package-level {@link javax.annotation.ParametersAreNonnullByDefault} annotation. 4 | */ 5 | @ParametersAreNonnullByDefault 6 | package io.jenkins.plugins.casc.impl.configurators.nonnull.nonnullparampackage; 7 | 8 | import javax.annotation.ParametersAreNonnullByDefault; 9 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/impl/configurators/nonnull/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package contains classes used by {@link io.jenkins.plugins.casc.impl.configurators.DataBoundConfiguratorTest} 3 | * for checking behaviour of {@code Nonnull} parameters. 4 | */ 5 | package io.jenkins.plugins.casc.impl.configurators.nonnull; 6 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/junit/jupiter/JenkinsConfiguredWithCodeMethodRuleTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.junit.jupiter; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertNotNull; 4 | 5 | import hudson.model.User; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 8 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 9 | import java.util.Collections; 10 | import org.junit.jupiter.api.Test; 11 | 12 | class JenkinsConfiguredWithCodeMethodRuleTest { 13 | 14 | @Test 15 | @WithJenkinsConfiguredWithCode 16 | @ConfiguredWithCode("admin.yml") 17 | void user_created(JenkinsConfiguredWithCodeRule rule) { 18 | assertNotNull(rule); 19 | User admin = User.get("admin", false, Collections.emptyMap()); 20 | assertNotNull(admin); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test-harness/src/test/java/io/jenkins/plugins/casc/junit/jupiter/JenkinsConfiguredWithCodeRuleClassRuleTest.java: -------------------------------------------------------------------------------- 1 | package io.jenkins.plugins.casc.junit.jupiter; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertNotNull; 4 | 5 | import hudson.model.User; 6 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 7 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 8 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 9 | import java.util.Collections; 10 | import org.junit.jupiter.api.BeforeAll; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @WithJenkinsConfiguredWithCode 14 | class JenkinsConfiguredWithCodeRuleClassRuleTest { 15 | @ConfiguredWithCode("admin.yml") 16 | public static JenkinsConfiguredWithCodeRule j; 17 | 18 | @BeforeAll 19 | static void beforeAll() { 20 | assertNotNull(j); 21 | } 22 | 23 | @Test 24 | void user_created() { 25 | User admin = User.get("admin", false, Collections.emptyMap()); 26 | assertNotNull(admin); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/ArtifactoryBuilderTest.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | artifactorybuilder: 3 | useCredentialsPlugin: true 4 | jfrogInstances: 5 | - instanceId: artifactory 6 | url: http://acme.com/artifactory 7 | resolverCredentialsConfig: 8 | username: artifactory_user 9 | password: ${ARTIFACTORY_PASSWORD} 10 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/BackwardCompatibilityTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | nodes: 3 | - DumbSlave: 4 | name: "foo" 5 | - dumb: 6 | name: "bar" 7 | - slave: 8 | name: "qix" 9 | # see https://github.com/jenkinsci/jenkins/pull/3475 10 | # - permanent: 11 | # name: "zot" 12 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/GetConfiguratorsTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n" 3 | numExecutors: 5 4 | mode: NORMAL 5 | scmCheckoutRetryCount: 4 6 | clouds: 7 | - docker: 8 | name: "docker" 9 | dockerApi: 10 | dockerHost: 11 | uri: "unix:///var/run/docker.sock" 12 | templates: 13 | - labelString: "docker-agent" 14 | dockerTemplateBase: 15 | image: "jenkins/slave" 16 | volumes: 17 | - hello:/hello 18 | - world:/world 19 | environmentsString: | 20 | hello=world 21 | foo=bar 22 | remoteFs: "/home/jenkins/agent" 23 | connector: 24 | attach: 25 | user: "jenkins" 26 | instanceCapStr: "10" 27 | 28 | unclassified: 29 | location: 30 | adminAddress: admin@acme.org 31 | mailer: 32 | replyToAddress: do-not-reply@acme.org 33 | smtpHost: smtp.acme.org 34 | smtpPort: 4441 35 | globalLibraries: 36 | libraries: 37 | - name: "awesome-lib" 38 | retriever: 39 | modernSCM: 40 | scm: 41 | git: 42 | remote: "https://github.com/jenkins-infra/pipeline-library.git" 43 | 44 | tool: 45 | git: 46 | installations: 47 | - name: git 48 | home: /usr/local/bin/git 49 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/GlobalSecurityConfiguration.yml: -------------------------------------------------------------------------------- 1 | securityConfig: 2 | markupFormatter: plainText 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/JenkinsConfigTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "configuration as code - JenkinsConfigTest" 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/aNonEmpty.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Configured by Configuration as Code plugin" 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/admin.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: 3 | local: 4 | allowsSignup: false 5 | users: 6 | - id: "admin" 7 | password: "admin" 8 | authorizationStrategy: loggedInUsersCanDoAnything 9 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/attributesNotFlattenedToTop.yml: -------------------------------------------------------------------------------- 1 | tool: 2 | acceptLicense: true -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/benchmarks.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Benchmark started with Configuration as Code" 3 | numExecutors: 22 4 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/ConfigureLabels.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | nodes: 3 | - permanent: 4 | labelString: "label1 label2" 5 | launcher: 6 | jnlp: 7 | workDirSettings: 8 | disabled: false 9 | failIfWorkDirIsMissing: false 10 | internalDir: "remoting" 11 | name: "myNode" 12 | numExecutors: 1 13 | remoteFS: "/" 14 | retentionStrategy: "always" 15 | labelAtoms: 16 | - name: "label1" 17 | properties: 18 | - myProperty: 19 | value: 2 20 | - anotherTestProperty: 21 | otherProperty: 4 22 | - name: "label2" 23 | properties: 24 | - myProperty: 25 | value: 3 26 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/ExpectedLabelsConfiguration.yml: -------------------------------------------------------------------------------- 1 | labelAtoms: 2 | - name: "built-in" 3 | - name: "label1" 4 | properties: 5 | - myProperty: 6 | value: 2 7 | - anotherTestProperty: 8 | otherProperty: 4 9 | - myProperty: 10 | value: 1 11 | - name: "label2" 12 | properties: 13 | - myProperty: 14 | value: 3 15 | - name: "myNode" 16 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/HeteroDescribable.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: local 3 | authorizationStrategy: 4 | loggedInUsersCanDoAnything: 5 | allowAnonymousRead: false 6 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/JenkinsConfiguratorCloudSupportTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | nodes: 3 | - dumb: 4 | mode: NORMAL 5 | name: "agent1" 6 | remoteFS: "/home/user1" 7 | launcher: jnlp 8 | - dumb: 9 | mode: NORMAL 10 | name: "agent2" 11 | remoteFS: "/home/user1" 12 | launcher: jnlp 13 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/MavenConfiguratorTest.yml: -------------------------------------------------------------------------------- 1 | tool: 2 | mavenGlobalConfig: 3 | settingsProvider: 4 | filePath: 5 | path: /usr/share/maven-settings.xml 6 | installations: 7 | - name: maven 8 | home: /usr/share/maven 9 | properties: 10 | - installSourceProperty: 11 | installers: 12 | - mavenInstaller: 13 | id: "3.5.0" 14 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/Primitives.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | slaveAgentPort: 6666 3 | authorizationStrategy: loggedInUsersCanDoAnything 4 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/Proxy.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | proxy: 3 | name: "proxyhost" 4 | port: 80 5 | userName: "login" 6 | secretPassword: "password" 7 | noProxyHost: "externalhost" 8 | testUrl: "http://google.com" 9 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/ProxyMinimal.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | proxy: 3 | name: "proxyhost" 4 | port: 80 5 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/ProxyWithSecrets.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | proxy: 3 | name: "${PROXY_HOST}" 4 | port: ${PROXY_PORT} 5 | userName: "${PROXY_USER}" 6 | secretPassword: "${PROXY_PASSWORD}" 7 | noProxyHost: "${PROXY_NOPROXY}" 8 | testUrl: "${PROXY_TEST_URL}" 9 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/SetEnvironmentVariable.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | nodeProperties: 3 | - envVars: 4 | env: 5 | - key: FOO 6 | value: BAR 7 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/UnsecuredAuthorizationStrategyConfiguratorTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: 3 | local: 4 | allowsSignup: false 5 | authorizationStrategy: unsecured 6 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/core/UpdateCenter.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | updateCenter: 3 | sites: 4 | - id: "default" 5 | url: "https://updates.jenkins.io/update-center.json" 6 | - id: "experimental" 7 | url: "https://updates.jenkins.io/experimental/update-center.json" 8 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/empty.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/configuration-as-code-plugin/ab8a57267457703956f65572415c4c352503c5e9/test-harness/src/test/resources/io/jenkins/plugins/casc/empty.yml -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/folder/jenkins.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "configuration as code - JenkinsConfigTestFolder" 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/folder/jenkins2.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | quietPeriod: 10 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/DataBoundDescriptorNonNull.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | disableRememberMe: false 3 | markupFormatter: "plainText" 4 | myViewsTabBar: "standard" 5 | primaryView: 6 | all: 7 | name: "all" 8 | views: 9 | - all: 10 | name: "all" 11 | - list: 12 | columns: 13 | - "status" 14 | - "jobName" 15 | - "lastSuccess" 16 | - "lastFailure" 17 | - "lastDuration" 18 | - "buildButton" 19 | includeRegex: ".+" 20 | name: "listView" 21 | - list: 22 | columns: 23 | - "status" 24 | - "weather" 25 | - "jobName" 26 | - "lastSuccess" 27 | - "lastFailure" 28 | - "lastDuration" 29 | - "buildButton" 30 | name: "other list view" 31 | # Currently not possible due to missing getter/setter in Jenkins Core 32 | # jobNames: 33 | # - "testJob1" 34 | viewsTabBar: "standard" 35 | authorizationStrategy: "loggedInUsersCanDoAnything" 36 | securityRealm: 37 | local: 38 | allowsSignup: false 39 | users: 40 | - id: "admin" 41 | password: "admin" 42 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/DescriptorConfiguratorTest_camelCase.yml: -------------------------------------------------------------------------------- 1 | --- 2 | unclassified: 3 | fooBar: 4 | foo: "foo" 5 | bar: "bar" 6 | baz: "1.0" 7 | flt: "1e3" 8 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/DescriptorConfiguratorTest_lowerCase.yml: -------------------------------------------------------------------------------- 1 | --- 2 | unclassified: 3 | foobar: 4 | foo: "foo" 5 | bar: "bar" 6 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/DuplicateKeyDescribableConfigure.yml: -------------------------------------------------------------------------------- 1 | unclassified: 2 | fooBarGlobal: 3 | fooBar: 4 | fooBarInner: 5 | foo: hello 6 | bar: world 7 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/MissingConfiguratorTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: 3 | local: 4 | allowsSignup: false 5 | users: 6 | - id: admin 7 | password: ${adminpw:-passw0rd} 8 | authorizationStrategy: 9 | globalMatrix: 10 | permissions: 11 | - "Overall/Administer:authenticated" 12 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/SelfConfiguratorRestrictedTest.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | rawBuildsDir: /tmp 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/impl/configurators/SelfConfiguratorTest.yml: -------------------------------------------------------------------------------- 1 | configuration-as-code: 2 | version: 1 3 | deprecated: warn 4 | restricted: warn 5 | unknown: warn 6 | 7 | jenkins: 8 | rawBuildsDir: /tmp 9 | doesntexist: foo 10 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/invalidBaseConfig.yml: -------------------------------------------------------------------------------- 1 | invalidBaseConfigurator: "I do nothing" 2 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/invalidSchemaConfig.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Configured by Configuration as Code plugin" 3 | numExecutors: "Hello" 4 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/invalidToolBaseConfig.yml: -------------------------------------------------------------------------------- 1 | tool: 2 | git: 3 | installations: 4 | - name: git 5 | home: 000 6 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/junit/jupiter/admin.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | securityRealm: 3 | local: 4 | allowsSignup: false 5 | users: 6 | - id: "admin" 7 | password: "admin" 8 | authorizationStrategy: loggedInUsersCanDoAnything 9 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/maxAliasesLimit.yml: -------------------------------------------------------------------------------- 1 | x-jenkins-linux-node: &jenkins_linux_node_anchor 2 | remoteFS: "/home/jenkins" 3 | launcher: 4 | jnlp: 5 | workDirSettings: 6 | disabled: true 7 | failIfWorkDirIsMissing: false 8 | internalDir: "remoting" 9 | workDirPath: "/tmp" 10 | jenkins: 11 | nodes: 12 | - permanent: 13 | name: "static-agent1" 14 | <<: *jenkins_linux_node_anchor 15 | - permanent: 16 | name: "static-agent2" 17 | <<: *jenkins_linux_node_anchor 18 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/merge1.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | numExecutors: 0 3 | 4 | nodes: 5 | - dumb: 6 | mode: NORMAL 7 | name: "agent1" 8 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/merge2.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | numExecutors: 20 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/merge3.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Configured by Configuration as Code plugin" 3 | 4 | nodes: 5 | - dumb: 6 | mode: NORMAL 7 | name: "agent3" 8 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/multi-line1.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: | 3 | Welcome to our build server. 4 | 5 | This Jenkins is 100% configured and managed 'as code'. 6 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/multi-line2.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Welcome to our build server.\n\nThis Jenkins is 100% configured and managed 'as code'.\n" 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/validJenkinsBaseConfig.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Hello world" -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/validJenkinsBaseConfigWithSymbol.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | crumbIssuer: 3 | standard: 4 | excludeClientIPFromCrumb: false -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/validSchemaConfig.yml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: "Configured by JCasC" 3 | -------------------------------------------------------------------------------- /test-harness/src/test/resources/io/jenkins/plugins/casc/validSelfConfig.yml: -------------------------------------------------------------------------------- 1 | configuration-as-code: 2 | version: "1" 3 | deprecated: "warn" 4 | restricted: "warn" 5 | unknown: "warn" --------------------------------------------------------------------------------