Skip to content

Commit 2a4a912

Browse files
baymacjetersen
andauthored
[JENKINS-57988] Remove hashmap (#16)
* added link to token creation section * broken code with serverMap * added java streams support for server filters * removed warning for server url * serverMap is no more transient * added more Java 8 streams to filter gitlab servers * added info for jcasc in README * removed hashmaps from GitLabServers * removed commented code * removed unnecessary newline * use newer Jenkins Version for PersistentDescriptor, which calls load PersistentDescriptor calls load on PostConstruct See: jenkinsci/jenkins#3570 Follow the doc saying you should call save on setters: https://github.com/jenkinsci/jenkins/blob/c489b07f311eb1c3068d0457ff7813261ec8ece5/core/src/main/java/jenkins/model/GlobalConfiguration.java#L35 Though the docs is a bit outdated it is not aware of PersistentDescriptor * relative links Co-Authored-By: Joseph Petersen <[email protected]>
1 parent af8726b commit 2a4a912

File tree

5 files changed

+91
-68
lines changed

5 files changed

+91
-68
lines changed

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ Assuming plugin installation has been done already.
238238
239239
6. Adding a Personal Access Token Credentials:
240240
241-
This is a manual setup. To automatically generate Personal Accees Token see next section
241+
This is a manual setup. To automatically generate Personal Accees Token see next [section](#creating-personal-access-token-within-jenkins).
242242
243243
i. User is required to add a `GitLab Personal Access Token` type credentials entry to securely persist the token inside Jenkins
244244
@@ -310,6 +310,34 @@ required scope. You can go back to the GitLab Server Configuration to select the
310310
credentials with the `id` returned by token creator. It should be a a 128-bit long UUID-4 string (36 characters).
311311
312312
![gitlab-token-creator](docs/img/gitlab-token-creator.png)
313+
314+
### Configuration as Code
315+
316+
There is an easier way to setup GitLab Server configuration on your Jenkins server. Jenkins
317+
Configuration as Code (JCasC) allows you to configure your Jenkins Global Configuration by a simple `yaml` file. If you
318+
use Jenkins Code as Configuration on your Jenkins Instance, you can add the following to your `jenkins.yaml`.
319+
320+
```yaml
321+
credentials:
322+
system:
323+
domainCredentials:
324+
- credentials:
325+
- gitlabPersonalAccessToken:
326+
scope: SYSTEM
327+
id: "i<3GitLab"
328+
token: "XfsqZvVtAx5YCph5bq3r" # gitlab personal access token
329+
330+
unclassified:
331+
gitLabServers:
332+
servers:
333+
- credentialsId: "i<3GitLab"
334+
manageHooks: true
335+
name: "gitlab.com"
336+
serverUrl: "https://gitlab.com"
337+
```
338+
339+
See handling secrets [section](https://github.com/jenkinsci/configuration-as-code-plugin#handling-secrets) for better
340+
security.
313341
314342
### Setting up GitLab for jobs
315343

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<revision>0.0.2.</revision>
1616
<changelist>-SNAPSHOT</changelist>
1717
<!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. -->
18-
<jenkins.version>2.138.4</jenkins.version>
18+
<jenkins.version>2.150.3</jenkins.version>
1919
<java.level>8</java.level>
2020
<!-- Other properties you may want to use:
2121
~ jenkins-test-harness.version: Jenkins Test Harness version you use to test the plugin. For Jenkins version >= 1.580.1 use JTH 2.0 or higher.

src/main/java/io/jenkins/plugins/gitlabserverconfig/servers/GitLabServer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,9 @@ public static FormValidation doCheckServerUrl(@QueryParameter String value) {
226226
// TODO:[JENKINS-57747] Add support for GitLab Ultimate (self hosted) and Gold (saas)
227227
if (GITLAB_SERVER_URL.equals(value)) {
228228
LOGGER.info("Server URL is fine - %s", value);
229-
return FormValidation.ok();
230229
}
231230
LOGGER.info("Unable to validate serverUrl - %s", value);
232-
return FormValidation.warning(Messages.GitLabServer_recheckUrl());
231+
return FormValidation.ok();
233232
}
234233

235234
@NonNull

src/main/java/io/jenkins/plugins/gitlabserverconfig/servers/GitLabServers.java

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,33 @@
22

33
import hudson.Extension;
44
import hudson.ExtensionList;
5-
import hudson.Util;
65
import hudson.model.Descriptor;
6+
import hudson.model.PersistentDescriptor;
77
import hudson.util.ListBoxModel;
88
import io.jenkins.plugins.gitlabserverconfig.servers.helpers.GitLabPersonalAccessTokenCreator;
99
import java.util.ArrayList;
1010
import java.util.Collections;
11-
import java.util.Iterator;
1211
import java.util.List;
12+
import java.util.Map;
13+
import java.util.concurrent.ConcurrentHashMap;
14+
import java.util.function.Function;
15+
import java.util.function.Predicate;
16+
import java.util.stream.Collectors;
1317
import javax.annotation.CheckForNull;
1418
import javax.annotation.Nonnull;
1519
import jenkins.model.GlobalConfiguration;
1620
import jenkins.model.Jenkins;
17-
import net.sf.json.JSONObject;
1821
import org.apache.commons.lang.StringUtils;
19-
import org.kohsuke.stapler.StaplerRequest;
2022
import org.slf4j.Logger;
2123
import org.slf4j.LoggerFactory;
2224

25+
import static hudson.Util.fixNull;
26+
2327
/**
2428
* Represents the global configuration of GitLab servers.
2529
*/
2630
@Extension
27-
public class GitLabServers extends GlobalConfiguration {
31+
public class GitLabServers extends GlobalConfiguration implements PersistentDescriptor {
2832

2933
private static final Logger LOGGER = LoggerFactory.getLogger(GitLabServers.class);
3034

@@ -35,20 +39,17 @@ public class GitLabServers extends GlobalConfiguration {
3539
private List<GitLabServer> servers;
3640

3741
/**
38-
* Constructor.
39-
*/
40-
public GitLabServers() {
41-
load();
42-
}
43-
44-
/**
45-
* {@inheritDoc}
42+
* Helper function to get predicate to filter servers
43+
* based on their names
44+
*
45+
* @param keyExtractor the Function to filter
46+
* @param <T> In this case it is server
47+
* @return a predicate to filter servers list
4648
*/
47-
@Override
48-
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
49-
servers = req.bindJSONToList(GitLabServer.class, json.get("servers"));
50-
save();
51-
return super.configure(req, json);
49+
private static <T> Predicate<T> distinctByKey(
50+
Function<? super T, ?> keyExtractor) {
51+
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
52+
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
5253
}
5354

5455
/**
@@ -61,15 +62,15 @@ public static GitLabServers get() {
6162
}
6263

6364
/**
64-
* Populates a {@link ListBoxModel} with the endpoints.
65+
* Populates a {@link ListBoxModel} with the servers.
6566
*
66-
* @return A {@link ListBoxModel} with all the endpoints
67+
* @return A {@link ListBoxModel} with all the servers
6768
*/
6869
public ListBoxModel getServerItems() {
6970
ListBoxModel result = new ListBoxModel();
70-
for (GitLabServer endpoint : getServers()) {
71-
String serverUrl = endpoint.getServerUrl();
72-
String displayName = endpoint.getName();
71+
for (GitLabServer server : getServers()) {
72+
String serverUrl = server.getServerUrl();
73+
String displayName = server.getName();
7374
result.add(StringUtils.isBlank(displayName) ? serverUrl : displayName + " (" + serverUrl + ")", serverUrl);
7475
}
7576
return result;
@@ -103,74 +104,70 @@ public List<Descriptor> actions() {
103104
}
104105

105106
/**
106-
* Sets the list of endpoints.
107+
* Sets the list of GitLab Servers
107108
*
108-
* @param endpoints the list of endpoints.
109+
* @param servers the list of endpoints.
109110
*/
110-
public void setServers(@CheckForNull List<? extends GitLabServer> endpoints) {
111+
public void setServers(@CheckForNull List<? extends GitLabServer> servers) {
111112
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
112-
servers = new ArrayList<>(Util.fixNull(endpoints));
113+
this.servers = fixNull(servers).stream()
114+
.filter(distinctByKey(GitLabServer::getName)).collect(Collectors.toList());
115+
save();
113116
}
114117

115118
/**
116-
* Adds an endpoint
119+
* Adds an server
117120
* Checks if the GitLab Server name is unique
118121
*
119-
* @param endpoint the endpoint to add.
122+
* @param server the server to add.
120123
* @return {@code true} if the list of endpoints was modified
121124
*/
122-
public boolean addServer(@Nonnull GitLabServer endpoint) {
123-
List<GitLabServer> endpoints = new ArrayList<>(getServers());
124-
for (GitLabServer ep : endpoints) {
125-
if (Util.fixNull(ep.getName()).equals(Util.fixNull(endpoint.getName()))) {
126-
return false;
127-
}
125+
public boolean addServer(@Nonnull GitLabServer server) {
126+
List<GitLabServer> servers = new ArrayList<>(getServers());
127+
GitLabServer s = servers.stream()
128+
.filter(server1 -> server1.getName().equals(server.getName()))
129+
.findAny()
130+
.orElse(null);
131+
if(s != null) {
132+
return false;
128133
}
129-
endpoints.add(endpoint);
130-
setServers(endpoints);
134+
servers.add(server);
135+
setServers(servers);
131136
return true;
132137
}
133138

134139
/**
135140
* Updates an existing endpoint (or adds if missing)
136141
* Checks if the GitLab Server name is matched
137142
*
138-
* @param endpoint the endpoint to update.
143+
* @param server the server to update.
144+
* @return {@code true} if the list of endpoints was modified
139145
*/
140-
public void updateServer(@Nonnull GitLabServer endpoint) {
141-
List<GitLabServer> endpoints = new ArrayList<>(getServers());
142-
boolean found = false;
143-
for (int i = 0; i < endpoints.size(); i++) {
144-
GitLabServer ep = endpoints.get(i);
145-
if (Util.fixNull(ep.getName()).equals(Util.fixNull(endpoint.getName()))) {
146-
endpoints.set(i, endpoint);
147-
found = true;
148-
break;
149-
}
150-
}
151-
if (!found) {
152-
endpoints.add(endpoint);
146+
public boolean updateServer(@Nonnull GitLabServer server) {
147+
List<GitLabServer> servers = new ArrayList<>(getServers());
148+
if(!servers.contains(server)) {
149+
return false;
153150
}
154-
setServers(endpoints);
151+
servers = servers.stream()
152+
.map(oldServer -> oldServer.getName().equals(server.getName()) ? server : oldServer)
153+
.collect(Collectors.toList());
154+
setServers(servers);
155+
return true;
155156
}
156157

157158
/**
158-
* Removes an endpoint.
159+
* Removes a server entry
159160
* Checks if the GitLab Server name is matched
160161
*
161-
* @param name the server URL to remove.
162+
* @param name the server name to remove.
162163
* @return {@code true} if the list of endpoints was modified
163164
*/
164165
public boolean removeServer(@CheckForNull String name) {
165-
boolean modified = false;
166-
List<GitLabServer> endpoints = new ArrayList<>(getServers());
167-
for (Iterator<GitLabServer> iterator = endpoints.iterator(); iterator.hasNext(); ) {
168-
if (Util.fixNull(name).equals(Util.fixNull(iterator.next().getName()))) {
169-
iterator.remove();
170-
modified = true;
171-
}
166+
List<GitLabServer> servers = new ArrayList<>(getServers());
167+
boolean removed = servers.removeIf(s -> s.getName().equals(name));
168+
if(removed) {
169+
setServers(servers);
172170
}
173-
setServers(endpoints);
174-
return modified;
171+
return removed;
175172
}
176173
}

src/main/resources/io/jenkins/plugins/gitlabserverconfig/servers/Messages.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ GitLabServer.serverVersion=GitLab Version: <code>{0}</code>
88
GitLabServer.failedValidation=Failed to validate the account <code>{0}</code>
99
GitLabServer.credentialsNotResolved=Cannot resolve suitable credentials with id: <code>{0}</code>
1010
GitLabServer.advancedSectionForFuture=Advanced configurations will be added in later release
11-
GitLabServer.recheckUrl=Checks for community version of GitLab is supported but GitLab Gold, Ultimate, Community self hosted etc are not supported yet. Please test the connection to see if your URL is valid

0 commit comments

Comments
 (0)