Skip to content

Commit e65eb70

Browse files
author
Rafael Grigorian
committed
Initial Upload
0 parents  commit e65eb70

File tree

7 files changed

+295
-0
lines changed

7 files changed

+295
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Files
2+
.DS_Store
3+
4+
# Directories
5+
vendor

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM golang:alpine as build-env
2+
WORKDIR /go/src/app
3+
ENV GOOS=linux GOARCH=amd64 CGO_ENABLED=0
4+
RUN apk -Uuq add git dep ca-certificates
5+
COPY Gopkg.toml Gopkg.lock src/main.go /go/src/app/
6+
RUN dep ensure
7+
RUN go build -o main
8+
9+
FROM alpine
10+
LABEL maintainer development@jetrails.com
11+
COPY --from=build-env /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
12+
COPY --from=build-env /go/src/app/main /usr/local/bin/main
13+
RUN chmod +x /usr/local/bin/main
14+
ENTRYPOINT [ "main" ]

Gopkg.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[prune]
2+
go-tests = true
3+
unused-packages = true
4+
5+
[[constraint]]
6+
name = "github.com/cloudflare/cloudflare-go"
7+
version = "0.9.4"
8+
9+
[[constraint]]
10+
name = "github.com/caarlos0/env"
11+
version = "6.0.0"

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# The MIT License (MIT)
2+
Copyright 2019 JetRails®
3+
4+
* * *
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy of
7+
this software and associated documentation files (the "Software"), to deal in
8+
the Software without restriction, including without limitation the rights to
9+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10+
the Software, and to permit persons to whom the Software is furnished to do so,
11+
subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
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, FITNESS
18+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Drone — Cloudflare Caching
2+
> Drone plugin to purge cache via Cloudflare's API
3+
4+
![](https://img.shields.io/badge/License-MIT-lightgray.svg?style=for-the-badge)
5+
![](https://img.shields.io/docker/stars/jetrails/drone-cloudflare-caching.svg?style=for-the-badge&colorB=9f9f9f)
6+
![](https://img.shields.io/docker/pulls/jetrails/drone-cloudflare-caching.svg?style=for-the-badge&colorB=9f9f9f)
7+
8+
## About
9+
10+
> **WARNING**: Logic works if authenticated with email and global API token, not currently working with scoped API tokens. This is an issue with Cloudflare and should hopefully be resolved soon.
11+
12+
Our Drone plugin enables the ability for your pipeline to interface with Cloudflare's API to purge cache. This plugin is written in Go and it uses the [cloudflare-go](https://github.com/cloudflare/cloudflare-go) package to communicate with Cloudflare's API. For information on Cloudflare's API please refer to their [documentation](https://api.cloudflare.com/#zone-purge-all-files) page.
13+
14+
## Cloudflare Token
15+
16+
The API token that is used to authenticate with Cloudflare's API can be created in Cloudflare's dashboard. It is recommended to create an API token that includes only the zone resource you want to manipulate and give edit permissions only to the Cache Purge resource.
17+
18+
## Build
19+
20+
Develop locally by running the plugin with the following commands. Also please note that you should specify environmental variables for the plugin either via the inline method (`FOO=bar go run src/main`) or via the `export FOO=bar` method before the `go run` command.
21+
22+
```shell
23+
$ dep ensure
24+
$ go run src/main.go
25+
```
26+
27+
## Docker
28+
29+
Drone plugins work off of docker images. The following commands will go over building, pushing, and running the docker image for this plugin.
30+
31+
###### Build Docker Image:
32+
33+
```shell
34+
$ docker build -t jetrails/drone-cloudflare-caching .
35+
```
36+
37+
###### Run Docker Container:
38+
39+
You can then replicate the command that Drone will use to launch the plugin by running:
40+
41+
```shell
42+
$ docker run --rm \
43+
-e PLUGIN_API_TOKEN="u4C7ev06GMS8_vWBTpjqtVReT3I7FwGpW7MG44ZD" \
44+
-e PLUGIN_ZONE_IDENTIFIER="eJzrjE44s6Ki67x1tSDJzI8LdXxM3nj7" \
45+
-e PLUGIN_ACTION="purge_everything" \
46+
-v $(pwd):/drone/src \
47+
-w /drone/src \
48+
jetrails/drone-cloudflare-caching
49+
```
50+
51+
###### Push Docker Image:
52+
53+
Finally, push this image to our Docker Hub [repository](https://hub.docker.com/r/jetrails/drone-cloudflare-caching) (assuming you have permission):
54+
55+
```shell
56+
$ docker push jetrails/drone-cloudflare-caching
57+
```
58+
59+
## Usage
60+
61+
This plugin supports purging all cache, purging hosts, purging files, and purging tags. Please refer to the table below with all possible settings that can be passed to the plugin:
62+
63+
| Name | Required | Default | Case-Sensitive | Type |
64+
|:---------------:|:--------------------------:|:-------:|:--------------:|:---------------------------------------------------------:|
65+
| api_token | Yes | - | Yes | STRING |
66+
| zone_identifier | Yes | - | Yes | STRING |
67+
| action | Yes | - | No | ENUM[purge_everything,purge_hosts,purge_files,purge_tags] |
68+
| list | action != purge_everything | - | Yes | ARRAY\<STRING\> |
69+
70+
## Examples
71+
72+
```yaml
73+
kind: pipeline
74+
name: default
75+
76+
steps:
77+
- name: cloudflare
78+
image: jetrails/drone-cloudflare-caching
79+
settings:
80+
api_token:
81+
from_secret: cloudflare_token
82+
zone_identifier:
83+
from_secret: cloudflare_zone_identifier
84+
action: purge_everything
85+
```
86+
87+
```yaml
88+
kind: pipeline
89+
name: default
90+
91+
steps:
92+
- name: cloudflare
93+
image: jetrails/drone-cloudflare-caching
94+
settings:
95+
api_token:
96+
from_secret: cloudflare_token
97+
zone_identifier:
98+
from_secret: cloudflare_zone_identifier
99+
action: purge_hosts
100+
list:
101+
- example.com
102+
- foo.example.com
103+
- bar.example.com
104+
```
105+
106+
```yaml
107+
kind: pipeline
108+
name: default
109+
110+
steps:
111+
- name: cloudflare
112+
image: jetrails/drone-cloudflare-caching
113+
settings:
114+
api_token:
115+
from_secret: cloudflare_token
116+
zone_identifier:
117+
from_secret: cloudflare_zone_identifier
118+
action: purge_files
119+
list:
120+
- https://example.com/script.js
121+
- https://example.com/logo.svg
122+
```
123+
124+
```yaml
125+
kind: pipeline
126+
name: default
127+
128+
steps:
129+
- name: cloudflare
130+
image: jetrails/drone-cloudflare-caching
131+
settings:
132+
api_token:
133+
from_secret: cloudflare_token
134+
zone_identifier:
135+
from_secret: cloudflare_zone_identifier
136+
action: purge_tags
137+
list:
138+
- foo
139+
- bar
140+
```
141+
142+
## Feature Requests / Issues
143+
144+
Feel free to open an issue for any feature requests and issues that you may come across. For furthur inquery, please contact [development@jetrails.com](mailto://development@jetrails.com).

src/main.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package main
2+
3+
import "fmt"
4+
import "os"
5+
import "strings"
6+
import "github.com/caarlos0/env"
7+
import "github.com/cloudflare/cloudflare-go"
8+
9+
type Input struct {
10+
Debug bool `env:"PLUGIN_DEBUG" envDefault:false`
11+
ApiToken string `env:"PLUGIN_API_TOKEN,required"`
12+
ZoneIdentifier string `env:"PLUGIN_ZONE_IDENTIFIER,required"`
13+
Action string `env:"PLUGIN_ACTION,required"`
14+
List [] string `env:"PLUGIN_LIST" envSeparator:","`
15+
}
16+
17+
func contains ( a [] string, x string ) bool {
18+
for _, n := range a {
19+
if x == n {
20+
return true
21+
}
22+
}
23+
return false
24+
}
25+
26+
func handleCloudflareError ( instance error ) {
27+
if instance != nil {
28+
fmt.Printf ( "error: %#v\n", instance )
29+
os.Exit ( 3 )
30+
}
31+
}
32+
33+
func main () {
34+
// Define valid actions
35+
validActions := [] string {
36+
"purge_everything",
37+
"purge_hosts",
38+
"purge_files",
39+
"purge_tags",
40+
}
41+
// Parse environmental variables
42+
input := Input {}
43+
if error := env.Parse ( &input ); error != nil {
44+
fmt.Printf ( "%+v\n", error )
45+
os.Exit ( 1 )
46+
}
47+
// Normalize input
48+
input.Action = strings.ToLower ( input.Action )
49+
// Semantic checks
50+
if !contains ( validActions, input.Action ) {
51+
fmt.Printf (
52+
"error: PLUGIN_ACTION must equal one of [%s]\n",
53+
strings.Join ( validActions, "," ),
54+
)
55+
os.Exit ( 2 )
56+
} else if input.Action != "purge_everything" && len ( input.List ) < 1 {
57+
fmt.Printf (
58+
"error: PLUGIN_LIST must be set with '%s' action\n",
59+
input.Action,
60+
)
61+
os.Exit ( 2 )
62+
}
63+
// Create client for cloudflare api communication
64+
api, error := cloudflare.NewWithAPIToken ( input.ApiToken )
65+
handleCloudflareError ( error )
66+
// Print input if debug mode is on
67+
if input.Debug {
68+
fmt.Printf ( "Input: %+v\n", input )
69+
}
70+
// Execute action
71+
request := cloudflare.PurgeCacheRequest { false, nil, nil, nil }
72+
switch input.Action {
73+
case "purge_everything":
74+
request.Everything = true
75+
break
76+
case "purge_hosts":
77+
request.Hosts = input.List
78+
break
79+
case "purge_files":
80+
request.Files = input.List
81+
break
82+
case "purge_tags":
83+
request.Tags = input.List
84+
break
85+
}
86+
res, error := api.PurgeCache ( input.ZoneIdentifier, request )
87+
handleCloudflareError ( error )
88+
if input.Debug {
89+
fmt.Printf ( "PurgeCache: %+v\n", res )
90+
}
91+
}

0 commit comments

Comments
 (0)