From 1bcacbb8feb33aa5cf144185cfe2f86d679f2b2a Mon Sep 17 00:00:00 2001 From: Joel Strasser Date: Mon, 8 May 2023 22:10:59 +0200 Subject: [PATCH 1/5] [broken] new structure --- .../gocd/elasticagent/azure/AzurePlugin.java | 45 +++-- .../elasticagent/azure/ClusterProfile.java | 78 ++++++++ .../azure/ClusterProfileProperties.java | 42 ++++ .../elasticagent/azure/PluginRequest.java | 22 +-- .../elasticagent/azure/PluginSettings.java | 181 ++++++------------ .../gocd/elasticagent/azure/Request.java | 41 ++-- ...ClusterProfileValidateRequestExecutor.java | 70 +++++++ ...=> GetClusterProfileMetadataExecutor.java} | 42 ++-- ...GetClusterProfileViewRequestExecutor.java} | 6 +- ...tElasticAgentProfileMetadataExecutor.java} | 2 +- ...> GetElasticAgentProfileViewExecutor.java} | 2 +- ...ecutor.java => GetPluginIconExecutor.java} | 2 +- .../ProfileValidateRequestExecutor.java | 70 ------- .../ValidateConfigurationExecutor.java | 2 +- .../requests/AgentStatusReportRequest.java | 30 +-- ...ava => ClusterProfileValidateRequest.java} | 12 +- .../gocd/elasticagent/azure/utils/Util.java | 6 +- .../AzureNetworkSettingsValidation.java | 2 +- .../validations/AzureRegionValidation.java | 2 +- .../AzureResourceGroupValidation.java | 2 +- .../azure/validations/FieldValidation.java | 4 +- .../azure/validations/ImageValidation.java | 2 +- .../azure/validations/MetadataValidation.java | 4 +- .../validations/OsDiskSizeValidation.java | 4 +- .../OsDiskStorageTypeValidation.java | 2 +- .../UnknownProfileFieldValidation.java | 4 +- ...ate.html => cluster-profile.template.html} | 2 +- .../GetPluginConfigurationExecutorTest.java | 6 +- .../GetPluginSettingsIconExecutorTest.java | 2 +- ...PluginSettingsViewRequestExecutorTest.java | 4 +- .../GetProfileMetadataExecutorTest.java | 6 +- .../executors/GetProfileViewExecutorTest.java | 2 +- .../ProfileValidateRequestExecutorTest.java | 6 +- .../AzureNetworkSettingsValidationTest.java | 2 +- .../AzureRegionValidationTest.java | 2 +- .../AzureResourceGroupValidationTest.java | 2 +- .../validations/FieldValidationTest.java | 2 +- .../validations/ImageValidationTest.java | 2 +- 38 files changed, 383 insertions(+), 334 deletions(-) create mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java create mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java create mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ClusterProfileValidateRequestExecutor.java rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/{GetPluginConfigurationExecutor.java => GetClusterProfileMetadataExecutor.java} (71%) rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/{GetPluginSettingsViewRequestExecutor.java => GetClusterProfileViewRequestExecutor.java} (89%) rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/{GetProfileMetadataExecutor.java => GetElasticAgentProfileMetadataExecutor.java} (97%) rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/{GetProfileViewExecutor.java => GetElasticAgentProfileViewExecutor.java} (94%) rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/{GetPluginSettingsIconExecutor.java => GetPluginIconExecutor.java} (95%) delete mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutor.java rename src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/{ProfileValidateRequest.java => ClusterProfileValidateRequest.java} (72%) rename src/main/resources/{plugin-settings.template.html => cluster-profile.template.html} (99%) diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java index 1b35da8..1c9e624 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.thoughtworks.go.plugin.api.GoApplicationAccessor; @@ -25,6 +24,12 @@ import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest; import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_AGENT_STATUS_REPORT; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_CAPABILITIES; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_GET_CLUSTER_PROFILE_METADATA; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_GET_ELASTIC_AGENT_PROFILE_METADATA; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_GET_ELASTIC_AGENT_PROFILE_VIEW; +import static com.thoughtworks.gocd.elasticagent.azure.Request.REQUEST_JOB_COMPLETION; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; import com.thoughtworks.gocd.elasticagent.azure.exceptions.PluginSettingsNotConfiguredException; import com.thoughtworks.gocd.elasticagent.azure.executors.*; @@ -57,6 +62,8 @@ public void initializeGoApplicationAccessor(GoApplicationAccessor accessor) { public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRequestTypeException { try { switch (Request.fromString(request.requestName())) { + case REQUEST_GET_ICON: + return new GetPluginIconExecutor().execute(); case REQUEST_SHOULD_ASSIGN_WORK: refreshInstances(); return ShouldAssignWorkRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest.getPluginSettings(), serverHealthMessagingService).execute(); @@ -66,30 +73,26 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe case REQUEST_SERVER_PING: refreshInstances(); return new ServerPingRequestExecutor(agentInstances, pluginRequest, serverHealthMessagingService).execute(); - case PLUGIN_SETTINGS_GET_VIEW: - return new GetPluginSettingsViewRequestExecutor().execute(); - case REQUEST_GET_PROFILE_METADATA: - return new GetProfileMetadataExecutor().execute(); - case REQUEST_GET_PROFILE_VIEW: - return new GetProfileViewExecutor().execute(); - case REQUEST_VALIDATE_PROFILE: - return ProfileValidateRequest.fromJSON(request.requestBody()).executor(pluginRequest, clientFactory).execute(); - case PLUGIN_SETTINGS_GET_ICON: - return new GetPluginSettingsIconExecutor().execute(); - case PLUGIN_SETTINGS_GET_CONFIGURATION: - return new GetPluginConfigurationExecutor().execute(); - case PLUGIN_SETTINGS_VALIDATE_CONFIGURATION: - return ValidatePluginSettings.fromJSON(request.requestBody()).executor(clientFactory).execute(); - case REQUEST_STATUS_REPORT: - return new StatusReportExecutor(pluginRequest, agentInstances,TemplateReader.instance()).execute(); - case REQUEST_AGENT_STATUS_REPORT: + case REQUEST_GET_ELASTIC_AGENT_PROFILE_METADATA: + return new GetElasticAgentProfileMetadataExecutor().execute(); + case REQUEST_GET_ELASTIC_AGENT_PROFILE_VIEW: + return new GetElasticAgentProfileViewExecutor().execute(); + case REQUEST_JOB_COMPLETION: refreshInstances(); - return AgentStatusReportRequest.fromJSON(request.requestBody()).executor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); + return JobCompletionRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest).execute(); case REQUEST_CAPABILITIES: return new GetCapabilitiesExecutor().execute(); - case REQUEST_JOB_COMPLETION: + case REQUEST_AGENT_STATUS_REPORT: refreshInstances(); - return JobCompletionRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest).execute(); + return AgentStatusReportRequest.fromJSON(request.requestBody()).executor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); + case REQUEST_GET_CLUSTER_PROFILE_METADATA: + return new GetClusterProfileMetadataExecutor().execute(); + case REQUEST_GET_CLUSTER_PROFILE_VIEW: + return new GetClusterProfileViewRequestExecutor().execute(); + case REQUEST_VALIDATE_CLUSTER_PROFILE: + return ClusterProfileValidateRequest.fromJSON(request.requestBody()).executor(pluginRequest, clientFactory).execute(); + case REQUEST_PLUGIN_STATUS_REPORT: + return new StatusReportExecutor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); default: throw new UnhandledRequestTypeException(request.requestName()); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java new file mode 100644 index 0000000..c25c690 --- /dev/null +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java @@ -0,0 +1,78 @@ +/* + * Copyright 2017 ThoughtWorks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.thoughtworks.gocd.elasticagent.azure; + +import com.google.gson.annotations.Expose; + +import java.util.Objects; + +import static com.example.elasticagent.ExamplePlugin.GSON; + +// TODO: Implement any settings that your plugin needs +public class ClusterProfile { + @Expose + private final String id; + + @Expose + private final String pluginId; + + @Expose + private final ClusterProfileProperties properties; + + public ClusterProfile() { + this("", "", new ClusterProfileProperties()); + } + + public ClusterProfile(String id, String pluginId, ClusterProfileProperties clusterProfileProperties) { + this.id = id; + this.pluginId = pluginId; + this.properties = clusterProfileProperties; + } + + public static ClusterProfile fromJSON(String json) { + return GSON.fromJson(json, ClusterProfile.class); + } + + public String getId() { + return id; + } + + public String getPluginId() { + return pluginId; + } + + public ClusterProfileProperties getProperties() { + return properties; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ClusterProfile that = (ClusterProfile) o; + + if (id != null ? !id.equals(that.id) : that.id != null) return false; + if (pluginId != null ? !pluginId.equals(that.pluginId) : that.pluginId != null) return false; + return properties != null ? properties.equals(that.properties) : that.properties == null; + } + + @Override + public int hashCode() { + return Objects.hash(id, pluginId, properties); + } +} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java new file mode 100644 index 0000000..4d7e64d --- /dev/null +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017 ThoughtWorks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.thoughtworks.gocd.elasticagent.azure; + +import java.util.Map; +import org.joda.time.Period; + +// TODO: Implement any settings that your plugin needs +public class ClusterProfileProperties extends PluginSettings { + + public ClusterProfileProperties() { + } + + public ClusterProfileProperties(String goServerUrl, String autoRegisterTimeout, String apiUser, String apiKey, String apiUrl, Period autoRegisterPeriod) { + super(goServerUrl, autoRegisterTimeout, apiUser, apiKey, apiUrl, autoRegisterPeriod); + } + + public static ClusterProfileProperties fromJSON(String json) { + return GSON.fromJson(json, ClusterProfileProperties.class); + } + + public static ClusterProfileProperties fromConfiguration(Map clusterProfile) { + return GSON.fromJson(GSON.toJson(clusterProfile), ClusterProfileProperties.class); + } + + public String uuid() { + return Integer.toHexString(hashCode()); + } +} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginRequest.java index 9e1ad48..8d8d0f2 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginRequest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.google.gson.FieldNamingPolicy; @@ -22,7 +21,6 @@ import com.thoughtworks.go.plugin.api.GoApplicationAccessor; import com.thoughtworks.go.plugin.api.request.DefaultGoApiRequest; import com.thoughtworks.go.plugin.api.response.GoApiResponse; -import com.thoughtworks.gocd.elasticagent.azure.exceptions.PluginSettingsNotConfiguredException; import com.thoughtworks.gocd.elasticagent.azure.exceptions.ServerRequestFailedException; import com.thoughtworks.gocd.elasticagent.azure.models.PluginHealthMessage; import com.thoughtworks.gocd.elasticagent.azure.models.ServerInfo; @@ -31,13 +29,12 @@ import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import static com.thoughtworks.gocd.elasticagent.azure.Constants.*; -import static org.apache.commons.lang3.StringUtils.isBlank; - /** * Instances of this class know how to send messages to the GoCD Server. */ public class PluginRequest { + private final GoApplicationAccessor accessor; private static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).excludeFieldsWithoutExposeAnnotation().create(); @@ -45,25 +42,10 @@ public PluginRequest(GoApplicationAccessor accessor) { this.accessor = accessor; } - public PluginSettings getPluginSettings() throws ServerRequestFailedException, PluginSettingsNotConfiguredException { - DefaultGoApiRequest request = new DefaultGoApiRequest(Constants.REQUEST_SERVER_GET_PLUGIN_SETTINGS, PLUGIN_SETTINGS_PROCESSOR_API_VERSION, PLUGIN_IDENTIFIER); - GoApiResponse response = accessor.submit(request); - - if (response.responseCode() != 200) { - throw ServerRequestFailedException.getPluginSettings(response); - } - - if (isBlank(response.responseBody())) { - throw new PluginSettingsNotConfiguredException(); - } - - return PluginSettings.fromJSON(response.responseBody()); - } - public ServerInfo getServerInfo() throws ServerRequestFailedException { GoApiResponse response = invokeServerInfoApi(SERVER_INFO_PROCESSOR_V2_API_VERSION); - if(response.responseCode() != 200){ + if (response.responseCode() != 200) { LOG.info("Falling back to V1 Server info api"); response = invokeServerInfoApi(SERVER_INFO_PROCESSOR_V1_API_VERSION); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java index 6a5c004..77d85dc 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.google.gson.FieldNamingPolicy; @@ -21,22 +20,17 @@ import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import com.microsoft.azure.management.resources.fluentcore.arm.Region; -import com.thoughtworks.gocd.elasticagent.azure.utils.Util; -import lombok.AccessLevel; +import java.util.Map; import lombok.Getter; import org.joda.time.Period; -import java.util.Objects; - -import static org.apache.commons.lang3.StringUtils.isBlank; - @Getter public class PluginSettings { + public static final Gson GSON = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .excludeFieldsWithoutExposeAnnotation() - .create(); + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .excludeFieldsWithoutExposeAnnotation() + .create(); @Expose @SerializedName("go_server_url") @@ -47,159 +41,102 @@ public class PluginSettings { private String autoRegisterTimeout; @Expose - @SerializedName("idle_timeout") - private String idleTimeout; - - @Expose - @SerializedName("domain") - private String domain; - - @Expose - @SerializedName("client_id") - private String clientId; - - @Expose - @SerializedName("secret") - private String secret; - - @Expose - @SerializedName("network_id") - private String networkId; - - @Expose - @SerializedName("subnet") - @Getter(AccessLevel.NONE) - private String subnetNames; - - @Expose - @SerializedName("network_security_group_id") - private String networkSecurityGroupId; - - @Expose - @SerializedName("resource_group") - private String resourceGroup; - - @Expose - @SerializedName("region_name") - @Getter(AccessLevel.NONE) - private String regionName; - - @Expose - @SerializedName("linux_user_name") - private String linuxUserName; - - @Expose - @SerializedName("ssh_key") - private String sshKey; + @SerializedName("api_user") + private String apiUser; @Expose - @SerializedName("windows_user_name") - private String windowsUserName; + @SerializedName("api_key") + private String apiKey; @Expose - @SerializedName("windows_password") - private String windowsPassword; - + @SerializedName("api_url") + private String apiUrl; private Period autoRegisterPeriod; - private Period idleTimeoutPeriod; - - @Getter(AccessLevel.NONE) - private String[] subnetNamesArray; - public static PluginSettings fromJSON(String json) { - return GSON.fromJson(json, PluginSettings.class); + public PluginSettings() { } - public PluginSettings(String goServerUrl, - String autoRegisterTimeout, - String idleTimeout, - String domain, - String clientId, - String secret, - Period autoRegisterPeriod, - String networkId, - String subnetNames, - String networkSecurityGroupId, - String resourceGroup, - String sshKey, - String regionName, - String linuxUserName, - String windowsUserName, - String windowsPassword) { + public PluginSettings(String goServerUrl, String autoRegisterTimeout, String apiUser, String apiKey, String apiUrl, Period autoRegisterPeriod) { this.goServerUrl = goServerUrl; this.autoRegisterTimeout = autoRegisterTimeout; - this.idleTimeout = idleTimeout; - this.domain = domain; - this.clientId = clientId; - this.secret = secret; + this.apiUser = apiUser; + this.apiKey = apiKey; + this.apiUrl = apiUrl; this.autoRegisterPeriod = autoRegisterPeriod; - this.networkId = networkId; - this.subnetNames = subnetNames; - this.networkSecurityGroupId = networkSecurityGroupId; - this.resourceGroup = resourceGroup; - this.regionName = regionName; - this.linuxUserName = linuxUserName; - this.sshKey = sshKey; - this.windowsUserName = windowsUserName; - this.windowsPassword = windowsPassword; } + public static PluginSettings fromJSON(String json) { + return GSON.fromJson(json, PluginSettings.class); + } - public PluginSettings() { + public static PluginSettings fromConfiguration(Map pluginSettings) { + return GSON.fromJson(GSON.toJson(pluginSettings), PluginSettings.class); } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PluginSettings that = (PluginSettings) o; - if (goServerUrl != null ? !goServerUrl.equals(that.goServerUrl) : that.goServerUrl != null) return false; - if (autoRegisterTimeout != null ? !autoRegisterTimeout.equals(that.autoRegisterTimeout) : that.autoRegisterTimeout != null) + if (goServerUrl != null ? !goServerUrl.equals(that.goServerUrl) : that.goServerUrl != null) { + return false; + } + if (autoRegisterTimeout != null ? !autoRegisterTimeout.equals(that.autoRegisterTimeout) : that.autoRegisterTimeout != null) { + return false; + } + if (apiUser != null ? !apiUser.equals(that.apiUser) : that.apiUser != null) { return false; - if (domain != null ? !domain.equals(that.domain) : that.domain != null) return false; - if (clientId != null ? !clientId.equals(that.clientId) : that.clientId != null) return false; - return secret != null ? secret.equals(that.secret) : that.secret == null; + } + if (apiKey != null ? !apiKey.equals(that.apiKey) : that.apiKey != null) { + return false; + } + return apiUrl != null ? apiUrl.equals(that.apiUrl) : that.apiUrl == null; } @Override public int hashCode() { - return Objects.hash(goServerUrl, autoRegisterTimeout, domain, clientId, secret, autoRegisterPeriod); + int result = goServerUrl != null ? goServerUrl.hashCode() : 0; + result = 31 * result + (getAutoRegisterPeriod() != null ? getAutoRegisterPeriod().hashCode() : 0); + result = 31 * result + (apiUser != null ? apiUser.hashCode() : 0); + result = 31 * result + (apiKey != null ? apiKey.hashCode() : 0); + result = 31 * result + (apiUrl != null ? apiUrl.hashCode() : 0); + return result; } public Period getAutoRegisterPeriod() { if (this.autoRegisterPeriod == null) { - this.autoRegisterPeriod = new Period().withMinutes(Integer.parseInt(autoRegisterTimeout)); + this.autoRegisterPeriod = new Period().withMinutes(Integer.parseInt(getAutoRegisterTimeout())); } return this.autoRegisterPeriod; } - public Period getIdleTimeoutPeriod() { - if (this.idleTimeoutPeriod == null) { - this.idleTimeoutPeriod = new Period().withMinutes(Integer.parseInt(getIdleTimeout())); + private String getAutoRegisterTimeout() { + if (autoRegisterTimeout == null) { + autoRegisterTimeout = "10"; } - return this.idleTimeoutPeriod; + return autoRegisterTimeout; } - public Region getRegion() { - return Region.findByLabelOrName(regionName); + public String getApiUser() { + return apiUser; } - public String[] getSubnetNames() { - if (this.subnetNamesArray == null) { - this.subnetNamesArray = Util.splitByComma(subnetNames); - } - return this.subnetNamesArray; + public String getApiKey() { + return apiKey; } - public String getRandomSubnet() { - int index = (this.getSubnetNames().length == 0) ? 0 : Util.random((getSubnetNames().length)); - return getSubnetNames()[index]; + public String getApiUrl() { + return apiUrl; } - private String getIdleTimeout() { - return isBlank(idleTimeout) ? "0" : idleTimeout; + public String getGoServerUrl() { + return goServerUrl; } - } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/Request.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/Request.java index 8816752..35d0fc5 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/Request.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/Request.java @@ -13,30 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; /** - * Enumerable that represents one of the messages that the server sends to the plugin + * Enumerable that represents one of the messages that the server sends to the + * plugin */ public enum Request { // elastic agent related requests that the server makes to the plugin - REQUEST_CREATE_AGENT(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".create-agent"), - REQUEST_SERVER_PING(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".server-ping"), - REQUEST_SHOULD_ASSIGN_WORK(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".should-assign-work"), - REQUEST_GET_PROFILE_METADATA(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".get-profile-metadata"), - REQUEST_GET_PROFILE_VIEW(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".get-profile-view"), - - // settings related requests that the server makes to the plugin - REQUEST_VALIDATE_PROFILE(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".validate-profile"), - PLUGIN_SETTINGS_GET_ICON(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".get-icon"), - PLUGIN_SETTINGS_GET_CONFIGURATION(Constants.GO_PLUGIN_SETTINGS_PREFIX + ".get-configuration"), - PLUGIN_SETTINGS_GET_VIEW(Constants.GO_PLUGIN_SETTINGS_PREFIX + ".get-view"), - PLUGIN_SETTINGS_VALIDATE_CONFIGURATION(Constants.GO_PLUGIN_SETTINGS_PREFIX + ".validate-configuration"), - REQUEST_STATUS_REPORT(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".status-report"), - REQUEST_AGENT_STATUS_REPORT(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".agent-status-report"), - REQUEST_CAPABILITIES(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".get-capabilities"), - REQUEST_JOB_COMPLETION(Constants.ELASTIC_AGENT_REQUEST_PREFIX + ".job-completion"); + REQUEST_CREATE_AGENT(Constants.REQUEST_PREFIX + ".create-agent"), + REQUEST_SERVER_PING(Constants.REQUEST_PREFIX + ".server-ping"), + REQUEST_SHOULD_ASSIGN_WORK(Constants.REQUEST_PREFIX + ".should-assign-work"), + REQUEST_GET_ELASTIC_AGENT_PROFILE_METADATA(Constants.REQUEST_PREFIX + ".get-elastic-agent-profile-metadata"), + REQUEST_GET_ELASTIC_AGENT_PROFILE_VIEW(Constants.REQUEST_PREFIX + ".get-elastic-agent-profile-view"), + REQUEST_VALIDATE_ELASTIC_AGENT_PROFILE(Constants.REQUEST_PREFIX + ".validate-elastic-agent-profile"), + REQUEST_GET_CLUSTER_PROFILE_METADATA(Constants.REQUEST_PREFIX + ".get-cluster-profile-metadata"), + REQUEST_GET_CLUSTER_PROFILE_VIEW(Constants.REQUEST_PREFIX + ".get-cluster-profile-view"), + REQUEST_VALIDATE_CLUSTER_PROFILE(Constants.REQUEST_PREFIX + ".validate-cluster-profile"), + REQUEST_AGENT_STATUS_REPORT(Constants.REQUEST_PREFIX + ".agent-status-report"), + REQUEST_CLUSTER_STATUS_REPORT(Constants.REQUEST_PREFIX + ".cluster-status-report"), + REQUEST_PLUGIN_STATUS_REPORT(Constants.REQUEST_PREFIX + ".plugin-status-report"), + REQUEST_CAPABILITIES(Constants.REQUEST_PREFIX + ".get-capabilities"), + REQUEST_GET_ICON(Constants.REQUEST_PREFIX + ".get-icon"), + REQUEST_JOB_COMPLETION(Constants.REQUEST_PREFIX + ".job-completion"), + REQUEST_MIGRATE_CONFIGURATION(Constants.REQUEST_PREFIX + ".migrate-config"), + REQUEST_CLUSTER_PROFILE_CHANGED(Constants.REQUEST_PREFIX + ".cluster-profile-changed"); private final String requestName; @@ -57,7 +58,7 @@ public static Request fromString(String requestName) { } private static class Constants { - static final String ELASTIC_AGENT_REQUEST_PREFIX = "cd.go.elastic-agent"; - static final String GO_PLUGIN_SETTINGS_PREFIX = "go.plugin-settings"; + + static final String REQUEST_PREFIX = "cd.go.elastic-agent"; } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ClusterProfileValidateRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ClusterProfileValidateRequestExecutor.java new file mode 100644 index 0000000..b23df36 --- /dev/null +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ClusterProfileValidateRequestExecutor.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Thoughtworks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.thoughtworks.gocd.elasticagent.azure.executors; + +import com.google.gson.Gson; +import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; +import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; +import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.CLUSTER_PROFILE_FIELDS; +import com.thoughtworks.gocd.elasticagent.azure.models.Field; +import com.thoughtworks.gocd.elasticagent.azure.requests.ClusterProfileValidateRequest; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ClusterProfileValidateRequestExecutor implements RequestExecutor { + + private final ClusterProfileValidateRequest request; + private static final Gson GSON = new Gson(); + + public ClusterProfileValidateRequestExecutor(ClusterProfileValidateRequest request) { + this.request = request; + } + + @Override + public GoPluginApiResponse execute() throws Exception { + ArrayList> result = new ArrayList<>(); + + List knownFields = new ArrayList<>(); + + for (Field field : CLUSTER_PROFILE_FIELDS.values()) { + knownFields.add(field.key()); + Map validationError = field.validate(request.getProperties().get(field.key())); + + if (!validationError.isEmpty()) { + result.add(validationError); + } + } + + Set set = new HashSet<>(request.getProperties().keySet()); + set.removeAll(knownFields); + + if (!set.isEmpty()) { + for (String key : set) { + LinkedHashMap validationError = new LinkedHashMap<>(); + validationError.put("key", key); + validationError.put("message", "Is an unknown property"); + result.add(validationError); + } + } + + return DefaultGoPluginApiResponse.success(GSON.toJson(result)); + } +} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileMetadataExecutor.java similarity index 71% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutor.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileMetadataExecutor.java index 6114c6c..01fce75 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileMetadataExecutor.java @@ -27,7 +27,7 @@ import java.util.LinkedHashMap; import java.util.Map; -public class GetPluginConfigurationExecutor implements RequestExecutor { +public class GetClusterProfileMetadataExecutor implements RequestExecutor { private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); @@ -51,31 +51,31 @@ public class GetPluginConfigurationExecutor implements RequestExecutor { public static final Field WINDOWS_USER_NAME = new WindowsUsernameField("windows_user_name", "Windows User Name", null, true, "13"); public static final Field WINDOWS_PASSWORD = new WindowsPasswordField("windows_password", "Windows Password", null, true, "14"); - public static final Map FIELDS = new LinkedHashMap<>(); + public static final Map CLUSTER_PROFILE_FIELDS = new LinkedHashMap<>(); static { - FIELDS.put(GO_SERVER_URL.key(), GO_SERVER_URL); - FIELDS.put(AUTOREGISTER_TIMEOUT.key(), AUTOREGISTER_TIMEOUT); - FIELDS.put(IDLE_TIMEOUT.key(), IDLE_TIMEOUT); - - FIELDS.put(LINUX_USER_NAME.key(), LINUX_USER_NAME); - FIELDS.put(SSH_KEY.key(), SSH_KEY); - - FIELDS.put(WINDOWS_USER_NAME.key(), WINDOWS_USER_NAME); - FIELDS.put(WINDOWS_PASSWORD.key(), WINDOWS_PASSWORD); - - FIELDS.put(DOMAIN.key(), DOMAIN); - FIELDS.put(CLIENT_ID.key(), CLIENT_ID); - FIELDS.put(SECRET.key(), SECRET); - FIELDS.put(RESOURCE_GROUP.key(), RESOURCE_GROUP); - FIELDS.put(REGION_NAME.key(), REGION_NAME); - FIELDS.put(NETWORK_ID.key(), NETWORK_ID); - FIELDS.put(SUBNET_NAMES.key(), SUBNET_NAMES); - FIELDS.put(NETWORK_SECURITY_GROUP_ID.key(), NETWORK_SECURITY_GROUP_ID); + CLUSTER_PROFILE_FIELDS.put(GO_SERVER_URL.key(), GO_SERVER_URL); + CLUSTER_PROFILE_FIELDS.put(AUTOREGISTER_TIMEOUT.key(), AUTOREGISTER_TIMEOUT); + CLUSTER_PROFILE_FIELDS.put(IDLE_TIMEOUT.key(), IDLE_TIMEOUT); + + CLUSTER_PROFILE_FIELDS.put(LINUX_USER_NAME.key(), LINUX_USER_NAME); + CLUSTER_PROFILE_FIELDS.put(SSH_KEY.key(), SSH_KEY); + + CLUSTER_PROFILE_FIELDS.put(WINDOWS_USER_NAME.key(), WINDOWS_USER_NAME); + CLUSTER_PROFILE_FIELDS.put(WINDOWS_PASSWORD.key(), WINDOWS_PASSWORD); + + CLUSTER_PROFILE_FIELDS.put(DOMAIN.key(), DOMAIN); + CLUSTER_PROFILE_FIELDS.put(CLIENT_ID.key(), CLIENT_ID); + CLUSTER_PROFILE_FIELDS.put(SECRET.key(), SECRET); + CLUSTER_PROFILE_FIELDS.put(RESOURCE_GROUP.key(), RESOURCE_GROUP); + CLUSTER_PROFILE_FIELDS.put(REGION_NAME.key(), REGION_NAME); + CLUSTER_PROFILE_FIELDS.put(NETWORK_ID.key(), NETWORK_ID); + CLUSTER_PROFILE_FIELDS.put(SUBNET_NAMES.key(), SUBNET_NAMES); + CLUSTER_PROFILE_FIELDS.put(NETWORK_SECURITY_GROUP_ID.key(), NETWORK_SECURITY_GROUP_ID); } public GoPluginApiResponse execute() { - return new DefaultGoPluginApiResponse(200, GSON.toJson(FIELDS)); + return new DefaultGoPluginApiResponse(200, GSON.toJson(CLUSTER_PROFILE_FIELDS)); } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileViewRequestExecutor.java similarity index 89% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutor.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileViewRequestExecutor.java index c96e2e7..17c9ee4 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetClusterProfileViewRequestExecutor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.google.gson.Gson; @@ -23,13 +22,14 @@ import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.utils.Util; -public class GetPluginSettingsViewRequestExecutor implements RequestExecutor { +public class GetClusterProfileViewRequestExecutor implements RequestExecutor { + private static final Gson GSON = new Gson(); @Override public GoPluginApiResponse execute() throws Exception { JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("template", Util.readResource("/plugin-settings.template.html")); + jsonObject.addProperty("template", Util.readResource("/cluster-profile.template.html")); DefaultGoPluginApiResponse defaultGoPluginApiResponse = new DefaultGoPluginApiResponse(200, GSON.toJson(jsonObject)); return defaultGoPluginApiResponse; } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileMetadataExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileMetadataExecutor.java similarity index 97% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileMetadataExecutor.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileMetadataExecutor.java index f2212ff..cb8de44 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileMetadataExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileMetadataExecutor.java @@ -26,7 +26,7 @@ import java.util.ArrayList; import java.util.List; -public class GetProfileMetadataExecutor implements RequestExecutor { +public class GetElasticAgentProfileMetadataExecutor implements RequestExecutor { private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); public static final Metadata IDLE_TIMEOUT = new NonNegativeIntegerMetadata(ElasticProfile.IDLE_TIMEOUT, false, false); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileViewExecutor.java similarity index 94% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutor.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileViewExecutor.java index 3e8493d..dcd2ee5 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetElasticAgentProfileViewExecutor.java @@ -23,7 +23,7 @@ import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.utils.Util; -public class GetProfileViewExecutor implements RequestExecutor { +public class GetElasticAgentProfileViewExecutor implements RequestExecutor { private static final Gson GSON = new Gson(); @Override diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginIconExecutor.java similarity index 95% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutor.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginIconExecutor.java index 49420d2..e6cd126 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginIconExecutor.java @@ -24,7 +24,7 @@ import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.utils.Util; -public class GetPluginSettingsIconExecutor implements RequestExecutor { +public class GetPluginIconExecutor implements RequestExecutor { private static final Gson GSON = new Gson(); @Override diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutor.java deleted file mode 100644 index 944c1d4..0000000 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2020 Thoughtworks, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.thoughtworks.gocd.elasticagent.azure.executors; - -import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; -import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; -import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; -import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; -import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; -import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; -import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; -import com.thoughtworks.gocd.elasticagent.azure.exceptions.PluginSettingsNotConfiguredException; -import com.thoughtworks.gocd.elasticagent.azure.models.ValidationResult; -import com.thoughtworks.gocd.elasticagent.azure.requests.ProfileValidateRequest; -import com.thoughtworks.gocd.elasticagent.azure.validations.Validation; - -import java.util.List; - -import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; - -public class ProfileValidateRequestExecutor implements RequestExecutor { - public static final String PLUGIN_SETTINGS_NOT_CONFIGURED_MESSAGE = "Azure plugin settings not configured."; - public static final String UNEXPECTED_ERROR_MESSAGE = "Validation failed due to unexpected error."; - private final ProfileValidateRequest request; - private final PluginRequest pluginRequest; - private final GoCDAzureClientFactory goCDAzureClientFactory; - private List validations; - - public ProfileValidateRequestExecutor(ProfileValidateRequest request, PluginRequest pluginRequest, GoCDAzureClientFactory goCDAzureClientFactory, List validations) { - this.request = request; - this.pluginRequest = pluginRequest; - this.goCDAzureClientFactory = goCDAzureClientFactory; - this.validations = validations; - } - - @Override - public GoPluginApiResponse execute() { - ValidationResult validationResult = new ValidationResult(); - try { - PluginSettings pluginSettings = pluginRequest.getPluginSettings(); - GoCDAzureClient goCDAzureClient = goCDAzureClientFactory.initialize(pluginSettings); - validations.forEach(validation -> validationResult.addErrors(validation.run(request.getProperties(), pluginSettings, goCDAzureClient))); - return DefaultGoPluginApiResponse.success(validationResult.toJson()); - } catch (PluginSettingsNotConfiguredException e) { - return DefaultGoPluginApiResponse.success(errorResult(validationResult, PLUGIN_SETTINGS_NOT_CONFIGURED_MESSAGE).toJson()); - } catch (Exception e) { - LOG.error("Failed to validated Profile due to error: {}", e.getMessage()); - return DefaultGoPluginApiResponse.success(errorResult(validationResult, UNEXPECTED_ERROR_MESSAGE).toJson()); - } - } - - private ValidationResult errorResult(ValidationResult validationResult, String s) { - GetProfileMetadataExecutor.FIELDS.forEach(metadata -> validationResult.addError(metadata.getKey(), s)); - return validationResult; - } -} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ValidateConfigurationExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ValidateConfigurationExecutor.java index 615f404..023c9a8 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ValidateConfigurationExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ValidateConfigurationExecutor.java @@ -30,7 +30,7 @@ import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import static com.thoughtworks.gocd.elasticagent.azure.Errors.AZURE_AUTHENTICATION_ERROR; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.*; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.*; public class ValidateConfigurationExecutor implements RequestExecutor { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java index 5e3a0a2..cc94abb 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.requests; import com.google.gson.FieldNamingPolicy; @@ -25,13 +24,13 @@ import com.thoughtworks.gocd.elasticagent.azure.executors.AgentStatusReportExecutor; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.utils.TemplateReader; - import java.util.Objects; public class AgentStatusReportRequest { + private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); @Expose private String elasticAgentId; @@ -39,6 +38,9 @@ public class AgentStatusReportRequest { @Expose private JobIdentifier jobIdentifier; + @Expose + private ClusterProfileProperties clusterProfileProperties; + public AgentStatusReportRequest() { } @@ -65,11 +67,15 @@ public AgentStatusReportExecutor executor(PluginRequest pluginRequest, AzureAgen @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } AgentStatusReportRequest that = (AgentStatusReportRequest) o; - return Objects.equals(elasticAgentId, that.elasticAgentId) && - Objects.equals(jobIdentifier, that.jobIdentifier); + return Objects.equals(elasticAgentId, that.elasticAgentId) + && Objects.equals(jobIdentifier, that.jobIdentifier); } @Override @@ -79,9 +85,9 @@ public int hashCode() { @Override public String toString() { - return "AgentStatusReportRequest{" + - "elasticAgentId='" + elasticAgentId + '\'' + - ", jobIdentifierHash=" + jobIdentifier + - '}'; + return "AgentStatusReportRequest{" + + "elasticAgentId='" + elasticAgentId + '\'' + + ", jobIdentifierHash=" + jobIdentifier + + '}'; } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ProfileValidateRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java similarity index 72% rename from src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ProfileValidateRequest.java rename to src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java index 9ec4c13..6055d2b 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ProfileValidateRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java @@ -21,17 +21,17 @@ import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; -import com.thoughtworks.gocd.elasticagent.azure.executors.ProfileValidateRequestExecutor; +import com.thoughtworks.gocd.elasticagent.azure.executors.ClusterProfileValidateRequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.validations.Validation; import java.util.Map; -public class ProfileValidateRequest { +public class ClusterProfileValidateRequest { private static final Gson GSON = new Gson(); private Map properties; - public ProfileValidateRequest(Map properties) { + public ClusterProfileValidateRequest(Map properties) { this.properties = properties; } @@ -40,12 +40,12 @@ public Map getProperties() { return properties; } - public static ProfileValidateRequest fromJSON(String json) { - return new ProfileValidateRequest(GSON.fromJson(json, new TypeToken>() { + public static ClusterProfileValidateRequest fromJSON(String json) { + return new ClusterProfileValidateRequest(GSON.fromJson(json, new TypeToken>() { }.getType())); } public RequestExecutor executor(PluginRequest pluginRequest, GoCDAzureClientFactory factory) { - return new ProfileValidateRequestExecutor(this, pluginRequest, factory, Validation.ELASTIC_PROFILE_VALIDATIONS); + return new ClusterProfileValidateRequestExecutor(this, pluginRequest, factory, Validation.ELASTIC_PROFILE_VALIDATIONS); } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/utils/Util.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/utils/Util.java index b7ff6c6..301a1f5 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/utils/Util.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/utils/Util.java @@ -18,7 +18,7 @@ import com.google.common.io.ByteStreams; import com.google.common.io.CharStreams; -import com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginSettingsViewRequestExecutor; +import com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileViewRequestExecutor; import java.io.IOException; import java.io.InputStream; @@ -36,7 +36,7 @@ public class Util { private static Random random = new Random(); public static String readResource(String resourceFile) { - try (InputStreamReader reader = new InputStreamReader(GetPluginSettingsViewRequestExecutor.class.getResourceAsStream(resourceFile), StandardCharsets.UTF_8)) { + try (InputStreamReader reader = new InputStreamReader(GetClusterProfileViewRequestExecutor.class.getResourceAsStream(resourceFile), StandardCharsets.UTF_8)) { return CharStreams.toString(reader); } catch (IOException e) { throw new RuntimeException("Could not find resource " + resourceFile, e); @@ -44,7 +44,7 @@ public static String readResource(String resourceFile) { } public static byte[] readResourceBytes(String resourceFile) { - try (InputStream in = GetPluginSettingsViewRequestExecutor.class.getResourceAsStream(resourceFile)) { + try (InputStream in = GetClusterProfileViewRequestExecutor.class.getResourceAsStream(resourceFile)) { return ByteStreams.toByteArray(in); } catch (IOException e) { throw new RuntimeException("Could not find resource " + resourceFile, e); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidation.java index 86ecbc2..5e5e889 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidation.java @@ -26,7 +26,7 @@ import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import static com.thoughtworks.gocd.elasticagent.azure.Errors.AZURE_INVALID_NSG_ID; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.*; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.*; import static org.apache.commons.lang3.StringUtils.isNotBlank; public class AzureNetworkSettingsValidation implements Validation { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidation.java index b4c8dcc..fa1ad13 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidation.java @@ -23,7 +23,7 @@ import java.util.Map; import static com.thoughtworks.gocd.elasticagent.azure.Errors.AZURE_INVALID_REGION; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.REGION_NAME; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.REGION_NAME; import static org.apache.commons.lang3.StringUtils.isNotBlank; public class AzureRegionValidation implements Validation { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidation.java index f4b1137..8b6b0d5 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidation.java @@ -24,7 +24,7 @@ import java.util.Map; import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.RESOURCE_GROUP; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.RESOURCE_GROUP; import static org.apache.commons.lang3.StringUtils.isNotBlank; public class AzureResourceGroupValidation implements Validation { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidation.java index acede37..c1e6822 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidation.java @@ -18,7 +18,7 @@ import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; -import com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor; +import com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor; import com.thoughtworks.gocd.elasticagent.azure.models.Field; import java.util.HashMap; @@ -28,7 +28,7 @@ public class FieldValidation implements Validation { @Override public Map run(Map properties, PluginSettings settings, GoCDAzureClient client) { Map errors = new HashMap<>(); - for (Map.Entry entry : GetPluginConfigurationExecutor.FIELDS.entrySet()) { + for (Map.Entry entry : GetClusterProfileMetadataExecutor.CLUSTER_PROFILE_FIELDS.entrySet()) { Field field = entry.getValue(); errors.putAll(field.validate(properties.get(entry.getKey()))); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidation.java index c24fe2b..e70cb45 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidation.java @@ -24,7 +24,7 @@ import java.util.Map; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor.*; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor.*; public class ImageValidation implements Validation { public static final String IMAGE_URN_OR_CUSTOM_IMAGE_SET_MESSAGE = "Image URN or Custom image id must be set."; diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/MetadataValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/MetadataValidation.java index 10887a8..b593632 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/MetadataValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/MetadataValidation.java @@ -18,7 +18,7 @@ import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; -import com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor; +import com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor; import java.util.HashMap; import java.util.Map; @@ -27,7 +27,7 @@ public class MetadataValidation implements Validation { @Override public Map run(Map properties, PluginSettings settings, GoCDAzureClient client) { HashMap errors = new HashMap<>(); - GetProfileMetadataExecutor.FIELDS.stream().forEach(field -> { + GetElasticAgentProfileMetadataExecutor.FIELDS.stream().forEach(field -> { Map validationError = field.validate(properties.get(field.getKey())); if (!validationError.isEmpty()) { errors.putAll(validationError); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskSizeValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskSizeValidation.java index 403b786..19baf3b 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskSizeValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskSizeValidation.java @@ -25,8 +25,8 @@ import java.util.Collections; import java.util.Map; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor.OS_DISK_SIZE; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor.PLATFORM; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor.OS_DISK_SIZE; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor.PLATFORM; public class OsDiskSizeValidation implements Validation { @Override diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskStorageTypeValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskStorageTypeValidation.java index 3c761ad..d5aba2e 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskStorageTypeValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/OsDiskStorageTypeValidation.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.stream.Collectors; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor.OS_DISK_STORAGE_ACCOUNT_TYPE; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor.OS_DISK_STORAGE_ACCOUNT_TYPE; public class OsDiskStorageTypeValidation implements Validation { @Override diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/UnknownProfileFieldValidation.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/UnknownProfileFieldValidation.java index c2b84c5..bd46c7f 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/UnknownProfileFieldValidation.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/validations/UnknownProfileFieldValidation.java @@ -18,7 +18,7 @@ import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; -import com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor; +import com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor; import java.util.*; import java.util.stream.Collectors; @@ -30,7 +30,7 @@ public class UnknownProfileFieldValidation implements Validation { public Map run(Map properties, PluginSettings settings, GoCDAzureClient client) { HashMap errors = new HashMap<>(); Set set = new HashSet<>(properties.keySet()); - set.removeAll(GetProfileMetadataExecutor.FIELDS.stream().map(metadata -> metadata.getKey()).collect(Collectors.toCollection(ArrayList::new))); + set.removeAll(GetElasticAgentProfileMetadataExecutor.FIELDS.stream().map(metadata -> metadata.getKey()).collect(Collectors.toCollection(ArrayList::new))); set.forEach(s -> errors.put(s, UNKNOWN_PROPERTY_MESSAGE)); return errors; } diff --git a/src/main/resources/plugin-settings.template.html b/src/main/resources/cluster-profile.template.html similarity index 99% rename from src/main/resources/plugin-settings.template.html rename to src/main/resources/cluster-profile.template.html index f93a9b0..2005bbe 100644 --- a/src/main/resources/plugin-settings.template.html +++ b/src/main/resources/cluster-profile.template.html @@ -197,7 +197,7 @@
- {{GOINPUTNAME[ssh_key].$error.server}}
Use these credentials to log into Linux agent virtual machines. diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutorTest.java index cca8b8d..fd7d8f8 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginConfigurationExecutorTest.java @@ -33,18 +33,18 @@ class GetPluginConfigurationExecutorTest { @Test void shouldSerializeAllFields() { - GoPluginApiResponse response = new GetPluginConfigurationExecutor().execute(); + GoPluginApiResponse response = new GetClusterProfileMetadataExecutor().execute(); Map hashMap = new Gson().fromJson(response.responseBody(), new TypeToken>() { }.getType()); assertEquals(hashMap.size(), - GetPluginConfigurationExecutor.FIELDS.size(), + GetClusterProfileMetadataExecutor.CLUSTER_PROFILE_FIELDS.size(), "Are you using anonymous inner classes — see https://github.com/google/gson/issues/298" ); } @Test void assertJsonStructure() throws Exception { - GoPluginApiResponse response = new GetPluginConfigurationExecutor().execute(); + GoPluginApiResponse response = new GetClusterProfileMetadataExecutor().execute(); assertThat(response.responseCode(), is(200)); String expectedJSON = "{\n" + diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutorTest.java index 7072150..ac4ed2f 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsIconExecutorTest.java @@ -32,7 +32,7 @@ class GetPluginSettingsIconExecutorTest { @Test void rendersIconInBase64() throws Exception { - GoPluginApiResponse response = new GetPluginSettingsIconExecutor().execute(); + GoPluginApiResponse response = new GetPluginIconExecutor().execute(); HashMap hashMap = new Gson().fromJson(response.responseBody(), new TypeToken>() { }.getType()); assertThat(hashMap.size(), is(2)); diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutorTest.java index 4a85ea7..ee0ba16 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetPluginSettingsViewRequestExecutorTest.java @@ -34,7 +34,7 @@ class GetPluginSettingsViewRequestExecutorTest { @Test void shouldRenderTheTemplateInJSON() throws Exception { - GoPluginApiResponse response = new GetPluginSettingsViewRequestExecutor().execute(); + GoPluginApiResponse response = new GetClusterProfileViewRequestExecutor().execute(); assertThat(response.responseCode(), is(200)); Map hashSet = new Gson().fromJson(response.responseBody(), new TypeToken>() { }.getType()); @@ -45,7 +45,7 @@ void shouldRenderTheTemplateInJSON() throws Exception { void allFieldsShouldBePresentInView() throws Exception { String template = Util.readResource("/plugin-settings.template.html"); - for (Map.Entry fieldEntry : GetPluginConfigurationExecutor.FIELDS.entrySet()) { + for (Map.Entry fieldEntry : GetClusterProfileMetadataExecutor.CLUSTER_PROFILE_FIELDS.entrySet()) { assertThat(template, containsString("ng-model=\"" + fieldEntry.getKey() + "\"")); assertThat(template, containsString(" list = new Gson().fromJson(response.responseBody(), new TypeToken>() { }.getType()); - assertEquals(list.size(), GetProfileMetadataExecutor.FIELDS.size()); + assertEquals(list.size(), GetElasticAgentProfileMetadataExecutor.FIELDS.size()); } @Test void assertJsonStructure() throws Exception { - GoPluginApiResponse response = new GetProfileMetadataExecutor().execute(); + GoPluginApiResponse response = new GetElasticAgentProfileMetadataExecutor().execute(); assertThat(response.responseCode(), is(200)); String expectedJSON = "[\n" + diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutorTest.java index 3369e2f..7164d00 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/GetProfileViewExecutorTest.java @@ -31,7 +31,7 @@ class GetProfileViewExecutorTest { @Test void shouldRenderTheTemplateInJSON() throws Exception { - GoPluginApiResponse response = new GetProfileViewExecutor().execute(); + GoPluginApiResponse response = new GetElasticAgentProfileViewExecutor().execute(); assertThat(response.responseCode(), is(200)); Map hashSet = new Gson().fromJson(response.responseBody(), new TypeToken>() { }.getType()); diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutorTest.java index 5f903e2..4ce4e7d 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/executors/ProfileValidateRequestExecutorTest.java @@ -22,7 +22,7 @@ import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; import com.thoughtworks.gocd.elasticagent.azure.exceptions.PluginSettingsNotConfiguredException; -import com.thoughtworks.gocd.elasticagent.azure.requests.ProfileValidateRequest; +import com.thoughtworks.gocd.elasticagent.azure.requests.ClusterProfileValidateRequest; import com.thoughtworks.gocd.elasticagent.azure.validations.Validation; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; @@ -64,7 +64,7 @@ void setup() throws Exception { void shouldShowErrorOnAllFieldsIfPluginSettingsNotConfigured() throws Exception { when(mockPluginRequest.getPluginSettings()).thenThrow(PluginSettingsNotConfiguredException.class); - ProfileValidateRequestExecutor executor = new ProfileValidateRequestExecutor(new ProfileValidateRequest(Collections.emptyMap()), mockPluginRequest, mockClientFactory, Collections.emptyList()); + ClusterProfileValidateRequestExecutor executor = new ClusterProfileValidateRequestExecutor(new ClusterProfileValidateRequest(Collections.emptyMap()), mockPluginRequest, mockClientFactory, Collections.emptyList()); String json = executor.execute().responseBody(); JSONAssert.assertEquals("[" + @@ -85,7 +85,7 @@ void shouldRunAllValidations() throws JSONException { Validation validation2 = mock(Validation.class); List validations = Arrays.asList(validation1, validation2); Map properties = Collections.emptyMap(); - ProfileValidateRequestExecutor executor = new ProfileValidateRequestExecutor(new ProfileValidateRequest(properties), mockPluginRequest, mockClientFactory, validations); + ClusterProfileValidateRequestExecutor executor = new ClusterProfileValidateRequestExecutor(new ClusterProfileValidateRequest(properties), mockPluginRequest, mockClientFactory, validations); when(validation1.run(properties, mockPluginSettings, mockAzureClient)).thenReturn(Collections.emptyMap()); when(validation2.run(properties, mockPluginSettings, mockAzureClient)).thenReturn(Collections.singletonMap("field key", "error message")); diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidationTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidationTest.java index 48a72c9..8ed8ac0 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidationTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureNetworkSettingsValidationTest.java @@ -26,7 +26,7 @@ import java.util.Map; import static com.thoughtworks.gocd.elasticagent.azure.Errors.*; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.*; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.*; import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidationTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidationTest.java index b594816..8339fb4 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidationTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureRegionValidationTest.java @@ -25,7 +25,7 @@ import java.util.Map; import static com.thoughtworks.gocd.elasticagent.azure.Errors.AZURE_INVALID_REGION; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.REGION_NAME; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.REGION_NAME; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidationTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidationTest.java index 3e1eeb1..4650c14 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidationTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/AzureResourceGroupValidationTest.java @@ -25,7 +25,7 @@ import java.util.Map; import static com.thoughtworks.gocd.elasticagent.azure.Errors.AZURE_INVALID_RESOURCE_GROUP; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.RESOURCE_GROUP; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.RESOURCE_GROUP; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidationTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidationTest.java index 16d6459..9d4db67 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidationTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/FieldValidationTest.java @@ -21,7 +21,7 @@ import java.util.Collections; import java.util.Map; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetPluginConfigurationExecutor.*; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetClusterProfileMetadataExecutor.*; import static org.junit.jupiter.api.Assertions.assertEquals; class FieldValidationTest { diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidationTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidationTest.java index b80105e..0214f97 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidationTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/azure/validations/ImageValidationTest.java @@ -29,7 +29,7 @@ import java.util.HashMap; import java.util.Map; -import static com.thoughtworks.gocd.elasticagent.azure.executors.GetProfileMetadataExecutor.VM_IMAGE_URN; +import static com.thoughtworks.gocd.elasticagent.azure.executors.GetElasticAgentProfileMetadataExecutor.VM_IMAGE_URN; import static com.thoughtworks.gocd.elasticagent.azure.models.ImageMetadata.IMAGE_URN_INVALID_GENERIC_MESSAGE; import static com.thoughtworks.gocd.elasticagent.azure.models.Platform.LINUX; import static org.junit.jupiter.api.Assertions.assertEquals; From 4ee30bb664b0772e76c094423167b060d09124a4 Mon Sep 17 00:00:00 2001 From: Joel Strasser Date: Mon, 8 May 2023 22:24:02 +0200 Subject: [PATCH 2/5] [broken] new structure --- .../gocd/elasticagent/azure/AzurePlugin.java | 41 ++++++--- .../elasticagent/azure/ClusterProfile.java | 90 ++++++++++--------- .../azure/ClusterProfileProperties.java | 1 - 3 files changed, 75 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java index 1c9e624..e3ad52b 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java @@ -63,36 +63,51 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe try { switch (Request.fromString(request.requestName())) { case REQUEST_GET_ICON: - return new GetPluginIconExecutor().execute(); + return new GetPluginIconExecutor() + .execute(); case REQUEST_SHOULD_ASSIGN_WORK: refreshInstances(); - return ShouldAssignWorkRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest.getPluginSettings(), serverHealthMessagingService).execute(); + return ShouldAssignWorkRequest.fromJSON(request.requestBody()) + .executor(agentInstances, pluginRequest.getPluginSettings(), serverHealthMessagingService) + .execute(); case REQUEST_CREATE_AGENT: refreshInstances(); - return CreateAgentRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest, requestFingerprintCache, serverHealthMessagingService).execute(); + return CreateAgentRequest.fromJSON(request.requestBody()) + .executor(agentInstances, pluginRequest, requestFingerprintCache, serverHealthMessagingService) + .execute(); case REQUEST_SERVER_PING: refreshInstances(); - return new ServerPingRequestExecutor(agentInstances, pluginRequest, serverHealthMessagingService).execute(); + return new ServerPingRequestExecutor(agentInstances, pluginRequest, serverHealthMessagingService) + .execute(); case REQUEST_GET_ELASTIC_AGENT_PROFILE_METADATA: - return new GetElasticAgentProfileMetadataExecutor().execute(); + return new GetElasticAgentProfileMetadataExecutor() + .execute(); case REQUEST_GET_ELASTIC_AGENT_PROFILE_VIEW: - return new GetElasticAgentProfileViewExecutor().execute(); + return new GetElasticAgentProfileViewExecutor() + .execute(); case REQUEST_JOB_COMPLETION: refreshInstances(); - return JobCompletionRequest.fromJSON(request.requestBody()).executor(agentInstances, pluginRequest).execute(); + return JobCompletionRequest.fromJSON(request.requestBody()) + .executor(agentInstances, pluginRequest).execute(); case REQUEST_CAPABILITIES: - return new GetCapabilitiesExecutor().execute(); + return new GetCapabilitiesExecutor() + .execute(); case REQUEST_AGENT_STATUS_REPORT: refreshInstances(); - return AgentStatusReportRequest.fromJSON(request.requestBody()).executor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); + return AgentStatusReportRequest.fromJSON(request.requestBody()) + .executor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); case REQUEST_GET_CLUSTER_PROFILE_METADATA: - return new GetClusterProfileMetadataExecutor().execute(); + return new GetClusterProfileMetadataExecutor() + .execute(); case REQUEST_GET_CLUSTER_PROFILE_VIEW: - return new GetClusterProfileViewRequestExecutor().execute(); + return new GetClusterProfileViewRequestExecutor() + .execute(); case REQUEST_VALIDATE_CLUSTER_PROFILE: - return ClusterProfileValidateRequest.fromJSON(request.requestBody()).executor(pluginRequest, clientFactory).execute(); + return ClusterProfileValidateRequest.fromJSON(request.requestBody()) + .executor(pluginRequest, clientFactory).execute(); case REQUEST_PLUGIN_STATUS_REPORT: - return new StatusReportExecutor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); + return new StatusReportExecutor(pluginRequest, agentInstances, TemplateReader.instance()) + .execute(); default: throw new UnhandledRequestTypeException(request.requestName()); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java index c25c690..258984a 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java @@ -13,66 +13,70 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.google.gson.annotations.Expose; - import java.util.Objects; -import static com.example.elasticagent.ExamplePlugin.GSON; - -// TODO: Implement any settings that your plugin needs public class ClusterProfile { - @Expose - private final String id; - @Expose - private final String pluginId; + @Expose + private final String id; - @Expose - private final ClusterProfileProperties properties; + @Expose + private final String pluginId; - public ClusterProfile() { - this("", "", new ClusterProfileProperties()); - } + @Expose + private final ClusterProfileProperties properties; - public ClusterProfile(String id, String pluginId, ClusterProfileProperties clusterProfileProperties) { - this.id = id; - this.pluginId = pluginId; - this.properties = clusterProfileProperties; - } - - public static ClusterProfile fromJSON(String json) { - return GSON.fromJson(json, ClusterProfile.class); - } + public ClusterProfile() { + this("", "", new ClusterProfileProperties()); + } - public String getId() { - return id; - } + public ClusterProfile(String id, String pluginId, ClusterProfileProperties clusterProfileProperties) { + this.id = id; + this.pluginId = pluginId; + this.properties = clusterProfileProperties; + } - public String getPluginId() { - return pluginId; - } + public static ClusterProfile fromJSON(String json) { + return GSON.fromJson(json, ClusterProfile.class); + } - public ClusterProfileProperties getProperties() { - return properties; - } + public String getId() { + return id; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public String getPluginId() { + return pluginId; + } - ClusterProfile that = (ClusterProfile) o; + public ClusterProfileProperties getProperties() { + return properties; + } - if (id != null ? !id.equals(that.id) : that.id != null) return false; - if (pluginId != null ? !pluginId.equals(that.pluginId) : that.pluginId != null) return false; - return properties != null ? properties.equals(that.properties) : that.properties == null; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } - @Override - public int hashCode() { - return Objects.hash(id, pluginId, properties); + ClusterProfile that = (ClusterProfile) o; + + if (id != null ? !id.equals(that.id) : that.id != null) { + return false; + } + if (pluginId != null ? !pluginId.equals(that.pluginId) : that.pluginId != null) { + return false; } + return properties != null ? properties.equals(that.properties) : that.properties == null; + } + + @Override + public int hashCode() { + return Objects.hash(id, pluginId, properties); + } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java index 4d7e64d..632261d 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java @@ -18,7 +18,6 @@ import java.util.Map; import org.joda.time.Period; -// TODO: Implement any settings that your plugin needs public class ClusterProfileProperties extends PluginSettings { public ClusterProfileProperties() { From 1efed09ef6c0e6bc93e0301f1029d0cfdfbb933b Mon Sep 17 00:00:00 2001 From: Joel Strasser Date: Tue, 9 May 2023 23:36:09 +0200 Subject: [PATCH 3/5] update requests and executors to match reference implementation --- .../elasticagent/azure/AzureInstance.java | 48 +++--- .../gocd/elasticagent/azure/AzurePlugin.java | 5 +- .../elasticagent/azure/ClusterProfile.java | 12 ++ .../azure/ClusterProfileProperties.java | 12 +- .../elasticagent/azure/PluginSettings.java | 152 +++++++++++++----- .../executors/AgentStatusReportExecutor.java | 13 +- .../executors/CreateAgentRequestExecutor.java | 20 +-- .../JobCompletionRequestExecutor.java | 20 +-- .../ShouldAssignWorkRequestExecutor.java | 7 +- .../requests/AgentStatusReportRequest.java | 14 +- .../ClusterProfileValidateRequest.java | 6 +- .../azure/requests/CreateAgentRequest.java | 39 +++-- .../azure/requests/JobCompletionRequest.java | 47 ++++-- .../requests/ShouldAssignWorkRequest.java | 23 +-- 14 files changed, 269 insertions(+), 149 deletions(-) diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureInstance.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureInstance.java index 8700f33..12c660c 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureInstance.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureInstance.java @@ -13,27 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.microsoft.azure.management.compute.ImageReference; import com.thoughtworks.gocd.elasticagent.azure.models.ElasticProfile; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.models.Platform; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import org.joda.time.DateTime; - +import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.*; import java.util.Map; import java.util.Optional; import java.util.UUID; - -import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; import static org.apache.commons.lang3.StringUtils.isNotBlank; +import org.joda.time.DateTime; @Getter @EqualsAndHashCode public class AzureInstance { + private String name; private String hostName; private String id; @@ -50,18 +48,18 @@ public class AzureInstance { private Platform platform; public AzureInstance(String name, - String hostName, - String id, - DateTime createdAt, - ImageReference imageReference, - String size, - String os, - Integer diskSize, - String provisioningState, - String powerState, - String resourceGroupName, - String primaryNetworkInterface, - Map tags, Platform platform) { + String hostName, + String id, + DateTime createdAt, + ImageReference imageReference, + String size, + String os, + Integer diskSize, + String provisioningState, + String powerState, + String resourceGroupName, + String primaryNetworkInterface, + Map tags, Platform platform) { this.name = name; this.hostName = hostName; this.id = id; @@ -82,7 +80,7 @@ public Boolean jobIdentifierMatches(JobIdentifier identifier) { return getJobIdentifierHash().equals(identifier.hash()); } - public Boolean elasticProfileMatches(ElasticProfile elasticProfile){ + public Boolean elasticProfileMatches(ElasticProfile elasticProfile) { return getElasticProfileHash().equals(elasticProfile.hash()); } @@ -98,8 +96,8 @@ public JobState getJobState() { return isAssigned() ? JobState.Assigned : JobState.Unassigned; } - public boolean canBeAssigned(ElasticProfile elasticProfile) { - return getElasticProfileHash().equals(elasticProfile.hash()) && !isAssigned() && (neverAssigned() || !isIdleAfterIdleTimeout()); + public boolean canBeAssigned(ClusterProfileProperties clusterProfileProperties) { + return getElasticProfileHash().equals(clusterProfileProperties.hash()) && !isAssigned() && (neverAssigned() || !isIdleAfterIdleTimeout()); } public boolean isIdleAfterIdleTimeout() { @@ -130,14 +128,14 @@ private String getJobIdentifierHash() { return Optional.ofNullable(this.tags.get(JOB_IDENTIFIER_TAG_KEY)).orElse(String.valueOf(UUID.randomUUID())); } - private int getIdleTimeout(){ + private int getIdleTimeout() { String idleTimeout = this.tags.get(IDLE_TIMEOUT); return idleTimeout != null ? Integer.valueOf(idleTimeout) : 0; } - private DateTime idleSince(){ + private DateTime idleSince() { DateTime lastJobRunTime = getLastJobRunTime(); - return lastJobRunTime !=null ? lastJobRunTime : createdAt; + return lastJobRunTime != null ? lastJobRunTime : createdAt; } public enum JobState { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java index e3ad52b..7289d4c 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java @@ -60,15 +60,18 @@ public void initializeGoApplicationAccessor(GoApplicationAccessor accessor) { @Override public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRequestTypeException { + ClusterProfileProperties clusterProfileProperties; try { switch (Request.fromString(request.requestName())) { case REQUEST_GET_ICON: return new GetPluginIconExecutor() .execute(); case REQUEST_SHOULD_ASSIGN_WORK: + ShouldAssignWorkRequest shouldAssignWorkRequest = ShouldAssignWorkRequest.fromJSON(request.requestBody()); + clusterProfileProperties = shouldAssignWorkRequest.getClusterProfileProperties(); refreshInstances(); return ShouldAssignWorkRequest.fromJSON(request.requestBody()) - .executor(agentInstances, pluginRequest.getPluginSettings(), serverHealthMessagingService) + .executor(agentInstances, clusterProfileProperties, serverHealthMessagingService) .execute(); case REQUEST_CREATE_AGENT: refreshInstances(); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java index 258984a..dccdb6c 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfile.java @@ -15,18 +15,30 @@ */ package com.thoughtworks.gocd.elasticagent.azure; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; import java.util.Objects; public class ClusterProfile { + public static final Gson GSON = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .excludeFieldsWithoutExposeAnnotation() + .create(); + @Expose + @SerializedName("id") private final String id; @Expose + @SerializedName("plugin_id") private final String pluginId; @Expose + @SerializedName("properties") private final ClusterProfileProperties properties; public ClusterProfile() { diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java index 632261d..95e4e7a 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/ClusterProfileProperties.java @@ -16,17 +16,9 @@ package com.thoughtworks.gocd.elasticagent.azure; import java.util.Map; -import org.joda.time.Period; public class ClusterProfileProperties extends PluginSettings { - public ClusterProfileProperties() { - } - - public ClusterProfileProperties(String goServerUrl, String autoRegisterTimeout, String apiUser, String apiKey, String apiUrl, Period autoRegisterPeriod) { - super(goServerUrl, autoRegisterTimeout, apiUser, apiKey, apiUrl, autoRegisterPeriod); - } - public static ClusterProfileProperties fromJSON(String json) { return GSON.fromJson(json, ClusterProfileProperties.class); } @@ -38,4 +30,8 @@ public static ClusterProfileProperties fromConfiguration(Map clu public String uuid() { return Integer.toHexString(hashCode()); } + + public String hash() { + return String.valueOf(hashCode()); + } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java index 77d85dc..bb680df 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/PluginSettings.java @@ -20,8 +20,12 @@ import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import java.util.Map; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import com.thoughtworks.gocd.elasticagent.azure.utils.Util; +import java.util.Objects; +import lombok.AccessLevel; import lombok.Getter; +import static org.apache.commons.lang3.StringUtils.isBlank; import org.joda.time.Period; @Getter @@ -41,37 +45,104 @@ public class PluginSettings { private String autoRegisterTimeout; @Expose - @SerializedName("api_user") - private String apiUser; + @SerializedName("idle_timeout") + private String idleTimeout; @Expose - @SerializedName("api_key") - private String apiKey; + @SerializedName("domain") + private String domain; @Expose - @SerializedName("api_url") - private String apiUrl; + @SerializedName("client_id") + private String clientId; + + @Expose + @SerializedName("secret") + private String secret; + + @Expose + @SerializedName("network_id") + private String networkId; + + @Expose + @SerializedName("subnet") + @Getter(AccessLevel.NONE) + private String subnetNames; + + @Expose + @SerializedName("network_security_group_id") + private String networkSecurityGroupId; + + @Expose + @SerializedName("resource_group") + private String resourceGroup; + + @Expose + @SerializedName("region_name") + @Getter(AccessLevel.NONE) + private String regionName; + + @Expose + @SerializedName("linux_user_name") + private String linuxUserName; + + @Expose + @SerializedName("ssh_key") + private String sshKey; + + @Expose + @SerializedName("windows_user_name") + private String windowsUserName; + + @Expose + @SerializedName("windows_password") + private String windowsPassword; private Period autoRegisterPeriod; + private Period idleTimeoutPeriod; - public PluginSettings() { + @Getter(AccessLevel.NONE) + private String[] subnetNamesArray; + + public static PluginSettings fromJSON(String json) { + return GSON.fromJson(json, PluginSettings.class); } - public PluginSettings(String goServerUrl, String autoRegisterTimeout, String apiUser, String apiKey, String apiUrl, Period autoRegisterPeriod) { + public PluginSettings(String goServerUrl, + String autoRegisterTimeout, + String idleTimeout, + String domain, + String clientId, + String secret, + Period autoRegisterPeriod, + String networkId, + String subnetNames, + String networkSecurityGroupId, + String resourceGroup, + String sshKey, + String regionName, + String linuxUserName, + String windowsUserName, + String windowsPassword) { this.goServerUrl = goServerUrl; this.autoRegisterTimeout = autoRegisterTimeout; - this.apiUser = apiUser; - this.apiKey = apiKey; - this.apiUrl = apiUrl; + this.idleTimeout = idleTimeout; + this.domain = domain; + this.clientId = clientId; + this.secret = secret; this.autoRegisterPeriod = autoRegisterPeriod; + this.networkId = networkId; + this.subnetNames = subnetNames; + this.networkSecurityGroupId = networkSecurityGroupId; + this.resourceGroup = resourceGroup; + this.regionName = regionName; + this.linuxUserName = linuxUserName; + this.sshKey = sshKey; + this.windowsUserName = windowsUserName; + this.windowsPassword = windowsPassword; } - public static PluginSettings fromJSON(String json) { - return GSON.fromJson(json, PluginSettings.class); - } - - public static PluginSettings fromConfiguration(Map pluginSettings) { - return GSON.fromJson(GSON.toJson(pluginSettings), PluginSettings.class); + public PluginSettings() { } @Override @@ -82,7 +153,6 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - PluginSettings that = (PluginSettings) o; if (goServerUrl != null ? !goServerUrl.equals(that.goServerUrl) : that.goServerUrl != null) { @@ -91,52 +161,52 @@ public boolean equals(Object o) { if (autoRegisterTimeout != null ? !autoRegisterTimeout.equals(that.autoRegisterTimeout) : that.autoRegisterTimeout != null) { return false; } - if (apiUser != null ? !apiUser.equals(that.apiUser) : that.apiUser != null) { + if (domain != null ? !domain.equals(that.domain) : that.domain != null) { return false; } - if (apiKey != null ? !apiKey.equals(that.apiKey) : that.apiKey != null) { + if (clientId != null ? !clientId.equals(that.clientId) : that.clientId != null) { return false; } - return apiUrl != null ? apiUrl.equals(that.apiUrl) : that.apiUrl == null; + return secret != null ? secret.equals(that.secret) : that.secret == null; } @Override public int hashCode() { - int result = goServerUrl != null ? goServerUrl.hashCode() : 0; - result = 31 * result + (getAutoRegisterPeriod() != null ? getAutoRegisterPeriod().hashCode() : 0); - result = 31 * result + (apiUser != null ? apiUser.hashCode() : 0); - result = 31 * result + (apiKey != null ? apiKey.hashCode() : 0); - result = 31 * result + (apiUrl != null ? apiUrl.hashCode() : 0); - return result; + return Objects.hash(goServerUrl, autoRegisterTimeout, domain, clientId, secret, autoRegisterPeriod); } public Period getAutoRegisterPeriod() { if (this.autoRegisterPeriod == null) { - this.autoRegisterPeriod = new Period().withMinutes(Integer.parseInt(getAutoRegisterTimeout())); + this.autoRegisterPeriod = new Period().withMinutes(Integer.parseInt(autoRegisterTimeout)); } return this.autoRegisterPeriod; } - private String getAutoRegisterTimeout() { - if (autoRegisterTimeout == null) { - autoRegisterTimeout = "10"; + public Period getIdleTimeoutPeriod() { + if (this.idleTimeoutPeriod == null) { + this.idleTimeoutPeriod = new Period().withMinutes(Integer.parseInt(getIdleTimeout())); } - return autoRegisterTimeout; + return this.idleTimeoutPeriod; } - public String getApiUser() { - return apiUser; + public Region getRegion() { + return Region.findByLabelOrName(regionName); } - public String getApiKey() { - return apiKey; + public String[] getSubnetNames() { + if (this.subnetNamesArray == null) { + this.subnetNamesArray = Util.splitByComma(subnetNames); + } + return this.subnetNamesArray; } - public String getApiUrl() { - return apiUrl; + public String getRandomSubnet() { + int index = (this.getSubnetNames().length == 0) ? 0 : Util.random((getSubnetNames().length)); + return getSubnetNames()[index]; } - public String getGoServerUrl() { - return goServerUrl; + private String getIdleTimeout() { + return isBlank(idleTimeout) ? "0" : idleTimeout; } + } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/AgentStatusReportExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/AgentStatusReportExecutor.java index 8cbff9d..705faa8 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/AgentStatusReportExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/AgentStatusReportExecutor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.google.gson.JsonObject; @@ -27,11 +26,11 @@ import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.requests.AgentStatusReportRequest; import com.thoughtworks.gocd.elasticagent.azure.utils.TemplateReader; -import org.apache.commons.lang3.StringUtils; - import java.util.HashMap; +import org.apache.commons.lang3.StringUtils; public class AgentStatusReportExecutor { + private static final Logger LOG = Logger.getLoggerFor(AgentStatusReportExecutor.class); private final AgentStatusReportRequest request; private final PluginRequest pluginRequest; @@ -39,9 +38,9 @@ public class AgentStatusReportExecutor { private final TemplateReader templateReader; public AgentStatusReportExecutor(AgentStatusReportRequest request, - PluginRequest pluginRequest, - AzureAgentInstances agentInstances, - TemplateReader templateReader) { + PluginRequest pluginRequest, + AzureAgentInstances agentInstances, + TemplateReader templateReader) { this.request = request; this.pluginRequest = pluginRequest; this.agentInstances = agentInstances; @@ -55,7 +54,7 @@ public GoPluginApiResponse execute() throws Exception { try { AzureInstance agentInstance = getAgentInstance(elasticAgentId, jobIdentifier); if (agentInstance != null) { - AgentStatusReport agentStatusReport = agentInstances.getAgentStatusReport(pluginRequest.getPluginSettings(), agentInstance); + AgentStatusReport agentStatusReport = agentInstances.getAgentStatusReport(request.getClusterProfile(), agentInstance); final String statusReportView = templateReader.read("agent-status-report.template.ftlh", agentStatusReport); return constructResponseForReport(statusReportView); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/CreateAgentRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/CreateAgentRequestExecutor.java index a381dd6..06a81cf 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/CreateAgentRequestExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/CreateAgentRequestExecutor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; @@ -30,6 +29,7 @@ import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; public class CreateAgentRequestExecutor implements RequestExecutor { + private final AzureAgentInstances agentInstances; private final PluginRequest pluginRequest; private RequestFingerprintCache requestFingerprintCache; @@ -37,9 +37,9 @@ public class CreateAgentRequestExecutor implements RequestExecutor { private ServerHealthMessagingService serverHealthMessagingService; public CreateAgentRequestExecutor(CreateAgentRequest request, - AzureAgentInstances agentInstances, - PluginRequest pluginRequest, - RequestFingerprintCache requestFingerprintCache, ServerHealthMessagingService serverHealthMessagingService) { + AzureAgentInstances agentInstances, + PluginRequest pluginRequest, + RequestFingerprintCache requestFingerprintCache, ServerHealthMessagingService serverHealthMessagingService) { this.request = request; this.agentInstances = agentInstances; this.pluginRequest = pluginRequest; @@ -50,15 +50,15 @@ public CreateAgentRequestExecutor(CreateAgentRequest request, @Override public GoPluginApiResponse execute() throws Exception { String requestFingerprint = request.jobIdentifier().hash(); - PluginSettings pluginSettings = pluginRequest.getPluginSettings(); + PluginSettings pluginSettings = request.getClusterProfileProperties(); ServerInfo serverInfo = pluginRequest.getServerInfo(); try { requestFingerprintCache.getOrExecute(requestFingerprint, - pluginSettings.getAutoRegisterPeriod(), - () -> { - agentInstances.create(request, pluginSettings, serverInfo); - serverHealthMessagingService.clearHealthMessage(request.jobIdentifier().getJobRepresentation()); - }); + pluginSettings.getAutoRegisterPeriod(), + () -> { + agentInstances.create(request, pluginSettings, serverInfo); + serverHealthMessagingService.clearHealthMessage(request.jobIdentifier().getJobRepresentation()); + }); } catch (ProvisionFailedException e) { serverHealthMessagingService.sendHealthMessage(e.jobRepresentation(), PluginHealthMessage.error(e.getMessage())); return DefaultGoPluginApiResponse.error(e.getMessage()); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/JobCompletionRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/JobCompletionRequestExecutor.java index c40eea9..0705280 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/JobCompletionRequestExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/JobCompletionRequestExecutor.java @@ -13,34 +13,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import com.thoughtworks.gocd.elasticagent.azure.*; +import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import com.thoughtworks.gocd.elasticagent.azure.requests.JobCompletionRequest; - +import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.JOB_IDENTIFIER_TAG_KEY; +import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.LAST_JOB_RUN_TAG_KEY; import java.io.IOException; import java.util.Collections; import java.util.List; -import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; -import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.JOB_IDENTIFIER_TAG_KEY; -import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.LAST_JOB_RUN_TAG_KEY; - - public class JobCompletionRequestExecutor implements RequestExecutor { + private final JobCompletionRequest jobCompletionRequest; private final AzureAgentInstances agentInstances; private final PluginRequest pluginRequest; private Clock clock; - public JobCompletionRequestExecutor(JobCompletionRequest jobCompletionRequest, - AzureAgentInstances agentInstances, - PluginRequest pluginRequest, - Clock clock) { + AzureAgentInstances agentInstances, + PluginRequest pluginRequest, + Clock clock) { this.jobCompletionRequest = jobCompletionRequest; this.agentInstances = agentInstances; this.pluginRequest = pluginRequest; @@ -49,7 +45,7 @@ public JobCompletionRequestExecutor(JobCompletionRequest jobCompletionRequest, @Override public GoPluginApiResponse execute() throws Exception { - PluginSettings pluginSettings = pluginRequest.getPluginSettings(); + PluginSettings pluginSettings = jobCompletionRequest.getClusterProfileProperties(); String elasticAgentId = jobCompletionRequest.getElasticAgentId(); Agent agent = new Agent(elasticAgentId); Agents agents = pluginRequest.listAgents(); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ShouldAssignWorkRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ShouldAssignWorkRequestExecutor.java index eb99bab..202e26d 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ShouldAssignWorkRequestExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ShouldAssignWorkRequestExecutor.java @@ -13,22 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import com.thoughtworks.gocd.elasticagent.azure.AgentInstances; import com.thoughtworks.gocd.elasticagent.azure.AzureInstance; +import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.requests.ShouldAssignWorkRequest; import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; - -import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.JOB_IDENTIFIER_TAG_KEY; public class ShouldAssignWorkRequestExecutor implements RequestExecutor { + private final AgentInstances agentInstances; private PluginSettings pluginSettings; private ServerHealthMessagingService serverHealthMessagingService; @@ -50,7 +49,7 @@ public GoPluginApiResponse execute() { return DefaultGoPluginApiResponse.success("false"); } - if (instance.canBeAssigned(request.elasticProfile())) { + if (instance.canBeAssigned(request.getClusterProfileProperties())) { agentInstances.addTag(pluginSettings, instance.getName(), JOB_IDENTIFIER_TAG_KEY, request.jobIdentifier().hash()); serverHealthMessagingService.clearHealthMessage(request.jobIdentifier().getJobRepresentation()); return DefaultGoPluginApiResponse.success("true"); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java index cc94abb..33adcd9 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/AgentStatusReportRequest.java @@ -19,11 +19,14 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; import com.thoughtworks.gocd.elasticagent.azure.AzureAgentInstances; +import com.thoughtworks.gocd.elasticagent.azure.ClusterProfileProperties; import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; import com.thoughtworks.gocd.elasticagent.azure.executors.AgentStatusReportExecutor; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.utils.TemplateReader; +import java.util.Map; import java.util.Objects; public class AgentStatusReportRequest { @@ -38,15 +41,20 @@ public class AgentStatusReportRequest { @Expose private JobIdentifier jobIdentifier; + @Expose + @SerializedName("cluster_profile_properties") + private ClusterProfileProperties clusterProfile; + @Expose private ClusterProfileProperties clusterProfileProperties; public AgentStatusReportRequest() { } - public AgentStatusReportRequest(String elasticAgentId, JobIdentifier jobIdentifier) { + public AgentStatusReportRequest(String elasticAgentId, JobIdentifier jobIdentifier, Map clusterProfileProperties) { this.elasticAgentId = elasticAgentId; this.jobIdentifier = jobIdentifier; + this.clusterProfile = ClusterProfileProperties.fromConfiguration(clusterProfileProperties); } public static AgentStatusReportRequest fromJSON(String json) { @@ -61,6 +69,10 @@ public JobIdentifier getJobIdentifier() { return jobIdentifier; } + public ClusterProfileProperties getClusterProfile() { + return clusterProfile; + } + public AgentStatusReportExecutor executor(PluginRequest pluginRequest, AzureAgentInstances agentInstances, TemplateReader templateReader) { return new AgentStatusReportExecutor(this, pluginRequest, agentInstances, templateReader); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java index 6055d2b..82ea263 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ClusterProfileValidateRequest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.requests; import com.google.gson.Gson; @@ -22,8 +21,6 @@ import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; import com.thoughtworks.gocd.elasticagent.azure.executors.ClusterProfileValidateRequestExecutor; -import com.thoughtworks.gocd.elasticagent.azure.validations.Validation; - import java.util.Map; public class ClusterProfileValidateRequest { @@ -35,7 +32,6 @@ public ClusterProfileValidateRequest(Map properties) { this.properties = properties; } - public Map getProperties() { return properties; } @@ -46,6 +42,6 @@ public static ClusterProfileValidateRequest fromJSON(String json) { } public RequestExecutor executor(PluginRequest pluginRequest, GoCDAzureClientFactory factory) { - return new ClusterProfileValidateRequestExecutor(this, pluginRequest, factory, Validation.ELASTIC_PROFILE_VALIDATIONS); + return new ClusterProfileValidateRequestExecutor(this); } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/CreateAgentRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/CreateAgentRequest.java index 6189e95..1b2630b 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/CreateAgentRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/CreateAgentRequest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.requests; import com.google.gson.FieldNamingPolicy; @@ -21,51 +20,53 @@ import com.google.gson.GsonBuilder; import com.google.gson.annotations.SerializedName; import com.thoughtworks.gocd.elasticagent.azure.AzureAgentInstances; +import com.thoughtworks.gocd.elasticagent.azure.ClusterProfileProperties; import com.thoughtworks.gocd.elasticagent.azure.Constants; import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.executors.CreateAgentRequestExecutor; -import com.thoughtworks.gocd.elasticagent.azure.models.ElasticProfile; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; -import org.apache.commons.lang3.StringUtils; - +import java.util.Map; import java.util.Properties; +import org.apache.commons.lang3.StringUtils; public class CreateAgentRequest { + private static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); @SerializedName("auto_register_key") private String autoRegisterKey; - @SerializedName("properties") - private ElasticProfile elasticProfile; - @SerializedName("environment") private String environment; @SerializedName("job_identifier") private JobIdentifier jobIdentifier; + private Map elasticAgentProfileProperties; + private ClusterProfileProperties clusterProfileProperties; - public CreateAgentRequest() { + public CreateAgentRequest(String autoRegisterKey, Map elasticAgentProfileProperties, String environment, JobIdentifier jobIdentifier, Map clusterProfileProperties) { + this.autoRegisterKey = autoRegisterKey; + this.elasticAgentProfileProperties = elasticAgentProfileProperties; + this.environment = environment; + this.jobIdentifier = jobIdentifier; + this.clusterProfileProperties = ClusterProfileProperties.fromConfiguration(clusterProfileProperties); } - public CreateAgentRequest(String autoRegisterKey, ElasticProfile elasticProfile, String environment, JobIdentifier jobIdentifier) { + public CreateAgentRequest(String autoRegisterKey, Map elasticAgentProfileProperties, String environment, JobIdentifier jobIdentifier, ClusterProfileProperties clusterProfileProperties) { this.autoRegisterKey = autoRegisterKey; - this.elasticProfile = elasticProfile; + this.elasticAgentProfileProperties = elasticAgentProfileProperties; this.environment = environment; this.jobIdentifier = jobIdentifier; + this.clusterProfileProperties = clusterProfileProperties; } public String autoRegisterKey() { return autoRegisterKey; } - public ElasticProfile elasticProfile() { - return elasticProfile; - } - public String environment() { return environment; } @@ -74,6 +75,14 @@ public JobIdentifier jobIdentifier() { return jobIdentifier; } + public Map properties() { + return elasticAgentProfileProperties; + } + + public ClusterProfileProperties getClusterProfileProperties() { + return clusterProfileProperties; + } + public static CreateAgentRequest fromJSON(String json) { return GSON.fromJson(json, CreateAgentRequest.class); } @@ -99,6 +108,4 @@ public Properties autoregisterProperties(String elasticAgentId) { return properties; } - - } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/JobCompletionRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/JobCompletionRequest.java index f3c8d55..13b2383 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/JobCompletionRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/JobCompletionRequest.java @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.requests; - import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -24,28 +22,49 @@ import com.google.gson.annotations.SerializedName; import com.thoughtworks.gocd.elasticagent.azure.AzureAgentInstances; import com.thoughtworks.gocd.elasticagent.azure.Clock; +import com.thoughtworks.gocd.elasticagent.azure.ClusterProfileProperties; import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.executors.JobCompletionRequestExecutor; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; +import java.util.Map; public class JobCompletionRequest { + private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); @Expose @SerializedName("elastic_agent_id") private String elasticAgentId; + @Expose @SerializedName("job_identifier") private JobIdentifier jobIdentifier; + @Expose + @SerializedName("elastic_agent_profile_properties") + private Map properties; + + @Expose + @SerializedName("cluster_profile_properties") + private ClusterProfileProperties clusterProfileProperties; + public JobCompletionRequest() { } - public JobCompletionRequest(String elasticAgentId, JobIdentifier jobIdentifier) { + public JobCompletionRequest(String elasticAgentId, JobIdentifier jobIdentifier, Map properties, Map clusterProfile) { this.elasticAgentId = elasticAgentId; this.jobIdentifier = jobIdentifier; + this.properties = properties; + this.clusterProfileProperties = ClusterProfileProperties.fromConfiguration(clusterProfile); + } + + public JobCompletionRequest(String elasticAgentId, JobIdentifier jobIdentifier, Map properties, ClusterProfileProperties clusterProfileProperties) { + this.elasticAgentId = elasticAgentId; + this.jobIdentifier = jobIdentifier; + this.properties = properties; + this.clusterProfileProperties = clusterProfileProperties; } public static JobCompletionRequest fromJSON(String json) { @@ -61,15 +80,25 @@ public JobIdentifier jobIdentifier() { return jobIdentifier; } + public ClusterProfileProperties getClusterProfileProperties() { + return clusterProfileProperties; + } + + public Map getProperties() { + return properties; + } + public RequestExecutor executor(AzureAgentInstances agentInstances, PluginRequest pluginRequest) { return new JobCompletionRequestExecutor(this, agentInstances, pluginRequest, Clock.DEFAULT); } @Override public String toString() { - return "JobCompletionRequest{" + - "elasticAgentId='" + elasticAgentId + '\'' + - ", jobIdentifierHash=" + jobIdentifier + - '}'; + return "JobCompletionRequest{" + + "elasticAgentId='" + elasticAgentId + '\'' + + ", jobIdentifier=" + jobIdentifier + + ", properties=" + properties + + ", clusterProfileProperties=" + clusterProfileProperties + + '}'; } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ShouldAssignWorkRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ShouldAssignWorkRequest.java index 4dc7a51..707c0e0 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ShouldAssignWorkRequest.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ShouldAssignWorkRequest.java @@ -13,36 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.requests; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.annotations.SerializedName; import com.thoughtworks.gocd.elasticagent.azure.*; import com.thoughtworks.gocd.elasticagent.azure.executors.ShouldAssignWorkRequestExecutor; -import com.thoughtworks.gocd.elasticagent.azure.models.ElasticProfile; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; +import java.util.Map; /** * Represents the {@link Request#REQUEST_SHOULD_ASSIGN_WORK} message. */ public class ShouldAssignWorkRequest { + public static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); private Agent agent; private String environment; private JobIdentifier jobIdentifier; + private Map properties; + private ClusterProfileProperties clusterProfileProperties; - @SerializedName("properties") - private ElasticProfile elasticProfile; - - public ShouldAssignWorkRequest(Agent agent, String environment, JobIdentifier jobIdentifier, ElasticProfile elasticProfile) { + public ShouldAssignWorkRequest(Agent agent, String environment, JobIdentifier jobIdentifier, Map properties, Map clusterProfileProperties) { this.agent = agent; this.environment = environment; this.jobIdentifier = jobIdentifier; - this.elasticProfile = elasticProfile; + this.properties = properties; + this.clusterProfileProperties = ClusterProfileProperties.fromConfiguration(clusterProfileProperties); } public ShouldAssignWorkRequest() { @@ -60,8 +59,12 @@ public JobIdentifier jobIdentifier() { return jobIdentifier; } - public ElasticProfile elasticProfile() { - return elasticProfile; + public Map properties() { + return properties; + } + + public ClusterProfileProperties getClusterProfileProperties() { + return clusterProfileProperties; } public static ShouldAssignWorkRequest fromJSON(String json) { From ad8e33c77e67fc13699936bc7b273e1ed5fe1407 Mon Sep 17 00:00:00 2001 From: Joel Strasser Date: Wed, 10 May 2023 22:38:37 +0200 Subject: [PATCH 4/5] rewrite and update requests --- .../elasticagent/azure/AgentInstances.java | 60 ++++++----- .../azure/AzureAgentInstances.java | 39 ++++--- .../gocd/elasticagent/azure/AzurePlugin.java | 35 +++--- .../azure/client/GoCDAzureClientFactory.java | 14 ++- .../executors/ServerPingRequestExecutor.java | 46 ++++---- .../azure/executors/StatusReportExecutor.java | 80 -------------- .../azure/models/ElasticProfile.java | 37 ++++--- .../azure/requests/ServerPingRequest.java | 74 +++++++++++++ .../gocd/elasticagent/azure/vm/VmConfig.java | 102 +++++++++--------- 9 files changed, 249 insertions(+), 238 deletions(-) delete mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/StatusReportExecutor.java create mode 100644 src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ServerPingRequest.java diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AgentInstances.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AgentInstances.java index 2473889..20a992d 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AgentInstances.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AgentInstances.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; import com.thoughtworks.gocd.elasticagent.azure.executors.ServerPingRequestExecutor; @@ -22,22 +21,24 @@ import com.thoughtworks.gocd.elasticagent.azure.models.ServerInfo; import com.thoughtworks.gocd.elasticagent.azure.models.StatusReport; import com.thoughtworks.gocd.elasticagent.azure.requests.CreateAgentRequest; - import java.io.IOException; - /** - * Plugin implementors should implement these methods to interface to your cloud. - * This interface is merely a suggestion for a very simple plugin. You may change it to your needs. + * Plugin implementors should implement these methods to interface to your + * cloud. This interface is merely a suggestion for a very simple plugin. You + * may change it to your needs. */ public interface AgentInstances { + /** * This message is sent to request creation of an agent instance. - * Implementations may, at their discretion choose to not spin up an agent instance. + * Implementations may, at their discretion choose to not spin up an agent + * instance. *

- * So that instances created are auto-registered with the server, the agent instance MUST have an - * autoregister.properties file. - * @param request the request object + * So that instances created are auto-registered with the server, the agent + * instance MUST have an autoregister.properties file. + * + * @param request the request object * @param settings   the plugin settings object * @param serverInfo the server info object */ @@ -46,7 +47,7 @@ public interface AgentInstances { /** * This message is sent when the plugin needs to terminate the agent instance. * - * @param agentId the elastic agent id + * @param agentId the elastic agent id * @param settings the plugin settings object */ void terminate(String agentId, PluginSettings settings) throws Exception; @@ -54,39 +55,43 @@ public interface AgentInstances { AzureInstance addTag(PluginSettings settings, String agentId, String tagName, String tagValue) throws IOException; /** - * This message is sent from the {@link ServerPingRequestExecutor} - * to terminate instances that did not register with the server after a timeout. The timeout may be configurable and - * set via the {@link PluginSettings} instance that is passed in. + * This message is sent from the {@link ServerPingRequestExecutor} to + * terminate instances that did not register with the server after a timeout. + * The timeout may be configurable and set via the {@link PluginSettings} + * instance that is passed in. * * @param settings the plugin settings object - * @param agents the list of all the agents + * @param agents the list of all the agents */ void terminateUnregisteredInstances(PluginSettings settings, Agents agents) throws Exception; /** - * This message is sent from the {@link ServerPingRequestExecutor} - * to filter out any new agents, that have registered before the timeout period. The timeout may be configurable and - * set via the {@link PluginSettings} instance that is passed in. + * This message is sent from the {@link ServerPingRequestExecutor} to filter + * out any new agents, that have registered before the timeout period. The + * timeout may be configurable and set via the {@link PluginSettings} instance + * that is passed in. * * @param settings the plugin settings object - * @param agents the list of all the agents - * @return a list of agent instances which were created after {@link PluginSettings#getAutoRegisterPeriod()} ago. + * @param agents the list of all the agents + * @return a list of agent instances which were created after + * {@link PluginSettings#getAutoRegisterPeriod()} ago. */ Agents instancesToBeDisabled(PluginSettings settings, Agents agents); /** - * This message is sent after plugin initialization time so that the plugin may connect to the cloud provider - * and fetch a list of all instances that have been spun up by this plugin (before the server was shut down). - * This call should be should ideally remember if the agent instances are refreshed, and do nothing if instances - * were previously refreshed. + * This message is sent after plugin initialization time so that the plugin + * may connect to the cloud provider and fetch a list of all instances that + * have been spun up by this plugin (before the server was shut down). This + * call should be should ideally remember if the agent instances are + * refreshed, and do nothing if instances were previously refreshed. * * @param pluginRequest the plugin request object */ - void refreshAll(PluginRequest pluginRequest) throws Exception; + void refreshAll(ClusterProfileProperties clusterProfileProperties) throws Exception; /** - * This - * Returns an agent instance with the specified id or null, if the agent is not found. + * This Returns an agent instance with the specified id or + * null, if the agent is not found. * * @param agentId the elastic agent id */ @@ -113,11 +118,10 @@ public interface AgentInstances { * Get the status report of an agent instance * * @param pluginSettings The plugin settings object - * @param agentInstance The agent instance + * @param agentInstance The agent instance * @return An AgentStatusReport object */ AgentStatusReport getAgentStatusReport(PluginSettings pluginSettings, T agentInstance); void removeTag(PluginSettings settings, String agentId, String tagName) throws Exception; } - diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureAgentInstances.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureAgentInstances.java index 04f6107..4076601 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureAgentInstances.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzureAgentInstances.java @@ -13,17 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure; +import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClient; import com.thoughtworks.gocd.elasticagent.azure.client.GoCDAzureClientFactory; import com.thoughtworks.gocd.elasticagent.azure.models.*; import com.thoughtworks.gocd.elasticagent.azure.requests.CreateAgentRequest; import com.thoughtworks.gocd.elasticagent.azure.utils.Util; -import org.joda.time.DateTime; -import org.joda.time.Period; - import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; @@ -31,8 +28,8 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; - -import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; +import org.joda.time.DateTime; +import org.joda.time.Period; public class AzureAgentInstances implements AgentInstances { @@ -62,7 +59,7 @@ public AzureInstance create(CreateAgentRequest request, PluginSettings settings, LOG.info(MessageFormat.format("Task is already scheduled on instance {0}.", instance.getName())); return instance; } - AzureInstance instanceByElasticProfile = findAvailableInstance(request.elasticProfile()); + AzureInstance instanceByElasticProfile = findAvailableInstance(request.getClusterProfileProperties()); if (instanceByElasticProfile != null) { LOG.info(MessageFormat.format("Instance {0} provisioned already with the same elastic profile.", instanceByElasticProfile.getName())); return instanceByElasticProfile; @@ -88,10 +85,10 @@ public AzureInstance addTag(PluginSettings settings, String agentId, String tagN LOG.info("Adding Tag {} to Agent {} with value {}", tagName, agentId, tagValue); GoCDAzureClient goCDAzureClient = clientFactory.initialize(settings); Optional.ofNullable(instances.get(agentId)) - .ifPresent(instance -> { - AzureInstance instanceWithTags = azureInstanceManager.addTag(goCDAzureClient, instance, tagName, tagValue); - register(instanceWithTags); - }); + .ifPresent(instance -> { + AzureInstance instanceWithTags = azureInstanceManager.addTag(goCDAzureClient, instance, tagName, tagValue); + register(instanceWithTags); + }); return instances.get(agentId); } @@ -100,10 +97,10 @@ public void removeTag(PluginSettings settings, String agentId, String tagName) t LOG.info("Removing Tag {} on Agent {}", tagName, agentId); GoCDAzureClient goCDAzureClient = clientFactory.initialize(settings); Optional.ofNullable(instances.get(agentId)) - .ifPresent(instance -> { - AzureInstance instanceWithoutTag = azureInstanceManager.removeTag(goCDAzureClient, instance, tagName); - register(instanceWithoutTag); - }); + .ifPresent(instance -> { + AzureInstance instanceWithoutTag = azureInstanceManager.removeTag(goCDAzureClient, instance, tagName); + register(instanceWithoutTag); + }); } @Override @@ -111,8 +108,8 @@ public void terminateUnregisteredInstances(PluginSettings settings, Agents agent List instancesToTerminate = unregisteredAfterTimeout(settings.getAutoRegisterPeriod(), agents); if (!instancesToTerminate.isEmpty()) { String instanceNames = String.join(",", instancesToTerminate.stream() - .map(AzureInstance::getName) - .collect(Collectors.toCollection(ArrayList::new))); + .map(AzureInstance::getName) + .collect(Collectors.toCollection(ArrayList::new))); LOG.warn("Terminating instances that did not register " + instanceNames); for (AzureInstance instance : instancesToTerminate) { terminate(instance.getName(), settings); @@ -139,10 +136,10 @@ private boolean isCreatedAfterAutoRegisterTimeout(PluginSettings settings, Azure } @Override - public void refreshAll(PluginRequest pluginRequest) throws Exception { - GoCDAzureClient goCDAzureClient = clientFactory.initialize(pluginRequest.getPluginSettings()); + public void refreshAll(ClusterProfileProperties clusterProfileProperties) throws Exception { + GoCDAzureClient goCDAzureClient = clientFactory.initialize(clusterProfileProperties); if (!refreshed) { - List instances = azureInstanceManager.listInstances(goCDAzureClient, pluginRequest.getServerInfo().getServerId()); + List instances = azureInstanceManager.listInstances(goCDAzureClient, clusterProfileProperties.getResourceGroup()); instances.forEach(instance -> register(instance)); refreshed = true; } @@ -166,7 +163,7 @@ public AzureInstance find(JobIdentifier jobIdentifier) { return instances.values().stream().filter((instance) -> instance.jobIdentifierMatches(jobIdentifier)).findFirst().orElse(null); } - public AzureInstance findAvailableInstance(ElasticProfile elasticProfile) { + public AzureInstance findAvailableInstance(ClusterProfileProperties elasticProfile) { return instances.values().stream().filter((instance) -> instance.canBeAssigned(elasticProfile)).findFirst().orElse(null); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java index 7289d4c..90f74fe 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/AzurePlugin.java @@ -69,18 +69,26 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe case REQUEST_SHOULD_ASSIGN_WORK: ShouldAssignWorkRequest shouldAssignWorkRequest = ShouldAssignWorkRequest.fromJSON(request.requestBody()); clusterProfileProperties = shouldAssignWorkRequest.getClusterProfileProperties(); - refreshInstances(); + refreshInstances(clusterProfileProperties); return ShouldAssignWorkRequest.fromJSON(request.requestBody()) .executor(agentInstances, clusterProfileProperties, serverHealthMessagingService) .execute(); case REQUEST_CREATE_AGENT: - refreshInstances(); - return CreateAgentRequest.fromJSON(request.requestBody()) + CreateAgentRequest createAgentRequest = CreateAgentRequest.fromJSON(request.requestBody()); + refreshInstances(createAgentRequest.getClusterProfileProperties()); + return createAgentRequest .executor(agentInstances, pluginRequest, requestFingerprintCache, serverHealthMessagingService) .execute(); case REQUEST_SERVER_PING: - refreshInstances(); - return new ServerPingRequestExecutor(agentInstances, pluginRequest, serverHealthMessagingService) + ServerPingRequest serverPingRequest = ServerPingRequest.fromJSON(request.requestBody()); + serverPingRequest.allClusterProfileProperties().forEach(x -> { + try { + refreshInstances(x); + } catch (Exception ex) { + LOG.error(null, ex); + } + }); + return new ServerPingRequestExecutor(ServerPingRequest.fromJSON(request.requestBody()), agentInstances, pluginRequest, serverHealthMessagingService) .execute(); case REQUEST_GET_ELASTIC_AGENT_PROFILE_METADATA: return new GetElasticAgentProfileMetadataExecutor() @@ -89,15 +97,17 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe return new GetElasticAgentProfileViewExecutor() .execute(); case REQUEST_JOB_COMPLETION: - refreshInstances(); - return JobCompletionRequest.fromJSON(request.requestBody()) + JobCompletionRequest jobCompletionRequest = JobCompletionRequest.fromJSON(request.requestBody()); + refreshInstances(jobCompletionRequest.getClusterProfileProperties()); + return jobCompletionRequest .executor(agentInstances, pluginRequest).execute(); case REQUEST_CAPABILITIES: return new GetCapabilitiesExecutor() .execute(); case REQUEST_AGENT_STATUS_REPORT: - refreshInstances(); - return AgentStatusReportRequest.fromJSON(request.requestBody()) + AgentStatusReportRequest agentStatusReportRequest = AgentStatusReportRequest.fromJSON(request.requestBody()); + refreshInstances(agentStatusReportRequest.getClusterProfile()); + return agentStatusReportRequest .executor(pluginRequest, agentInstances, TemplateReader.instance()).execute(); case REQUEST_GET_CLUSTER_PROFILE_METADATA: return new GetClusterProfileMetadataExecutor() @@ -108,9 +118,6 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe case REQUEST_VALIDATE_CLUSTER_PROFILE: return ClusterProfileValidateRequest.fromJSON(request.requestBody()) .executor(pluginRequest, clientFactory).execute(); - case REQUEST_PLUGIN_STATUS_REPORT: - return new StatusReportExecutor(pluginRequest, agentInstances, TemplateReader.instance()) - .execute(); default: throw new UnhandledRequestTypeException(request.requestName()); } @@ -127,8 +134,8 @@ public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRe } } - private void refreshInstances() throws Exception { - agentInstances.refreshAll(pluginRequest); + private void refreshInstances(ClusterProfileProperties clusterProfileProperties) throws Exception { + agentInstances.refreshAll(clusterProfileProperties); } @Override diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/client/GoCDAzureClientFactory.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/client/GoCDAzureClientFactory.java index 885e519..4a3c8e9 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/client/GoCDAzureClientFactory.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/client/GoCDAzureClientFactory.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.client; import com.microsoft.azure.AzureEnvironment; @@ -21,7 +20,6 @@ import com.microsoft.azure.management.Azure; import com.microsoft.rest.LogLevel; import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; - import java.io.IOException; public class GoCDAzureClientFactory { @@ -37,14 +35,14 @@ public GoCDAzureClient initialize(String clientId, String domain, String secret, protected GoCDAzureClient createClient(String clientId, String domain, String secret, String resourceGroup, String subscriptionID) { ApplicationTokenCredentials credentials = new ApplicationTokenCredentials(clientId, - domain, - secret, - AzureEnvironment.AZURE); + domain, + secret, + AzureEnvironment.AZURE); Azure azure = Azure.configure() - .withLogLevel(LogLevel.BASIC) - .authenticate(credentials) - .withSubscription(subscriptionID); + .withLogLevel(LogLevel.BASIC) + .authenticate(credentials) + .withSubscription(subscriptionID); return new GoCDAzureClient(azure, resourceGroup, new NetworkDecorator(azure)); } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ServerPingRequestExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ServerPingRequestExecutor.java index 7b29f97..b1c1ba8 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ServerPingRequestExecutor.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/ServerPingRequestExecutor.java @@ -13,26 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.executors; import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import com.thoughtworks.gocd.elasticagent.azure.*; +import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; import com.thoughtworks.gocd.elasticagent.azure.exceptions.ServerRequestFailedException; +import com.thoughtworks.gocd.elasticagent.azure.requests.ServerPingRequest; import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; - import java.util.Collection; - -import static com.thoughtworks.gocd.elasticagent.azure.AzurePlugin.LOG; +import java.util.List; public class ServerPingRequestExecutor implements RequestExecutor { + private final ServerPingRequest request; private final AzureAgentInstances agentInstances; private final PluginRequest pluginRequest; private ServerHealthMessagingService serverHealthMessagingService; - public ServerPingRequestExecutor(AzureAgentInstances agentInstances, PluginRequest pluginRequest, ServerHealthMessagingService serverHealthMessagingService) { + public ServerPingRequestExecutor(ServerPingRequest serverPingRequest, AzureAgentInstances agentInstances, PluginRequest pluginRequest, ServerHealthMessagingService serverHealthMessagingService) { + this.request = serverPingRequest; this.agentInstances = agentInstances; this.pluginRequest = pluginRequest; this.serverHealthMessagingService = serverHealthMessagingService; @@ -40,29 +41,32 @@ public ServerPingRequestExecutor(AzureAgentInstances agentInstances, PluginReque @Override public GoPluginApiResponse execute() throws Exception { - PluginSettings pluginSettings = pluginRequest.getPluginSettings(); + List pluginSettings = request.allClusterProfileProperties(); - Agents allAgents = pluginRequest.listAgents(); - Agents missingAgents = new Agents(); + for (ClusterProfileProperties clusterProfileProperties : pluginSettings) { + Agents allAgents = pluginRequest.listAgents(); + Agents missingAgents = new Agents(); - for (Agent agent : allAgents.agents()) { - if (agentInstances.find(agent.elasticAgentId()) == null) { - LOG.warn("Was expecting an instance with name " + agent.elasticAgentId() + ", but it was missing!"); - missingAgents.add(agent); + for (Agent agent : allAgents.agents()) { + if (agentInstances.find(agent.elasticAgentId()) == null) { + LOG.warn("Was expecting an instance with name " + agent.elasticAgentId() + ", but it was missing!"); + missingAgents.add(agent); + } } - } - Agents agentsToDisable = agentInstances.instancesToBeDisabled(pluginSettings, allAgents); - agentsToDisable.addAll(missingAgents); + Agents agentsToDisable = agentInstances.instancesToBeDisabled(clusterProfileProperties, allAgents); + agentsToDisable.addAll(missingAgents); - disableIdleAgents(agentsToDisable); + disableIdleAgents(agentsToDisable); - allAgents = pluginRequest.listAgents(); - terminateDisabledAgents(allAgents, pluginSettings); + allAgents = pluginRequest.listAgents(); + terminateDisabledAgents(allAgents, clusterProfileProperties); + + agentInstances.terminateUnregisteredInstances(clusterProfileProperties, allAgents); + agentInstances.terminateProvisionFailedInstances(clusterProfileProperties, pluginRequest.getServerInfo()); + serverHealthMessagingService.clearExpiredHealthMessages(); + } - agentInstances.terminateUnregisteredInstances(pluginSettings, allAgents); - agentInstances.terminateProvisionFailedInstances(pluginSettings, pluginRequest.getServerInfo()); - serverHealthMessagingService.clearExpiredHealthMessages(); return DefaultGoPluginApiResponse.success(""); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/StatusReportExecutor.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/StatusReportExecutor.java deleted file mode 100644 index 86cda8a..0000000 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/executors/StatusReportExecutor.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2020 Thoughtworks, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.thoughtworks.gocd.elasticagent.azure.executors; - -import com.google.gson.JsonObject; -import com.thoughtworks.go.plugin.api.logging.Logger; -import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; -import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; -import com.thoughtworks.gocd.elasticagent.azure.AzureAgentInstances; -import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; -import com.thoughtworks.gocd.elasticagent.azure.RequestExecutor; -import com.thoughtworks.gocd.elasticagent.azure.exceptions.PluginSettingsNotConfiguredException; -import com.thoughtworks.gocd.elasticagent.azure.models.StatusReport; -import com.thoughtworks.gocd.elasticagent.azure.utils.TemplateReader; - -import java.util.HashMap; -import java.util.Map; - -public class StatusReportExecutor implements RequestExecutor { - - public static final String STATUS_REPORT_TEMPLATE = "plugin-status-report.template.ftlh"; - public static final String ERROR_TEMPLATE = "error.template.ftlh"; - private final PluginRequest pluginRequest; - private final AzureAgentInstances agentInstances; - private static final Logger LOG = Logger.getLoggerFor(AgentStatusReportExecutor.class); - private final TemplateReader templateReader; - - public StatusReportExecutor(PluginRequest pluginRequest, AzureAgentInstances agentInstances, TemplateReader templateReader) { - this.pluginRequest = pluginRequest; - this.agentInstances = agentInstances; - this.templateReader = templateReader; - } - - @Override - public GoPluginApiResponse execute() throws Exception { - LOG.info("[status-report] Generating status report"); - try { - agentInstances.refreshAll(pluginRequest); - StatusReport statusReport = agentInstances.getStatusReport(pluginRequest.getPluginSettings()); - - final String statusReportView = templateReader.read(STATUS_REPORT_TEMPLATE, statusReport); - - return constructApiResponse(statusReportView); - } catch (PluginSettingsNotConfiguredException e) { - final String statusReportView = templateReader.read(ERROR_TEMPLATE, errorMessage("Unable to generate status report", "Azure Plugin not configured")); - return constructApiResponse(statusReportView); - } catch (Exception e) { - LOG.error("Failed to generate status report, {}", e.getMessage()); - final String statusReportView = templateReader.read(ERROR_TEMPLATE, errorMessage("Failed to generate status report", e.getMessage())); - return constructApiResponse(statusReportView); - } - } - - private Map errorMessage(String message, String description) { - return new HashMap(){{ - put("message", message); - put("description", description); - }}; - } - - private GoPluginApiResponse constructApiResponse(String statusReportView) { - JsonObject responseJSON = new JsonObject(); - responseJSON.addProperty("view", statusReportView); - return DefaultGoPluginApiResponse.success(responseJSON.toString()); - } -} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/models/ElasticProfile.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/models/ElasticProfile.java index 48160b7..f521e58 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/models/ElasticProfile.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/models/ElasticProfile.java @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.models; import com.google.gson.annotations.SerializedName; import com.microsoft.azure.management.compute.ImageReference; import com.microsoft.azure.management.compute.StorageAccountTypes; +import java.util.Map; +import java.util.Optional; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; import org.apache.commons.lang3.StringUtils; -import org.joda.time.Period; - -import java.util.Optional; - import static org.apache.commons.lang3.StringUtils.isBlank; +import org.joda.time.Period; @Getter @EqualsAndHashCode @@ -71,15 +69,16 @@ public class ElasticProfile { @SerializedName(SUBNET_NAME) private String subnetName; - public ElasticProfile() { } + public ElasticProfile() { + } public ElasticProfile(String vmSize, - String vmImageURN, - String customImageId, - String customScript, - Platform platform, - String osDiskStorageAccountType, - String idleTimeout, String osDiskSize, String subnet) { + String vmImageURN, + String customImageId, + String customScript, + Platform platform, + String osDiskStorageAccountType, + String idleTimeout, String osDiskSize, String subnet) { this.vmSize = vmSize; this.vmImageURN = vmImageURN; this.vmCustomImageId = customImageId; @@ -91,6 +90,10 @@ public ElasticProfile(String vmSize, this.subnetName = subnet; } + public ElasticProfile(Map properties) { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + public ImageReference getImageReference() { return isBlank(vmImageURN) ? null : new ImageURN(vmImageURN).toImageReference(); } @@ -103,7 +106,7 @@ public StorageAccountTypes getOsDiskStorageAccountType() { return isBlank(osDiskStorageAccountType) ? StorageAccountTypes.STANDARD_SSD_LRS : StorageAccountTypes.fromString(osDiskStorageAccountType); } - public Period getIdleTimeoutPeriod(){ + public Period getIdleTimeoutPeriod() { if (StringUtils.isNotBlank(this.idleTimeout)) { return new Period().withMinutes(Integer.parseInt(this.idleTimeout)); } @@ -117,4 +120,12 @@ public Optional getOsDiskSize() { public Optional getSubnetName() { return isBlank(subnetName) ? Optional.empty() : Optional.of(subnetName); } + + public String getIdleTimeout() { + return idleTimeout; + } + + public Platform getPlatform() { + return platform; + } } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ServerPingRequest.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ServerPingRequest.java new file mode 100644 index 0000000..0256de1 --- /dev/null +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/requests/ServerPingRequest.java @@ -0,0 +1,74 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package com.thoughtworks.gocd.elasticagent.azure.requests; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thoughtworks.gocd.elasticagent.azure.AzureAgentInstances; +import com.thoughtworks.gocd.elasticagent.azure.ClusterProfileProperties; +import com.thoughtworks.gocd.elasticagent.azure.PluginRequest; +import com.thoughtworks.gocd.elasticagent.azure.executors.ServerPingRequestExecutor; +import com.thoughtworks.gocd.elasticagent.azure.service.ServerHealthMessagingService; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * + * @author joestr + */ +public class ServerPingRequest { + + private static final Gson GSON = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); + private List allClusterProfileProperties = new ArrayList<>(); + + public ServerPingRequest() { + } + + public ServerPingRequest(List> allClusterProfileProperties) { + this.allClusterProfileProperties = allClusterProfileProperties.stream() + .map(ClusterProfileProperties::fromConfiguration) + .collect(Collectors.toList()); + } + + public List allClusterProfileProperties() { + return allClusterProfileProperties; + } + + public static ServerPingRequest fromJSON(String json) { + return GSON.fromJson(json, ServerPingRequest.class); + } + + @Override + public String toString() { + return "ServerPingRequest{" + + "allClusterProfileProperties=" + allClusterProfileProperties + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ServerPingRequest that = (ServerPingRequest) o; + return Objects.equals(allClusterProfileProperties, that.allClusterProfileProperties); + } + + @Override + public int hashCode() { + return Objects.hash(allClusterProfileProperties); + } + + public ServerPingRequestExecutor executor(AzureAgentInstances agentInstances, PluginRequest pluginRequest, ServerHealthMessagingService serverHealthMessagingService) { + return new ServerPingRequestExecutor(this, agentInstances, pluginRequest, serverHealthMessagingService); + } +} diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java index 285b675..3d67115 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.thoughtworks.gocd.elasticagent.azure.vm; import com.microsoft.azure.management.compute.ImageReference; @@ -21,23 +20,21 @@ import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.thoughtworks.gocd.elasticagent.azure.AgentConfig; +import static com.thoughtworks.gocd.elasticagent.azure.Constants.DEFAULT_GO_SERVER_VERSION; import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.models.ElasticProfile; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.models.Platform; +import static com.thoughtworks.gocd.elasticagent.azure.models.Platform.LINUX; import com.thoughtworks.gocd.elasticagent.azure.models.ServerInfo; import com.thoughtworks.gocd.elasticagent.azure.requests.CreateAgentRequest; -import lombok.Getter; -import org.apache.commons.lang3.StringUtils; - +import static com.thoughtworks.gocd.elasticagent.azure.utils.Util.uniqueString; +import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.*; import java.util.HashMap; import java.util.Map; import java.util.Optional; - -import static com.thoughtworks.gocd.elasticagent.azure.Constants.DEFAULT_GO_SERVER_VERSION; -import static com.thoughtworks.gocd.elasticagent.azure.models.Platform.LINUX; -import static com.thoughtworks.gocd.elasticagent.azure.utils.Util.uniqueString; -import static com.thoughtworks.gocd.elasticagent.azure.vm.VMTags.*; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; @Getter public class VmConfig { @@ -69,26 +66,26 @@ public String toString() { String imageReferenceString = ""; if (imageReference != null) { imageReferenceString = String.format("{publisher:%s,offer:%s,sku:%s,version:%s}", - imageReference.publisher(), - imageReference.offer(), - imageReference.sku(), - imageReference.version()); + imageReference.publisher(), + imageReference.offer(), + imageReference.sku(), + imageReference.version()); } - return "VmConfig{" + - "agentConfig=" + agentConfig + - ", region=" + region + - ", resourceGroup='" + resourceGroup + '\'' + - ", networkId='" + networkId + '\'' + - ", UserName='" + userName + '\'' + - ", subnet='" + subnet + '\'' + - ", name='" + name + '\'' + - ", size='" + size + '\'' + - ", osDiskStorageAccountType='" + osDiskStorageAccountType + '\'' + - ", osDiskSize='" + (osDiskSize.isPresent() ? osDiskSize.get() : "") + '\'' + - ", customImageId=" + customImageId + - ", imageReference=" + imageReferenceString + - ", tags=" + tags + - '}'; + return "VmConfig{" + + "agentConfig=" + agentConfig + + ", region=" + region + + ", resourceGroup='" + resourceGroup + '\'' + + ", networkId='" + networkId + '\'' + + ", UserName='" + userName + '\'' + + ", subnet='" + subnet + '\'' + + ", name='" + name + '\'' + + ", size='" + size + '\'' + + ", osDiskStorageAccountType='" + osDiskStorageAccountType + '\'' + + ", osDiskSize='" + (osDiskSize.isPresent() ? osDiskSize.get() : "") + '\'' + + ", customImageId=" + customImageId + + ", imageReference=" + imageReferenceString + + ", tags=" + tags + + '}'; } // ToDo: Find server version, check vm name limit, How to specify Custom image id ? @@ -96,7 +93,7 @@ public String toString() { this.name = uniqueString(VM_NAME_PREFIX); this.environment = builder.environment; this.agentConfig = new AgentConfig(builder.goServerUrl, builder.autoregisterKey, builder.serverVersion, - this.environment, this.name); + this.environment, this.name); this.region = builder.region; this.resourceGroup = builder.resourceGroup; this.networkId = builder.networkId; @@ -162,7 +159,7 @@ public VmConfig build() { this.environment = Optional.ofNullable(request.environment()).orElse(""); this.autoregisterKey = request.autoRegisterKey(); - ElasticProfile elasticProfile = request.elasticProfile(); + ElasticProfile elasticProfile = new ElasticProfile(request.properties()); this.subnet = getSubnetName(elasticProfile); this.size = getSize(elasticProfile); this.imageReference = getImageReference(elasticProfile); @@ -175,10 +172,9 @@ public VmConfig build() { //overrides this.userName = LINUX.equals(platform) ? settings.getLinuxUserName() : settings.getWindowsUserName(); - tags.put(ENVIRONMENT_TAG_KEY, environment); if (elasticProfile != null) { - tags.put(ELASTIC_PROFILE_TAG_KEY, request.elasticProfile().hash()); + tags.put(ELASTIC_PROFILE_TAG_KEY, request.getClusterProfileProperties().hash()); } tags.put(IDLE_TIMEOUT, String.format("%s", getEffectiveIdleTimeoutPeriodInMins(elasticProfile, settings))); return new VmConfig(this); @@ -186,20 +182,20 @@ public VmConfig build() { private String getSubnetName(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .flatMap(ElasticProfile::getSubnetName) - .orElse(settings.getRandomSubnet()); + .flatMap(ElasticProfile::getSubnetName) + .orElse(settings.getRandomSubnet()); } private Optional getOsDiskSize(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getOsDiskSize) - .orElse(Optional.empty()); + .map(ElasticProfile::getOsDiskSize) + .orElse(Optional.empty()); } private StorageAccountTypes getOSDiskStorageAccountType(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getOsDiskStorageAccountType) - .orElse(StorageAccountTypes.STANDARD_SSD_LRS); + .map(ElasticProfile::getOsDiskStorageAccountType) + .orElse(StorageAccountTypes.STANDARD_SSD_LRS); } public Builder setRequestParams(CreateAgentRequest request) { @@ -220,41 +216,41 @@ public Builder setServerInfoParams(ServerInfo serverInfo) { private int getEffectiveIdleTimeoutPeriodInMins(ElasticProfile elasticProfile, PluginSettings settings) { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getIdleTimeoutPeriod) - .orElse(settings.getIdleTimeoutPeriod()) - .getMinutes(); + .map(ElasticProfile::getIdleTimeoutPeriod) + .orElse(settings.getIdleTimeoutPeriod()) + .getMinutes(); } - private String getCustomImageId(ElasticProfile elasticProfile){ + private String getCustomImageId(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getVmCustomImageId) - .orElse(""); + .map(ElasticProfile::getVmCustomImageId) + .orElse(""); } private Platform getPlatform(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(profile -> Optional.ofNullable(profile.getPlatform()).orElse(LINUX)) - .orElse(LINUX); + .map(profile -> Optional.ofNullable(profile.getPlatform()).orElse(LINUX)) + .orElse(LINUX); } private String getCustomScript(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(profile -> StringUtils.defaultIfEmpty(profile.getCustomScript(), "").trim()) - .orElse(""); + .map(profile -> StringUtils.defaultIfEmpty(profile.getCustomScript(), "").trim()) + .orElse(""); } private String getSize(ElasticProfile elasticProfile) { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getVmSize) - .filter(s -> !s.isEmpty()) - .orElse(VirtualMachineSizeTypes.STANDARD_D3_V2.toString()); + .map(ElasticProfile::getVmSize) + .filter(s -> !s.isEmpty()) + .orElse(VirtualMachineSizeTypes.STANDARD_D3_V2.toString()); } private ImageReference getImageReference(ElasticProfile elasticProfile) { try { return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getImageReference) - .orElse(null); + .map(ElasticProfile::getImageReference) + .orElse(null); } catch (IllegalArgumentException e) { return null; } From 3a415d87920202f457bcd4e42987967bdd49b88d Mon Sep 17 00:00:00 2001 From: Joel Strasser Date: Thu, 11 May 2023 23:09:13 +0200 Subject: [PATCH 5/5] use request for VmConfig --- .../gocd/elasticagent/azure/vm/VmConfig.java | 99 +++++-------------- 1 file changed, 24 insertions(+), 75 deletions(-) diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java index 3d67115..2a4077d 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/azure/vm/VmConfig.java @@ -17,12 +17,12 @@ import com.microsoft.azure.management.compute.ImageReference; import com.microsoft.azure.management.compute.StorageAccountTypes; -import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.thoughtworks.gocd.elasticagent.azure.AgentConfig; import static com.thoughtworks.gocd.elasticagent.azure.Constants.DEFAULT_GO_SERVER_VERSION; import com.thoughtworks.gocd.elasticagent.azure.PluginSettings; import com.thoughtworks.gocd.elasticagent.azure.models.ElasticProfile; +import com.thoughtworks.gocd.elasticagent.azure.models.ImageURN; import com.thoughtworks.gocd.elasticagent.azure.models.JobIdentifier; import com.thoughtworks.gocd.elasticagent.azure.models.Platform; import static com.thoughtworks.gocd.elasticagent.azure.models.Platform.LINUX; @@ -35,6 +35,8 @@ import java.util.Optional; import lombok.Getter; import org.apache.commons.lang3.StringUtils; +import static org.apache.commons.lang3.StringUtils.isBlank; +import org.joda.time.Period; @Getter public class VmConfig { @@ -159,50 +161,27 @@ public VmConfig build() { this.environment = Optional.ofNullable(request.environment()).orElse(""); this.autoregisterKey = request.autoRegisterKey(); - ElasticProfile elasticProfile = new ElasticProfile(request.properties()); - this.subnet = getSubnetName(elasticProfile); - this.size = getSize(elasticProfile); - this.imageReference = getImageReference(elasticProfile); - this.customImageId = getCustomImageId(elasticProfile); - this.osDiskStorageAccountType = getOSDiskStorageAccountType(elasticProfile); - this.osDiskSize = getOsDiskSize(elasticProfile); - this.customScript = getCustomScript(elasticProfile); - this.platform = getPlatform(elasticProfile); + this.subnet = request.properties().get(ElasticProfile.SUBNET_NAME); + this.size = request.properties().get(ElasticProfile.VM_SIZE); + this.imageReference = new ImageURN(request.properties().get(ElasticProfile.VM_IMAGE_URN)).toImageReference(); + this.customImageId = request.properties().get(ElasticProfile.VM_CUSTOM_IMAGE_ID); + this.osDiskStorageAccountType + = isBlank(request.properties().get(ElasticProfile.OS_DISK_STORAGE_ACCOUNT_TYPE)) + ? StorageAccountTypes.STANDARD_SSD_LRS + : StorageAccountTypes.fromString(request.properties().get(ElasticProfile.OS_DISK_STORAGE_ACCOUNT_TYPE)); + this.osDiskSize = isBlank(request.properties().get(ElasticProfile.OS_DISK_SIZE)) ? Optional.empty() : Optional.of(Integer.valueOf(request.properties().get(ElasticProfile.OS_DISK_SIZE))); + this.customScript = request.properties().get(ElasticProfile.SUBNET_NAME); + this.platform = Platform.valueOf(request.properties().get(ElasticProfile.PLATFORM)); this.jobIdentifier = request.jobIdentifier(); //overrides this.userName = LINUX.equals(platform) ? settings.getLinuxUserName() : settings.getWindowsUserName(); tags.put(ENVIRONMENT_TAG_KEY, environment); - if (elasticProfile != null) { - tags.put(ELASTIC_PROFILE_TAG_KEY, request.getClusterProfileProperties().hash()); - } - tags.put(IDLE_TIMEOUT, String.format("%s", getEffectiveIdleTimeoutPeriodInMins(elasticProfile, settings))); + tags.put(ELASTIC_PROFILE_TAG_KEY, request.getClusterProfileProperties().hash()); + tags.put(IDLE_TIMEOUT, String.format("%s", getIdleTimeoutPeriod(request.properties().get(ElasticProfile.IDLE_TIMEOUT)))); return new VmConfig(this); } - private String getSubnetName(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .flatMap(ElasticProfile::getSubnetName) - .orElse(settings.getRandomSubnet()); - } - - private Optional getOsDiskSize(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getOsDiskSize) - .orElse(Optional.empty()); - } - - private StorageAccountTypes getOSDiskStorageAccountType(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getOsDiskStorageAccountType) - .orElse(StorageAccountTypes.STANDARD_SSD_LRS); - } - - public Builder setRequestParams(CreateAgentRequest request) { - this.request = request; - return this; - } - public Builder setSettingsParams(PluginSettings settings) { this.settings = settings; return this; @@ -214,46 +193,16 @@ public Builder setServerInfoParams(ServerInfo serverInfo) { return this; } - private int getEffectiveIdleTimeoutPeriodInMins(ElasticProfile elasticProfile, PluginSettings settings) { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getIdleTimeoutPeriod) - .orElse(settings.getIdleTimeoutPeriod()) - .getMinutes(); - } - - private String getCustomImageId(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getVmCustomImageId) - .orElse(""); - } - - private Platform getPlatform(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(profile -> Optional.ofNullable(profile.getPlatform()).orElse(LINUX)) - .orElse(LINUX); - } - - private String getCustomScript(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(profile -> StringUtils.defaultIfEmpty(profile.getCustomScript(), "").trim()) - .orElse(""); - } - - private String getSize(ElasticProfile elasticProfile) { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getVmSize) - .filter(s -> !s.isEmpty()) - .orElse(VirtualMachineSizeTypes.STANDARD_D3_V2.toString()); + public Period getIdleTimeoutPeriod(String idleTimeout) { + if (StringUtils.isNotBlank(idleTimeout)) { + return new Period().withMinutes(Integer.parseInt(idleTimeout)); + } + return null; } - private ImageReference getImageReference(ElasticProfile elasticProfile) { - try { - return Optional.ofNullable(elasticProfile) - .map(ElasticProfile::getImageReference) - .orElse(null); - } catch (IllegalArgumentException e) { - return null; - } + public Builder setRequestParams(CreateAgentRequest request) { + this.request = request; + return this; } } }