Skip to content

Commit

Permalink
Merge pull request #202 from mawinter69/JENKINS-63528
Browse files Browse the repository at this point in the history
[JENKINS-63528] add possibility to check for regex of agent roles
  • Loading branch information
mawinter69 authored Jul 3, 2022
2 parents 8596733 + 263f564 commit ed5445d
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,29 @@ public void doGetMatchingJobs(@QueryParameter(required = true) String pattern,
writer.close();
}

/**
* API method to get a list of agents matching a pattern
* Example: curl -X GET localhost:8080/role-strategy/strategy/getMatchingAgents?pattern=^linux.*
*
* @param pattern Pattern to match against
* @param maxAgents Maximum matching agents to search for
* @throws IOException when unable to write response
*/
@GET
@Restricted(NoExternalUse.class)
public void doGetMatchingAgents(@QueryParameter(required = true) String pattern,
@QueryParameter() int maxAgents) throws IOException {
checkAdminPerm();
List<String> matchingAgents = RoleMap.getMatchingAgentNames(Pattern.compile(pattern), maxAgents);
JSONObject responseJson = new JSONObject();
responseJson.put("matchingAgents", matchingAgents);
StaplerResponse response = Stapler.getCurrentResponse();
response.setContentType("application/json;charset=UTF-8");
Writer writer = response.getCompressedWriter(Stapler.getCurrentRequest());
responseJson.write(writer);
writer.close();
}

@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Node;
import hudson.model.User;
import hudson.security.AccessControlled;
import hudson.security.Permission;
Expand Down Expand Up @@ -439,6 +440,23 @@ public static List<String> getMatchingJobNames(Pattern pattern, int maxJobs) {
return matchingJobNames;
}

/**
* Get all agent names matching the given pattern, viewable to the requesting user
* @param pattern Pattern to match against
* @param maxAgents Max matching agents to look for
* @return List of matching agent names
*/
public static List<String> getMatchingAgentNames(Pattern pattern, int maxAgents) {
List<String> matchingAgentNames = new ArrayList<>();
for (Node node: Jenkins.get().getNodes()) {
if (pattern.matcher(node.getNodeName()).matches()) {
matchingAgentNames.add(node.getNodeName());
if (matchingAgentNames.size() >= maxAgents) break;
}
}
return matchingAgentNames;
}

/**
* The Acl class that will delegate the permission check to the {@link RoleMap} object.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@
var child = copy.childNodes[1];
var doubleQuote = '"';
child.innerHTML = escapeHTML(name);
child.next().innerHTML = doubleQuote + escapeHTML(pattern) + doubleQuote;
var patternString = doubleQuote + escapeHTML(pattern) + doubleQuote;
child.next().innerHTML = '<a href="#" class="patternAnchor">' + patternString + '</a>';

var hidden = document.createElement('input');
hidden.setAttribute('name', '[pattern]');
Expand All @@ -185,6 +186,10 @@
item.outerHTML = item.outerHTML.replace("{{ROLE}}", doubleEscapeHTML(name)).replace("{{PATTERN}}", doubleEscapeHTML(pattern));
});

child = copy.childNodes[1];
var link = child.next().children[0];
bindAgentListenerToPattern(link);

<j:if test="${nbAgentRoles lt 20}">
table.appendChild(copy);
</j:if>
Expand All @@ -196,8 +201,62 @@
});
})();

var bindAgentListenerToPattern = function(elem) {
elem.addEventListener('click', showMatchingAgents);
}

var showMatchingAgents = function() {
var pattern = this.text.substring(1, this.text.length - 1); // Ignore quotes for the pattern
var maxAgents = 10; // Maximum agents to search for
var url = 'strategy/getMatchingAgents';
reqParams = {
'pattern' : pattern,
'maxAgents' : maxAgents
}

new Ajax.Request(url, {
method: 'get',
parameters: reqParams,
onSuccess: function(req) {
var matchingAgents = req.responseText.evalJSON().matchingAgents;

if(matchingAgents != null) {
showAgentsModal(matchingAgents);
} else {
showAgentErrorMessageModal();
}
},
onFailure: showAgentErrorMessageModal
});
}

var showAgentsModal = function(agents) {
modalText = '';
if(agents.length > 0) {
modalText += 'Matching Agents:\n\n';
for(var i = 0; i != agents.length; i++) {
modalText += ' - ' + agents[i] + '\n';
}
} else {
modalText += 'No matching Agents found.';
}
modalText += '\n\n';
alert(modalText);
}

var showAgentErrorMessageModal = function() {
alert('Unable to fetch matching Agents.');
}

Event.observe(window, 'load', function(event) {
agentTableHighlighter = new TableHighlighter('agentRoles', 3, 2);
// Show agents matching a pattern on click
var agentRolesTable = document.getElementById('agentRoles')
var patterns = agentRolesTable.getElementsByClassName('patternAnchor');
for(var i = 0; i != patterns.length; i++) {
bindAgentListenerToPattern(patterns[i]);
}

});

var deleteAgentRole = function(e) {
Expand All @@ -217,7 +276,9 @@
this.innerHTML = '<input type="text" name="[pattern]" value="' + this.childNodes[1].value + '" size="' + (this.childNodes[1].value.length+10) + '"/>';
}
else {
this.innerHTML = this.childNodes[0].value.escapeHTML() + '<input type="hidden" name="[pattern]" value="' + this.childNodes[0].value + '"/>';
this.innerHTML = '<a href="#" class="patternAnchor">&quot;' + this.childNodes[0].value.escapeHTML() + '&quot;</a><input type="hidden" name="[pattern]" value="' + this.childNodes[0].value + '"/>';
child = this.children[0];
bindAgentListenerToPattern(this.children[0]);
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
</f:entry>
</l:isAdmin>
<script>
var tableHighlighter;
var projecttableHighlighter;
(function() {
<!-- place master outside the DOM tree so that it won't creep into the submitted form -->
var master = document.getElementById('${id}');
Expand Down Expand Up @@ -166,7 +166,6 @@
child.innerHTML = escapeHTML(name);
var patternString = doubleQuote + escapeHTML(pattern) + doubleQuote;
child.next().innerHTML = '<a href="#" class="patternAnchor">' + patternString + '</a>';
bindListenerToPattern(child.next().children[0]);

var hidden = document.createElement('input');
hidden.setAttribute('name', '[pattern]');
Expand All @@ -179,6 +178,10 @@
item.outerHTML = item.outerHTML.replace("{{ROLE}}", doubleEscapeHTML(name)).replace("{{PATTERN}}", doubleEscapeHTML(pattern));
});

child = copy.childNodes[1];
var link = child.next().children[0];
bindListenerToPattern(link);

copy.setAttribute("name",'['+name+']');
<j:if test="${nbProjectRoles lt 20}">
table.appendChild(copy);
Expand Down Expand Up @@ -242,7 +245,8 @@
projecttableHighlighter = new TableHighlighter('projectRoles', 3, 2);

// Show jobs matching a pattern on click
var patterns = document.getElementsByClassName('patternAnchor');
var projectRolesTable = document.getElementById('projectRoles')
var patterns = projectRolesTable.getElementsByClassName('patternAnchor');
for(var i = 0; i != patterns.length; i++) {
bindListenerToPattern(patterns[i]);
}
Expand All @@ -266,6 +270,7 @@
}
else {
this.innerHTML = '<a href="#" class="patternAnchor">&quot;' + this.childNodes[0].value.escapeHTML() + '&quot;</a><input type="hidden" name="[pattern]" value="' + this.childNodes[0].value + '"/>';
bindListenerToPattern(this.children[0]);
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,7 @@
<j:set var="pattern" value="&lt;br/&gt; &lt;b&gt;Pattern&lt;/b&gt; : ${h.escape(attrs.role.pattern.toString())}"/>
</j:if>
<td width="*" class="in-place-edit">
<j:if test="${attrs.project}">
<a href="#" class="patternAnchor">&quot;${attrs.role.pattern.toString()}&quot;</a>
</j:if>
<j:if test="${!attrs.project}">
&quot;${h.escape(attrs.role.pattern.toString())}&quot;
</j:if>
<a href="#" class="patternAnchor">&quot;${attrs.role.pattern.toString()}&quot;</a>
<input type="hidden" name="[pattern]" value="${attrs.role.pattern}" />
</td>
</j:if>
Expand Down

0 comments on commit ed5445d

Please sign in to comment.