-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add optional usage restriction for a cloud using folder properties #282
Conversation
Pipeline usage example:
|
I understand the intent but I'm not sure requiring a secret string is the most elegant solution. Why not add a boolean property in the cloud, as well as a folder property? Thinking further, one could imagine an extension point checking whether a given podTemplate is allowed given the context (e.g. forbid privileged containers in all folders but allow them in a specific one) |
@Vlatombe |
The way I see it, you would define a boolean property in the cloud to allow/disallow usage of pod templates in pipeline by default. Then, the folder property would define the list of Kubernetes clouds allowed to be used inside the folder. |
Thanks for the clarification, got you now. I assume this would require the Folders Plus Version of the Plugin because on my install it seems I can't add any Properties at all (v6.3)? In the configure view of the folder only the header "Properties" is visible but no add button. |
The This section lists properties contributed by plugins. In your screenshot, we can see the JIRA plugin is contributing a |
Aaah, a Layer 8 problem on my side. After adding the Folder Plugin Maven Dependency to the POM I added a Any pointers for how to check this value from within the Kubernetes Plugin are highly appreciated :-) |
From |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going in the right direction, added some additional comments
} | ||
|
||
@Deprecated | ||
public KubernetesCloud(String name, List<? extends PodTemplate> templates, String serverUrl, String namespace, | ||
String jenkinsUrl, String containerCapStr, int connectTimeout, int readTimeout, int retentionTimeout) { | ||
String jenkinsUrl, String containerCapStr, int connectTimeout, int readTimeout, int retentionTimeout, boolean usageRestricted) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed (since you have @DataBoundSetter
on the setter method) and it would break potential usages of this constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pom.xml
Outdated
@@ -89,6 +89,12 @@ | |||
<version>${jenkins-kubernetes-credentials.version}</version> | |||
</dependency> | |||
|
|||
<dependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent with spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
ItemGroup<?> parent = job.getParent(); // Inspect the Parent of the Job | ||
|
||
Set<String> allowedClouds = new HashSet<>(); | ||
if(parent instanceof Folder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractFolder
is a better check than Folder
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
ItemGroup<?> parent = job.getParent(); // Inspect the Parent of the Job | ||
|
||
Set<String> allowedClouds = new HashSet<>(); | ||
if(parent instanceof Folder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could recurse into folder hierarchy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
collectAllowedClouds
is already traversing the hierarchy internally.
<?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"> | ||
<f:section title="Kubernetes Plugin"> | ||
<f:entry title="${%Allowed Clouds}" field="allowedClouds"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be more structured, like providing a list of checkboxes (one line per cloud instance) and storing a collection of cloud names in the folder property class.
Could please someone with more Jenkins and Jelly knowledge help me out with the UI stuff. I tried to implement a list of Checkboxes (one for each available cloud) which, if a cloud is inherited from a parent folder, would render the corresponding Checkbox as selected and read-only. Only non-inherited selected clouds should be saved in the folder property. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting some changes to clean up the patch but this looks good overall. Will try the PR locally as well.
|
||
|
||
public boolean isUsageRestricted() { | ||
return usageRestricted; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
return isModifyable() ? "" : "disabled=\"disabled\""; | ||
} | ||
|
||
private boolean isModifyable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isModifiable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
* | ||
* @return | ||
*/ | ||
public List<UsagePermission> getEffectivePermissions() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
@SuppressWarnings("unused") // Used by jelly
@Restricted(DoNotUse.class) // Used by jelly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
||
String name = kubernetesCloud.name; | ||
p.setName(name); | ||
p.setGranted(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessary, a boolean
is false by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
String name = kubernetesCloud.name; | ||
p.setName(name); | ||
p.setGranted(false); | ||
p.setInherited(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Cloud cloud = Jenkins.getInstance().getCloud(cloudName); | ||
if (cloud == null) { | ||
throw new AbortException(String.format("Cloud does not exist: %s", cloudName)); | ||
} | ||
if (!(cloud instanceof KubernetesCloud)) { | ||
throw new AbortException(String.format("Cloud is not a Kubernetes cloud: %s (%s)", cloudName, | ||
cloud.getClass().getName())); | ||
throw new AbortException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting change, should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
PodTemplateAction podTemplateAction = run.getAction(PodTemplateAction.class); | ||
NamespaceAction namespaceAction = run.getAction(NamespaceAction.class); | ||
String parentTemplates = podTemplateAction != null ? podTemplateAction.getParentTemplates() : null; | ||
|
||
//Let's generate a random name based on the user specified to make sure that we don't have | ||
//issues with concurrent builds, or messing with pre-existing configuration | ||
// Let's generate a random name based on the user specified to make sure that we |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove formatting change (older is better)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
} | ||
KubernetesCloud kubernetesCloud = (KubernetesCloud) cloud; | ||
|
||
Run<?, ?> run = getContext().get(Run.class); | ||
if (kubernetesCloud.isUsageRestricted()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not the ideal design (ideally PodTemplateStepExecution
should not depend on KubernetesFolderProperty
) but could be revisited later by introducing a new extension point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no idea how to do this and, to be totally honest, I don't feel the urge to dig any deeper into the internals of Jenkins and its quirks.
@@ -127,8 +156,8 @@ public void onResume() { | |||
throw new RuntimeException(String.format("Cloud does not exist: %s", cloudName)); | |||
} | |||
if (!(cloud instanceof KubernetesCloud)) { | |||
throw new RuntimeException(String.format("Cloud is not a Kubernetes cloud: %s (%s)", cloudName, | |||
cloud.getClass().getName())); | |||
throw new RuntimeException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid formatting change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -46,6 +50,18 @@ | |||
|
|||
private Map<String, String> systemProperties = new HashMap<>(); | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem related to the main change but ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -55,6 +55,10 @@ | |||
<f:entry title="${%Container Cleanup Timeout (minutes)}" field="retentionTimeout"> | |||
<f:textbox default="5"/> | |||
</f:entry> | |||
|
|||
<f:entry title="${%Requires permission}" field="usageRestricted"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing inline help (Add help-usageRestricted.html
).
Maybe the title could specify that this applies to pipeline jobs. (Requires permission to use in pipeline jobs)
Having the permission in the advanced section is not very discoverable (but this is a general problem in the plugin due to the high number of settings).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added help file but still in the advanced section.
<f:advanced> | ||
<f:entry title="Usage restricted Kubernetes Clouds available to any Pipeline jobs inside this folder:"/> | ||
<j:forEach var="permission" items="${instance.getEffectivePermissions()}"> | ||
<f:entry title="${permission.name}"><j:expr value="${permission.htmlCheckbox()}" escapeText="false" /></f:entry> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use <f:checkbox>
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldn't figure out how to get the checkbox visually rendered as disabled in jelly.
by using readonly it looked like an active checkbox. i thought this would be confusing for the user.
1343fb3
to
a9a7c2c
Compare
fixed most of the issues. sorry for letting this pr get stale but I didn't find time to do this sooner. |
https://github.com/jenkinsci/kubernetes-plugin.git into usage-restriction Conflicts: src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecution.java
Sorry for the review delay, going through a new round now. |
* Merge with master * Reuse KubernetesFolderProperty instance on save * Some labels re-wording * Create taglib for checkbox with disabled attribute support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have submitted sixtyeight#1 with my suggested changes to this PR.
Usage restriction
@Vlatombe does it look good to you now? I think it deserves an entry in the README |
Hi,
Yes! :-) Thanks for your help. I didn't find time to play around with it so far. Will write something this evening.
Kind regards, Christian
… Gesendet: Mittwoch, 11. Juli 2018 um 09:59 Uhr
Von: "Carlos Sanchez" ***@***.***>
An: jenkinsci/kubernetes-plugin ***@***.***>
Cc: sixtyeight ***@***.***>, Author ***@***.***>
Betreff: Re: [jenkinsci/kubernetes-plugin] added optional usage restriction for a cloud (#282)
@Vlatombe does it look good to you now?
I think it deserves an entry in the README
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#282 (comment)
|
Lgtm
Le mer. 11 juil. 2018 à 10:27, sixtyeight <notifications@github.com> a
écrit :
Hi,
Yes! :-) Thanks for your help. I didn't find time to play around with it
so far. Will write something this evening.
Kind regards, Christian
> Gesendet: Mittwoch, 11. Juli 2018 um 09:59 Uhr
> Von: "Carlos Sanchez" ***@***.***>
> An: jenkinsci/kubernetes-plugin ***@***.***>
> Cc: sixtyeight ***@***.***>, Author ***@***.***>
> Betreff: Re: [jenkinsci/kubernetes-plugin] added optional usage
restriction for a cloud (#282)
>
> @Vlatombe does it look good to you now?
>
> I think it deserves an entry in the README
>
> --
> You are receiving this because you authored the thread.
> Reply to this email directly or view it on GitHub:
>
#282 (comment)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#282 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAKdw1CrDVxs6r2PUdhVu6fzF_MRAZW0ks5uFbblgaJpZM4R9eTF>
.
--
*Vincent Latombe*
Software Engineer
CloudBees, Inc.
[image: CloudBees-Logo.png]
|
In our Jenkins setup we would like to control (at least at a basic level) who can use a cloud definition.
I added an optional "secret" field to the KubernetesCloud which is, if not empty, compared with the value of the "cloudSecret" attribute in the PodTemplateStepExecution before actually provisioning the new agent.
Using this approach enables us to define the secret credential for example at folder scope.