HTTP Request inside plugins - How to give permission in a Matrix Based Security System?

66 views
Skip to first unread message

PF66

unread,
Dec 30, 2016, 7:30:35 PM12/30/16
to Jenkins Developers
As the tittle says, how can I do it?

I was trying to get data from the metadata-plugin (https://wiki.jenkins-ci.org/display/JENKINS/Metadata+plugin) through their cli. 
This was working on my local machine until I deployed it on a real system and stopped working. I noticed that it was responding with a 403 - Forbidden and realized that it was because this instance of Jenkins is using the Matrix Based Security.

Once I turned it on my testing environment, stopped retrieving as expected.

The question is, how can I give my Plugin permissions to execute this requests?
The same goes to making the 'Update' method, that doesn't work since the start, maybe because of the same reason.

I read somewhere it might be something about ACL but not sure, I'm still inexperienced in Jenkins developing.

Have installed the HTTP Request plugin if it matters.

My code if it helps:

    public ArrayList<Tag> getBuildTags(int buildNr, String jobName){
       
ArrayList<Tag> tags = new ArrayList<Tag>();
       
try {
           
String requestString;
           
String jenkinsUrl = Jenkins.getInstance().getRootUrl();
           
String encodedJobName = java.net.URLEncoder.encode(jobName, "UTF-8").replace("+", "%20");
           
String metadataApiRequest = "metadata-httpcli/get?job=" + encodedJobName + "&build=" + buildNr;
            requestString
= jenkinsUrl + metadataApiRequest;
            URL url
= new URL(requestString);
           
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection
.setRequestMethod("GET");
           
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
               
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
               
StringBuffer resultString = new StringBuffer();
               
String response;

               
while ((response = rd.readLine()) != null) {
                    resultString
.append(response);
               
}
                rd
.close();

               
JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON(resultString.toString());

               
for (int i = 0; i < jsonArray.size(); i++) {
                   
String name = jsonArray.getJSONObject(i).get("name").toString();
                   
switch (name) {
                       
//Hide metadata-plugin predefined tags
                       
case "job-info":
                           
break;
                       
case "build":
                           
break;
                       
default:
                           
String value = jsonArray.getJSONObject(i).get("value").toString();
                            tags
.add(new Tag(name.toUpperCase(), value.toLowerCase()));
                           
break;
                   
}
               
}
           
}
        connection
.disconnect();
       
}catch (IOException e){
            e
.printStackTrace();
       
}

       
return tags;
   
}


Gavin Mogan

unread,
Dec 31, 2016, 3:43:07 AM12/31/16
to Jenkins Developers
Are you making a plugin to access data from another plugin using the rest API?

I'm on mobile right now so I can't check but I'm pretty sure that plugin like most others will have actions (getActions()) attached to the build. Nothing exposed by rest should be hidden from native interfaces.

If you are just writing a script, it belongs on the users list, but you'll need to create/reuse an existing user. All users will have username and API tokens on thier edit profile page, you should be able to use that to basic authenticate for APIs.

Gavin

PF66

unread,
Jan 1, 2017, 11:59:49 AM1/1/17
to Jenkins Developers
On the plugin there is a doGet() and doUpdate() (https://github.com/jenkinsci/metadata-plugin/blob/0a780cfd6ce11aba43bcd5e220bd3a318f0b33e9/src/main/java/com/sonyericsson/hudson/plugins/metadata/cli/HttpCliRootAction.java)

How can I call those inside my own plugin? I'm having trouble create the StaplerRequest/Response and process them.
Maybe it isn't this the way to go?

Tomas Westling

unread,
Jan 3, 2017, 4:45:24 AM1/3/17
to Jenkins Developers
As Gavin says, if you want to read or manipulate the metadata from a plugin, you shouldn't use the rest api.
For nodes, the metadata is stored as NodeProperties, look at MetadadataNodeProperty.java.
For Jobs and Builds, look at the actions MetadataJobAction.java and MetadataBuildAction.java, these are available on jobs and builds
that have metadata associated with them.

Br Tomas

Daniel Beck

unread,
Jan 3, 2017, 6:02:47 AM1/3/17
to jenkin...@googlegroups.com

> On 03.01.2017, at 10:45, Tomas Westling <tomas.w...@axis.com> wrote:
>
> As Gavin says, if you want to read or manipulate the metadata from a plugin, you shouldn't use the rest api.
> For nodes, the metadata is stored as NodeProperties, look at MetadadataNodeProperty.java.
> For Jobs and Builds, look at the actions MetadataJobAction.java and MetadataBuildAction.java, these are available on jobs and builds
> that have metadata associated with them.

PF66 already got help on IRC (and didn't bother updating this thread with that information).

PF66

unread,
Jan 3, 2017, 8:19:22 AM1/3/17
to Jenkins Developers
Thanks for the reply.
As Daniel Beck said, I got the answer yesterday and forgot to update this thread. My mistake.

Resolved by doing this:

MetadataBuildAction metadataBuild = Jenkins.getInstance().getItemByFullName(jobName, Job.class).getBuildByNumber(buildNr).getAction(MetadataBuildAction.class);

if(metadataBuild != null) {
    Collection<String> metadataNames = metadataBuild.getChildNames();

I'm sorry if it might seem trivial but since I'm fairly new to this, I still have to catch all this little nuances.

But still related, how can I do the 'update' of a value on a groovy script inside a pipeline job? 
I still need to access like this or do a cli/request?

Tomas Westling

unread,
Jan 3, 2017, 9:19:56 AM1/3/17
to Jenkins Developers
Yes, I would still do it like this.
The rest api is meant to be used to control/query Jenkins from the outside of Jenkins, e.g. from other services that aren't running in Jenkins.
If you are in groovy inside the Jenkins instance, it's sort of a detour to use the rest api.

Look at e.g. the BuildContributorsController.onCompleted method and the StandardBuildMetadataContributor, it adds metadata to a build as it completes and do something similar in your script.

Br Tomas

PF66

unread,
Jan 3, 2017, 2:53:55 PM1/3/17
to Jenkins Developers
Tried to search how to do it, and have this issue:

Noticed that I can't add Metadata to a Pipeline, and was pointed out on IRC that MetadataJobProperty extends AbstractProject, while Pipeline (WorkflowJob) doesn't extend it:

stage 'testMetadata'
node{

    def testJob = currentBuild;
    properties([[$class :'MetadataJobProperty', 
                values : [[
                            $class: 'StringMetadataValue', 
                            name : 'owner', 
                            value : 'bob'
                        ]]
                ]]);
}

This returns the error: ERROR: cannot apply com.sonyericsson.hudson.plugins.metadata.model.MetadataJobProperty to a WorkflowJob
So is it possible to correct this?

Robert Sandell

unread,
Jan 4, 2017, 7:53:27 AM1/4/17
to jenkin...@googlegroups.com
The metadata plugin was written in the "pre-pipeline job type era" (it is expecting AbstractProjects) and needs some work to be able to store metadata on pipeline jobs.

/B

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/d8306864-e156-425e-962b-3467dad93f23%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Robert Sandell
Software Engineer
CloudBees Inc.
Reply all
Reply to author
Forward
0 new messages