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-50204] Implemented the Credentials view page #7

Merged
merged 5 commits into from Apr 13, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
4 changes: 4 additions & 0 deletions pom.xml
Expand Up @@ -67,6 +67,10 @@
<id>teilo</id>
<name>James Nord</name>
</developer>
<developer>
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

<id>agentgonzo</id>
<name>Steve Arch</name>
</developer>
</developers>

<dependencyManagement>
Expand Down
Expand Up @@ -49,9 +49,12 @@
import hudson.init.TermMilestone;
import hudson.init.Terminator;
import hudson.model.ItemGroup;
import hudson.model.ModelObject;
import hudson.security.ACL;
import jenkins.model.Jenkins;
import com.cloudbees.plugins.credentials.Credentials;
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.CredentialsStore;
import com.cloudbees.plugins.credentials.common.IdCredentials;

@Extension
Expand All @@ -67,6 +70,8 @@ public class KubernetesCredentialProvider extends CredentialsProvider implements
@CheckForNull
private Watch watch;

private KubernetesCredentialsStore store = new KubernetesCredentialsStore(this);

@Initializer(after=InitMilestone.PLUGINS_PREPARED, fatal=false)
@Restricted(NoExternalUse.class) // only for callbacks from Jenkins
public void startWatchingForSecrets() {
Expand All @@ -92,15 +97,15 @@ public void startWatchingForSecrets() {
// XXX https://github.com/fabric8io/kubernetes-client/issues/1014
// watch(resourceVersion, watcher) is deprecated but there is nothing to say why?
client = _client;
LOG.log(Level.FINER, "regestering watch");
LOG.log(Level.FINER, "registering watch");
watch = _client.secrets().withLabel(SecretUtils.JENKINS_IO_CREDENTIALS_TYPE_LABEL).watch(list.getMetadata().getResourceVersion(), this);
LOG.log(Level.FINER, "registered watch, retreiving secrets");
LOG.log(Level.FINER, "registered watch, retrieving secrets");
} catch (KubernetesClientException kex) {
LOG.log(Level.SEVERE, "Failed to initialise k8s secret provider, secrets from Kubernetes will not be available", kex);
// TODO add an administrative warning to report this clearly to the admin
}
}


@Terminator(after=TermMilestone.STARTED)
@Restricted(NoExternalUse.class) // only for callbacks from Jenkins
Expand Down Expand Up @@ -195,11 +200,21 @@ IdCredentials convertSecret(Secret s) {
else {
LOG.log(Level.WARNING, "Failed to convert Secret ''{0}'' of type {1} due to {2}", new Object[] {SecretUtils.getCredentialId(s), type, ex.getMessage()});
}
return null;
return null;
}
}
LOG.log(Level.WARNING, "No SecretToCredentialConveror found to convert secrets of type {0}", type);
return null;
}

@Override
public CredentialsStore getStore(ModelObject object) {
return object == Jenkins.getInstance() ? store : null;
}

@Override
public String getIconClassName() {
return "icon-credentials-kubernetes-store";
}

}
@@ -0,0 +1,128 @@
package com.cloudbees.jenkins.plugins.kubernetes_credentials_provider;

import java.util.Collections;
import java.util.List;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.acegisecurity.Authentication;
import org.jenkins.ui.icon.Icon;
import org.jenkins.ui.icon.IconSet;
import org.jenkins.ui.icon.IconType;
import org.kohsuke.stapler.export.ExportedBean;
import hudson.model.ModelObject;
import hudson.security.ACL;
import hudson.security.Permission;
import jenkins.model.Jenkins;
import com.cloudbees.plugins.credentials.Credentials;
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.CredentialsStore;
import com.cloudbees.plugins.credentials.CredentialsStoreAction;
import com.cloudbees.plugins.credentials.domains.Domain;

public class KubernetesCredentialsStore extends CredentialsStore {

private final KubernetesCredentialProvider provider;
private final KubernetesCredentialsStoreAction action = new KubernetesCredentialsStoreAction(this);

public KubernetesCredentialsStore(KubernetesCredentialProvider provider) {
super(KubernetesCredentialProvider.class);
this.provider = provider;
}

@NonNull
@Override
public ModelObject getContext() {
return Jenkins.getInstance();
}

@Override
public boolean hasPermission(@NonNull Authentication authentication, @NonNull Permission permission) {
return CredentialsProvider.VIEW.equals(permission) &&
Jenkins.getInstance().getACL().hasPermission(authentication, permission);
}

@NonNull
@Override
public List<Credentials> getCredentials(@NonNull Domain domain) {
// Only the global domain is supported
return Domain.global().equals(domain)
? provider.getCredentials(Credentials.class, Jenkins.getInstance(), ACL.SYSTEM)
Copy link
Member

Choose a reason for hiding this comment

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

Ahh I think you need to pass jenkins.getAuthentication() rather than ACL.SYSTEM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I do that, then this check fails and we don't see the credentials

Copy link
Member

Choose a reason for hiding this comment

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

Hmm.. I used this code as a reference for that.

: Collections.emptyList();
}

@Override
public boolean addCredentials(@NonNull Domain domain, @NonNull Credentials credentials) {
throw new UnsupportedOperationException();
}

@Override
public boolean removeCredentials(@NonNull Domain domain, @NonNull Credentials credentials) {
throw new UnsupportedOperationException();
}

@Override
public boolean updateCredentials(@NonNull Domain domain, @NonNull Credentials current,
@NonNull Credentials replacement) {
throw new UnsupportedOperationException();
}

@Nullable
@Override
public CredentialsStoreAction getStoreAction() {
return action;
}

/**
* Expose the store.
*/
@ExportedBean
public static class KubernetesCredentialsStoreAction extends CredentialsStoreAction {

private final KubernetesCredentialsStore store;

private KubernetesCredentialsStoreAction(KubernetesCredentialsStore store) {
this.store = store;
addIcons();
}

private void addIcons() {
IconSet.icons.addIcon(new Icon("icon-credentials-kubernetes-store icon-sm",
"kubernetes-credentials-provider/images/16x16/kubernetes-store.png",
Icon.ICON_SMALL_STYLE, IconType.PLUGIN));
IconSet.icons.addIcon(new Icon("icon-credentials-kubernetes-store icon-md",
"kubernetes-credentials-provider/images/24x24/kubernetes-store.png",
Icon.ICON_MEDIUM_STYLE, IconType.PLUGIN));
IconSet.icons.addIcon(new Icon("icon-credentials-kubernetes-store icon-lg",
"kubernetes-credentials-provider/images/32x32/kubernetes-store.png",
Icon.ICON_LARGE_STYLE, IconType.PLUGIN));
IconSet.icons.addIcon(new Icon("icon-credentials-kubernetes-store icon-xlg",
"kubernetes-credentials-provider/images/48x48/kubernetes-store.png",
Icon.ICON_XLARGE_STYLE, IconType.PLUGIN));
}

@Override
@NonNull
public CredentialsStore getStore() {
Copy link
Member

Choose a reason for hiding this comment

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

@Override

return store;
}

@Override
public String getIconFileName() {
return isVisible()
? "/plugin/kubernetes-credentials-provider/images/32x32/kubernetes-store.png"
: null;
}

@Override
public String getIconClassName() {
return isVisible()
Copy link
Member

Choose a reason for hiding this comment

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

what is isVisible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

? "icon-credentials-kubernetes-store"
: null;
}

@Override
public String getDisplayName() {
return "Kubernetes";
}
}
}
Binary file added src/main/webapp/images/16x16/kubernetes-store.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.