Skip to content

Commit ee281ec

Browse files
committed
Add v3 of agents API to render (read-only) elastic agent attributes
1 parent 3d514c1 commit ee281ec

File tree

23 files changed

+1274
-21
lines changed

23 files changed

+1274
-21
lines changed

common/src/com/thoughtworks/go/domain/AgentInstance.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.thoughtworks.go.domain;
1818

1919
import com.thoughtworks.go.config.AgentConfig;
20+
import com.thoughtworks.go.config.Resource;
2021
import com.thoughtworks.go.config.Resources;
2122
import com.thoughtworks.go.remote.AgentIdentifier;
2223
import com.thoughtworks.go.security.Registration;
@@ -48,6 +49,7 @@ public class AgentInstance implements Comparable<AgentInstance> {
4849
private volatile Date lastHeardTime;
4950
private TimeProvider timeProvider;
5051
private SystemEnvironment systemEnvironment;
52+
private ConfigErrors errors;
5153

5254
protected AgentInstance(AgentConfig agentConfig, AgentType agentType, SystemEnvironment systemEnvironment) {
5355
this.systemEnvironment = systemEnvironment;
@@ -347,6 +349,12 @@ public static AgentInstance createFromConfig(AgentConfig agentInConfig,
347349
AgentType type = agentInConfig.isFromLocalHost() ? AgentType.LOCAL : AgentType.REMOTE;
348350
AgentInstance result = new AgentInstance(agentInConfig, type, systemEnvironment);
349351
result.agentConfigStatus = agentInConfig.isDisabled() ? AgentConfigStatus.Disabled : AgentConfigStatus.Enabled;
352+
353+
result.errors = new ConfigErrors();
354+
result.errors.addAll(agentInConfig.errors());
355+
for (Resource resource : agentInConfig.getResources()) {
356+
result.errors.addAll(resource.errors());
357+
}
350358
return result;
351359
}
352360

@@ -368,6 +376,10 @@ public static AgentInstance createFromLiveAgent(AgentRuntimeInfo agentRuntimeInf
368376
return instance;
369377
}
370378

379+
public ConfigErrors errors() {
380+
return errors;
381+
}
382+
371383
public boolean equals(Object that) {
372384
if (this == that) { return true; }
373385
if (that == null) { return false; }

common/test/unit/com/thoughtworks/go/helper/AgentInstanceMother.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ public static AgentInstance updateHostname(AgentInstance agentInstance, String h
143143
return agentInstance;
144144
}
145145

146+
public static AgentInstance updateElasticAgentId(AgentInstance agentInstance, String elasticAgentId) {
147+
AgentConfig agentConfig = agentInstance.agentConfig();
148+
agentConfig.setElasticAgentId(elasticAgentId);
149+
150+
agentInstance.syncConfig(agentConfig);
151+
return agentInstance;
152+
}
153+
154+
public static AgentInstance updateElasticPluginId(AgentInstance agentInstance, String elasticPluginId) {
155+
AgentConfig agentConfig = agentInstance.agentConfig();
156+
agentConfig.setElasticPluginId(elasticPluginId);
157+
158+
agentInstance.syncConfig(agentConfig);
159+
return agentInstance;
160+
}
161+
146162
public static AgentInstance updateRuntimeStatus(AgentInstance agentInstance, AgentRuntimeStatus status) {
147163
AgentConfig agentConfig = agentInstance.agentConfig();
148164
AgentRuntimeInfo newRuntimeInfo = AgentRuntimeInfo.fromServer(agentConfig, true, agentInstance.getLocation(), agentInstance.getUsableSpace(), "linux", false);

server/src/com/thoughtworks/go/server/service/AgentService.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@
5050
import java.io.FileInputStream;
5151
import java.io.FileNotFoundException;
5252
import java.io.InputStream;
53-
import java.util.ArrayList;
54-
import java.util.List;
53+
import java.util.*;
5554

5655
import static java.lang.String.format;
5756

@@ -118,10 +117,19 @@ public List<String> getUniqueAgentOperatingSystems() {
118117
return new ArrayList<>(agentInstances.getAllOperatingSystems());
119118
}
120119

120+
@Deprecated // used by old code, stop using AgentViewModel
121121
public AgentsViewModel agents() {
122122
return toAgentViewModels(agentInstances.allAgents());
123123
}
124124

125+
public Map<AgentInstance, Collection<String>> agentEnvironmentMap() {
126+
Map<AgentInstance, Collection<String>> allAgents = new LinkedHashMap<>();
127+
for (AgentInstance agentInstance : agentInstances.allAgents()) {
128+
allAgents.put(agentInstance, environmentConfigService.environmentsFor(agentInstance.getUuid()));
129+
}
130+
return allAgents;
131+
}
132+
125133
public AgentsViewModel registeredAgents() {
126134
return toAgentViewModels(agentInstances.findRegisteredAgents());
127135
}
@@ -171,8 +179,9 @@ public AgentInstance updateAgentAttributes(Username username, HttpOperationResul
171179
}
172180

173181
AgentConfig agentConfig = agentConfigService.updateAgentAttributes(uuid, username, newHostname, resources, environments, enable, agentInstances, result);
174-
if (agentConfig != null)
182+
if (agentConfig != null) {
175183
return AgentInstance.createFromConfig(agentConfig, systemEnvironment);
184+
}
176185
return null;
177186
}
178187

@@ -228,7 +237,7 @@ public void deleteAgents(Username username, HttpOperationResult operationResult,
228237
return;
229238
}
230239
List<AgentInstance> agents = new ArrayList<>();
231-
if (!populateAgentInstancesForUUIDs(operationResult, uuids, agents)){
240+
if (!populateAgentInstancesForUUIDs(operationResult, uuids, agents)) {
232241
return;
233242
}
234243

server/src/com/thoughtworks/go/server/ui/AgentViewModel.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,6 +28,7 @@
2828
/**
2929
* @understands agent information for the UI
3030
*/
31+
@Deprecated
3132
public class AgentViewModel implements Comparable<AgentViewModel>{
3233
static final String MISSING_AGENT_BOOTSTRAPPER_VERSION = "Unknown";
3334
static final String OLDER_AGENT_BOOTSTRAPPER_VERSION = "Older";

server/src/com/thoughtworks/go/server/ui/AgentsViewModel.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,33 @@
1-
/*************************GO-LICENSE-START*********************************
2-
* Copyright 2014 ThoughtWorks, Inc.
1+
/*
2+
* Copyright 2016 ThoughtWorks, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
15-
*************************GO-LICENSE-END***********************************/
15+
*/
1616

1717
package com.thoughtworks.go.server.ui;
1818

19-
import java.util.Arrays;
20-
import java.util.Collection;
21-
import java.util.Collections;
22-
import java.util.Comparator;
23-
import java.util.HashMap;
24-
import java.util.Map;
25-
2619
import com.thoughtworks.go.domain.AgentStatus;
2720
import com.thoughtworks.go.domain.BaseCollection;
2821
import com.thoughtworks.go.util.StringUtil;
2922
import org.apache.commons.collections.CollectionUtils;
3023
import org.apache.commons.collections.Predicate;
3124

25+
import java.util.*;
26+
3227
/**
3328
* @understands collection of agents view model
3429
*/
30+
@Deprecated
3531
public class AgentsViewModel extends BaseCollection<AgentViewModel> {
3632

3733
private static final String RESOURCE = "resource";

server/webapp/WEB-INF/rails.new/app/controllers/api_v2/agents_controller.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,17 @@ def set_cache_control
9797
response.headers['Cache-Control'] = 'private, must-revalidate'
9898
end
9999

100+
private
101+
100102
attr_reader :agent_instance
101103

102104
def to_enabled_tristate
103105
enabled = params[:agent_config_state]
104106
if enabled.blank?
105107
TriState.UNSET
106-
elsif enabled =~ /enabled/i
108+
elsif enabled =~ /\Aenabled\Z/i
107109
TriState.TRUE
108-
elsif enabled =~ /disabled/i
110+
elsif enabled =~ /\Adisabled\Z/i
109111
TriState.FALSE
110112
else
111113
raise BadRequest.new('The value of `agent_config_state` can be one of `Enabled`, `Disabled` or null.')

server/webapp/WEB-INF/rails.new/app/controllers/api_v2/base_controller.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,11 @@ def to_tristate(var)
6666
end
6767

6868
def render_http_operation_result(result, data = {})
69+
status = result.httpCode()
6970
if result.instance_of?(HttpOperationResult)
70-
render json_hal_v2: { message: result.detailedMessage().strip }.merge(data), status: result.httpCode()
71+
render_message(result.detailedMessage(), status, data)
7172
else
72-
render json_hal_v2: { message: result.message(Spring.bean('localizer')).strip }.merge(data), status: result.httpCode()
73+
render_message(result.message(Spring.bean('localizer')), status, data)
7374
end
7475
end
7576

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
##########################################################################
2+
# Copyright 2016 ThoughtWorks, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
##########################################################################
16+
17+
module ApiV3
18+
class AgentsController < ApiV3::BaseController
19+
20+
before_action :set_cache_control
21+
before_action :check_user_and_404
22+
before_action :check_admin_user_and_401, except: [:index, :show]
23+
before_action :set_default_values_if_not_present, only: [:bulk_update]
24+
before_action :load_agent, only: [:show, :edit, :update, :destroy, :enable, :disable]
25+
26+
def index
27+
presenters = AgentsRepresenter.new(agent_service.agentEnvironmentMap)
28+
response_hash = presenters.to_hash(url_builder: self)
29+
30+
if stale?(etag: Digest::MD5.hexdigest(JSON.generate(response_hash)))
31+
render DEFAULT_FORMAT => response_hash
32+
end
33+
end
34+
35+
def show
36+
render DEFAULT_FORMAT => agent_presenter.to_hash(url_builder: self)
37+
end
38+
39+
def update
40+
result = HttpOperationResult.new
41+
42+
@agent_instance = agent_service.updateAgentAttributes(current_user, result, params[:uuid], params[:hostname], maybe_join(params[:resources]), maybe_join(params[:environments]), to_enabled_tristate)
43+
44+
if result.isSuccess
45+
load_agent
46+
render DEFAULT_FORMAT => agent_presenter.to_hash(url_builder: self)
47+
else
48+
json = agent_presenter.to_hash(url_builder: self)
49+
render_http_operation_result(result, { data: json })
50+
end
51+
end
52+
53+
def destroy
54+
result = HttpOperationResult.new
55+
agent_service.deleteAgents(current_user, result, [params[:uuid]])
56+
render_http_operation_result(result)
57+
end
58+
59+
def bulk_update
60+
result = HttpLocalizedOperationResult.new
61+
uuids = params[:uuids]
62+
resources_to_add = params[:operations][:resources][:add]
63+
resources_to_remove = params[:operations][:resources][:remove]
64+
environments_to_add = params[:operations][:environments][:add]
65+
environment_to_remove = params[:operations][:environments][:remove]
66+
agent_service.bulkUpdateAgentAttributes(current_user, result, uuids, resources_to_add, resources_to_remove, environments_to_add, environment_to_remove, to_enabled_tristate)
67+
render_http_operation_result(result)
68+
end
69+
70+
def bulk_destroy
71+
result = HttpOperationResult.new
72+
agent_service.deleteAgents(current_user, result, Array.wrap(params[:uuids]))
73+
render_http_operation_result(result)
74+
end
75+
76+
private
77+
78+
def set_default_values_if_not_present
79+
params[:uuids] = params[:uuids] || []
80+
params[:operations] = params[:operations] || {}
81+
params[:operations][:resources] = params[:operations][:resources] || {}
82+
params[:operations][:environments] = params[:operations][:environments] || {}
83+
params[:operations][:resources][:add] = params[:operations][:resources][:add] || []
84+
params[:operations][:resources][:remove] = params[:operations][:resources][:remove] || []
85+
params[:operations][:environments][:add] = params[:operations][:environments][:add] || []
86+
params[:operations][:environments][:remove] = params[:operations][:environments][:remove] || []
87+
end
88+
89+
def maybe_join(obj)
90+
if obj.is_a?(Array)
91+
obj.join(',')
92+
else
93+
obj
94+
end
95+
end
96+
97+
def set_cache_control
98+
response.headers['Cache-Control'] = 'private, must-revalidate'
99+
end
100+
101+
private
102+
103+
attr_reader :agent_instance
104+
105+
def to_enabled_tristate
106+
enabled = params[:agent_config_state]
107+
if enabled.blank?
108+
TriState.UNSET
109+
elsif enabled =~ /\Aenabled\Z/i
110+
TriState.TRUE
111+
elsif enabled =~ /\Adisabled\Z/i
112+
TriState.FALSE
113+
else
114+
raise BadRequest.new('The value of `agent_config_state` can be one of `Enabled`, `Disabled` or null.')
115+
end
116+
end
117+
118+
def load_agent
119+
@agent_instance = agent_service.findAgent(params[:uuid])
120+
raise RecordNotFound if @agent_instance.nil? || @agent_instance.isNullAgent()
121+
end
122+
123+
def agent_presenter
124+
AgentRepresenter.new([@agent_instance, environment_config_service.environmentsFor(@agent_instance.getUuid())])
125+
end
126+
127+
end
128+
129+
end

0 commit comments

Comments
 (0)