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 all 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
3 changes: 1 addition & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
<connectorHost />
<jenkins.host.address />
<slaveAgentPort />
<!-- TODO fix KubernetesCloudTest todos once past 2.414 -->
<jenkins.version>2.401.1</jenkins.version>
<jenkins.version>2.415</jenkins.version>
Copy link
Member

Choose a reason for hiding this comment

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

I imagine this bump is there to retrieve some necessary updates from core?

Cause it is higher than the recommended minimum version: https://www.jenkins.io/doc/developer/tutorial-improve/update-base-jenkins-version/

And also it does not align with the bom anymore (bom is using 2.401.x).

If it is intended and mandatory to have 2.415 it could be interesting to write a comment explaining it and a TODO to align the bom as soon as available?

Copy link
Member

Choose a reason for hiding this comment

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

Afair this is to get <l:delete ...>.

BOM should be bumped to the closest LTS which is 2.414.x.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The change was suggested by @Vlatombe, we need a version after jenkinsci/jenkins#7658, other than that ...

<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,6 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;

import edu.umd.cs.findbugs.annotations.CheckForNull;
Expand All @@ -34,12 +33,17 @@
import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuth;
import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
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 @@ -58,6 +62,7 @@
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 Down Expand Up @@ -600,6 +605,12 @@ public boolean canProvision(@NonNull Cloud.CloudState state) {
public PodTemplate getTemplate(@CheckForNull Label label) {
return PodTemplateUtils.getTemplateByLabel(label, getAllTemplates());
}

@SuppressWarnings("unused ") // stapler
@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);
}

@CheckForNull
public PodTemplate getTemplateById(@NonNull String id) {
Expand Down Expand Up @@ -716,6 +727,25 @@ public void setWaitForPodSec(Integer waitForPodSec) {
this.waitForPodSec = waitForPodSec;
}

@Restricted(NoExternalUse.class) // jelly
public PodTemplate.DescriptorImpl getTemplateDescriptor() {
return (PodTemplate.DescriptorImpl) Jenkins.get().getDescriptorOrDie(PodTemplate.class);
}

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

@Extension
public static class DescriptorImpl extends Descriptor<Cloud> {
@Override
Expand Down
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,7 @@
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

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 @@ -37,18 +38,24 @@
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.AncestorInPath;
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.verb.POST;
import hudson.Extension;
import hudson.Util;
import hudson.model.labels.LabelAtom;
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 +638,44 @@ public void addEnvVars(List<TemplateEnvVar> envVars) {
}
}

/**
* Deletes the template.
*/
@POST
public HttpResponse doDoDelete(@AncestorInPath KubernetesCloud kubernetesCloud) throws IOException {
Jenkins j = Jenkins.get();
j.checkPermission(Jenkins.ADMINISTER);
if (kubernetesCloud == null) {
throw new IllegalStateException("Cloud could not be found");
}
kubernetesCloud.removeTemplate(this);
j.save();
// take the user back.
return new HttpRedirect("../../templates");
}

@POST
public HttpResponse doConfigSubmit(StaplerRequest req, @AncestorInPath KubernetesCloud kubernetesCloud) throws IOException, ServletException, Descriptor.FormException {
Jenkins j = Jenkins.get();
j.checkPermission(Jenkins.ADMINISTER);
if (kubernetesCloud == null) {
throw new IllegalStateException("Cloud could not be found");
}
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;
}
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
@@ -1,3 +1,22 @@
<!--
The MIT License
Copyright (c) 2023, CloudBees 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:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:c="/lib/credentials">

Expand Down Expand Up @@ -104,18 +123,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,44 @@
<!--
The MIT License
Copyright (c) 2023, CloudBees 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:f="/lib/form">
<l:layout permission="${app.SYSTEM_READ}" title="${%New pod template}">
<j:set var="readOnlyMode" value="${!app.hasPermission(app.ADMINISTER)}"/>
<l:breadcrumb title="${%New pod template }"/>
<st:include page="sidepanel.jelly" it="${it}"/>
<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 -->

<j:set var="descriptor" value="${it.templateDescriptor}"/>
<st:include class="${descriptor.clazz}" page="config.jelly"/>
<l:isAdmin>
<f:bottomButtonBar>
<f:submit value="${%Create}"/>
</f:bottomButtonBar>
</l:isAdmin>
</f:form>
<l:isAdmin>
<st:adjunct includes="lib.form.confirm"/>
</l:isAdmin>
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!--
The MIT License
Copyright (c) 2023, CloudBees 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-details" title="${%Pod 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>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
delete.cloud=Delete the cloud ''{0}'' ?
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!--
The MIT License
Copyright (c) 2023, CloudBees 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:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<!-- with empty type attribute, takes full width space, works only because core doesn't provide a CSS "app-page-body-" -->
<l:layout title="${it.name} - ${%Pod templates}"
type="${request.hasParameter('expand') ? 'full-screen' : 'two-column'}">
<st:include page="sidepanel.jelly"/>

<l:main-panel>
<j:choose>
<j:when test="${not empty it.templates}">
<l:app-bar title="${it.name} - ${%Pod templates}">
<l:isAdmin>
<a name="newTemplate" class="jenkins-button jenkins-button--primary" href="new">
<l:icon src="symbol-add"/>
${%Add a pod template}
</a>
</l:isAdmin>
</l:app-bar>
<table id="templates" class="jenkins-table sortable">
<thead>
<tr>
<th initialSortDir="down">${%Name}</th>
<th class="jenkins-table__cell--tight"/>
</tr>
</thead>
<tbody>
<j:forEach var="template" items="${it.templates}">
<tr id="template_${template.id}">
<td>
<a href="${it.getCloudUrl(request,app,cloud)}template/${template.id}" class="jenkins-table__button">${template.name}</a>
</td>
<td class="jenkins-table__cell--tight">
<div class="jenkins-table__cell__button-wrapper">
<a href="${it.getCloudUrl(request,app,cloud)}template/${template.id}" class="jenkins-table__button">
<l:icon src="symbol-settings"/>
</a>
</div>
</td>
</tr>
</j:forEach>
</tbody>
</table>
</j:when>
<j:otherwise>
<l:app-bar title="${it.name} - ${%Pod templates}"/>
<div >
<section>
<div>
<div class="jenkins-!-padding-bottom-3">No pod template added yet.</div>
<div>
<a name="newTemplate" class="jenkins-button jenkins-button--primary" href="new">
<l:icon src="symbol-add"/>
${%Add a pod template}
</a>
</div>
</div>
</section>
</div>
</j:otherwise>
</j:choose>
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ KubernetesSlave.HomeWarning=[WARNING] HOME is set to / in the jnlp container. Yo
troubles when using tools or ssh client. This usually happens if the uid doesn't have any \
entry in /etc/passwd. Please add a user to your Dockerfile or set the HOME environment \
variable to a valid directory in the pod template definition.
KubernetesCloudNotAllowed.Description=Kubernetes cloud {0} is not allowed for folder containing job {1}
KubernetesCloudNotAllowed.Description=Kubernetes cloud {0} is not allowed for folder containing job {1}