Skip to content
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

[JENKINS-72176] Split cloud management page into multiple pages #1443

Merged
merged 47 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
f9571b2
[broken] wip
scherler Oct 6, 2023
be4fca7
[BEE-30772] working listing page
scherler Oct 9, 2023
2e89c57
[BEE-30772] WIP
scherler Oct 10, 2023
b7bdefe
[BEE-30772] Working edit of template, missing new
scherler Oct 10, 2023
cee3420
[BEE-30772] remove unused imports
scherler Oct 10, 2023
b183580
[BEE-30772] remove unused code
scherler Oct 10, 2023
558cb42
[BEE-30772] remove unused code
scherler Oct 10, 2023
0661f6d
[BEE-30772] remove unused code
scherler Oct 10, 2023
f1d29e6
[BEE-30772] remove unused code
scherler Oct 10, 2023
5848de2
[BEE-30772] remove unused code
scherler Oct 10, 2023
93b833d
Merge branch 'master' into BEE-30772
scherler Oct 10, 2023
227712c
[BEE-30772] try the action
scherler Oct 10, 2023
aefb1d9
[BEE-30772] implement new template
scherler Oct 11, 2023
20c0acf
[BEE-30772] working delete basically
scherler Oct 11, 2023
2dbd016
[BEE-30772] refactor so all stays in one class
scherler Oct 11, 2023
d921fc9
[BEE-30772] fix different issues
scherler Oct 11, 2023
189c5ac
[BEE-30772] wrap up
scherler Oct 11, 2023
a011a9d
[BEE-30772] fix test as pointed out by james
scherler Oct 13, 2023
d31ac1f
[BEE-30772] fix delete and add security check
scherler Oct 13, 2023
30753a8
Update src/main/java/org/csanchez/jenkins/plugins/kubernetes/Kubernet…
scherler Oct 13, 2023
c86ad89
[BEE-30772] fix idiom of code
scherler Oct 13, 2023
49c0ac3
Merge branch 'BEE-30772' of github.com:scherler/kubernetes-plugin int…
scherler Oct 13, 2023
75b7c78
[BEE-30772] remove custom icon
scherler Oct 13, 2023
c1342c6
[BEE-30772] fix different issues
scherler Oct 13, 2023
bee1a7f
[BEE-30772] fix test
scherler Oct 13, 2023
3c2a4a3
[BEE-30772] better code thanks to vincent
scherler Oct 16, 2023
4442a4a
[BEE-30772] fix test
scherler Oct 16, 2023
a6295db
Update pom.xml
scherler Oct 16, 2023
7b875ed
[BEE-30772] remove obsolete code
scherler Oct 16, 2023
af6373b
Merge branch 'BEE-30772' of github.com:scherler/kubernetes-plugin int…
scherler Oct 16, 2023
a5699ee
[BEE-30772] remove obsolete code
scherler Oct 17, 2023
bcafb81
[BEE-30772] add more tests a
scherler Oct 18, 2023
b1edb7f
Apply suggestions from code review
scherler Oct 19, 2023
3be2fde
[BEE-30772] fix merge and apply suggestions
scherler Oct 19, 2023
31be218
[BEE-30772] revert test
scherler Oct 19, 2023
0e3cbb0
Update src/main/resources/org/csanchez/jenkins/plugins/kubernetes/Kub…
scherler Oct 20, 2023
0986f8e
[BEE-30772] fix jenkins bug in renaming cloud and redirect
scherler Oct 20, 2023
dd65959
[BEE-30772] add fixme note
scherler Oct 20, 2023
2a9048c
Merge branch 'master' into BEE-30772
scherler Oct 20, 2023
ea4047a
Apply suggestions from code review
scherler Oct 23, 2023
d03c902
Merge branch 'master' into BEE-30772
scherler Oct 23, 2023
c7180ab
[BEE-30772] remove fix for core
scherler Oct 23, 2023
758d8c8
Merge branch 'master' into BEE-30772
scherler Oct 24, 2023
2775886
Apply suggestions from code review
scherler Oct 24, 2023
08866ec
[BEE-30772] removed unused
scherler Oct 24, 2023
697f605
Apply suggestions from code review
scherler Oct 24, 2023
18c219c
[BEE-30772] add name of the pod to confirmation
scherler Oct 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<jenkins.host.address />
<slaveAgentPort />
<!-- TODO fix KubernetesCloudTest todos once past 2.414 -->
scherler marked this conversation as resolved.
Show resolved Hide resolved
<jenkins.version>2.401.1</jenkins.version>
<jenkins.version>2.414.2</jenkins.version>
scherler marked this conversation as resolved.
Show resolved Hide resolved
<bom>2.401.x</bom>
<bom.version>2357.v1043f8578392</bom.version>
<no-test-jar>false</no-test-jar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;

import edu.umd.cs.findbugs.annotations.CheckForNull;
Expand All @@ -37,9 +38,12 @@
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.interceptor.RequirePOST;

import org.kohsuke.stapler.verb.POST;
import com.cloudbees.plugins.credentials.CredentialsMatchers;
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
Expand All @@ -48,16 +52,19 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.Functions;
import hudson.TcpSlaveAgentListener;
import hudson.Util;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
import hudson.model.Descriptor;
import hudson.model.DescriptorVisibilityFilter;
import hudson.model.Failure;
import hudson.model.Label;
import hudson.security.ACL;
import hudson.slaves.Cloud;
import hudson.slaves.NodeProvisioner;
import hudson.util.FormApply;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import io.fabric8.kubernetes.client.KubernetesClient;
Expand All @@ -70,6 +77,7 @@
import static org.csanchez.jenkins.plugins.kubernetes.MetricNames.metricNameForLabel;

import jenkins.websocket.WebSockets;
import net.sf.json.JSONObject;

/**
* Kubernetes cloud provider.
Expand Down Expand Up @@ -100,6 +108,10 @@ public class KubernetesCloud extends Cloud {

@NonNull
private List<PodTemplate> templates = new ArrayList<>();

public boolean hasTemplates() {
return templates.size() > 0;
scherler marked this conversation as resolved.
Show resolved Hide resolved
}
private String serverUrl;
private boolean useJenkinsProxy;
@CheckForNull
Expand Down Expand Up @@ -600,7 +612,40 @@ public boolean canProvision(@NonNull Cloud.CloudState state) {
public PodTemplate getTemplate(@CheckForNull Label label) {
return PodTemplateUtils.getTemplateByLabel(label, getAllTemplates());
}

@CheckForNull
public PodTemplate getTemplate(@NonNull String id) {
scherler marked this conversation as resolved.
Show resolved Hide resolved
scherler marked this conversation as resolved.
Show resolved Hide resolved
return getTemplateById(id);
}

public PodTemplate currentTemplate;
scherler marked this conversation as resolved.
Show resolved Hide resolved

public void doTemplates(StaplerRequest req, StaplerResponse rsp, @QueryParameter String id)
throws IOException, ServletException {
if (id != null) {
currentTemplate = getTemplateById(id);
} else {
currentTemplate = null;
}
req.getView(this, "templates.jelly").forward(req, rsp);
}
scherler marked this conversation as resolved.
Show resolved Hide resolved

@POST
public HttpResponse doUpdateTemplate(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
Jenkins j = Jenkins.get();
removeTemplate(currentTemplate);
PodTemplate newTemplate = reconfigureTemplate(req, req.getSubmittedForm());
addTemplate(newTemplate);
j.save();
// take the user back.
return FormApply.success("./templates");
}
scherler marked this conversation as resolved.
Show resolved Hide resolved

private PodTemplate reconfigureTemplate(@NonNull final StaplerRequest req, JSONObject form) throws Descriptor.FormException {
if (form == null) return null;
return currentTemplate.getDescriptor().newInstance(req, form);
}

@CheckForNull
public PodTemplate getTemplateById(@NonNull String id) {
return getAllTemplates().stream().filter(t -> id.equals(t.getId())).findFirst().orElse(null);
Expand Down Expand Up @@ -716,6 +761,23 @@ public void setWaitForPodSec(Integer waitForPodSec) {
this.waitForPodSec = waitForPodSec;
}

/**
* Creating a new template.
*/
@POST
public HttpResponse doCreate(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
PodTemplate newTemplate=new PodTemplate().getDescriptor().newInstance(req, req.getSubmittedForm());
addTemplate(newTemplate);
Jenkins j = Jenkins.get();
j.save();
// take the user back.
return FormApply.success("templates");
}

public PodTemplate getNewTemplate(){
scherler marked this conversation as resolved.
Show resolved Hide resolved
return new PodTemplate();
}

@Extension
public static class DescriptorImpl extends Descriptor<Cloud> {
@Override
Expand Down Expand Up @@ -985,4 +1047,5 @@ public static void hpiRunInit() {
}
}
}

scherler marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.csanchez.jenkins.plugins.kubernetes;

import java.io.IOException;
import java.io.Serializable;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
Expand All @@ -15,7 +16,9 @@
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
Expand All @@ -39,16 +42,25 @@
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
scherler marked this conversation as resolved.
Show resolved Hide resolved
import org.kohsuke.stapler.interceptor.RequirePOST;
import org.kohsuke.stapler.verb.POST;
import hudson.Extension;
import hudson.Functions;
import hudson.Util;
import hudson.model.labels.LabelAtom;
import hudson.slaves.Cloud;
import hudson.slaves.NodeProperty;
import hudson.util.FormApply;
import hudson.util.XStream2;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.client.KubernetesClient;
import java.io.StringReader;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;

/**
* Kubernetes Pod Template
Expand Down Expand Up @@ -631,6 +643,65 @@ public void addEnvVars(List<TemplateEnvVar> envVars) {
}
}

/**
* Deletes the cloud.
*/
@RequirePOST
scherler marked this conversation as resolved.
Show resolved Hide resolved
public HttpResponse doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException {
scherler marked this conversation as resolved.
Show resolved Hide resolved
String context = Functions.getNearestAncestorUrl(req, this);
// Define regular expressions to match the desired substrings
// there maybe a better way to do this, but I don't know how to do it.
String regex1 = ".*/cloud/(.*)/template/(.*)";
Pattern pattern = Pattern.compile(regex1);
Matcher matcher = pattern.matcher(context);
// Find and extract the substrings
if (matcher.find()) {
String cloudName = matcher.group(1); // cloud name
Jenkins j = Jenkins.get();
Cloud cloud = j.getCloud(cloudName);
if (cloud instanceof KubernetesCloud) {
KubernetesCloud kubernetesCloud = (KubernetesCloud) cloud;
// maybe there is a smarter way to modify?
kubernetesCloud.removeTemplate(this);
j.save();
}
}
// take the user back.
return new HttpRedirect("../../templates");
}

@POST
public HttpResponse doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is ATM not in use anymore

String context = Functions.getNearestAncestorUrl(req, this);
// Define regular expressions to match the desired substrings
// there maybe a better way to do this, but I don't know how to do it.
String regex1 = ".*/cloud/(.*)/template/(.*)";
Pattern pattern = Pattern.compile(regex1);
Matcher matcher = pattern.matcher(context);

// Find and extract the substrings
if (matcher.find()) {
String cloudName = matcher.group(1); // cloud name
Jenkins j = Jenkins.get();
Cloud cloud = j.getCloud(cloudName);
if (cloud instanceof KubernetesCloud) {
KubernetesCloud kubernetesCloud = (KubernetesCloud) cloud;
// maybe there is a smarter way to modify?
kubernetesCloud.removeTemplate(this);
PodTemplate newTemplate = reconfigure(req, req.getSubmittedForm());
kubernetesCloud.addTemplate(newTemplate);
j.save();
}
}
// take the user back.
return FormApply.success("../../templates");
}

private PodTemplate reconfigure(@NonNull final StaplerRequest req, JSONObject form) throws Descriptor.FormException {
if (form == null) return null;
scherler marked this conversation as resolved.
Show resolved Hide resolved
return getDescriptor().newInstance(req, form);
}

@DataBoundSetter
public void setEnvVars(List<TemplateEnvVar> envVars) {
if (envVars != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.csanchez.jenkins.plugins.kubernetes;

import hudson.Extension;
import hudson.model.Action;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jenkins.model.TransientActionFactory;

@Extension
public class PodTemplateAction extends TransientActionFactory<KubernetesCloud> implements Action{
scherler marked this conversation as resolved.
Show resolved Hide resolved

@Override
public String getIconFileName() {
return "symbol-copy-outline plugin-ionicons-api";
scherler marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public String getDisplayName() {
return "Pod templates";
}

@Override
public String getUrlName() {
return "templates";
}

@Override
public Class<KubernetesCloud> type() {
return KubernetesCloud.class;
}

@Override
public Collection<? extends Action> createFor(KubernetesCloud target) {
List<Action> actions = new ArrayList<>();
actions.add(new PodTemplateAction());
return actions;
}
}
3 changes: 3 additions & 0 deletions src/main/resources/images/symbols/copy.svg
scherler marked this conversation as resolved.
Show resolved Hide resolved
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,6 @@
<f:textbox default=""/>
</f:entry>
</f:advanced>
</f:advanced>

<f:advanced title="${%Pod Templates}">
<f:entry title="${%Pod Templates}" description="${%List of Pods to be launched as agents}">
<f:repeatableProperty field="templates" add="${%Add Pod Template}" header="${%Pod Template}">
<f:block>
<div align="right">
<f:repeatableDeleteButton value="${%Delete Pod Template}"/>
</div>
</f:block>
</f:repeatableProperty>
</f:entry>
</f:advanced>

</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form">
<l:layout permission="${app.SYSTEM_READ}" title="${%title(it.name)}" type="one-column">
<j:set var="readOnlyMode" value="${!app.hasPermission(app.ADMINISTER)}"/>
<j:set var="instance" value="${it.newTemplate}"/>
<j:set var="descriptor" value="${instance.descriptor}"/>
scherler marked this conversation as resolved.
Show resolved Hide resolved
<l:breadcrumb title="${%New Template }"/>
<l:main-panel>
<h1>${%New Pod template settings}</h1>
<f:form method="post" action="create" name="config" class="jenkins-form">
<!-- main body of the configuration -->

<st:include it="${instance}" page="config.jelly"/>
scherler marked this conversation as resolved.
Show resolved Hide resolved
<l:isAdmin>
<f:bottomButtonBar>
<f:submit value="${%Create}"/>
<f:apply value="${%Apply}"/>
</f:bottomButtonBar>
</l:isAdmin>
</f:form>
<l:isAdmin>
<st:adjunct includes="lib.form.confirm"/>
</l:isAdmin>
</l:main-panel>
</l:layout>
</j:jelly>
scherler marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!--
The MIT License

Copyright (c) 2017 Red Hat, inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:t="/lib/hudson">
<l:header />
<l:side-panel>
<l:tasks>
<l:task contextMenu="false" href="." icon="symbol-computer" title="${%Status}"/>
<l:task href="templates" icon="symbol-copy" title="${%Templates}"/>
<l:task href="configure" icon="symbol-settings"
title="${app.hasPermission(app.ADMINISTER) ? '%Configure' : '%View Configuration'}"/>
<l:delete permission="${app.ADMINISTER}" title="${%Delete Cloud}" message="${%delete.cloud(it.displayName)}"/>
<t:actions />
</l:tasks>
<j:forEach var="action" items="${it.allActions}">
<st:include it="${action}" page="box.jelly" optional="true"/>
</j:forEach>
</l:side-panel>
</j:jelly>