diff --git a/README.md b/README.md index 3845f69..eb2a594 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Both steps are also exposed in the pipeline job as `lrcRunTest` and `lrcGenTrend ### System configuration - Navigate to **Manage Jenkins** → **System Configuration** → **Configure System** → **LoadRunner Cloud** and then configure the following settings: - - **Username** and **Password** - - If you use [API Access keys](https://admhelp.microfocus.com/lrc/en/Latest/Content/Storm/Admin-APIAccess.htm), select the **Use OAuth token** checkbox, then input the **Client ID** and **Client Secret**. + - **Client ID** and **Client Secret** + Refer to [API access keys](https://admhelp.microfocus.com/lrc/en/Latest/Content/Storm/Admin-APIAccess.htm) for details. You can still input **Username** and **Password** in the fields (depends on the feature toggle in your tenant). However, it's recommended to use API access keys. - **URL**, default: "https://loadrunner-cloud.saas.microfocus.com" - **Tenant ID**, for example: 123456789 - **Proxy** settings (optional). If you need to use a proxy to access LoadRunner Cloud, select **Connect LoadRunner Cloud via proxy** checkbox, then configure the following fields. @@ -45,10 +45,7 @@ Both steps are also exposed in the pipeline job as `lrcRunTest` and `lrcGenTrend unclassified: lrcRunTest: tenantId: "" - username: "" - password: "" url: "https://loadrunner-cloud.saas.microfocus.com" - useOAuth: false clientId: "" clientSecret: "" useProxy: false diff --git a/images/system_config.png b/images/system_config.png index 53893f1..893126f 100644 Binary files a/images/system_config.png and b/images/system_config.png differ diff --git a/pom.xml b/pom.xml index 6a148d2..44d62ea 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ https://github.com/${gitHubRepo} - 5.0.5- + 5.1.0- -SNAPSHOT diff --git a/src/main/java/com/microfocus/lrc/core/entity/ProxyConfiguration.java b/src/main/java/com/microfocus/lrc/core/entity/ProxyConfiguration.java index b29bec2..f426b90 100644 --- a/src/main/java/com/microfocus/lrc/core/entity/ProxyConfiguration.java +++ b/src/main/java/com/microfocus/lrc/core/entity/ProxyConfiguration.java @@ -33,7 +33,7 @@ public final class ProxyConfiguration implements Serializable { // #endregion public ProxyConfiguration(final String host, final int port, final String username, final String password) { - if (host == null || host.length() == 0) { + if (host == null || host.isEmpty()) { throw new IllegalArgumentException("host must not be empty."); } if (port <= 0 || port > MAX_PORT_RANGE) { @@ -43,7 +43,7 @@ public ProxyConfiguration(final String host, final int port, final String userna this.host = host; this.port = port; - if (username != null && password != null && username.length() > 0 && password.length() > 0) { + if (username != null && password != null && !username.isEmpty() && !password.isEmpty()) { this.username = username; this.password = Secret.fromString(password); } @@ -51,7 +51,7 @@ public ProxyConfiguration(final String host, final int port, final String userna public ProxyConfiguration(final String host, final String port, final String username, final String password) throws IllegalArgumentException { - if (host == null || host.length() == 0) { + if (host == null || host.isEmpty()) { throw new IllegalArgumentException("host must not be empty."); } int portNum; @@ -67,7 +67,7 @@ public ProxyConfiguration(final String host, final String port, final String use this.host = host; this.port = portNum; - if (username != null && password != null && username.length() > 0 && password.length() > 0) { + if (username != null && password != null && !username.isEmpty() && !password.isEmpty()) { this.username = username; this.password = Secret.fromString(password); } diff --git a/src/main/java/com/microfocus/lrc/jenkins/TestRunBuilder.java b/src/main/java/com/microfocus/lrc/jenkins/TestRunBuilder.java index 863ac7b..8949442 100644 --- a/src/main/java/com/microfocus/lrc/jenkins/TestRunBuilder.java +++ b/src/main/java/com/microfocus/lrc/jenkins/TestRunBuilder.java @@ -74,7 +74,7 @@ public TestRunBuilder( static Map readStringConfigFromEnvVars(final Run run, final Launcher launcher) { Map map = new HashMap<>(); - for (StringOptionInEnvVars key : StringOptionInEnvVars.values()) { + for (StringOptionInEnvVars key : StringOptionInEnvVars.getEntries()) { String value = EnvVarsUtil.getEnvVar(run, launcher, key.name()); if (StringUtils.isNotBlank(value)) { map.put(key.name(), value.trim()); @@ -333,7 +333,7 @@ public void perform( private Map readBoolConfigFromEnvVars(final Run run, final Launcher launcher) { Map map = new HashMap<>(); - for (BooleanOptionInEnvVars key : BooleanOptionInEnvVars.values()) { + for (BooleanOptionInEnvVars key : BooleanOptionInEnvVars.getEntries()) { String value = EnvVarsUtil.getEnvVar(run, launcher, key.name()); if (StringUtils.isNotBlank(value) && !value.equals("0") && !value.equalsIgnoreCase("false") && !value.equalsIgnoreCase("no")) { @@ -452,22 +452,21 @@ public static final class DescriptorImpl extends BuildStepDescriptor { public DescriptorImpl() { load(); + + if (Boolean.FALSE.equals(this.useOAuth) && !StringUtils.isBlank(this.username)) { + this.clientId = this.username; + this.clientSecret = this.password; + } + + this.useOAuth = true; // always use fields: 'clientId' and 'clientSecret' } public String getUser() { - if (Boolean.TRUE.equals(this.useOAuth)) { - return this.clientId; - } else { - return this.username; - } + return this.clientId; } public String getPswd() { - if (Boolean.TRUE.equals(this.useOAuth)) { - return (this.clientSecret != null) ? this.clientSecret.getPlainText() : ""; - } else { - return (this.password != null) ? this.password.getPlainText() : ""; - } + return (this.clientSecret != null) ? this.clientSecret.getPlainText() : ""; } @Override @@ -515,9 +514,8 @@ private Boolean getBooleanConfig(final JSONObject data, final String key) { public boolean configure(final StaplerRequest req, final JSONObject formData) throws FormException { // set all properties from formData // validate all properties, throw FormException if invalid - this.username = this.getStringConfig(formData, Constants.USERNAME); - this.password = this.getPasswordConfig(formData, Constants.PASSWORD); this.url = StringUtils.stripEnd(this.getStringConfig(formData, Constants.URL), "/"); + this.tenantId = this.getStringConfig(formData, Constants.TENANTID); this.useProxy = this.getBooleanConfig(formData, "useProxy"); this.proxyHost = this.getStringConfig(formData, "proxyHost"); @@ -533,10 +531,12 @@ public boolean configure(final StaplerRequest req, final JSONObject formData) th this.proxyPassword = this.getPasswordConfig(formData, "proxyPassword"); - this.useOAuth = this.getBooleanConfig(formData, Constants.USE_OAUTH); this.clientId = this.getStringConfig(formData, Constants.CLIENT_ID); this.clientSecret = this.getPasswordConfig(formData, Constants.CLIENT_SECRET); - this.tenantId = this.getStringConfig(formData, Constants.TENANTID); + this.useOAuth = true; + + this.username = ""; + this.password = null; save(); return super.configure(req, formData); @@ -545,7 +545,7 @@ public boolean configure(final StaplerRequest req, final JSONObject formData) th @POST public FormValidation doCheckUrl(@QueryParameter final String value) { String errorMsg = "Please input a valid URL"; - if (value == null || value.trim().length() == 0) { + if (value == null || value.trim().isEmpty()) { return FormValidation.error(errorMsg); } @@ -558,8 +558,8 @@ public FormValidation doCheckUrl(@QueryParameter final String value) { @POST public FormValidation doCheckTenantId(@QueryParameter final String value) { - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a Tenant ID"); + if (value == null || value.trim().isEmpty()) { + return FormValidation.error("Please input tenant id"); } return FormValidation.ok(); @@ -568,15 +568,10 @@ public FormValidation doCheckTenantId(@QueryParameter final String value) { @SuppressWarnings("checkstyle:HiddenField") @POST public FormValidation doCheckUsername( - @QueryParameter final String value, - @QueryParameter final String useOAuth + @QueryParameter final String value ) { - if (Boolean.parseBoolean(useOAuth)) { - return FormValidation.ok(); - } - - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a Username"); + if (value == null || value.trim().isEmpty()) { + return FormValidation.error("Please input client id or username"); } return FormValidation.ok(); @@ -585,49 +580,10 @@ public FormValidation doCheckUsername( @SuppressWarnings("checkstyle:HiddenField") @POST public FormValidation doCheckPassword( - @QueryParameter final String value, - final @QueryParameter String useOAuth + @QueryParameter final String value ) { - if (Boolean.parseBoolean(useOAuth)) { - return FormValidation.ok(); - } - - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a Password"); - } - - return FormValidation.ok(); - } - - @SuppressWarnings("checkstyle:HiddenField") - @POST - public FormValidation doCheckClientId( - @QueryParameter final String value, - @QueryParameter final String useOAuth - ) { - if (!Boolean.parseBoolean(useOAuth)) { - return FormValidation.ok(); - } - - if (!ApiClient.isOAuthClientId(value.trim())) { - return FormValidation.error("Please input a valid Client ID"); - } - - return FormValidation.ok(); - } - - @SuppressWarnings("checkstyle:HiddenField") - @POST - public FormValidation doCheckClientSecret( - @QueryParameter final String value, - @QueryParameter final String useOAuth - ) { - if (!Boolean.parseBoolean(useOAuth)) { - return FormValidation.ok(); - } - - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a valid Client Secret"); + if (value == null || value.trim().isEmpty()) { + return FormValidation.error("Please input client secret or password"); } return FormValidation.ok(); @@ -643,8 +599,8 @@ public FormValidation doCheckProxyHost( return FormValidation.ok(); } - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a Host"); + if (value == null || value.trim().isEmpty()) { + return FormValidation.error("Please input a valid proxy host"); } return FormValidation.ok(); @@ -660,18 +616,18 @@ public FormValidation doCheckProxyPort( return FormValidation.ok(); } - if (value == null || value.trim().length() == 0) { + if (value == null || value.trim().isEmpty()) { return FormValidation.ok(); } if (!StringUtils.isNumeric(value)) { - return FormValidation.error("Please input a valid port number."); + return FormValidation.error("Please input a valid port number"); } int portVal = Integer.parseInt(value); if (portVal < 0 || portVal > 65535) { - return FormValidation.error("Please input a valid port number."); + return FormValidation.error("Please input a valid port number"); } return FormValidation.ok(); @@ -679,12 +635,12 @@ public FormValidation doCheckProxyPort( @POST public FormValidation doCheckProjectID(@QueryParameter final String value) { - if (value == null || value.trim().length() == 0) { - return FormValidation.error("Please input a Project ID"); + if (value == null || value.trim().isEmpty()) { + return FormValidation.error("Please input project id"); } if (!value.matches("^\\d+$")) { - return FormValidation.error("Invalid Project ID"); + return FormValidation.error("Invalid project id"); } return FormValidation.ok(); } @@ -795,8 +751,6 @@ public void setUseOAuth(final Boolean useOAuth) { @SuppressWarnings({"java:S107", "checkstyle:ParameterNumber", "checkstyle:HiddenField"}) @POST public FormValidation doTestConnection( - @QueryParameter("username") final String username, - @QueryParameter("password") final Secret password, @QueryParameter("url") final String url, @QueryParameter("proxyHost") final String proxyHost, @QueryParameter("proxyPort") final String proxyPort, @@ -805,7 +759,6 @@ public FormValidation doTestConnection( @QueryParameter("clientId") final String clientId, @QueryParameter("clientSecret") final Secret clientSecret, @QueryParameter("tenantId") final String tenantId, - @QueryParameter("useOAuth") final String useOAuth, @QueryParameter("useProxy") final String useProxy ) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); @@ -818,15 +771,8 @@ public FormValidation doTestConnection( return FormValidation.error("Invalid parameter: Tenant ID"); } - boolean useOAuthFlag = Boolean.parseBoolean(useOAuth); - String user = useOAuthFlag ? clientId : username; - String pswd; - - if (useOAuthFlag) { - pswd = (clientSecret != null) ? clientSecret.getPlainText() : ""; - } else { - pswd = (password != null) ? password.getPlainText() : ""; - } + String user = clientId; + String pswd = (clientSecret != null) ? clientSecret.getPlainText() : ""; ServerConfiguration config = new ServerConfiguration( url, diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/global.jelly b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/global.jelly index 3c2a87c..1765f49 100644 --- a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/global.jelly +++ b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/global.jelly @@ -27,10 +27,10 @@ so it should be straightforward to find them. --> - + - + @@ -39,16 +39,6 @@ - - - - - - - - - - @@ -68,7 +58,7 @@ diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientId.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientId.html new file mode 100644 index 0000000..88e9593 --- /dev/null +++ b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientId.html @@ -0,0 +1,3 @@ +
+ Your client id or username to login LoadRunner Cloud +
diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientSecret.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientSecret.html new file mode 100644 index 0000000..c2f5a01 --- /dev/null +++ b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-clientSecret.html @@ -0,0 +1,3 @@ +
+ Your client secret or password to login LoadRunner Cloud +
diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-password.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-password.html deleted file mode 100644 index 79cbd84..0000000 --- a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-password.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Your password to login LoadRunner Cloud -
diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-testId.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-testId.html index 42a6559..68c43c0 100644 --- a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-testId.html +++ b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-testId.html @@ -1,3 +1,3 @@
- Test ID. Navigate to the General page of target load test in LoadRunner Cloud to see the ID. + Test ID. Navigate to "Test settings" page of target load test in LoadRunner Cloud to see the ID.
diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-url.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-url.html index 0e9a015..9d59463 100644 --- a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-url.html +++ b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-url.html @@ -1,3 +1,3 @@
- LoadRunner Cloud URL, for example: https://loadrunner-cloud.saas.microfocus.com + LoadRunner Cloud URL. For example: https://loadrunner-cloud.saas.microfocus.com
diff --git a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-username.html b/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-username.html deleted file mode 100644 index 2d09933..0000000 --- a/src/main/resources/com/microfocus/lrc/jenkins/TestRunBuilder/help-username.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Your username to login LoadRunner Cloud, for example: loadrunner-cloud@microfocus.com -
diff --git a/src/test/java/com/microfocus/lrc/jenkins/ConfigurationAsCodeTest.java b/src/test/java/com/microfocus/lrc/jenkins/ConfigurationAsCodeTest.java index 4ef3be4..67c577f 100644 --- a/src/test/java/com/microfocus/lrc/jenkins/ConfigurationAsCodeTest.java +++ b/src/test/java/com/microfocus/lrc/jenkins/ConfigurationAsCodeTest.java @@ -88,4 +88,40 @@ public void shouldSupportCACSExport() throws Exception { jsonObject.getString("proxyPassword"); }); } + + @Test + @ConfiguredWithCode("configuration-as-code-new.yml") + public void shouldSupportCACS_new() throws Exception { + TestRunBuilder.DescriptorImpl descriptor = new TestRunBuilder.DescriptorImpl(); + + assertEquals(TENANTID, descriptor.getTenantId()); + assertEquals(URL, descriptor.getUrl()); + + assertEquals(CLIENT_ID, descriptor.getClientId()); + assertNotNull(descriptor.getClientSecret()); + + assertTrue(descriptor.getUseProxy()); + assertEquals(PROXYHOST, descriptor.getProxyHost()); + assertEquals(PROXYPORT, descriptor.getProxyPort()); + } + + @Test + @ConfiguredWithCode("configuration-as-code-new.yml") + public void shouldSupportCACSExport_new() throws Exception { + ConfiguratorRegistry registry = ConfiguratorRegistry.get(); + ConfigurationContext context = new ConfigurationContext(registry); + CNode yourAttribute = getUnclassifiedRoot(context).get("lrcRunTest"); + + JSONObject jsonObject = JSONObject.fromObject(convertToJson(toYamlString(yourAttribute))); + + assertEquals(URL, jsonObject.getString("url")); + assertEquals(TENANTID, jsonObject.getString("tenantId")); + + assertEquals(CLIENT_ID, jsonObject.getString("clientId")); + assertNotNull(jsonObject.getString("clientSecret")); + + assertTrue(jsonObject.getBoolean("useProxy")); + assertEquals(PROXYHOST, jsonObject.getString("proxyHost")); + assertEquals(PROXYPORT, jsonObject.getString("proxyPort")); + } } diff --git a/src/test/resources/com/microfocus/lrc/jenkins/configuration-as-code-new.yml b/src/test/resources/com/microfocus/lrc/jenkins/configuration-as-code-new.yml new file mode 100644 index 0000000..709a9c3 --- /dev/null +++ b/src/test/resources/com/microfocus/lrc/jenkins/configuration-as-code-new.yml @@ -0,0 +1,9 @@ +unclassified: + lrcRunTest: + tenantId: "123456789" + url: "https://loadrunner-cloud.saas.microfocus.com" + clientId: "oauth2-XXXXXXXXXXXXXXXXXXXX@microfocus.com" + clientSecret: "{AQAAABAAAAAgfkVMlYtw5Idd/fl5a+BMRYmhXXu4BjJ88A0tyk8+tvJxa9lgj1/pNMsDwpJubGtR}" + useProxy: true + proxyHost: "172.31.128.1" + proxyPort: "8080"