Skip to content

Data table #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@
<artifactId>workflow-multibranch</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>data-tables-api</artifactId>
<version>1.10.20-12</version>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>

<licenses>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,37 @@
import jenkins.tasks.SimpleBuildStep;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import javax.annotation.Nonnull;
import java.io.IOException;

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

public class BuildAddUrl extends Builder implements SimpleBuildStep {

private final String title;
private final String url;

private String users;
private String groups;

@DataBoundConstructor
public BuildAddUrl(String title, String url) {
this.url = url;
this.title = title;
}

@DataBoundSetter
public void setUsers(String users) {
this.users = users;
}

@DataBoundSetter
public void setGroups(String groups) {
this.groups = groups;
}

public String getTitle() {
return title;
Expand All @@ -31,6 +48,14 @@ public String getUrl() {
return url;
}

public String getUsers() {
return users;
}

public String getGroups() {
return groups;
}

@Override
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
Expand All @@ -43,7 +68,7 @@ public void perform(
@Nonnull Launcher launcher,
@Nonnull TaskListener listener
) throws InterruptedException, IOException {
run.addAction(new BuildUrlAction(title, url));
run.addAction(new BuildUrlAction(title, url, users, groups));
}

@Extension
Expand All @@ -64,15 +89,49 @@ public boolean isApplicable(Class<? extends AbstractProject> t) {
public static class BuildUrlAction implements Action {
private final String title;
private final String url;
private final ArrayList<String> userList = new ArrayList<String>();
private final ArrayList<String> groupList = new ArrayList<String>();

BuildUrlAction(String title, String url) {
BuildUrlAction(String title, String url, String users, String groups) {
this.title = title;
this.url = url;
if (users != null && !"".equals(users)) {
this.userList.addAll(Arrays.asList(users.split(",")));
}
if (groups != null && !"".equals(groups)) {
this.groupList.addAll(Arrays.asList(groups.split(",")));
}
}

@Override
public String getIconFileName() {
return String.format("/plugin/%s/deploy.png", getClass().getPackage().getImplementationTitle());
String iconFileName = String.format("/plugin/%s/deploy.png", getClass().getPackage().getImplementationTitle());

User currentUser = User.current();
if (currentUser == null) return null;

String currentUserId = currentUser.getId();
List<String> currentUserGroups = currentUser.getAuthorities();

if (!checkPermissions() || isUserInList(currentUserId) || isUserInGroup(currentUserGroups))
return iconFileName;

return null;
}

private boolean checkPermissions() {
return userList.size() > 0 || groupList.size() > 0;
}

private boolean isUserInList(String userId) {
return userList.contains(userId);
}

private boolean isUserInGroup(List<String> userGroups) {
for(String userGroup: userGroups)
if (groupList.contains(userGroup))
return true;
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.jenkinsci.plugins.environmentdashboard;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jenkins.plugins.datatables.TableConfiguration;

public class DeploymentTableConfiguration extends TableConfiguration{

private final Map<String, Object> configuration = new HashMap<>();

DeploymentTableConfiguration() {
super();

this.configuration.put("rowsGroup", new int[]{0});
this.configuration.put("pagingType", "full_numbers");
this.configuration.put("stateSave", true);
}

@Override
public String getConfiguration() {
try {
return new ObjectMapper().writeValueAsString(configuration);
}
catch (JsonProcessingException exception) {
throw new IllegalArgumentException(
String.format("Can't convert table configuration '%s' to JSON object", configuration), exception);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package org.jenkinsci.plugins.environmentdashboard;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.jenkinsci.plugins.environmentdashboard.Deployment.DeploymentAction;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;

import hudson.model.Job;
import hudson.model.Run;
import hudson.model.TopLevelItem;
import io.jenkins.plugins.datatables.TableColumn;
import io.jenkins.plugins.datatables.TableConfiguration;
import io.jenkins.plugins.datatables.TableModel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

public class DeploymentTableModel extends TableModel {
private String id;
List<? extends TopLevelItem> items;

DeploymentTableModel(String id) {
this.id = id;
}

public TableModel populate(List<? extends TopLevelItem> items) {
this.items = items;
return this;
}

private String getStatusHTML(String altText, String imageUrl, String href) {
// Issue with URL
href = href.substring(href.indexOf("/job"));
return new StringBuffer().append("<a href=\"")
.append(href)
.append("\"><img alt=\"")
.append(altText)
.append("\" src=\"")
.append(imageUrl)
.append("\" /></a>")
.toString();
}

private String getPopupHTML(int row, int col, String envName) {
return new StringBuffer().append("<a href=\"javascript:toggle('")
.append(row).append("_").append(col)
.append("');\">").append(envName).append("</a>")
.toString();
}

@Override
public String getId() {
return id;
}

@Override
public TableConfiguration getTableConfiguration() {
return new DeploymentTableConfiguration();
}

@Override
public List<TableColumn> getColumns() {
List<TableColumn> columns = new ArrayList<TableColumn>();
columns.add(new TableColumn("Job", "job"));
columns.add(new TableColumn("Environment", "environment"));
columns.add(new TableColumn("Release", "release"));
columns.add(new TableColumn("Result", "result"));
columns.add(new TableColumn("Completed", "completed"));
return columns;
}

@Override
public List<Object> getRows() {
List<Object> rows = new ArrayList<Object>();

int i=0;
for (Unit unit: getUnits(items)) {
int j=0;
for (Unit.Environment env: unit.environments) {
DeploymentAction action = env.getCurrentAction();
Run run = action.getRun();
rows.add(new DeploymentTableRow(unit.job.getName(),
getPopupHTML(i, j, env.name),
action.getBuildNumber(),
getStatusHTML(run.getDescription(),
run.getIconColor().getImageOf("32x32"),
run.getUrl()),
run.getTimestampString() + " ago"));
++j;
}
++i;
}
return rows;
}

private List<Unit.Environment> getEnvs(TopLevelItem item) {
List<WorkflowRun> runs = Collections.emptyList();
if (item instanceof WorkflowMultiBranchProject) {
runs = ((WorkflowMultiBranchProject) item)
.getItems()
.stream()
.map(Job::getBuilds)
.flatMap(Collection::stream)
.collect(Collectors.toList());
} else if (item instanceof WorkflowJob) {
runs = ((WorkflowJob) item).getBuilds();
}

return runs
.stream()
.map(run -> run.getActions(DeploymentAction.class))
.flatMap(List::stream)
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(DeploymentAction::getEnv))
.entrySet()
.stream()
.map(e -> new Unit.Environment(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}

public List<Unit> getUnits(List<? extends TopLevelItem> items) {
return items.stream()
.map(item -> new Unit(item, getEnvs(item)))
.filter(unit -> !unit.getEnvironments().isEmpty())
.collect(Collectors.toList());
}

@Getter
@RequiredArgsConstructor
public static class Unit {
private final TopLevelItem job;
private final List<Environment> environments;

@Getter
@RequiredArgsConstructor
public static class Environment {
private final String name;
private final List<DeploymentAction> actions;

public DeploymentAction getCurrentAction() {
return actions.get(0);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.jenkinsci.plugins.environmentdashboard;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class DeploymentTableRow {
private String job;
private String environment;
private String release;
private String result;
private String completed;

DeploymentTableRow(String job, String environment, String release, String result, String completed) {
this.job = job;
this.environment = environment;
this.release = release;
this.result = result;
this.completed = completed;
}
}
Loading