3 | These access tokens serve as a way of authenticating requests to the
4 | dockerhub-webhook, dockerregistry-webhook and acr-webhook endpoints.
5 |
6 |
7 | By default, all requests to those endpoints must include a valid token in the path component before /notify.
8 | E.g. https://jenkins/dockerhub-webhook/{token}/notify
9 | However, it is possible to disable that requirement with the
10 | system property:
11 |
14 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/token/ApiTokens/resources.css:
--------------------------------------------------------------------------------
1 | .dockerhub-api-token-list .dockerhub-api-token-list-item-row {
2 | display: flex;
3 | align-items: center;
4 | max-width: 700px;
5 | }
6 | .dockerhub-api-token-list .dockerhub-api-token-list-item-row.dockerhub-api-token-list-existing-api-token {
7 | justify-content: space-between;
8 | }
9 | .dockerhub-api-token-list .dockerhub-api-token-list-item .hidden, .dockerhub-api-token-list .dockerhub-api-token-list-empty-item.hidden {
10 | display: none;
11 | }
12 |
13 | .dockerhub-api-token-list .dockerhub-api-token-revoke-button, .dockerhub-api-token-list .dockerhub-new-api-token-value {
14 | padding: 0 0.5rem;
15 | }
16 | .dockerhub-api-token-list .dockerhub-api-token-warning-message, .dockerhub-api-token-list .dockerhub-api-token-save-button {
17 | margin: 0.5rem 0;
18 | }
19 | .dockerhub-api-token-created {
20 | font-size: smaller;
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/acr/ACRWebHook.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.registry.notification.webhook.acr;
2 |
3 | import hudson.Extension;
4 | import net.sf.json.JSONObject;
5 | import org.jenkinsci.plugins.registry.notification.webhook.JSONWebHook;
6 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
7 |
8 | /**
9 | * The ACRWebHook handles incoming updates from the Azure Container Registry. The provided payload differs minimally
10 | * from what is transmitted by a standard Docker Registry v2 server, which made this separate implementation necessary.
11 | */
12 | @Extension
13 | public class ACRWebHook extends JSONWebHook {
14 | /**
15 | * The namespace under Jenkins context path that this Action is bound to.
16 | */
17 | public static final String URL_NAME = "acr-webhook";
18 |
19 | @Override
20 | protected WebHookPayload createPushNotification(JSONObject payload) {
21 | return new ACRWebHookPayload(payload);
22 | }
23 |
24 | public String getUrlName() {
25 | return URL_NAME;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/resources/private-registry-payload-1-repository.json:
--------------------------------------------------------------------------------
1 | {
2 | "events": [
3 | {
4 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
5 | "timestamp": "2015-10-06T13:00:54.450615408Z",
6 | "action": "push",
7 | "target": {
8 | "mediaType": "application/octet-stream",
9 | "size": 17680408,
10 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
11 | "length": 17680408,
12 | "repository": "jplock/zookeeper",
13 | "url": "http://registry:5000/v2/jplock/zookeeper/manifests/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
14 | },
15 | "request": {
16 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
17 | "addr": "172.17.42.1:48845",
18 | "host": "registry:5000",
19 | "method": "PUT",
20 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
21 | },
22 | "actor": {},
23 | "source": {
24 | "addr": "5dc36776cd85:5000",
25 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
26 | }
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2015, CloudBees, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | #TODO
2 |
3 | ##Auto Hook
4 | Currently the [Docker Hub API](https://docs.docker.com/docker-hub/repos/#webhooks) doesn't support adding web hooks.
5 | When support for that is added this plugin should be updated to *automagically* add the hook when configured.
6 |
7 | ##Hook origin Security
8 | The plugin currently blindly accept a wel formed HTTP POST to the end point that contains expected data.
9 | Some measures should be taken to be a bit more secure. Two examples that could both be implemented.
10 |
11 | ###Origin IP check
12 | The [Docker Hub API](https://docs.docker.com/docker-hub/repos/#webhooks) documentation mentions an IP range that all their hooks are coming from.
13 | Implement an IP range check that ignores HTTP POSTs from clients not in that range.
14 | The ranges should be configurable by an admin in case of for example internal proxies.
15 | Work has been started on the `from-trusted-ip` branch.
16 |
17 | ###Poll Docker Hub when a hook arrives to verify that something has actually happened.
18 | This could be tricky due to the CDN that Docker Hub is using. At least from a user's perspective
19 | information isn't updated in the UI until minutes after the actual push and web hook post.
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/index.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | title=Build results for push of {0} to Docker Hub at {1}
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/main.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | heading=Build results for push of {0} to Docker Hub at {1}
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn/columnHeader.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | tooltip=Docker Hub Notification: Triggered on image names.
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/jobs/JenkinsSlaveTrigger/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 |
14 |
15 |
16 |
17 |
18 | csanchez/jenkins-swarm-slave
19 |
20 |
21 |
22 |
23 |
24 | false
25 |
26 |
27 | env | sort | grep DOCKER
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/NoResultPage/main.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | blurb=Could not find the build results, it could be because Jenkins has removed all build records.
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn/help-showMax.html:
--------------------------------------------------------------------------------
1 |
26 |
The max ammount of image names to list. A value of < 0 will show all.
28 | Integrates Jenkins with DockerHub and Docker Registry
29 |
30 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/opt/impl/TriggerForAllUsedInJob/help.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | blurb=Trigger the job based on repositories used by any compatible docker plugin in this job. Currently installed compatible plugins are:
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn/columnHeader.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.TriggerListViewColumn
25 |
26 | th(tooltip: _("tooltip"), my.columnCaption)
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerViewFilter/help.html:
--------------------------------------------------------------------------------
1 |
26 |
27 | Show jobs that has a Run when a new image is pushed to Docker Hub trigger configured.
28 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/NoResultPage/main.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.ResultPage.NoResultPage
25 |
26 | h1(_("No result found"))
27 | p(_("blurb"))
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/DockerPullImageBuilder/help-image.html:
--------------------------------------------------------------------------------
1 |
26 |
27 | Image ID on DockerHub. When set in combination with DockerHub trigger, a build will run when dockerhub
28 | builds a new image.
29 |
30 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn/config.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.TriggerListViewColumn
25 |
26 | def f = namespace(lib.FormTagLib)
27 |
28 | f.entry(title: "Max", field: "showMax") {
29 | f.textbox(type: "number", name: "showMax")
30 | }
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerViewFilter/config.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.TriggerViewFilter
25 |
26 | def f = namespace(lib.FormTagLib)
27 |
28 | f.entry(title: _("Patterns")) {
29 | f.expandableTextbox(name: "patterns", field: "patterns", value: instance?.patterns?.join("\n"))
30 | }
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerViewFilter/help-patterns.html:
--------------------------------------------------------------------------------
1 |
26 |
27 | You can specify a list of
28 | Regular expressions
29 | to match on the image names. One pattern per line.
30 |
31 |
32 | Leave blank to match any image name.
33 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn/column.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.TriggerListViewColumn
25 |
26 | td {
27 | ul(style: "list-style: none; padding-left: 0; margin: 0") {
28 | my.getImageNames(job).each { String name ->
29 | li {
30 | text(name)
31 | }
32 | }
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/opt/impl/TriggerOnSpecifiedImageNames/config.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt.impl.TriggerOnSpecifiedImageNames
25 |
26 | def st = namespace("jelly:stapler")
27 | def f = namespace(lib.FormTagLib)
28 |
29 | f.entry(title:_("Repositories"), field: "repoNames") {
30 | f.expandableTextbox(value: instance?.repoNames?.join("\n"))
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/DockerPullImageBuilder/config.jelly:
--------------------------------------------------------------------------------
1 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/CallbackHandler.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import hudson.model.Run;
27 |
28 | import java.io.IOException;
29 | import java.util.concurrent.ExecutionException;
30 |
31 | public interface CallbackHandler {
32 | void notify(PushNotification pushNotification, Run, ?> run) throws InterruptedException, ExecutionException, IOException;
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/jobs/OneConfigured/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | rsandell/test
20 |
21 |
22 |
23 |
24 |
25 | false
26 |
27 |
28 | rsandell/test
29 |
30 | http://hub.rsandell.com
31 |
32 |
33 |
34 | env | sort
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/opt/impl/TriggerForAllUsedInJob/help.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt.impl.TriggerForAllUsedInJob
25 |
26 | import hudson.ExtensionList
27 | import jenkins.model.Jenkins
28 | import org.jenkinsci.plugins.docker.commons.DockerImageExtractor
29 |
30 | p(_("blurb"))
31 | ul {
32 | ExtensionList.lookup(DockerImageExtractor).collect{return Jenkins.instance.pluginManager.whichPlugin(it.class)}.toSet().each {
33 | if (it != null) {
34 | li(it.getDisplayName())
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/DockerHubTrigger/help.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | generalBlurb=The job will get triggered when Docker Hub/Registry/ACR notifies about Docker image(s) used in this job has been rebuilt.
26 | details=The Docker Hub does not yet support adding web hooks via the API, so you will need to configure that manually;\
27 | In your Docker Hub repository, you can find the "webhooks" section and point it to your jenkins instance,\
28 | set it to one of the below endpoints.
29 | dockerHubUrlBlurb=On Docker Hub
30 | dockerRegistryUrlBlurb=On Docker Registry
31 | acrUrlBlurb=On Azure Container Registry
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/opt/TriggerOption.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt;
25 |
26 | import edu.umd.cs.findbugs.annotations.NonNull;
27 | import hudson.model.AbstractDescribableImpl;
28 | import hudson.model.Job;
29 |
30 | import java.util.Collection;
31 |
32 | /**
33 | * A base option in the trigger config.
34 | *
35 | * @author Robert Sandell <rsandell@cloudbees.com>.
36 | */
37 | public abstract class TriggerOption extends AbstractDescribableImpl {
38 | @NonNull
39 | public abstract Collection getRepoNames(Job,?> job);
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/opt/TriggerOptionDescriptor.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt;
25 |
26 | import hudson.ExtensionList;
27 | import hudson.model.Descriptor;
28 |
29 | import java.util.List;
30 |
31 | /**
32 | * The descriptor of {@link TriggerOption}.
33 | *
34 | * @author Robert Sandell <rsandell@cloudbees.com>.
35 | */
36 | public abstract class TriggerOptionDescriptor extends Descriptor {
37 |
38 | public static List all() {
39 | return ExtensionList.lookup(TriggerOptionDescriptor.class);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/WebHookCause.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import edu.umd.cs.findbugs.annotations.NonNull;
27 | import hudson.model.Cause;
28 |
29 | public abstract class WebHookCause extends Cause {
30 | @NonNull
31 | protected PushNotification pushNotification;
32 |
33 | public WebHookCause(@NonNull PushNotification pushNotification) {
34 | this.pushNotification = pushNotification;
35 | }
36 |
37 | @NonNull
38 | public PushNotification getPushNotification() {
39 | return pushNotification;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/Messages.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2015, CloudBees, Inc.
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | DockerHubTrigger.DisplayName=Monitor Docker Hub/Registry for image changes
26 | DockerPullImageBuilder.DisplayName=Pull Docker image from Docker Hub/Registry
27 | ResultPage.DisplayName=Results for {0}
28 | TriggerViewFilter_DisplayName=Triggered by push to Docker Hub/Registry
29 | TriggerViewFilter_CompileError=Patterns could not be compiled
30 | TriggerListViewColumn_DisplayName=Docker Hub image names being triggered on
31 | TriggerListViewColumn.ColumnCaption=DHT
32 |
33 | TriggerOption.TriggerForAllUsedInJob.DisplayName=Any referenced Docker image can trigger this job
34 | TriggerOption.TriggerOnSpecifiedImageNames.DisplayName=Specified repositories will trigger this job
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/index.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.ResultPage
25 |
26 | import org.jenkinsci.plugins.registry.notification.TriggerStore
27 | import jenkins.model.Jenkins
28 |
29 | def l = namespace(lib.LayoutTagLib)
30 | def st = namespace("jelly:stapler")
31 |
32 | TriggerStore.TriggerEntry data = my.data
33 | String repoName = data != null ? data.pushNotification.repoName : ""
34 | Date timestamp = data?.pushNotification?.pushedAt;
35 |
36 |
37 | l.layout(title: _("title", repoName, timestamp), norefresh: true, permission: Jenkins.READ) {
38 | include(Jenkins.instance, "sidepanel.jelly")
39 | l."main-panel" {
40 | set("repoName", repoName)
41 | set("triggerData", data)
42 | include(my, "main.groovy")
43 | }
44 | }
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/DockerHubTrigger/config.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.DockerHubTrigger
25 |
26 | import org.jenkinsci.plugins.registry.notification.DockerHubTrigger
27 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOptionDescriptor
28 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerForAllUsedInJob
29 |
30 | def st = namespace("jelly:stapler")
31 | def f = namespace(lib.FormTagLib)
32 |
33 | def defaultOption = [:]
34 | defaultOption[TriggerForAllUsedInJob.DescriptorImpl.instance] = new TriggerForAllUsedInJob()
35 |
36 | DockerHubTrigger trigger = instance;
37 |
38 | f.descriptorList(title: null,
39 | field: "options",
40 | descriptors: TriggerOptionDescriptor.all(),
41 | instances: trigger != null ? trigger.optionsList : defaultOption)
42 |
--------------------------------------------------------------------------------
/src/test/resources/private-registry-payload-2-repositories.json:
--------------------------------------------------------------------------------
1 | {
2 | "events": [
3 | {
4 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
5 | "timestamp": "2015-10-06T13:00:54.450615408Z",
6 | "action": "push",
7 | "target": {
8 | "mediaType": "application/octet-stream",
9 | "size": 17680408,
10 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
11 | "length": 17680408,
12 | "repository": "jplock/zookeeper",
13 | "url": "http://registry:5000/v2/jplock/zookeeper/manifests/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
14 | },
15 | "request": {
16 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
17 | "addr": "172.17.42.1:48845",
18 | "host": "registry:5000",
19 | "method": "PUT",
20 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
21 | },
22 | "actor": {},
23 | "source": {
24 | "addr": "5dc36776cd85:5000",
25 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
26 | }
27 | },
28 | {
29 | "id": "154beacd-cd29-4989-bc5e-1a353a776337",
30 | "timestamp": "2015-10-09T13:25:04.102522145Z",
31 | "action": "push",
32 | "target": {
33 | "mediaType": "application/octet-stream",
34 | "size": 71478,
35 | "digest": "sha256:2dbe4abf311d67ec224f926d4b21b9be6f96dfba9be139e6936156a67b75a1ad",
36 | "length": 71478,
37 | "repository": "ubuntu",
38 | "url": "http://registry:5000/v2/ubuntu/manifests/sha256:2dbe4abf311d67ec224f926d4b21b9be6f96dfba9be139e6936156a67b75a1ad"
39 | },
40 | "request": {
41 | "id": "bd07c479-6ad8-4d80-b9cc-aaf9952e39d8",
42 | "addr": "172.17.42.1:41179",
43 | "host": "registry:5000",
44 | "method": "PUT",
45 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
46 | },
47 | "actor": {},
48 | "source": {
49 | "addr": "8c112cfc3fa7:5000",
50 | "instanceID": "a2e89cfe-90e3-4087-8bd5-c0ee89f5ce29"
51 | }
52 | }
53 | ]
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/DockerHubTrigger/help.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.DockerHubTrigger
25 |
26 | import jenkins.model.Jenkins
27 |
28 | def webHookUrl(String rootAction) {
29 | String rootUrl = Jenkins.instance?.getRootUrl() ?: "http://myJENKINS/";
30 | return rootUrl + "${rootAction}/{api-token}/notify"
31 | }
32 |
33 | p(_("generalBlurb"))
34 | p(_("details"))
35 | ul {
36 | li {
37 | em {
38 | strong(webHookUrl('dockerhub-webhook'))
39 | raw(' ')
40 | span(_('dockerHubUrlBlurb'))
41 | }
42 | }
43 | li {
44 | em {
45 | strong(webHookUrl('dockerregistry-webhook'))
46 | raw(' ')
47 | span(_('dockerRegistryUrlBlurb'))
48 | }
49 | }
50 | li {
51 | em {
52 | strong(webHookUrl('acr-webhook'))
53 | raw(' ')
54 | span(_('acrUrlBlurb'))
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/resources/private-registry-payload-blob-1-repository.json:
--------------------------------------------------------------------------------
1 | {
2 | "events": [
3 | {
4 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
5 | "timestamp": "2015-10-06T13:00:54.450615408Z",
6 | "action": "push",
7 | "target": {
8 | "mediaType": "application/octet-stream",
9 | "size": 17680408,
10 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
11 | "length": 17680408,
12 | "repository": "jplock/zookeeper",
13 | "url": "http://registry:5000/v2/jplock/zookeeper/blob/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
14 | },
15 | "request": {
16 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
17 | "addr": "172.17.42.1:48845",
18 | "host": "registry:5000",
19 | "method": "PUT",
20 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
21 | },
22 | "actor": {},
23 | "source": {
24 | "addr": "5dc36776cd85:5000",
25 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
26 | }
27 | },
28 | {
29 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
30 | "timestamp": "2015-10-06T13:00:54.450615408Z",
31 | "action": "push",
32 | "target": {
33 | "mediaType": "application/octet-stream",
34 | "size": 17680408,
35 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
36 | "length": 17680408,
37 | "repository": "jplock/zookeeper",
38 | "url": "http://registry:5000/v2/jplock/zookeeper/manifests/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
39 | },
40 | "request": {
41 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
42 | "addr": "172.17.42.1:48845",
43 | "host": "registry:5000",
44 | "method": "PUT",
45 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
46 | },
47 | "actor": {},
48 | "source": {
49 | "addr": "5dc36776cd85:5000",
50 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
51 | }
52 | }
53 | ]
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/resources/private-registry-payload-pull-1-repository.json:
--------------------------------------------------------------------------------
1 | {
2 | "events": [
3 | {
4 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
5 | "timestamp": "2015-10-06T13:00:54.450615408Z",
6 | "action": "pull",
7 | "target": {
8 | "mediaType": "application/octet-stream",
9 | "size": 17680408,
10 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
11 | "length": 17680408,
12 | "repository": "jplock/zookeeper",
13 | "url": "http://registry:5000/v2/jplock/zookeeper/manifests/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
14 | },
15 | "request": {
16 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
17 | "addr": "172.17.42.1:48845",
18 | "host": "registry:5000",
19 | "method": "PUT",
20 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
21 | },
22 | "actor": {},
23 | "source": {
24 | "addr": "5dc36776cd85:5000",
25 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
26 | }
27 | },
28 | {
29 | "id": "9d9e2ab1-d38e-4f71-8091-2ed699e7a6a5",
30 | "timestamp": "2015-10-06T13:00:54.450615408Z",
31 | "action": "push",
32 | "target": {
33 | "mediaType": "application/octet-stream",
34 | "size": 17680408,
35 | "digest": "sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720",
36 | "length": 17680408,
37 | "repository": "jplock/zookeeper",
38 | "url": "http://registry:5000/v2/jplock/zookeeper/manifests/sha256:55d2be3e073109b6dfa68aa6ffbce9f5441ab8dd451834eaf0e81874a0b1b720"
39 | },
40 | "request": {
41 | "id": "d5af37fb-e766-43a1-81a2-ff6270d96ac8",
42 | "addr": "172.17.42.1:48845",
43 | "host": "registry:5000",
44 | "method": "PUT",
45 | "useragent": "docker/1.7.0 go/go1.4.2 git-commit/0baf609 kernel/4.0.5-boot2docker os/linux arch/amd64"
46 | },
47 | "actor": {},
48 | "source": {
49 | "addr": "5dc36776cd85:5000",
50 | "instanceID": "7ca5f1ec-f184-4c47-b4ce-4ad7090dc25d"
51 | }
52 | }
53 |
54 | ]
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/acr/ACRWebHookPayload.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.registry.notification.webhook.acr;
2 |
3 | import edu.umd.cs.findbugs.annotations.NonNull;
4 | import net.sf.json.JSONObject;
5 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
6 | import org.joda.time.format.DateTimeFormatter;
7 | import org.joda.time.format.ISODateTimeFormat;
8 |
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | /**
13 | * Partially implements https://docs.microsoft.com/en-us/azure/container-registry/container-registry-webhook-reference.
14 | */
15 | public class ACRWebHookPayload extends WebHookPayload {
16 | private static final Logger logger = Logger.getLogger(ACRWebHookPayload.class.getName());
17 |
18 | public enum Action {
19 | PUSH("push");
20 | private String name;
21 |
22 | private Action(String name) {
23 | this.name = name;
24 | }
25 |
26 | public String getName() {
27 | return this.name;
28 | }
29 | }
30 |
31 | public ACRWebHookPayload(@NonNull final JSONObject data) {
32 | setData(data);
33 | setJson(data.toString());
34 |
35 | if (Action.PUSH.getName().equals(data.optString("action"))) {
36 | final JSONObject event = data;
37 | final String host = event.getJSONObject("request").getString("host");
38 | final String url = new StringBuilder()
39 | .append(host).append("/").append(event.getJSONObject("target").getString("repository"))
40 | .toString();
41 | if (logger.isLoggable(Level.FINE)) {
42 | logger.log(Level.FINE, "Creating push notification for " + url);
43 | }
44 | pushNotifications.add(new ACRPushNotification(this, url){{
45 | DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
46 | setPushedAt(parser.parseDateTime(event.getString("timestamp")).toDate());
47 | setRegistryHost(host);
48 | }});
49 | } else {
50 | logger.log(Level.FINER, "Unsupported event received: " + data.toString());
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerregistry/DockerRegistryWebHookCause.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, HolidayCheck AG.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerregistry;
25 |
26 |
27 | import edu.umd.cs.findbugs.annotations.NonNull;
28 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookCause;
29 |
30 | /**
31 | * The build cause of {@link DockerRegistryWebHook}.
32 | */
33 | public class DockerRegistryWebHookCause extends WebHookCause {
34 |
35 | public DockerRegistryWebHookCause(@NonNull DockerRegistryPushNotification dockerRegistryPushNotification) {
36 | super(dockerRegistryPushNotification);
37 | }
38 |
39 | @Override
40 | public String getShortDescription() {
41 | return String.format("Triggered by %s", getPushNotification().getShortDescription());
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return "DockerRegistryWebHookCause{" +
47 | "payload=" + getPushNotification().getWebHookPayload() +
48 | '}';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerregistry/DockerRegistryWebHook.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, HolidayCheck AG.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerregistry;
25 |
26 | import hudson.Extension;
27 | import net.sf.json.JSONObject;
28 | import org.jenkinsci.plugins.registry.notification.webhook.JSONWebHook;
29 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
30 |
31 | import java.util.logging.Logger;
32 |
33 | /**
34 | * The terminal point for the DockerRegistry web hook.
35 | * See Reference
36 | */
37 | @Extension
38 | public class DockerRegistryWebHook extends JSONWebHook {
39 | private static final Logger logger = Logger.getLogger(DockerRegistryWebHook.class.getName());
40 |
41 | /**
42 | * The namespace under Jenkins context path that this Action is bound to.
43 | */
44 | public static final String URL_NAME = "dockerregistry-webhook";
45 |
46 | @Override
47 | protected WebHookPayload createPushNotification(JSONObject payload) {
48 | return new DockerRegistryWebHookPayload(payload);
49 | }
50 |
51 | public String getUrlName() {
52 | return URL_NAME;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerhub/DockerHubWebHookCause.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerhub;
25 |
26 |
27 | import edu.umd.cs.findbugs.annotations.NonNull;
28 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookCause;
29 |
30 | /**
31 | * The build cause of {@link DockerHubWebHook}.
32 | */
33 | public class DockerHubWebHookCause extends WebHookCause {
34 |
35 | public DockerHubWebHookCause(@NonNull DockerHubPushNotification dockerHubPushNotification) {
36 | super(dockerHubPushNotification);
37 | }
38 |
39 | @Override
40 | public String getShortDescription() {
41 | return String.format("Triggered by %s", getPushNotification().getShortDescription());
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return "DockerHubWebHookCause{" +
47 | "payload=" + getPushNotification().getWebHookPayload() +
48 | '}';
49 | }
50 |
51 | private transient DockerHubWebHookPayload payload;
52 |
53 | public Object readResolve() {
54 | if (payload != null) {
55 | this.pushNotification = payload.getPushNotifications().get(0);
56 | }
57 | return this;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/registry/notification/webhook/WebHookPayloadTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import hudson.util.XStream2;
27 | import net.sf.json.JSONObject;
28 | import org.jenkinsci.plugins.registry.notification.webhook.dockerhub.DockerHubWebHookPayload;
29 | import org.junit.Test;
30 |
31 | import static org.hamcrest.core.IsNot.not;
32 | import static org.hamcrest.core.StringContains.containsString;
33 | import static org.hamcrest.MatcherAssert.assertThat;
34 | import static org.junit.Assert.assertNotNull;
35 |
36 | public class WebHookPayloadTest {
37 |
38 | @Test
39 | public void testSerialization() throws Exception {
40 | JSONObject json = new JSONObject();
41 | JSONObject repository = new JSONObject();
42 | repository.put("repo_name", "cb/jenkins");
43 | json.put("repository", repository);
44 | WebHookPayload obj = new DockerHubWebHookPayload(json);
45 |
46 | XStream2 xs = new XStream2();
47 | xs.allowTypes(new Class[] {DockerHubWebHookPayload.class});
48 | String xml = xs.toXML(obj);
49 | assertThat(xml, not(containsString("")));
50 |
51 | DockerHubWebHookPayload nObj = (DockerHubWebHookPayload)xs.fromXML(xml);
52 | assertNotNull(nObj.getData());
53 | assertNotNull(nObj.getData().get("repository"));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CloudBees Docker Hub/Registry Notification
2 | ================
3 |
4 | This plugin provides integration between
5 | * Jenkins and Docker Hub
6 | * Jenkins and Docker Registry 2.0
7 |
8 | It does so by utilizing webhooks to trigger one (or more) Jenkins job(s).
9 | This allows you to implement continuous delivery pipelines based on Docker in Jenkins.
10 |
11 | When Jenkins receives a notification of an updated image that is a web-hook from
12 | Docker Hub, it triggers all jobs that have the Docker Hub
13 | trigger enabled and use the Docker image as part of the build. A
14 | Docker Hub Pull build step is provided to retrieve the latest image from
15 | Hub.
16 |
17 | # Configuring Docker Hub
18 |
19 | On the Jenkins Configure Global Security page add an api key.
20 |
21 |
22 |
23 | Configure your Docker Hub repository with a webhook to your public jenkins instance `http://JENKINS/dockerhub-webhook/{api-key}/notify`
24 |
25 | In your hub.docker.com repository, you can find the "webhooks" section and point it to your jenkins instance:
26 |
27 |
28 |
29 | # Configuring Docker Registry 2.0
30 |
31 | Follow Docker Registry 2.0 [documentation](https://docs.docker.com/registry/notifications/) on how to configure registry so that it would send notifications to `http://JENKINS/dockerregistry-webhook/{api-key}/notify`
32 |
33 | The simplest viable configuration looks like this:
34 | ```
35 | notifications:
36 | endpoints:
37 | - name: jenkinslistener
38 | url: http://JENKINS/dockerregistry-webhook/{api-key}/notify
39 | timeout: 500ms
40 | threshold: 5
41 | backoff: 1s
42 | ```
43 |
44 | # Configuring Azure Container Registry
45 |
46 | You can find a detailed guide on how to configure webhooks on ACR on
47 | [docs.microsoft.com](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-webhook).
48 | Use `http://JENKINS/acr-webhook/{api-key}/notify` as a "Service URI".
49 |
50 |
51 | # Examples
52 |
53 | Payloads submitted by the hub:
54 |
55 | * [Payload from your own repository](src/test/resources/own-repository-payload.json).
56 | * [Payload from a public repository](src/test/resources/public-repository-payload.json).
57 |
58 | Payloads submitted by the registry:
59 |
60 | * [Payload from your own registry](/src/test/resources/private-registry-payload-1-repository.json).
61 |
62 | The plugin can be tested with
63 |
64 | ```bash
65 | curl -X POST -H "Content-Type: application/json" http://localhost:8080/jenkins/dockerhub-webhook/{api-key}/notify -d @src/test/resources/public-repository-payload.json
66 | ```
67 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/ResultPage.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import edu.umd.cs.findbugs.annotations.CheckForNull;
27 | import hudson.model.ModelObject;
28 | import org.jenkinsci.plugins.registry.notification.Messages;
29 | import org.jenkinsci.plugins.registry.notification.TriggerStore;
30 |
31 | /**
32 | * Landing page from Docker Hub when multiple builds where triggered for the same web hook.
33 | * @author Robert Sandell <rsandell@cloudbees.com>.
34 | *
35 | * See main.groovy
36 | */
37 | public class ResultPage implements ModelObject {
38 | public static final ResultPage NO_RESULT = new NoResultPage();
39 |
40 | private TriggerStore.TriggerEntry data;
41 |
42 | public ResultPage(TriggerStore.TriggerEntry data) {
43 | this.data = data;
44 | }
45 |
46 | @CheckForNull
47 | public TriggerStore.TriggerEntry getData() {
48 | return data;
49 | }
50 |
51 | @Override
52 | public String getDisplayName() {
53 | String repoName = "";
54 | if (data != null) {
55 | repoName = data.getPushNotification().getRepoName();
56 | }
57 | return Messages.ResultPage_DisplayName(repoName);
58 | }
59 |
60 | public static class NoResultPage extends ResultPage {
61 |
62 | public NoResultPage() {
63 | super(null);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/resources/own-repository-payload.json:
--------------------------------------------------------------------------------
1 | {
2 | "push_data": {
3 | "pushed_at": 1429028158,
4 | "images": [
5 | "imagehash1",
6 | "imagehash2",
7 | "imagehash3"
8 | ],
9 | "pusher": "csanchez"
10 | },
11 | "callback_url": "https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/hook/2g1gggacfij1c4a3jd00bf4fe3c3ec0da/",
12 | "repository": {
13 | "status": "Active",
14 | "description": "",
15 | "is_trusted": true,
16 | "full_description": "# Jenkins swarm slave\n\n[`csanchez/jenkins-swarm-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/)\n\nA [Jenkins swarm](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin) slave.\n\nFor a container with ssh enabled see\n[`csanchez/jenkins-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-slave/)\n\nFor a container with many build tools installed see\n[`maestrodev/build-agent`](https://registry.hub.docker.com/u/maestrodev/build-agent/)\n\n## Running\n\nTo run a Docker container passing [any parameters](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin#SwarmPlugin-AvailableOptions) to the slave\n\n docker run csanchez/jenkins-swarm-slave -master http://jenkins:8080 -username jenkins -password jenkins -executors 1\n\nLinking to the Jenkins master container there is no need to use `--master`\n\n docker run -d --name jenkins -p 8080:8080 csanchez/jenkins-swarm\n docker run -d --link jenkins:jenkins csanchez/jenkins-swarm-slave -username jenkins -password jenkins -executors 1\n\n\n# Building\n\n docker build -t csanchez/jenkins-swarm-slave .\n",
17 | "repo_url": "https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/",
18 | "owner": "csanchez",
19 | "is_official": false,
20 | "is_private": false,
21 | "name": "jenkins-swarm-slave",
22 | "namespace": "csanchez",
23 | "star_count": 2,
24 | "comment_count": 0,
25 | "date_created": 1410991410,
26 | "dockerfile": "FROM java:8u40-b22-jdk\n\nMAINTAINER Carlos Sanchez \n\nENV JENKINS_SWARM_VERSION 1.22\nENV HOME /home/jenkins-slave\n\nRUN useradd -c \"Jenkins Slave user\" -d $HOME -m jenkins-slave\nRUN curl --create-dirs -sSLo /usr/share/jenkins/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/plugins/swarm-client/$JENKINS_SWARM_VERSION/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar \\\n && chmod 755 /usr/share/jenkins\n\nCOPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh\n\nUSER jenkins-slave\n\nVOLUME /home/jenkins-slave\n\nENTRYPOINT [\"/usr/local/bin/jenkins-slave.sh\"]\n",
27 | "repo_name": "csanchez/jenkins-swarm-slave"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/EnvContributor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.registry.notification;
26 |
27 | import edu.umd.cs.findbugs.annotations.NonNull;
28 | import hudson.EnvVars;
29 | import hudson.Extension;
30 | import hudson.model.EnvironmentContributor;
31 | import hudson.model.ParameterValue;
32 | import hudson.model.Run;
33 | import hudson.model.TaskListener;
34 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookCause;
35 | import org.kohsuke.accmod.Restricted;
36 | import org.kohsuke.accmod.restrictions.NoExternalUse;
37 |
38 | import java.io.IOException;
39 | import java.util.Set;
40 |
41 | /**
42 | * Provides environment variables to builds triggered by the plugin.
43 | *
44 | * @author Robert Sandell <rsandell@cloudbees.com>.
45 | */
46 | @Extension
47 | @Restricted(NoExternalUse.class)
48 | public class EnvContributor extends EnvironmentContributor {
49 |
50 | @Override
51 | public void buildEnvironmentFor(@NonNull Run r, @NonNull EnvVars envs, @NonNull TaskListener listener) throws IOException, InterruptedException {
52 | WebHookCause cause = (WebHookCause)r.getCause(WebHookCause.class);
53 | if (cause != null) {
54 | Set parameters = cause.getPushNotification().getRunParameters();
55 | for (ParameterValue parameter : parameters) {
56 | parameter.buildEnvironment(r, envs);
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/Http.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import java.io.IOException;
27 |
28 | import edu.umd.cs.findbugs.annotations.NonNull;
29 | import io.jenkins.plugins.okhttp.api.JenkinsOkHttpClient;
30 | import net.sf.json.JSONObject;
31 | import okhttp3.MediaType;
32 | import okhttp3.OkHttpClient;
33 | import okhttp3.Request;
34 | import okhttp3.RequestBody;
35 | import okhttp3.Response;
36 |
37 | /**
38 | * @author Robert Sandell <rsandell@cloudbees.com>.
39 | */
40 | public class Http {
41 |
42 | private static final MediaType CONTENT_TYPE_JSON_UTF8_ENCODING = MediaType.get("application/json; charset=utf-8");
43 |
44 | public static int post(@NonNull final String url, @NonNull final JSONObject data) throws IOException {
45 | final OkHttpClient jenkinsHttpClient = JenkinsOkHttpClient.newClientBuilder(new OkHttpClient())
46 | .followRedirects(false)
47 | .followSslRedirects(false)
48 | .build();
49 |
50 | final Request request = new Request.Builder().post(
51 | RequestBody.create(CONTENT_TYPE_JSON_UTF8_ENCODING, data.toString())).url(url).build();
52 |
53 | Response response = jenkinsHttpClient.newCall(request).execute();
54 |
55 | return response.code();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | **Newer releases are noted in** [GitHub Releases](https://github.com/jenkinsci/dockerhub-notification-plugin/releases).
4 |
5 | Only noting significant user-visible or major API changes, not internal code cleanups and minor bug fixes.
6 |
7 | ## 2.4.0 (Mar 28, 2019)
8 |
9 | * dockerregistry: add TAG to parameters _([PR #22](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/22))_
10 |
11 | ## 2.3.0 (Jul 12, 2018)
12 |
13 | * Added support for ACR webhooks.
14 |
15 | ## 2.2.1 (Jan 04, 2018)
16 |
17 | * [JENKINS-47736](https://issues.jenkins-ci.org/browse/JENKINS-47736) -
18 | Stop serializing `JSONObjects` over the Remoting to make the plugin compatible with Jenkins 2.102+
19 | * More info: [Plugins affected by fix for JEP-200](https://wiki.jenkins.io/display/JENKINS/Plugins+affected+by+fix+for+JEP-200)
20 |
21 | ## 2.2.0 (Jun 15, 2016)
22 | * Expose tag and pusher in the build environment _([PR #15](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/15))_
23 | * _Dev:_ [JENKINS-35629](https://issues.jenkins-ci.org/browse/JENKINS-35629) Convert to new plugin parent pom _([PR #14](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/14))_
24 |
25 | ## 2.1.0 (May 30, 2016)
26 | * Fix for [SECURITY-170](https://issues.jenkins-ci.org/browse/SECURITY-170) by changing from adding parameters to the build to adding plain environment variables instead.
27 | _[PR #13](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/13)_
28 |
29 | ## 2.0.0 (March 24, 2016)
30 |
31 | * [JENKINS-30931](https://issues.jenkins-ci.org/browse/JENKINS-30931) Added improved support for Docker Registry 2.0.
32 | _[PR #5](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/5),
33 | [PR #7](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/7),
34 | [PR #11](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/11)_
35 | _This resulted in significant refactoring and API changes in the plugin, hence the bump of major version. Data from older versions of the plugin should migrate correctly._
36 | * Substitute Environment Variables into Image Name.
37 | _[PR #8](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/8)_
38 | * Added CSRF protection exclusions on the web hooks so that the plugin behaves correctly in a more secured Jenkins.
39 | _[PR #12](https://github.com/jenkinsci/dockerhub-notification-plugin/pull/12)_
40 |
41 | ## 1.0.2 (June 05, 2015)
42 |
43 | * The list view column is no longer added by default.
44 |
45 | ## 1.0.1 (June 02, 2015)
46 |
47 | * The action was not working correctly in a secured Jenkins environment due to [JENKINS-28688](https://issues.jenkins-ci.org/browse/JENKINS-28688) - thanks to [Shay Erlichmen](https://github.com/erlichmen)
48 |
49 | ## 1.0 (May 26, 2015)
50 |
51 | * first release
52 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/TriggerImageExtractor.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification;
25 |
26 | import edu.umd.cs.findbugs.annotations.NonNull;
27 | import hudson.Extension;
28 | import hudson.model.Job;
29 | import jenkins.model.ParameterizedJobMixIn;
30 | import org.jenkinsci.plugins.docker.commons.DockerImageExtractor;
31 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOption;
32 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerOnSpecifiedImageNames;
33 |
34 | import java.util.Collection;
35 | import java.util.Collections;
36 |
37 | /**
38 | * Extracts the explicitly stated images used by {@link DockerHubTrigger}.
39 | *
40 | * @author Robert Sandell <rsandell@cloudbees.com>.
41 | * @see DockerHubTrigger#getAllRepoNames()
42 | * @see TriggerOnSpecifiedImageNames
43 | */
44 | @Extension
45 | public class TriggerImageExtractor extends DockerImageExtractor {
46 | @NonNull
47 | @Override
48 | public Collection getDockerImagesUsedByJob(@NonNull Job,?> job) {
49 | if (job instanceof ParameterizedJobMixIn.ParameterizedJob) {
50 | DockerHubTrigger trigger = DockerHubTrigger.getTrigger((ParameterizedJobMixIn.ParameterizedJob)job);
51 | if (trigger != null) {
52 | for (TriggerOption option : trigger.getOptions()) {
53 | if (option instanceof TriggerOnSpecifiedImageNames) {
54 | return ((TriggerOnSpecifiedImageNames)option).getRepoNames();
55 | }
56 | }
57 | }
58 | }
59 | return Collections.emptySet();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/WebHookCrumbExclusion.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import hudson.Extension;
27 | import hudson.security.csrf.CrumbExclusion;
28 | import org.jenkinsci.plugins.registry.notification.webhook.acr.ACRWebHook;
29 | import org.jenkinsci.plugins.registry.notification.webhook.dockerhub.DockerHubWebHook;
30 | import org.jenkinsci.plugins.registry.notification.webhook.dockerregistry.DockerRegistryWebHook;
31 |
32 | import jakarta.servlet.FilterChain;
33 | import jakarta.servlet.ServletException;
34 | import jakarta.servlet.http.HttpServletRequest;
35 | import jakarta.servlet.http.HttpServletResponse;
36 | import java.io.IOException;
37 |
38 | /**
39 | * Excludes {@link DockerHubWebHook} and {@link DockerRegistryWebHook} from having a CSRF protection filter.
40 | *
41 | * @author Robert Sandell <rsandell@cloudbees.com>.
42 | */
43 | @Extension
44 | public class WebHookCrumbExclusion extends CrumbExclusion {
45 | private static final String REGISTRY_BASE = "/" + DockerRegistryWebHook.URL_NAME + "/";
46 | private static final String HUB_BASE = "/" + DockerHubWebHook.URL_NAME + "/";
47 | private static final String ACR_BASE = "/" + ACRWebHook.URL_NAME + "/";
48 |
49 | @Override
50 | public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
51 | String pathInfo = request.getPathInfo();
52 | if (pathInfo != null && (pathInfo.startsWith(REGISTRY_BASE) || pathInfo.startsWith(HUB_BASE) || pathInfo.startsWith(ACR_BASE))) {
53 | chain.doFilter(request, response);
54 | return true;
55 | }
56 | return false;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/acr/ACRPushNotification.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.registry.notification.webhook.acr;
2 |
3 | import edu.umd.cs.findbugs.annotations.CheckForNull;
4 | import hudson.Util;
5 | import hudson.model.Cause;
6 | import hudson.model.ParameterValue;
7 | import hudson.model.StringParameterValue;
8 | import net.sf.json.JSONObject;
9 | import org.apache.commons.lang.StringUtils;
10 | import org.jenkinsci.plugins.registry.notification.webhook.PushNotification;
11 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
12 |
13 | import java.util.HashSet;
14 | import java.util.Set;
15 |
16 | public class ACRPushNotification extends PushNotification {
17 | public static final String KEY_REPO_NAME = WebHookPayload.PREFIX + "REPO_NAME";
18 | public static final String KEY_DOCKER_REGISTRY_HOST = WebHookPayload.PREFIX + "DOCKER_REGISTRY_HOST";
19 | public static final String KEY_TAG = WebHookPayload.PREFIX + "TAG";
20 |
21 | private String registryHost;
22 | private String tag;
23 |
24 | public ACRPushNotification(ACRWebHookPayload webHookPayload, String repoName) {
25 | super(webHookPayload);
26 | if (webHookPayload != null) {
27 | JSONObject data = webHookPayload.getData();
28 | if (data != null) {
29 | JSONObject target = data.getJSONObject("target");
30 | if (target != null) {
31 | this.tag = target.optString("tag");
32 | }
33 | }
34 | }
35 | this.repoName = repoName;
36 | }
37 |
38 | @CheckForNull
39 | public String getRegistryHost() {
40 | return registryHost;
41 | }
42 |
43 | public void setRegistryHost(String registryHost) {
44 | this.registryHost = registryHost;
45 | }
46 |
47 | public String getTag() {
48 | return this.tag;
49 | }
50 |
51 | @Override
52 | public Cause getCause() {
53 | return new ACRWebHookCause(this);
54 | }
55 |
56 | @Override
57 | public Set getRunParameters() {
58 | Set parameters = new HashSet();
59 | parameters.add(new StringParameterValue(KEY_REPO_NAME, getRepoName()));
60 | parameters.add(new StringParameterValue(KEY_TAG, getTag()));
61 | String host = getRegistryHost();
62 | if (!StringUtils.isBlank(host)) {
63 | parameters.add(new StringParameterValue(KEY_DOCKER_REGISTRY_HOST, host));
64 | }
65 | return parameters;
66 | }
67 |
68 | @Override
69 | public String getCauseMessage() {
70 | return "Docker image " + getRepoName() + " has been rebuilt by ACR@" + getRegistryHost();
71 | }
72 |
73 | public String sha() {
74 | return Util.getDigestOf("acrNotification:" + repoName + Long.toBinaryString(getReceived()));
75 | }
76 |
77 | @Override
78 | public String getShortDescription() {
79 | return String.format("push of %s to ACR@%s", getRepoName(), getRegistryHost());
80 |
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/opt/impl/TriggerForAllUsedInJob.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt.impl;
25 |
26 | import edu.umd.cs.findbugs.annotations.CheckForNull;
27 | import hudson.Extension;
28 | import hudson.model.Job;
29 | import jenkins.model.Jenkins;
30 | import org.jenkinsci.plugins.docker.commons.DockerImageExtractor;
31 | import org.jenkinsci.plugins.registry.notification.Messages;
32 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOption;
33 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOptionDescriptor;
34 | import org.kohsuke.stapler.DataBoundConstructor;
35 |
36 | import java.util.Collection;
37 | import java.util.Collections;
38 |
39 | /**
40 | * {@link TriggerOption} to trigger on all images reported by all {@link DockerImageExtractor}s for the job.
41 | *
42 | * @author Robert Sandell <rsandell@cloudbees.com>.
43 | */
44 | public class TriggerForAllUsedInJob extends TriggerOption {
45 |
46 | @DataBoundConstructor
47 | public TriggerForAllUsedInJob() {
48 | }
49 |
50 | @Override
51 | public Collection getRepoNames(Job, ?> job) {
52 | if (job == null) {
53 | // DockerImageExtractor.getDockerImagesUsedByJobFromAll expects a non-null job argument
54 | // Return an empty list if the job argument is null
55 | return Collections.emptyList();
56 | }
57 | return DockerImageExtractor.getDockerImagesUsedByJobFromAll(job);
58 | }
59 |
60 | @Extension
61 | public static class DescriptorImpl extends TriggerOptionDescriptor {
62 | @Override
63 | public String getDisplayName() {
64 | return Messages.TriggerOption_TriggerForAllUsedInJob_DisplayName();
65 | }
66 |
67 | @CheckForNull
68 | public static DescriptorImpl getInstance() {
69 | Jenkins jenkins = Jenkins.getInstance();
70 | if (jenkins != null) {
71 | return jenkins.getDescriptorByType(DescriptorImpl.class);
72 | }
73 | return null;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/main.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.ResultPage
25 |
26 | import org.jenkinsci.plugins.registry.notification.TriggerStore
27 | import hudson.model.Item
28 | import hudson.model.Run
29 |
30 | import java.text.DateFormat
31 |
32 | def l = namespace(lib.LayoutTagLib)
33 |
34 | TriggerStore.TriggerEntry data = triggerData
35 |
36 | link(rel: "stylesheet", href: "${rootURL}/${res(my, "style.css")}", type: "text/css")
37 |
38 | h1(_("heading", repoName, data.pushNotification.pushedAt))
39 |
40 | data.entries.each { entry ->
41 | Run run = entry.run
42 | if (run != null && (run.hasPermission(Item.READ) || run.hasPermission(Item.DISCOVER))) {
43 | div(class: "build-entry result-${run.result.toString()} ${run.result.color.iconClassName}") {
44 | a(href: "${rootURL}/${run.url}", class: "result-icon") {
45 | l.icon(class: "${run.result.color.iconClassName} icon-lg", alt: run.result.color.description,
46 | tooltip: run.result.color.description)
47 | }
48 | div(class: "build-link") {
49 | a(href: "${rootURL}/${run.url}", class: "model-link", run.getFullDisplayName())
50 | }
51 | if (run.hasPermission(Item.READ)) {
52 | ul(class: "build-details") {
53 | li(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, request2.getLocale()).format(run.time))
54 | li(run.durationString)
55 | li(run.result.toString())
56 | }
57 | ul(class: "causes") {
58 | run.causes.each { cause ->
59 | li(cause.getShortDescription())
60 | }
61 | }
62 | div(class: "buttons") {
63 | a(class: "console", href: "${rootURL}/${run.url}console", _("Console"))
64 | run.getArtifactsUpTo(2).each { artifact ->
65 | a(class: "artifact", href: "${rootURL}/${run.url}artifact/${artifact.href}", artifact.displayPath)
66 | }
67 | }
68 | }
69 | }
70 | }
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/webhook/ResultPage/style.css:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | .build-entry {
25 | margin: 0 0 20px;
26 | padding:20px 20px 20px 168px;
27 | border:1px solid #ccc;
28 | position:relative;
29 | max-width:600px;
30 | min-height:168px;
31 | background:#fff;
32 | }
33 |
34 | .build-entry .build-link {font-size:150%; font-weight:bold; margin-bottom:10px;}
35 | body .build-entry > div.build-link > a{ text-decoration:none; background:none !important}
36 | .build-entry .build-link a:hover {box-shadow:none; text-decoration:underline;}
37 | .build-entry .result-icon{
38 | content:' ';
39 | position:absolute;
40 | border:1px solid;
41 | height:128px; width:128px; top:20px; left:20px;
42 | border-radius:3px;
43 | background:#fff url(docker_128_grey.png) no-repeat center;
44 | }
45 | .build-entry .result-icon > img {position:absolute; top:5px; left:5px;}
46 | .build-entry > ul {margin:0 0 10px; padding:0; list-style: none;}
47 |
48 |
49 | .build-entry ul.build-details li {
50 | display: inline-block;
51 | margin-right: 40px;
52 | }
53 | .build-entry a:hover {box-shadow:inset 0 1px 5px rgba(0,0,0,.3)}
54 | .build-entry .buttons {padding-top:10px}
55 | .build-entry .buttons > a {
56 | border: 1px solid black;
57 | margin-right:10px;
58 | padding: 5px 20px;
59 | border:1px solid #369;
60 | display:inline-block;
61 | border-radius:3px;
62 | text-decoration:none;
63 | color:#000;
64 | background:#eee;
65 | line-height:20px;
66 | }
67 | .build-entry .buttons > a.console:before{content:' '; height:24px; width:24px; margin:-2px 8px -2px -10px; float:left; display:inline-block; background:url(../../../../../../../../../../images/24x24/terminal.png) no-repeat center;}
68 | .build-entry .buttons > a.console:after {content:'...'}
69 | .build-entry.result-SUCCESS .result-icon {background-image:url(docker_128.png)}
70 | .build-entry.result-FAILURE {background:rgba(200,0,0,.1); border-color:#900; color:#600}
71 | .build-entry.result-FAILURE a {color:#900 !important; border-color:#900 !important; background-color:rgba(200,0,0,.1);}
72 | .build-entry.result-UNSTABLE {background:rgba(200,180,0,.1); border-color:#970; color:#640}
73 | .build-entry.result-UNSTABLE a {color:#970 !important; border-color:#970 !important; background-color:rgba(200,180,0,.1);}
74 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/TriggerListViewColumn.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification;
25 |
26 | import hudson.Extension;
27 | import hudson.model.TopLevelItem;
28 | import hudson.views.ListViewColumn;
29 | import hudson.views.ListViewColumnDescriptor;
30 | import jenkins.model.ParameterizedJobMixIn;
31 | import org.jenkinsci.Symbol;
32 | import org.kohsuke.stapler.DataBoundConstructor;
33 | import org.kohsuke.stapler.DataBoundSetter;
34 |
35 | import java.util.Arrays;
36 | import java.util.Collection;
37 | import java.util.Collections;
38 | import java.util.Set;
39 |
40 | /**
41 | * Lists the images that a job triggers on.
42 | *
43 | * @author Robert Sandell <rsandell@cloudbees.com>.
44 | */
45 | public class TriggerListViewColumn extends ListViewColumn {
46 |
47 | private int showMax;
48 |
49 | @DataBoundConstructor
50 | public TriggerListViewColumn() {
51 | showMax = 0;
52 | }
53 |
54 | public int getShowMax() {
55 | return showMax;
56 | }
57 |
58 | @DataBoundSetter
59 | public void setShowMax(int showMax) {
60 | this.showMax = showMax;
61 | }
62 |
63 | @Override
64 | public String getColumnCaption() {
65 | return Messages.TriggerListViewColumn_ColumnCaption();
66 | }
67 |
68 | public Collection getImageNames(TopLevelItem item) {
69 | if (item instanceof ParameterizedJobMixIn.ParameterizedJob) {
70 | DockerHubTrigger trigger = DockerHubTrigger.getTrigger((ParameterizedJobMixIn.ParameterizedJob)item);
71 | if (trigger != null) {
72 | Set names = trigger.getAllRepoNames();
73 | if (showMax <= 0 || names.size() <= showMax) {
74 | return names;
75 | } else {
76 | String[] array = names.toArray(new String[names.size()]);
77 | return Arrays.asList(Arrays.copyOf(array, showMax));
78 | }
79 | }
80 | }
81 | return Collections.emptySet();
82 | }
83 |
84 | @Extension @Symbol("dockerImageNames")
85 | public static class DescriptorImpl extends ListViewColumnDescriptor {
86 |
87 | @Override
88 | public String getDisplayName() {
89 | return Messages.TriggerListViewColumn_DisplayName();
90 | }
91 |
92 | @Override
93 | public boolean shownByDefault() {
94 | return false;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/registry/notification/DockerHubTriggerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification;
25 |
26 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerOnSpecifiedImageNames;
27 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerForAllUsedInJob;
28 |
29 | import hudson.model.Item;
30 | import hudson.model.FreeStyleProject;
31 |
32 | import org.junit.Rule;
33 | import org.junit.Test;
34 | import org.jvnet.hudson.test.JenkinsRule;
35 |
36 | import static org.hamcrest.collection.IsEmptyCollection.empty;
37 | import static org.hamcrest.MatcherAssert.assertThat;
38 | import static org.hamcrest.Matchers.contains;
39 | import static org.junit.Assert.assertNotNull;
40 |
41 | /**
42 | * Tests for {@link DockerHubTrigger}.
43 | */
44 | public class DockerHubTriggerTest {
45 |
46 | @Rule
47 | public JenkinsRule j = new JenkinsRule();
48 |
49 | @Test
50 | public void testConfigRoundTrip() throws Exception {
51 | String[] expectedRepoNames = new String[] {"cb/jenkins", "cb/je"};
52 | FreeStyleProject project = j.createFreeStyleProject();
53 | project.addTrigger(new DockerHubTrigger(new TriggerForAllUsedInJob(), new TriggerOnSpecifiedImageNames(expectedRepoNames)));
54 | DockerHubTrigger trigger = DockerHubTrigger.getTrigger(project);
55 | assertNotNull(trigger);
56 | assertThat(trigger.getAllRepoNames(), contains(expectedRepoNames));
57 | project = (FreeStyleProject) j.configRoundtrip((Item)project);
58 | trigger = DockerHubTrigger.getTrigger(project);
59 | assertNotNull(trigger);
60 | assertThat(trigger.getAllRepoNames(), contains(expectedRepoNames));
61 | assertThat(trigger.getAllRepoNames(), contains(expectedRepoNames));
62 | }
63 |
64 | @Test
65 | public void testConfigRoundTripEmptyNames() throws Exception {
66 | FreeStyleProject project = j.createFreeStyleProject();
67 | project.addTrigger(new DockerHubTrigger(new TriggerForAllUsedInJob(), new TriggerOnSpecifiedImageNames()));
68 | DockerHubTrigger trigger = DockerHubTrigger.getTrigger(project);
69 | assertNotNull(trigger);
70 | assertThat(trigger.getAllRepoNames(), empty());
71 | project = (FreeStyleProject) j.configRoundtrip((Item)project);
72 | trigger = DockerHubTrigger.getTrigger(project);
73 | assertNotNull(trigger);
74 | assertThat(trigger.getAllRepoNames(), empty());
75 | assertThat(trigger.getAllRepoNames(), empty());
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/WebHookPayload.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook;
25 |
26 | import edu.umd.cs.findbugs.annotations.CheckForNull;
27 | import net.sf.json.JSONObject;
28 |
29 | import java.io.Serializable;
30 | import java.util.ArrayList;
31 | import java.util.Collections;
32 | import java.util.List;
33 |
34 | public abstract class WebHookPayload implements Serializable {
35 |
36 | public static final String PREFIX = "DOCKER_TRIGGER_";
37 |
38 | @CheckForNull
39 | private transient JSONObject data;
40 | @CheckForNull
41 | private String json;
42 |
43 | protected final long received;
44 |
45 | protected List pushNotifications = new ArrayList();
46 |
47 | public WebHookPayload() {
48 | this.received = System.currentTimeMillis();
49 | }
50 |
51 | /**
52 | * {@link System#currentTimeMillis()} when this object's constructor was called.
53 | *
54 | * @return the object's creation time/when the payload was received.
55 | */
56 | public long getReceived() {
57 | return received;
58 | }
59 |
60 | public List getPushNotifications() {
61 | return Collections.unmodifiableList(pushNotifications);
62 | }
63 |
64 | @CheckForNull
65 | public JSONObject getData() {
66 | return data;
67 | }
68 |
69 | protected void setData(JSONObject data) {
70 | this.data = data;
71 | }
72 |
73 | protected void setJson(String json) {
74 | this.json = json;
75 | }
76 |
77 | @Override
78 | public boolean equals(Object o) {
79 | if (this == o) return true;
80 | if (o == null || getClass() != o.getClass()) return false;
81 |
82 | WebHookPayload that = (WebHookPayload) o;
83 |
84 | if (received != that.received) return false;
85 | return !(data != null ? !data.equals(that.data) : that.data != null);
86 |
87 | }
88 |
89 | @Override
90 | public int hashCode() {
91 | int result = data != null ? data.hashCode() : 0;
92 | result = 31 * result + (int) (received ^ (received >>> 32));
93 | return result;
94 | }
95 |
96 | protected Object readResolve() {
97 | if (this.data == null && this.json != null) {
98 | this.data = JSONObject.fromObject(this.json);
99 | }
100 | return this;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerhub/DockerHubWebHook.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerhub;
25 |
26 | import hudson.Extension;
27 | import hudson.Main;
28 | import net.sf.json.JSONObject;
29 | import org.jenkinsci.plugins.registry.notification.webhook.JSONWebHook;
30 | import org.jenkinsci.plugins.registry.notification.webhook.PushNotification;
31 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
32 | import org.kohsuke.stapler.QueryParameter;
33 | import org.kohsuke.stapler.StaplerResponse2;
34 |
35 | import java.io.IOException;
36 | import java.util.logging.Logger;
37 |
38 | /**
39 | * The terminal point for the DockerHub web hook.
40 | * See Reference
41 | */
42 | @Extension
43 | public class DockerHubWebHook extends JSONWebHook {
44 | private static final Logger logger = Logger.getLogger(DockerHubWebHook.class.getName());
45 |
46 | /**
47 | * The namespace under Jenkins context path that this Action is bound to.
48 | */
49 | public static final String URL_NAME = "dockerhub-webhook";
50 |
51 | private boolean isDebugMode() {
52 | if (Main.isDevelopmentMode || Main.isUnitTest) {
53 | return true;
54 | } else if (System.getProperty("hudson.hpi.run") != null) {
55 | return true;
56 | } else {
57 | return false;
58 | }
59 | }
60 |
61 | /**
62 | * Helper for development without Dockerub integration.
63 | *
64 | * @param image the docker image to trigger
65 | * @param response to send a redirect to
66 | * @throws IOException if so
67 | */
68 | public void doDebug(@QueryParameter(required = true) String image, StaplerResponse2 response) throws IOException {
69 | if (!isDebugMode()) {
70 | throw new IllegalStateException("This endpoint can only be used during development!");
71 | }
72 | DockerHubWebHookPayload dockerHubWebHookPayload = new DockerHubWebHookPayload(image);
73 | for (PushNotification pushNotification : dockerHubWebHookPayload.getPushNotifications()) {
74 | trigger(response, pushNotification); //TODO pre-filled json data when needed.
75 | }
76 | }
77 |
78 | @Override
79 | protected void trigger(StaplerResponse2 response, PushNotification pushNotification) throws IOException {
80 | super.trigger(response, pushNotification);
81 | response.sendRedirect("../");
82 | }
83 |
84 | @Override
85 | protected WebHookPayload createPushNotification(JSONObject payload) {
86 | return new DockerHubWebHookPayload(payload);
87 | }
88 |
89 | public String getUrlName() {
90 | return URL_NAME;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/registry/notification/JcasCTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2020, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification;
25 |
26 | import hudson.model.ListView;
27 | import hudson.model.View;
28 | import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
29 | import org.junit.runner.RunWith;
30 | import org.junit.runners.Parameterized;
31 | import org.jvnet.hudson.test.RestartableJenkinsRule;
32 |
33 | import static org.hamcrest.MatcherAssert.assertThat;
34 | import static org.hamcrest.Matchers.allOf;
35 | import static org.hamcrest.Matchers.equalTo;
36 | import static org.hamcrest.Matchers.hasItem;
37 | import static org.hamcrest.Matchers.hasProperty;
38 | import static org.hamcrest.Matchers.instanceOf;
39 | import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
40 | import static org.junit.Assert.assertNotNull;
41 |
42 | /**
43 | * Tests that {@link TriggerViewFilter} and {@link TriggerListViewColumn} can be configured with configuration as code.
44 | *
45 | * Testing both with a configuration before symbols where added and with the new symbols.
46 | *
47 | * @see Configuration as Code Plugin
48 | */
49 | @RunWith(Parameterized.class)
50 | public class JcasCTest extends RoundTripAbstractTest {
51 |
52 | private String resource;
53 |
54 | public JcasCTest(final String resource) {
55 | this.resource = resource;
56 | }
57 |
58 | @Override
59 | protected void assertConfiguredAsExpected(final RestartableJenkinsRule j, final String s) {
60 | final View view = j.j.jenkins.getView("Docker");
61 | assertNotNull(view);
62 | ListView dv = (ListView) view;
63 | assertThat(dv.getColumns(), hasItem(
64 | allOf(
65 | instanceOf(TriggerListViewColumn.class),
66 | hasProperty("showMax", equalTo(3))
67 | )
68 | ));
69 | assertThat(dv.getJobFilters(), hasItem(
70 | allOf(
71 | instanceOf(TriggerViewFilter.class),
72 | hasProperty("patterns", containsInAnyOrder(
73 | equalTo(".*"),
74 | equalTo("jenkins"))
75 | )
76 | )
77 | ));
78 | }
79 |
80 | @Override
81 | protected String stringInLogExpected() {
82 | return "Setting org.jenkinsci.plugins.registry.notification.TriggerListViewColumn";
83 | }
84 |
85 | @Parameterized.Parameters(name = "{0}")
86 | public static Object[][] params() {
87 | return new Object[][]{{"/jcasc_bare.yaml"}, {"/jcasc_symbols.yaml"}};
88 | }
89 |
90 | @Override
91 | protected String configResource() {
92 | return resource;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/opt/impl/TriggerOnSpecifiedImageNames.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.opt.impl;
25 |
26 | import hudson.Extension;
27 | import hudson.model.Job;
28 | import net.sf.json.JSONArray;
29 | import net.sf.json.JSONObject;
30 | import org.apache.commons.lang.StringUtils;
31 | import org.jenkinsci.plugins.registry.notification.Messages;
32 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOption;
33 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOptionDescriptor;
34 | import org.kohsuke.stapler.DataBoundConstructor;
35 | import org.kohsuke.stapler.DataBoundSetter;
36 | import org.kohsuke.stapler.StaplerRequest2;
37 |
38 | import java.util.*;
39 |
40 | /**
41 | * {@link TriggerOption} with manually specified names.
42 | *
43 | * @author Robert Sandell <rsandell@cloudbees.com>.
44 | */
45 | public class TriggerOnSpecifiedImageNames extends TriggerOption {
46 | private Set repoNames;
47 |
48 | @DataBoundConstructor
49 | public TriggerOnSpecifiedImageNames() {
50 | this.repoNames = Collections.emptySet();
51 | }
52 |
53 | public TriggerOnSpecifiedImageNames(Collection repoNames) {
54 | this.repoNames = new HashSet();
55 | if (repoNames != null) {
56 | this.repoNames.addAll(repoNames);
57 | }
58 | }
59 |
60 | public TriggerOnSpecifiedImageNames(String... repoNames) {
61 | this(Arrays.asList(repoNames));
62 | }
63 |
64 | public Set getRepoNames() {
65 | return repoNames;
66 | }
67 |
68 | @DataBoundSetter
69 | public void setRepoNames(Set repoNames) {
70 | this.repoNames = repoNames;
71 | }
72 |
73 | @Override
74 | public Collection getRepoNames(Job, ?> job) {
75 | return getRepoNames();
76 | }
77 |
78 | @Extension
79 | public static class DescriptorImpl extends TriggerOptionDescriptor {
80 | @Override
81 | public String getDisplayName() {
82 | return Messages.TriggerOption_TriggerOnSpecifiedImageNames_DisplayName();
83 | }
84 |
85 | @Override
86 | public TriggerOption newInstance(StaplerRequest2 req, JSONObject formData) throws FormException {
87 | // TODO JENKINS-27901: need a standard control for this
88 | if (formData.has("repoNames") && !StringUtils.isBlank(formData.optString("repoNames"))) {
89 | JSONArray array = new JSONArray();
90 | array.addAll(Arrays.asList(StringUtils.split(formData.getString("repoNames"))));
91 | formData.put("repoNames", array);
92 | } else {
93 | formData.put("repoNames", new JSONArray());
94 | }
95 | return super.newInstance(req, formData);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/registry/notification/ACRWebHookTest.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.registry.notification;
2 |
3 | import hudson.model.Cause;
4 | import hudson.model.FreeStyleProject;
5 | import hudson.model.Result;
6 | import hudson.model.Run;
7 | import hudson.model.listeners.RunListener;
8 | import net.sf.json.JSONObject;
9 | import org.apache.commons.io.IOUtils;
10 | import org.jenkinsci.plugins.registry.notification.opt.TriggerOption;
11 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerOnSpecifiedImageNames;
12 | import org.jenkinsci.plugins.registry.notification.token.ApiTokens;
13 | import org.jenkinsci.plugins.registry.notification.webhook.Http;
14 | import org.jenkinsci.plugins.registry.notification.webhook.acr.ACRPushNotification;
15 | import org.jenkinsci.plugins.registry.notification.webhook.acr.ACRWebHook;
16 | import org.jenkinsci.plugins.registry.notification.webhook.acr.ACRWebHookCause;
17 | import org.junit.Before;
18 | import org.junit.Rule;
19 | import org.junit.Test;
20 | import org.jvnet.hudson.test.JenkinsRule;
21 | import org.jvnet.hudson.test.MockBuilder;
22 | import org.jvnet.hudson.test.TestExtension;
23 |
24 | import java.io.IOException;
25 | import java.util.ArrayList;
26 | import java.util.Collections;
27 | import java.util.List;
28 |
29 | import static org.junit.Assert.assertEquals;
30 | import static org.junit.Assert.assertNotNull;
31 |
32 | /**
33 | * Testing ACR webhook.
34 | */
35 | public class ACRWebHookTest {
36 | @Rule
37 | public JenkinsRule j = new JenkinsRule();
38 |
39 | private String token;
40 |
41 | private String getWebHookURL() throws IOException {
42 | return this.j.getURL() + ACRWebHook.URL_NAME + "/" + token + "/notify";
43 | }
44 |
45 | @Before
46 | public void setUp() {
47 | final JSONObject test = ApiTokens.get().generateApiToken("test");
48 | token = test.getString("value");
49 | }
50 |
51 | @Test
52 | public void testValidRepoUpdate() throws Exception {
53 | PushNotificationRunListener listener = j.jenkins.getExtensionList(PushNotificationRunListener.class).get(0);
54 | listener.reset();
55 | createProjectWithTrigger(new TriggerOnSpecifiedImageNames(Collections.singletonList("myregistry.azurecr.io/hello-world")));
56 | JSONObject data = JSONObject.fromObject(IOUtils.toString(getClass().getResourceAsStream("/acr-payload-valid.json")));
57 | assertEquals(200, Http.post(getWebHookURL(), data));
58 | j.waitUntilNoActivity();
59 | ACRPushNotification notification = listener.getPushNotification();
60 | assertNotNull(notification);
61 | assertEquals("v1", notification.getTag());
62 | assertEquals("myregistry.azurecr.io", notification.getRegistryHost());
63 |
64 | }
65 |
66 | private void createProjectWithTrigger(TriggerOption... options) throws Exception {
67 | FreeStyleProject project = this.j.createFreeStyleProject();
68 | project.addTrigger(new DockerHubTrigger(options));
69 | project.getBuildersList().add(new MockBuilder(Result.SUCCESS));
70 | }
71 |
72 | @TestExtension
73 | public static class PushNotificationRunListener extends RunListener> {
74 | private List hits;
75 |
76 | public PushNotificationRunListener() {
77 | this.hits = new ArrayList();
78 | }
79 |
80 | @Override
81 | public void onFinalized(Run, ?> run) {
82 | super.onFinalized(run);
83 | this.hits.add(run);
84 | }
85 |
86 | public void reset() {
87 | this.hits.clear();
88 | }
89 |
90 | public ACRPushNotification getPushNotification() {
91 | for (Run hit : this.hits) {
92 | ACRWebHookCause cause = (ACRWebHookCause) hit.getCause(ACRWebHookCause.class);
93 | return (ACRPushNotification) cause.getPushNotification();
94 | }
95 | return null;
96 | }
97 | }
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/registry/notification/DockerHubWebHookTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification;
25 |
26 | import hudson.EnvVars;
27 | import hudson.Launcher;
28 | import hudson.model.AbstractBuild;
29 | import hudson.model.BuildListener;
30 | import hudson.model.FreeStyleBuild;
31 | import hudson.tasks.BuildStep;
32 | import hudson.tasks.Builder;
33 | import jenkins.tasks.SimpleBuildStep;
34 | import org.jenkinsci.plugins.registry.notification.opt.impl.TriggerOnSpecifiedImageNames;
35 | import hudson.model.FreeStyleProject;
36 | import hudson.model.Result;
37 | import org.jenkinsci.plugins.registry.notification.webhook.dockerhub.DockerHubPushNotification;
38 | import org.junit.Rule;
39 | import org.junit.Test;
40 | import org.jvnet.hudson.test.JenkinsRule;
41 | import org.jvnet.hudson.test.MockBuilder;
42 |
43 | import java.io.IOException;
44 | import java.util.Map;
45 |
46 | public class DockerHubWebHookTest {
47 |
48 | @Rule
49 | public JenkinsRule j = new JenkinsRule();
50 |
51 | @Test(timeout = 60000)
52 | public void testDoIndex() throws Exception {
53 | FreeStyleProject project = j.createFreeStyleProject();
54 | final String repoName = "cb/jenkins";
55 | project.addTrigger(new DockerHubTrigger(new TriggerOnSpecifiedImageNames(repoName)));
56 | project.getBuildersList().add(new MockBuilder(Result.SUCCESS));
57 | j.createWebClient().goTo("dockerhub-webhook/debug?image=" + repoName);
58 |
59 | j.waitUntilNoActivity();
60 |
61 | j.assertLogContains(repoName, project.getLastBuild());
62 | }
63 |
64 | @Test(timeout = 60000)
65 | public void testEnvironment() throws Exception {
66 | FreeStyleProject project = j.createFreeStyleProject();
67 | final String repoName = "cb/jenkins";
68 | project.addTrigger(new DockerHubTrigger(new TriggerOnSpecifiedImageNames(repoName)));
69 | project.getBuildersList().add(new PrintEnvironment());
70 | project.getBuildersList().add(new MockBuilder(Result.SUCCESS));
71 | j.createWebClient().goTo("dockerhub-webhook/debug?image=" + repoName);
72 |
73 | j.waitUntilNoActivity();
74 | FreeStyleBuild build = project.getLastBuild();
75 | j.assertLogContains(repoName, build);
76 | j.assertLogContains(DockerHubPushNotification.KEY_REPO_NAME + " = " + repoName, build);
77 | }
78 |
79 | static class PrintEnvironment extends Builder {
80 | @Override
81 | public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
82 | EnvVars vars = build.getEnvironment(listener);
83 | for (Map.Entry var : vars.entrySet()) {
84 | listener.getLogger().println(var.getKey() + " = " + var.getValue());
85 | }
86 | return true;
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/fingerprints/58/73/052b0750060b97b428e5dbdd1c03.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2016-03-14 14:53:40.641 UTC
4 | 5873052b0750060b97b428e5dbdd1c03
5 | csanchez/jenkins-swarm-slave
6 |
7 |
8 |
9 | 1457967220599
10 |
11 | csanchez/jenkins-swarm-slave
12 | {"push_data":{"pushed_at":1429028158,"images":["imagehash1","imagehash2","imagehash3"],"pusher":"csanchez"},"callback_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/hook/2g1gggacfij1c4a3jd00bf4fe3c3ec0da/","repository":{"status":"Active","description":"","is_trusted":true,"full_description":"# Jenkins swarm slave\n\n[`csanchez/jenkins-swarm-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/)\n\nA [Jenkins swarm](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin) slave.\n\nFor a container with ssh enabled see\n[`csanchez/jenkins-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-slave/)\n\nFor a container with many build tools installed see\n[`maestrodev/build-agent`](https://registry.hub.docker.com/u/maestrodev/build-agent/)\n\n## Running\n\nTo run a Docker container passing [any parameters](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin#SwarmPlugin-AvailableOptions) to the slave\n\n docker run csanchez/jenkins-swarm-slave -master http://jenkins:8080 -username jenkins -password jenkins -executors 1\n\nLinking to the Jenkins master container there is no need to use `--master`\n\n docker run -d --name jenkins -p 8080:8080 csanchez/jenkins-swarm\n docker run -d --link jenkins:jenkins csanchez/jenkins-swarm-slave -username jenkins -password jenkins -executors 1\n\n\n# Building\n\n docker build -t csanchez/jenkins-swarm-slave .\n","repo_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/","owner":"csanchez","is_official":false,"is_private":false,"name":"jenkins-swarm-slave","namespace":"csanchez","star_count":2,"comment_count":0,"date_created":1410991410,"dockerfile":"FROM java:8u40-b22-jdk\n\nMAINTAINER Carlos Sanchez <carlos@apache.org>\n\nENV JENKINS_SWARM_VERSION 1.22\nENV HOME /home/jenkins-slave\n\nRUN useradd -c \"Jenkins Slave user\" -d $HOME -m jenkins-slave\nRUN curl --create-dirs -sSLo /usr/share/jenkins/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/plugins/swarm-client/$JENKINS_SWARM_VERSION/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar \\\n && chmod 755 /usr/share/jenkins\n\nCOPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh\n\nUSER jenkins-slave\n\nVOLUME /home/jenkins-slave\n\nENTRYPOINT [\"/usr/local/bin/jenkins-slave.sh\"]\n","repo_name":"csanchez/jenkins-swarm-slave"}}
13 | 1457967220599
14 |
15 |
16 |
17 | JenkinsSlaveTrigger
18 | 1
19 | true
20 |
21 |
22 |
23 | error
24 | Build result FAILURE
25 | Jenkins
26 | dockerhub-webhook/details/5873052b0750060b97b428e5dbdd1c03
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/fingerprints/e9/d6/eb6cd6a7bfcd2bd622765a87893f.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2016-03-14 14:54:57.198 UTC
4 | e9d6eb6cd6a7bfcd2bd622765a87893f
5 | csanchez/jenkins-swarm-slave
6 |
7 |
8 |
9 | 1457967297196
10 |
11 | csanchez/jenkins-swarm-slave
12 | {"push_data":{"pushed_at":1429028158,"images":["imagehash1","imagehash2","imagehash3"],"pusher":"csanchez"},"callback_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/hook/2g1gggacfij1c4a3jd00bf4fe3c3ec0da/","repository":{"status":"Active","description":"","is_trusted":true,"full_description":"# Jenkins swarm slave\n\n[`csanchez/jenkins-swarm-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/)\n\nA [Jenkins swarm](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin) slave.\n\nFor a container with ssh enabled see\n[`csanchez/jenkins-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-slave/)\n\nFor a container with many build tools installed see\n[`maestrodev/build-agent`](https://registry.hub.docker.com/u/maestrodev/build-agent/)\n\n## Running\n\nTo run a Docker container passing [any parameters](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin#SwarmPlugin-AvailableOptions) to the slave\n\n docker run csanchez/jenkins-swarm-slave -master http://jenkins:8080 -username jenkins -password jenkins -executors 1\n\nLinking to the Jenkins master container there is no need to use `--master`\n\n docker run -d --name jenkins -p 8080:8080 csanchez/jenkins-swarm\n docker run -d --link jenkins:jenkins csanchez/jenkins-swarm-slave -username jenkins -password jenkins -executors 1\n\n\n# Building\n\n docker build -t csanchez/jenkins-swarm-slave .\n","repo_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/","owner":"csanchez","is_official":false,"is_private":false,"name":"jenkins-swarm-slave","namespace":"csanchez","star_count":2,"comment_count":0,"date_created":1410991410,"dockerfile":"FROM java:8u40-b22-jdk\n\nMAINTAINER Carlos Sanchez <carlos@apache.org>\n\nENV JENKINS_SWARM_VERSION 1.22\nENV HOME /home/jenkins-slave\n\nRUN useradd -c \"Jenkins Slave user\" -d $HOME -m jenkins-slave\nRUN curl --create-dirs -sSLo /usr/share/jenkins/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/plugins/swarm-client/$JENKINS_SWARM_VERSION/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar \\\n && chmod 755 /usr/share/jenkins\n\nCOPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh\n\nUSER jenkins-slave\n\nVOLUME /home/jenkins-slave\n\nENTRYPOINT [\"/usr/local/bin/jenkins-slave.sh\"]\n","repo_name":"csanchez/jenkins-swarm-slave"}}
13 | 1457967297196
14 |
15 |
16 |
17 | JenkinsSlaveTrigger
18 | 2
19 | true
20 |
21 |
22 |
23 | success
24 | Build result SUCCESS
25 | Jenkins
26 | dockerhub-webhook/details/e9d6eb6cd6a7bfcd2bd622765a87893f
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerregistry/DockerRegistryWebHookPayload.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, HolidayCheck AG.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerregistry;
25 |
26 | import edu.umd.cs.findbugs.annotations.NonNull;
27 | import net.sf.json.JSONArray;
28 | import net.sf.json.JSONObject;
29 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
30 | import org.joda.time.format.DateTimeFormatter;
31 | import org.joda.time.format.ISODateTimeFormat;
32 |
33 | import java.util.logging.Logger;
34 | import java.util.logging.Level;
35 |
36 | public class DockerRegistryWebHookPayload extends WebHookPayload {
37 |
38 | private static final Logger logger = Logger.getLogger(DockerRegistryPushNotification.class.getName());
39 |
40 | /**
41 | * Creates the object from the json payload
42 | *
43 | * @param data the json payload
44 | * @throws net.sf.json.JSONException if the key {@code repository.repo_name} doesn't exist.
45 | */
46 | public DockerRegistryWebHookPayload(@NonNull JSONObject data) {
47 | super();
48 | setData(data);
49 | setJson(data.toString());
50 |
51 | JSONArray events = data.getJSONArray("events");
52 |
53 | for (int i = 0, size = events.size(); i < size; i++) {
54 | JSONObject event = events.getJSONObject(i);
55 | String separator = "/";
56 |
57 | if ( event.optString("action").equals("push") ) {
58 | final String[] urlSegments = event.getJSONObject("target").optString("url").split(separator);
59 | StringBuffer sb = new StringBuffer();
60 | sb.append(urlSegments[2]);
61 | sb.append(separator);
62 | sb.append(event.getJSONObject("target").optString("repository"));
63 | String repository = sb.toString();
64 | if (urlSegments[urlSegments.length - 2 ].equals("manifests")) {
65 | pushNotifications.add(createPushNotification(repository, event));
66 | } else {
67 | logger.log(Level.FINER, "Skipping Layer Push notifications");
68 |
69 | }
70 | } else {
71 | logger.log(Level.FINER, "Skipping pull notification" + event.getJSONObject("target").optString("repository"));
72 | }
73 | }
74 |
75 | }
76 |
77 | private DockerRegistryPushNotification createPushNotification(@NonNull final String repoName, @NonNull JSONObject data) {
78 | final String timestamp = data.optString("timestamp");
79 | final String host = data.getJSONObject("request").optString("host");
80 | final String tag = data.getJSONObject("target").optString("tag");
81 | return new DockerRegistryPushNotification(this, repoName){{
82 | DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
83 | setTag(tag);
84 | setPushedAt(parser.parseDateTime(timestamp).toDate());
85 | setRegistryHost(host);
86 | }};
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/jobs/JenkinsSlaveTrigger/builds/1/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | DOCKER_TRIGGER_REPO_NAME
8 | csanchez/jenkins-swarm-slave
9 |
10 |
11 | DOCKER_TRIGGER_DOCKER_HUB_HOST
12 | registry.hub.example.com
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | csanchez/jenkins-swarm-slave
21 | {"push_data":{"pushed_at":1429028158,"images":["imagehash1","imagehash2","imagehash3"],"pusher":"csanchez"},"callback_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/hook/2g1gggacfij1c4a3jd00bf4fe3c3ec0da/","repository":{"status":"Active","description":"","is_trusted":true,"full_description":"# Jenkins swarm slave\n\n[`csanchez/jenkins-swarm-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/)\n\nA [Jenkins swarm](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin) slave.\n\nFor a container with ssh enabled see\n[`csanchez/jenkins-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-slave/)\n\nFor a container with many build tools installed see\n[`maestrodev/build-agent`](https://registry.hub.docker.com/u/maestrodev/build-agent/)\n\n## Running\n\nTo run a Docker container passing [any parameters](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin#SwarmPlugin-AvailableOptions) to the slave\n\n docker run csanchez/jenkins-swarm-slave -master http://jenkins:8080 -username jenkins -password jenkins -executors 1\n\nLinking to the Jenkins master container there is no need to use `--master`\n\n docker run -d --name jenkins -p 8080:8080 csanchez/jenkins-swarm\n docker run -d --link jenkins:jenkins csanchez/jenkins-swarm-slave -username jenkins -password jenkins -executors 1\n\n\n# Building\n\n docker build -t csanchez/jenkins-swarm-slave .\n","repo_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/","owner":"csanchez","is_official":false,"is_private":false,"name":"jenkins-swarm-slave","namespace":"csanchez","star_count":2,"comment_count":0,"date_created":1410991410,"dockerfile":"FROM java:8u40-b22-jdk\n\nMAINTAINER Carlos Sanchez <carlos@apache.org>\n\nENV JENKINS_SWARM_VERSION 1.22\nENV HOME /home/jenkins-slave\n\nRUN useradd -c \"Jenkins Slave user\" -d $HOME -m jenkins-slave\nRUN curl --create-dirs -sSLo /usr/share/jenkins/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/plugins/swarm-client/$JENKINS_SWARM_VERSION/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar \\\n && chmod 755 /usr/share/jenkins\n\nCOPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh\n\nUSER jenkins-slave\n\nVOLUME /home/jenkins-slave\n\nENTRYPOINT [\"/usr/local/bin/jenkins-slave.sh\"]\n","repo_name":"csanchez/jenkins-swarm-slave"}}
22 | 1457967220599
23 |
24 |
25 |
26 |
27 |
28 | 1457947426000
29 | 1457967226370
30 | FAILURE
31 | 978
32 | US-ASCII
33 | false
34 |
35 | /var/jenkins_home/workspace/JenkinsSlaveTrigger
36 | 1.580.1
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/test/resources/org/jenkinsci/plugins/registry/notification/BackCompat102Test/jobs/JenkinsSlaveTrigger/builds/2/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | DOCKER_TRIGGER_REPO_NAME
8 | csanchez/jenkins-swarm-slave
9 |
10 |
11 | DOCKER_TRIGGER_DOCKER_HUB_HOST
12 | registry.hub.example.com
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | csanchez/jenkins-swarm-slave
21 | {"push_data":{"pushed_at":1429028158,"images":["imagehash1","imagehash2","imagehash3"],"pusher":"csanchez"},"callback_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/hook/2g1gggacfij1c4a3jd00bf4fe3c3ec0da/","repository":{"status":"Active","description":"","is_trusted":true,"full_description":"# Jenkins swarm slave\n\n[`csanchez/jenkins-swarm-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-swarm-slave/)\n\nA [Jenkins swarm](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin) slave.\n\nFor a container with ssh enabled see\n[`csanchez/jenkins-slave`](https://registry.hub.docker.com/u/csanchez/jenkins-slave/)\n\nFor a container with many build tools installed see\n[`maestrodev/build-agent`](https://registry.hub.docker.com/u/maestrodev/build-agent/)\n\n## Running\n\nTo run a Docker container passing [any parameters](https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin#SwarmPlugin-AvailableOptions) to the slave\n\n docker run csanchez/jenkins-swarm-slave -master http://jenkins:8080 -username jenkins -password jenkins -executors 1\n\nLinking to the Jenkins master container there is no need to use `--master`\n\n docker run -d --name jenkins -p 8080:8080 csanchez/jenkins-swarm\n docker run -d --link jenkins:jenkins csanchez/jenkins-swarm-slave -username jenkins -password jenkins -executors 1\n\n\n# Building\n\n docker build -t csanchez/jenkins-swarm-slave .\n","repo_url":"https://registry.hub.example.com/u/csanchez/jenkins-swarm-slave/","owner":"csanchez","is_official":false,"is_private":false,"name":"jenkins-swarm-slave","namespace":"csanchez","star_count":2,"comment_count":0,"date_created":1410991410,"dockerfile":"FROM java:8u40-b22-jdk\n\nMAINTAINER Carlos Sanchez <carlos@apache.org>\n\nENV JENKINS_SWARM_VERSION 1.22\nENV HOME /home/jenkins-slave\n\nRUN useradd -c \"Jenkins Slave user\" -d $HOME -m jenkins-slave\nRUN curl --create-dirs -sSLo /usr/share/jenkins/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/plugins/swarm-client/$JENKINS_SWARM_VERSION/swarm-client-$JENKINS_SWARM_VERSION-jar-with-dependencies.jar \\\n && chmod 755 /usr/share/jenkins\n\nCOPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh\n\nUSER jenkins-slave\n\nVOLUME /home/jenkins-slave\n\nENTRYPOINT [\"/usr/local/bin/jenkins-slave.sh\"]\n","repo_name":"csanchez/jenkins-swarm-slave"}}
22 | 1457967297196
23 |
24 |
25 |
26 |
27 |
28 | 1457947506000
29 | 1457967306445
30 | SUCCESS
31 | 26
32 | US-ASCII
33 | false
34 |
35 | /var/jenkins_home/workspace/JenkinsSlaveTrigger
36 | 1.580.1
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/registry/notification/webhook/dockerregistry/DockerRegistryPushNotification.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License
3 | *
4 | * Copyright (c) 2015, HolidayCheck AG.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.registry.notification.webhook.dockerregistry;
25 |
26 | import edu.umd.cs.findbugs.annotations.CheckForNull;
27 | import hudson.Util;
28 | import hudson.model.Cause;
29 | import hudson.model.ParameterValue;
30 | import hudson.model.StringParameterValue;
31 | import org.apache.commons.lang.StringUtils;
32 | import org.jenkinsci.plugins.registry.notification.webhook.PushNotification;
33 | import org.jenkinsci.plugins.registry.notification.webhook.WebHookPayload;
34 |
35 | import java.util.HashSet;
36 | import java.util.Set;
37 | import java.util.logging.Logger;
38 |
39 | /**
40 | * Received notification from the Docker Registry web hook.
41 | * See Reference
42 | */
43 | public class DockerRegistryPushNotification extends PushNotification {
44 | private static final long serialVersionUID = 207798312860576090L;
45 | private static final Logger logger = Logger.getLogger(DockerRegistryPushNotification.class.getName());
46 | public static final String KEY_REPO_NAME = WebHookPayload.PREFIX + "REPO_NAME";
47 | public static final String KEY_TAG = WebHookPayload.PREFIX + "TAG";
48 | public static final String KEY_DOCKER_REGISTRY_HOST = WebHookPayload.PREFIX + "DOCKER_REGISTRY_HOST";
49 | private String registryHost;
50 | private String tag;
51 |
52 | public DockerRegistryPushNotification(DockerRegistryWebHookPayload webHookPayload, String repoName) {
53 | super(webHookPayload);
54 | this.repoName = repoName;
55 | }
56 |
57 | @CheckForNull
58 | public String getTag() {
59 | return tag;
60 | }
61 |
62 | public void setTag(String tag) {
63 | this.tag = tag;
64 | }
65 |
66 | @CheckForNull
67 | public String getRegistryHost() {
68 | return registryHost;
69 | }
70 |
71 | public void setRegistryHost(String registryHost) {
72 | this.registryHost = registryHost;
73 | }
74 |
75 | @Override
76 | public Cause getCause() {
77 | return new DockerRegistryWebHookCause(this);
78 | }
79 |
80 | @Override
81 | public Set getRunParameters() {
82 | Set parameters = new HashSet();
83 | parameters.add(new StringParameterValue(KEY_REPO_NAME, getRepoName()));
84 | String tag = getTag();
85 | if (!StringUtils.isBlank(tag)) {
86 | parameters.add(new StringParameterValue(KEY_TAG, tag));
87 | }
88 | String host = getRegistryHost();
89 | if (!StringUtils.isBlank(host)) {
90 | parameters.add(new StringParameterValue(KEY_DOCKER_REGISTRY_HOST, host));
91 | }
92 | return parameters;
93 | }
94 |
95 | @Override
96 | public String getCauseMessage() {
97 | return "Docker image " + getRepoName() + " has been rebuilt by DockerRegistry@" + getRegistryHost();
98 | }
99 |
100 | public String sha() {
101 | return Util.getDigestOf("dockerRegistryNotification:" + repoName + Long.toBinaryString(getReceived()));
102 | }
103 |
104 | @Override
105 | public String getShortDescription() {
106 | return String.format("push of %s to DockerRegistry@%s", getRepoName(), getRegistryHost());
107 |
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/registry/notification/token/ApiTokens/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |