Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema Generation for nested yml configurations #1027

Merged
merged 102 commits into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
774506b
Added initial schema test
Aug 7, 2019
7051ca9
Added Schema Validation functions
Aug 8, 2019
f1b2d30
Added test jsonSchemGenerator
Aug 10, 2019
17079c7
Added test to generate an intermediate schema
Aug 16, 2019
886bc5a
Added schema generation for a single descriptor
Aug 17, 2019
0271cd3
Completed the string generation 2/4 of the schema
Aug 21, 2019
522f4e5
Added exclusion
Aug 22, 2019
f264c70
generic get configurators
jetersen Aug 22, 2019
076fe14
Finished Descriptor Configuration generation
Aug 22, 2019
2bd7f9d
Base configurator and HetroDescribable Configurator Schema Generation…
Aug 22, 2019
0da381b
Added Base configurators with no attributes
Aug 23, 2019
3d45f6b
Added Base configurator attribute enumeration schema
Aug 23, 2019
cd9a9dd
Added Non-enumerated attributes to schema
Aug 23, 2019
4bf306c
Added fully validated Configured schema
Aug 23, 2019
4657e0c
Added validation initial test
Aug 24, 2019
c734c0f
Using JSON objects to construct Schema
Aug 24, 2019
fe1ce60
Added valid schema integration tests
Aug 25, 2019
8108038
Converted class names to simple names
Aug 26, 2019
38dad38
Upgraded schema version
Aug 26, 2019
d89e24c
Changes to test and pom.xml
Aug 26, 2019
3c4510c
Added functions to split up the generateSchema() function
Aug 26, 2019
f079505
Added additional methods in generateSchema()
Aug 26, 2019
76c0932
Code Cleanup
Aug 26, 2019
623914f
Inital impl for describeStructure
Aug 27, 2019
13e893a
Incremental Impl changes
Aug 27, 2019
2ede6f6
Concept implementation
Aug 27, 2019
ec07960
Added annotation and test implementations
Aug 28, 2019
448c4a2
Added addition configurator wise tests
Aug 28, 2019
3165323
Added the utlisation of describeStructure
Aug 28, 2019
ad57f8d
Added default configurators describe structure
Aug 29, 2019
14197bc
Added describe Strucure function to default Config
Aug 29, 2019
a338fbc
Added JSON Schema mode and boolean
Aug 30, 2019
d0f9349
Added describeStructure to Attribute and Configurator
Aug 31, 2019
6c4cb3c
Merge branch 'master' into nested_yaml_schema
Sep 4, 2019
901ac01
Lookup addition for configurators
Sep 6, 2019
4df5e1e
Added tests and added baseConfigurator LookupFeature
Sep 6, 2019
81b9a68
Merge master into current branch
Sep 12, 2019
fd886c8
Added test for rootConfiguratorGeneration
Sep 14, 2019
6c42055
Sequence indication fix
Sep 20, 2019
b0b870b
Configurator Lookup Addition
Sep 20, 2019
fe7b0b8
Added javadoc and logger warning for failing tests
Sep 24, 2019
dcd5f6f
Added storeConfigurators function
Sep 25, 2019
122c8d9
Added root configurator nesting
Sep 25, 2019
e5bde57
Fixed root configurators
Sep 26, 2019
b97f380
Merge branch 'master' into nested_yaml_schema
Sep 26, 2019
1e0a6a2
Added support for the root configurators
Sep 27, 2019
d0083d8
Added mock test
Sep 27, 2019
a030035
Merge branch 'master' into nested_yaml_schema
Sep 27, 2019
2b105a4
Added nesting support for every base configurator and tests for the same
Sep 28, 2019
79892a2
Removed functions that are not used
Sep 28, 2019
51ae5fd
Added jenkins base configurator test
Sep 30, 2019
cee3cf6
Added validSelfConfig Test
Sep 30, 2019
1f72339
Added validSelfConfig and validJenkinsBaseConfig files
Oct 2, 2019
67c3f81
Don't fetch the jenkins.model.Jenkins
timja Oct 2, 2019
dff9199
Resolved merge conflicts and reverted tim's changes
Oct 4, 2019
5388f66
Resolved conflicts
Nov 15, 2019
e992aee
WIP
timja Dec 2, 2019
0e9e3bd
Merge branch 'master' into nested_yaml_schema
timja Dec 2, 2019
5bacdd2
Fix self configurator
timja Dec 2, 2019
b07c22b
Fix formatting
timja Dec 2, 2019
9bc089a
More formatting
timja Dec 2, 2019
94e14d4
Undo whitespace changes
timja Dec 2, 2019
a96a4f7
Change json schema test API to return list of errors
timja Dec 3, 2019
802c9c9
Merge branch 'change-json-schema-test-api' into nested_yaml_schema
timja Dec 3, 2019
d50ad6e
Adding failing test demonstrating all attributes getting flattenned to
timja Dec 3, 2019
26341c4
Fix flattening issues
timja Dec 3, 2019
3ce5e2b
Remove print lines
timja Dec 3, 2019
b92032d
Fix spot bugs
timja Dec 3, 2019
5e9ce85
Checkstyle
timja Dec 3, 2019
a71b71e
Fix test
timja Dec 3, 2019
ce565f2
Fix checkstyle
timja Dec 3, 2019
cd01391
Introduce test-harness module
timja Dec 7, 2019
e50c94f
shush codacy + docs
timja Dec 7, 2019
55e0216
Fix javadoc
timja Dec 7, 2019
80221ea
Fix import
timja Dec 7, 2019
2ef14a3
Merge branch 'change-json-schema-test-api' into nested_yaml_schema
timja Dec 8, 2019
53342bf
Add integration tests for some of the remaining issues
timja Dec 8, 2019
2403838
Fix enforcer
timja Dec 8, 2019
0395bea
Comment out debug
timja Dec 8, 2019
30fdbf8
Fix tests
timja Dec 8, 2019
912b46d
Add symbol support and fix tests
timja Dec 8, 2019
603a577
Add for symbol support
timja Dec 9, 2019
d271135
Checkstyle
timja Dec 9, 2019
896d2cb
Add long to case
timja Dec 9, 2019
ee1c946
Add one level of array support
timja Dec 9, 2019
6ab2a31
remove unused imports
jetersen Dec 10, 2019
3e32f25
Merge branch 'master' into nested_yaml_schema
timja Dec 10, 2019
3be3926
Revert unneeded change
timja Dec 10, 2019
e7b2a8f
Fix earlier merge, restore help file support
timja Dec 10, 2019
314f1a7
Fix checkstyle
timja Dec 10, 2019
b646a04
Added system log and removed exception
Dec 14, 2019
423ee6c
Improved warning string
Dec 14, 2019
d5d10f4
Added describeForSchema Function
Jan 5, 2020
1cdd881
Fixed Checkstyle
Jan 5, 2020
1040a6a
Removed boolean
Jan 7, 2020
a242048
Fixed ClassCast Exception
Jan 7, 2020
0cfde4a
Combined declaration and assignment
Jan 8, 2020
1aa84b1
Added javadoc and beta class
Jan 9, 2020
1ff2aaf
Update plugin/src/main/java/io/jenkins/plugins/casc/Configurator.java
Jan 10, 2020
15a7500
Update plugin/src/main/java/io/jenkins/plugins/casc/Attribute.java
Jan 10, 2020
b468ee9
Update plugin/src/main/java/io/jenkins/plugins/casc/Configurator.java
Jan 10, 2020
772445a
Update plugin/src/main/java/io/jenkins/plugins/casc/Attribute.java
Jan 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion integrations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@
<version>3.0.0</version>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>azure-keyvault</artifactId>
<version>1.4</version>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>display-url-api</artifactId>
Expand Down Expand Up @@ -416,6 +422,31 @@

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-annotations</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>3.12.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.12.2</version>
</dependency>

<dependency>
<groupId>com.github.docker-java</groupId>
Expand Down Expand Up @@ -512,7 +543,7 @@
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>1.13.0</version>
<version>1.15.0</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.jenkins.plugins.casc;

import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule;
import org.junit.Rule;
import org.junit.Test;

import static io.jenkins.plugins.casc.misc.Util.convertYamlFileToJson;
import static io.jenkins.plugins.casc.misc.Util.validateSchema;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertThat;

public class AzureKeyVaultTest {

@Rule
public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule();

@Test
public void validJsonSchema() throws Exception {
assertThat(
validateSchema(convertYamlFileToJson(this, "azureKeyVault.yml")),
empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import org.junit.contrib.java.lang.system.EnvironmentVariables;
import org.junit.rules.RuleChain;

import static junit.framework.TestCase.assertNotNull;
import static io.jenkins.plugins.casc.misc.Util.convertYamlFileToJson;
import static io.jenkins.plugins.casc.misc.Util.validateSchema;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

/**
* @author v1v (Victor Martinez)
Expand All @@ -29,4 +33,11 @@ public void configure_slack() throws Exception {
SlackNotifier.DescriptorImpl slackNotifier = ExtensionList.lookupSingleton(SlackNotifier.DescriptorImpl.class);
assertNotNull(slackNotifier);
}

@Test
public void validJsonSchema() throws Exception {
assertThat(
validateSchema(convertYamlFileToJson(this, "slackSchema.yml")),
empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
import io.jenkins.plugins.casc.misc.ConfiguredWithReadme;
import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule;
import jenkins.model.GlobalConfiguration;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

import static io.jenkins.plugins.casc.misc.Util.convertYamlFileToJson;
import static io.jenkins.plugins.casc.misc.Util.validateSchema;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

/**
Expand Down Expand Up @@ -38,4 +43,18 @@ public void configure_sonar_globalconfig() throws Exception {
assertEquals("envVar", triggers.getEnvVar());
}

@Test
public void validJsonSchema() throws Exception {
assertThat(
validateSchema(convertYamlFileToJson(this, "sonarSchema.yml")),
empty());
}

@Test
@Ignore
public void validFullJsonSchema() throws Exception {
assertThat(
validateSchema(convertYamlFileToJson(this, "sonarSchemaFull.yml")),
empty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
unclassified:
azureKeyVault:
keyVaultURL: https://not-a-real-vault.vault.azure.net
credentialID: service-principal
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
unclassified:
slackNotifier:
teamDomain: workspace
tokenCredentialId: slack-token
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
unclassified:
sonarGlobalConfiguration:
buildWrapperEnabled: false
installations:
- additionalAnalysisProperties: sonar.organization=jenkinsci
name: SonarQube
serverAuthenticationToken: 'sonarcloud-api-token'
serverUrl: 'https://sonarcloud.io'
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
unclassified:
sonarGlobalConfiguration: # mandatory
buildWrapperEnabled: true
installations: # mandatory
- name: "TEST" # id of the SonarQube configuration - to be used in jobs
serverUrl: "http://url:9000"
#credentialsId: token-sonarqube # id of the credentials containing sonar auth token (since 2.9 version)
serverAuthenticationToken: "token" # for retrocompatibility with versions < 2.9
mojoVersion: "mojoVersion"
additionalProperties: "blah=blah"
additionalAnalysisProperties: "additionalAnalysisProperties"
triggers:
skipScmCause: true
skipUpstreamCause: true
envVar: "envVar"
68 changes: 64 additions & 4 deletions plugin/src/main/java/io/jenkins/plugins/casc/Attribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class Attribute<Owner, Type> {
private Setter<Owner, Type> setter;
private Getter<Owner, Type> getter;
private boolean secret;
private boolean isJsonSchema;

private boolean deprecated;

Expand Down Expand Up @@ -111,6 +112,14 @@ public Class<? extends AccessRestriction>[] getRestrictions() {
return restrictions != null ? restrictions : EMPTY;
}

/**
* Set jsonSchema is used to tell the describe function to call the describe structure
* so that it supports and returns a nested structure
*/
public void setJsonSchema(boolean jsonSchema) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Javadoc?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added +1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still required?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for closing now it is the separate thread

isJsonSchema = jsonSchema;
}

public boolean isRestricted() {
return restrictions != null && restrictions.length > 0;
}
Expand Down Expand Up @@ -225,7 +234,8 @@ public CNode describe(Owner instance, ConfigurationContext context) throws Confi
": No configurator found for type " + type);
}
try {
Object o = getValue(instance);
Object o;
o = getValue(instance);
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
if (o == null) {
return null;
}
Expand All @@ -235,8 +245,12 @@ public CNode describe(Owner instance, ConfigurationContext context) throws Confi
if (multiple) {
Sequence seq = new Sequence();
if (o.getClass().isArray()) o = Arrays.asList((Object[]) o);
for (Object value : (Iterable) o) {
seq.add(_describe(c, context, value, shouldBeMasked));
if (o instanceof Iterable) {
timja marked this conversation as resolved.
Show resolved Hide resolved
for (Object value : (Iterable) o) {
seq.add(_describe(c, context, value, shouldBeMasked));
}
} else {
LOGGER.log(Level.FINE, o.getClass().toString() + " is not iterable");
}
return seq;
}
Expand All @@ -249,6 +263,47 @@ public CNode describe(Owner instance, ConfigurationContext context) throws Confi
}
}

/**
* This function is for the JSONSchemaGeneration
* @param instance Owner Instance
* @param context Context to be passed
* @return CNode object describing the structure of the node
*/
timja marked this conversation as resolved.
Show resolved Hide resolved
public CNode describeForSchema (Owner instance, ConfigurationContext context) {

sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
final Configurator c = context.lookup(type);
if (c == null) {
return new Scalar("FAILED TO EXPORT\n" + instance.getClass().getName()+"#"+name +
": No configurator found for type " + type);
}
try {
Object o;
o = getType();
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
if (o == null) {
return null;
}

// In Export we sensitive only those values which do not get rendered as secrets
boolean shouldBeMasked = isSecret(instance);
if (multiple) {
Sequence seq = new Sequence();
if (o.getClass().isArray()) o = Arrays.asList(o);
if(o instanceof Iterable) {
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
for (Object value : (Iterable) o) {
seq.add(_describe(c, context, value, shouldBeMasked));
}
}
return seq;
}
return _describe(c, context, o, shouldBeMasked);
} catch (Exception e) {
// Don't fail the whole export, prefer logging this error
LOGGER.log(Level.WARNING, "Failed to export", e);
return new Scalar("FAILED TO EXPORT\n" + instance.getClass().getName() + "#" + name + ": "
+ printThrowable(e));
}
}

/**
* Describes a node.
* @param c Configurator
Expand All @@ -261,7 +316,12 @@ public CNode describe(Owner instance, ConfigurationContext context) throws Confi
*/
private CNode _describe(Configurator c, ConfigurationContext context, Object value, boolean shouldBeMasked)
throws Exception {
CNode node = c.describe(value, context);
CNode node;
if(isJsonSchema) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Casz Added this so that it would not throw any casting errors, since in the descirbe structure we were initally calling with value whereas now we needed the type. This reduces the castClassException

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still required?

sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
node = c.describeStructure(value, context);
} else {
node = c.describe(value, context);
}
if (shouldBeMasked && node instanceof Scalar) {
((Scalar)node).sensitive(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class ConfigurationContext implements ConfiguratorRegistry {

private transient final ConfiguratorRegistry registry;

private transient String mode;
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved

public ConfigurationContext(ConfiguratorRegistry registry) {
this.registry = registry;
}
Expand Down Expand Up @@ -62,6 +64,15 @@ public void setUnknown(Unknown unknown) {
this.unknown = unknown;
}

String getMode() {
return mode;
}

public void setMode(String mode) {
this.mode = mode;
}



// --- delegate methods for ConfigurationContext

Expand Down Expand Up @@ -123,6 +134,11 @@ public String value() {
public boolean isAtLeast(Version version) {
return this.ordinal() >= version.ordinal();
}

@Override
public String toString() {
return value;
}
}

static {
Expand Down
17 changes: 17 additions & 0 deletions plugin/src/main/java/io/jenkins/plugins/casc/Configurator.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.Symbol;


/**
* Define a {@link Configurator} which handles a configuration element, identified by name.
* @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
Expand Down Expand Up @@ -167,4 +168,20 @@ default CNode describe(T instance, ConfigurationContext context) throws Exceptio
return mapping;
}

@CheckForNull
Copy link
Member

@oleg-nenashev oleg-nenashev Jan 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs Javadoc since it will be consumed by plugins. @since TODO also

Copy link
Author

@sladyn98 sladyn98 Jan 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah added javadoc. Confused about the @since TODO ?

default CNode describeStructure(T instance, ConfigurationContext context)
timja marked this conversation as resolved.
Show resolved Hide resolved
throws Exception {
Mapping mapping = new Mapping();
for (Attribute attribute : getAttributes()) {
if(context.getMode().equals("JSONSchema")) {
sladyn98 marked this conversation as resolved.
Show resolved Hide resolved
attribute.setJsonSchema(true);
}
CNode value = attribute.describeForSchema(instance, context);
if (value != null) {
mapping.put(attribute.getName(), attribute.getType().getSimpleName());
}
}
return mapping;
}

}
Loading