├── Gopkg.lock
├── Gopkg.toml
├── LICENSE
├── Makefile
├── README.md
├── cmd
├── api.go
├── autogenerate
│ └── autogenerate.go
├── autogenerated.go
├── configure.go
└── root.go
├── definitions
├── README.md
├── definitions.go
├── definitions.toml
└── definitions_test.go
├── lib
├── .cf
│ └── credentials
├── creds.go
└── creds_test.go
├── logo.png
└── main.go
/Gopkg.lock:
--------------------------------------------------------------------------------
1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
2 |
3 |
4 | [[projects]]
5 | branch = "master"
6 | name = "github.com/99designs/keyring"
7 | packages = ["."]
8 | revision = "82da6802f65f1ac7963cfc3b7c62ae12dab8ee5d"
9 |
10 | [[projects]]
11 | name = "github.com/BurntSushi/toml"
12 | packages = ["."]
13 | revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005"
14 | version = "v0.3.1"
15 |
16 | [[projects]]
17 | branch = "master"
18 | name = "github.com/aulanov/go.dbus"
19 | packages = ["."]
20 | revision = "25c3068a42a0b50b877953fb249dbcffc6bd1bca"
21 |
22 | [[projects]]
23 | name = "github.com/aws/aws-sdk-go"
24 | packages = [
25 | "aws",
26 | "aws/awserr",
27 | "aws/awsutil",
28 | "aws/client",
29 | "aws/client/metadata",
30 | "aws/corehandlers",
31 | "aws/credentials",
32 | "aws/credentials/ec2rolecreds",
33 | "aws/credentials/endpointcreds",
34 | "aws/credentials/processcreds",
35 | "aws/credentials/stscreds",
36 | "aws/csm",
37 | "aws/defaults",
38 | "aws/ec2metadata",
39 | "aws/endpoints",
40 | "aws/request",
41 | "aws/session",
42 | "aws/signer/v4",
43 | "internal/ini",
44 | "internal/sdkio",
45 | "internal/sdkrand",
46 | "internal/sdkuri",
47 | "internal/shareddefaults",
48 | "private/protocol",
49 | "private/protocol/query",
50 | "private/protocol/query/queryutil",
51 | "private/protocol/rest",
52 | "private/protocol/xml/xmlutil",
53 | "service/sts"
54 | ]
55 | revision = "a86c8123483bed64c20a08cddc5155e8e8c89dcb"
56 | version = "v1.16.31"
57 |
58 | [[projects]]
59 | name = "github.com/cloudflare/cloudflare-go"
60 | packages = ["."]
61 | revision = "9837a599c0ba49ff8208dd679b4500e8ece407a5"
62 |
63 | [[projects]]
64 | name = "github.com/danieljoos/wincred"
65 | packages = ["."]
66 | revision = "412b574fb496839b312a75fba146bd32a89001cf"
67 | version = "v1.0.1"
68 |
69 | [[projects]]
70 | name = "github.com/dvsekhvalnov/jose2go"
71 | packages = [
72 | ".",
73 | "aes",
74 | "arrays",
75 | "base64url",
76 | "compact",
77 | "kdf",
78 | "keys/ecc",
79 | "padding"
80 | ]
81 | revision = "f21a8cedbbae609f623613ec8f81125c243212e6"
82 | version = "v1.3"
83 |
84 | [[projects]]
85 | name = "github.com/godbus/dbus"
86 | packages = ["."]
87 | revision = "2ff6f7ffd60f0f2410b3105864bdd12c7894f844"
88 | version = "v5.0.1"
89 |
90 | [[projects]]
91 | branch = "master"
92 | name = "github.com/gsterjov/go-libsecret"
93 | packages = ["."]
94 | revision = "a6f4afe4910cad8688db3e0e9b9ac92ad22d54e1"
95 |
96 | [[projects]]
97 | name = "github.com/inconshreveable/mousetrap"
98 | packages = ["."]
99 | revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
100 | version = "v1.0"
101 |
102 | [[projects]]
103 | name = "github.com/jmespath/go-jmespath"
104 | packages = ["."]
105 | revision = "c2b33e84"
106 |
107 | [[projects]]
108 | branch = "master"
109 | name = "github.com/keybase/go-keychain"
110 | packages = ["."]
111 | revision = "f1daa725cce4049b1715f1e97d6a51880e401e70"
112 |
113 | [[projects]]
114 | name = "github.com/konsorten/go-windows-terminal-sequences"
115 | packages = ["."]
116 | revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
117 | version = "v1.0.1"
118 |
119 | [[projects]]
120 | branch = "master"
121 | name = "github.com/marshallbrekka/go-u2fhost"
122 | packages = [
123 | ".",
124 | "bytes",
125 | "hid"
126 | ]
127 | revision = "72b0e7a3f583583996b3b382d2dfaa81fdc4b82c"
128 |
129 | [[projects]]
130 | branch = "master"
131 | name = "github.com/marshallbrekka/go.hid"
132 | packages = ["."]
133 | revision = "2c1c4616a9e71d08897a583653abca4b4ac55028"
134 |
135 | [[projects]]
136 | name = "github.com/mitchellh/go-homedir"
137 | packages = ["."]
138 | revision = "af06845cf3004701891bf4fdb884bfe4920b3727"
139 | version = "v1.1.0"
140 |
141 | [[projects]]
142 | name = "github.com/pkg/errors"
143 | packages = ["."]
144 | revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
145 | version = "v0.8.1"
146 |
147 | [[projects]]
148 | name = "github.com/segmentio/aws-okta"
149 | packages = [
150 | "lib",
151 | "lib/saml"
152 | ]
153 | revision = "798d7d0535489dc9c821d624ebc302f76b8123e4"
154 | version = "v0.19.5"
155 |
156 | [[projects]]
157 | name = "github.com/sirupsen/logrus"
158 | packages = ["."]
159 | revision = "e1e72e9de974bd926e5c56f83753fba2df402ce5"
160 | version = "v1.3.0"
161 |
162 | [[projects]]
163 | name = "github.com/spf13/cobra"
164 | packages = ["."]
165 | revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385"
166 | version = "v0.0.3"
167 |
168 | [[projects]]
169 | name = "github.com/spf13/pflag"
170 | packages = ["."]
171 | revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
172 | version = "v1.0.3"
173 |
174 | [[projects]]
175 | branch = "master"
176 | name = "github.com/vaughan0/go-ini"
177 | packages = ["."]
178 | revision = "a98ad7ee00ec53921f08832bc06ecf7fd600e6a1"
179 |
180 | [[projects]]
181 | branch = "master"
182 | name = "github.com/vitaminwater/cgo.wchar"
183 | packages = ["."]
184 | revision = "5dd6f4be3f2a8c064325fe63439975cf37a8aa1d"
185 |
186 | [[projects]]
187 | branch = "master"
188 | name = "golang.org/x/crypto"
189 | packages = ["ssh/terminal"]
190 | revision = "193df9c0f06f8bb35fba505183eaf0acc0136505"
191 |
192 | [[projects]]
193 | branch = "master"
194 | name = "golang.org/x/net"
195 | packages = [
196 | "html",
197 | "html/atom",
198 | "idna",
199 | "publicsuffix"
200 | ]
201 | revision = "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
202 |
203 | [[projects]]
204 | branch = "master"
205 | name = "golang.org/x/sys"
206 | packages = [
207 | "unix",
208 | "windows"
209 | ]
210 | revision = "3b5209105503162ded1863c307ac66fec31120dd"
211 |
212 | [[projects]]
213 | name = "golang.org/x/text"
214 | packages = [
215 | "collate",
216 | "collate/build",
217 | "internal/colltab",
218 | "internal/gen",
219 | "internal/tag",
220 | "internal/triegen",
221 | "internal/ucd",
222 | "language",
223 | "secure/bidirule",
224 | "transform",
225 | "unicode/bidi",
226 | "unicode/cldr",
227 | "unicode/norm",
228 | "unicode/rangetable"
229 | ]
230 | revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
231 | version = "v0.3.0"
232 |
233 | [[projects]]
234 | branch = "master"
235 | name = "golang.org/x/time"
236 | packages = ["rate"]
237 | revision = "85acf8d2951cb2a3bde7632f9ff273ef0379bcbd"
238 |
239 | [solve-meta]
240 | analyzer-name = "dep"
241 | analyzer-version = 1
242 | inputs-digest = "cdfce4f52044eb828996578b9195bbc99c5e6dec1216fe8b85f49ed0a9470f6f"
243 | solver-name = "gps-cdcl"
244 | solver-version = 1
245 |
--------------------------------------------------------------------------------
/Gopkg.toml:
--------------------------------------------------------------------------------
1 | # Gopkg.toml example
2 | #
3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
4 | # for detailed Gopkg.toml documentation.
5 | #
6 | # required = ["github.com/user/thing/cmd/thing"]
7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
8 | #
9 | # [[constraint]]
10 | # name = "github.com/user/project"
11 | # version = "1.0.0"
12 | #
13 | # [[constraint]]
14 | # name = "github.com/user/project2"
15 | # branch = "dev"
16 | # source = "github.com/myfork/project2"
17 | #
18 | # [[override]]
19 | # name = "github.com/x/y"
20 | # version = "2.4.0"
21 | #
22 | # [prune]
23 | # non-go = false
24 | # go-tests = true
25 | # unused-packages = true
26 |
27 |
28 | [[constraint]]
29 | branch = "master"
30 | name = "github.com/99designs/keyring"
31 |
32 | [[constraint]]
33 | name = "github.com/BurntSushi/toml"
34 | version = "0.3.1"
35 |
36 | [[constraint]]
37 | name = "github.com/cloudflare/cloudflare-go"
38 | revision="9837a599c0ba49ff8208dd679b4500e8ece407a5"
39 |
40 | [[constraint]]
41 | name = "github.com/segmentio/aws-okta"
42 | version = "0.19.5"
43 |
44 | [[constraint]]
45 | name = "github.com/spf13/cobra"
46 | version = "0.0.3"
47 |
48 | [prune]
49 | go-tests = true
50 | unused-packages = true
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2018 Evan Johnson
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | depends:
3 | dep ensure
4 |
5 | generate:
6 | go run cmd/autogenerate/autogenerate.go
7 |
8 | clean:
9 | -rm cf
10 | -rm -rf dist
11 |
12 | cf: generate
13 | go build
14 |
15 | all: depends clean cf
16 |
17 | dist-linux:
18 | GOOS=linux go build -o dist/cf-linux
19 |
20 | dist:
21 | -mkdir dist
22 |
23 | dist-osx:
24 | GOOS=darwin go build -o dist/cf-osx
25 |
26 | release: clean dist dist-linux dist-osx
27 |
28 | .PHONY: all
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 | A cloudflare command line interface. It makes heavy use of [cloudflare-go](https://github.com/cloudflare/cloudflare-go)
6 |
7 | # Installation
8 | ```
9 | go get -u github.com/ejcx/cf
10 | ```
11 |
12 | # Demo
13 |
14 |

15 |
16 |
17 | # Usage
18 | **The cf is a full featured cli. All product areas are divided in to subcommands. All commands and subcommands will describe themselves and list options, required arguments, and information about what the command does.**
19 |
20 |
21 |

22 |
23 |
24 | **Interacting with the full Cloudflare API and retrieving the most detailed information can be done quickly and easily.**
25 |
26 |
27 |

28 |
29 |
30 | **Automate common operations quickly and easily**
31 |
32 |
33 |

34 |
35 |
36 | # Credentials
37 | Your cloudflare api credentials can be stored in `~/.cf/credentials` as
38 | environment variables or in your keychain.
39 |
40 | ### Keychain
41 | To store your credentials in your keychain run `cf configure` and enter your
42 | email, apikey, and user service apikey.
43 | ```
44 | e :) cf configure
45 | Cloudflare Email: evan@cloudflare.com
46 | Cloudflare APIKey:
47 | Origin CA APIKey:
48 |
49 | e :)
50 | ```
51 | ### Ignore Keychain
52 | To avoid storing your credentials in the keychain, specify the `--no-keychain`
53 | flag when calling `cf configure` to store your api credentials in plaintext.
54 |
55 | ```
56 | e :) cf configure --help
57 | A command for configuring your cloudflare api credentials
58 |
59 | Usage:
60 | cf configure [flags]
61 |
62 | Flags:
63 | -h, --help help for configure
64 | --no-keychain Do not attempt to store cloudflare api credentials in the keychain. Just use plaintext file.
65 |
66 | e :) cf configure --no-keychain
67 | Cloudflare Email: evan@cloudflare.com
68 | Cloudflare APIKey:
69 | Service APIKey:
70 |
71 | e :) cat ~/.cf/credentials
72 | {"Email":"evan@cloudflare","Key":"xxx","UserServiceKey":"yyy","Keychain":false}%
73 | ```
74 |
75 | ### Environment Variables
76 | The three environment variables that should be set are `CF_API_KEY`, `CF_API_EMAIL`, and `CF_USER_SERVICE_KEY`. If any of the environment variables are set then the credentials file is ignored
--------------------------------------------------------------------------------
/cmd/api.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "io/ioutil"
7 | "log"
8 | "os"
9 | "strings"
10 | "time"
11 |
12 | cloudflare "github.com/cloudflare/cloudflare-go"
13 | )
14 |
15 | func ListZones(api *cloudflare.API, ZoneNameFilter string) (resp interface{}, err error) {
16 | if ZoneNameFilter != "" {
17 | resp, err = api.ListZones(ZoneNameFilter)
18 | } else {
19 | resp, err = api.ListZones()
20 | }
21 | return
22 | }
23 |
24 | func ListDnsRecords(api *cloudflare.API, ZoneId string, Type string, Name string, Content string) (resp interface{}, err error) {
25 | rec := cloudflare.DNSRecord{}
26 | if Type != "" {
27 | rec.Type = Type
28 | }
29 | if Name != "" {
30 | rec.Name = Name
31 | }
32 | if Content != "" {
33 | rec.Content = Content
34 | }
35 | resp, err = api.DNSRecords(ZoneId, rec)
36 | return
37 | }
38 |
39 | func CreateDnsRecord(api *cloudflare.API, ZoneId string, Type string, Name string, Content string, Ttl int, NotProxied bool, Priority int) (resp interface{}, err error) {
40 | rec := cloudflare.DNSRecord{}
41 | if Type != "" {
42 | rec.Type = Type
43 | }
44 | if Name != "" {
45 | rec.Name = Name
46 | }
47 | if Content != "" {
48 | rec.Content = Content
49 | }
50 | if Priority > 0 {
51 | rec.Priority = Priority
52 | }
53 | if Ttl != 0 {
54 | rec.TTL = Ttl
55 | }
56 | rec.Proxied = true
57 | if NotProxied {
58 | rec.Proxied = false
59 | }
60 | resp, err = api.CreateDNSRecord(ZoneId, rec)
61 | return
62 | }
63 |
64 | func DeleteDnsRecord(api *cloudflare.API, ZoneId string, RecordId string) (resp interface{}, err error) {
65 | err = api.DeleteDNSRecord(ZoneId, RecordId)
66 | if err == nil {
67 | resp = map[string]interface{}{
68 | "Success": true,
69 | }
70 | }
71 | return
72 | }
73 |
74 | func DeleteZone(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
75 | resp, err = api.DeleteZone(ZoneId)
76 | return
77 | }
78 |
79 | func CreateZone(api *cloudflare.API, Name string, Jumpstart bool, OrganizationId string) (resp interface{}, err error) {
80 | org := cloudflare.Organization{}
81 | if OrganizationId != "" {
82 | org.ID = OrganizationId
83 | }
84 | resp, err = api.CreateZone(Name, Jumpstart, org)
85 | return
86 | }
87 |
88 | func DNSRecord(api *cloudflare.API, ZoneId string, RecordId string) (resp interface{}, err error) {
89 | resp, err = api.DNSRecord(ZoneId, RecordId)
90 | return
91 | }
92 |
93 | func ListAllRateLimits(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
94 | resp, err = api.ListAllRateLimits(ZoneId)
95 | return
96 | }
97 |
98 | func ListLoadBalancers(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
99 | resp, err = api.ListLoadBalancers(ZoneId)
100 | return
101 | }
102 |
103 | func ListOrganizations(api *cloudflare.API) (resp interface{}, err error) {
104 | resp, _, err = api.ListOrganizations()
105 | return
106 | }
107 |
108 | func ListPageRules(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
109 | resp, err = api.ListPageRules(ZoneId)
110 | return
111 | }
112 |
113 | func ListCustomCerts(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
114 | resp, err = api.ListSSL(ZoneId)
115 | return
116 | }
117 |
118 | func ListUserAgentRules(api *cloudflare.API, ZoneId string, Page int) (resp interface{}, err error) {
119 | page := 1
120 | if Page != 0 {
121 | page = Page
122 | }
123 | resp, err = api.ListUserAgentRules(ZoneId, page)
124 | return
125 | }
126 |
127 | func ListWAFPackages(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
128 | resp, err = api.ListWAFPackages(ZoneId)
129 | return
130 | }
131 |
132 | func ListWAFRules(api *cloudflare.API, ZoneId string, PackageId string) (resp interface{}, err error) {
133 | resp, err = api.ListWAFRules(ZoneId, PackageId)
134 | return
135 | }
136 |
137 | func ListZoneLockdowns(api *cloudflare.API, ZoneId string, Page int) (resp interface{}, err error) {
138 | page := 1
139 | if Page != 0 {
140 | page = Page
141 | }
142 | resp, err = api.ListZoneLockdowns(ZoneId, page)
143 | return
144 | }
145 |
146 | func ZoneLockdown(api *cloudflare.API, ZoneId string, LockdownId string) (resp interface{}, err error) {
147 | resp, err = api.ZoneLockdown(ZoneId, LockdownId)
148 | return
149 | }
150 |
151 | func EditZonePaused(api *cloudflare.API, ZoneId string, Paused bool) (resp interface{}, err error) {
152 | z := cloudflare.ZoneOptions{
153 | Paused: &Paused,
154 | }
155 | resp, err = api.EditZone(ZoneId, z)
156 | return
157 | }
158 |
159 | func EditZoneVanityNS(api *cloudflare.API, ZoneId string, VanityNs string) (resp interface{}, err error) {
160 | vns := strings.Split(VanityNs, ",")
161 | z := cloudflare.ZoneOptions{
162 | VanityNS: vns,
163 | }
164 | resp, err = api.EditZone(ZoneId, z)
165 | return
166 | }
167 |
168 | func ZoneSetVanityNS(api *cloudflare.API, ZoneId string, VanityNs string) (resp interface{}, err error) {
169 | vns := strings.Split(VanityNs, ",")
170 | resp, err = api.ZoneSetVanityNS(ZoneId, vns)
171 | return
172 | }
173 |
174 | func EditDNSRecord(api *cloudflare.API, Proxied bool, ZoneId string, RecordId string, Type string, Name string, Content string, Ttl int) (resp interface{}, err error) {
175 | rec := cloudflare.DNSRecord{
176 | Type: Type,
177 | Name: Name,
178 | Content: Content,
179 | Proxied: Proxied,
180 | TTL: Ttl,
181 | }
182 | err = api.UpdateDNSRecord(ZoneId, RecordId, rec)
183 | return
184 | }
185 |
186 | func ListLoadBalancerMonitors(api *cloudflare.API) (resp interface{}, err error) {
187 | resp, err = api.ListLoadBalancerMonitors()
188 | return
189 | }
190 |
191 | func ListLoadBalancerPools(api *cloudflare.API) (resp interface{}, err error) {
192 | resp, err = api.ListLoadBalancerPools()
193 | return
194 | }
195 |
196 | func ListOrganizationAccessRules(api *cloudflare.API, OrganizationId string, Notes string, Mode string, Page int) (resp interface{}, err error) {
197 | ar := cloudflare.AccessRule{}
198 | if Notes != "" {
199 | ar.Notes = Notes
200 | }
201 | if Mode != "" {
202 | ar.Mode = Mode
203 | }
204 | resp, err = api.ListOrganizationAccessRules(OrganizationId, ar, Page)
205 | return
206 | }
207 |
208 | func ListRailguns(api *cloudflare.API) (resp interface{}, err error) {
209 | resp, err = api.ListRailguns(cloudflare.RailgunListOptions{})
210 | return
211 | }
212 |
213 | func ListZoneRailguns(api *cloudflare.API) (resp interface{}, err error) {
214 | resp, err = api.ZoneRailguns(ZoneId)
215 | return
216 | }
217 |
218 | func ListUserAccessRules(api *cloudflare.API, Notes string, Mode string, Page int) (resp interface{}, err error) {
219 | ar := cloudflare.AccessRule{}
220 | if Notes != "" {
221 | ar.Notes = Notes
222 | }
223 | if Mode != "" {
224 | ar.Mode = Mode
225 | }
226 | resp, err = api.ListUserAccessRules(ar, Page)
227 | return
228 | }
229 |
230 | func ListVirtualDns(api *cloudflare.API) (resp interface{}, err error) {
231 | resp, err = api.ListVirtualDNS()
232 | return
233 | }
234 |
235 | func AvailableZoneRatePlans(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
236 | resp, err = api.AvailableZoneRatePlans(ZoneId)
237 | return
238 | }
239 |
240 | func ConnectZoneRailgun(api *cloudflare.API, ZoneId string, RailgunId string) (resp interface{}, err error) {
241 | resp, err = api.ConnectZoneRailgun(ZoneId, RailgunId)
242 | return
243 | }
244 |
245 | func CreateCustomHostname(api *cloudflare.API, ZoneId string, Hostname string, Method string, Type string) (resp interface{}, err error) {
246 | resp, err = api.CreateCustomHostname(ZoneId, cloudflare.CustomHostname{
247 | Hostname: Hostname,
248 | SSL: cloudflare.CustomHostnameSSL{
249 | Method: Method,
250 | Type: Type,
251 | },
252 | })
253 | return
254 | }
255 |
256 | func CreateLoadBalancerMonitor(api *cloudflare.API, ExpectedCodes string, Method string, Header string, Timeout int, Path string, Interval int, Retries int, ExpectedBody string, Type string, Description string) (resp interface{}, err error) {
257 | l := cloudflare.LoadBalancerMonitor{ExpectedCodes: ExpectedCodes}
258 | if Method != "" {
259 | l.Method = Method
260 | }
261 | if Timeout > 0 {
262 | l.Timeout = Timeout
263 | }
264 | if Header != "" {
265 | h := make(map[string][]string)
266 | err = json.Unmarshal([]byte(Header), &h)
267 | if err != nil {
268 | return nil, err
269 | }
270 | l.Header = h
271 | }
272 | if Path != "" {
273 | l.Path = Path
274 | }
275 | if Interval > 0 {
276 | l.Interval = Interval
277 | }
278 | if Retries > 0 {
279 | l.Retries = Retries
280 | }
281 | if Type != "" {
282 | l.Type = Type
283 | }
284 | if Description != "" {
285 | l.Description = Description
286 | }
287 | resp, err = api.CreateLoadBalancerMonitor(l)
288 | return
289 | }
290 |
291 | func CreateLoadBalancer(api *cloudflare.API, ZoneId string, Name string, FallbackPool string, DefaultPools string, Proxied bool, Ttl int) (resp interface{}, err error) {
292 | d := strings.Split(DefaultPools, ",")
293 | l := cloudflare.LoadBalancer{
294 | Name: Name,
295 | FallbackPool: FallbackPool,
296 | DefaultPools: d,
297 | Proxied: Proxied,
298 | }
299 | if Ttl > 0 {
300 | l.TTL = Ttl
301 | }
302 | api.CreateLoadBalancer(ZoneId, l)
303 | return
304 | }
305 |
306 | func PurgeEverything(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
307 | resp, err = api.PurgeEverything(ZoneId)
308 | return
309 | }
310 |
311 | func ActivationCheck(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
312 | resp, err = api.ZoneActivationCheck(ZoneId)
313 | return
314 | }
315 |
316 | func ZoneDetails(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
317 | resp, err = api.ZoneDetails(ZoneId)
318 | return
319 | }
320 |
321 | func GetIDByName(api *cloudflare.API, ZoneName string) (resp interface{}, err error) {
322 | resp, err = api.ZoneIDByName(ZoneName)
323 | return
324 | }
325 |
326 | func ZoneSSLSettings(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
327 | resp, err = api.ZoneSSLSettings(ZoneId)
328 | return
329 | }
330 |
331 | func ZoneSettings(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
332 | resp, err = api.ZoneSettings(ZoneId)
333 | return
334 | }
335 |
336 | func UserDetails(api *cloudflare.API) (resp interface{}, err error) {
337 | resp, err = api.UserDetails()
338 | return
339 | }
340 |
341 | func UserBillingProfile(api *cloudflare.API) (resp interface{}, err error) {
342 | resp, err = api.UserBillingProfile()
343 | return
344 | }
345 |
346 | func VirtualDNS(api *cloudflare.API, VirtualDnsId string) (resp interface{}, err error) {
347 | resp, err = api.VirtualDNS(VirtualDnsId)
348 | return
349 | }
350 |
351 | func DeleteVirtualDNS(api *cloudflare.API, VirtualDnsId string) (resp interface{}, err error) {
352 | err = api.DeleteVirtualDNS(VirtualDnsId)
353 | return
354 | }
355 |
356 | func PageRule(api *cloudflare.API, ZoneId string, PageruleId string) (resp interface{}, err error) {
357 | resp, err = api.PageRule(ZoneId, PageruleId)
358 | return
359 | }
360 |
361 | func LoadBalancerDetails(api *cloudflare.API, ZoneId string, LoadbalancerId string) (resp interface{}, err error) {
362 | resp, err = api.LoadBalancerDetails(ZoneId, LoadbalancerId)
363 | return
364 | }
365 |
366 | func LoadBalancerMonitorDetails(api *cloudflare.API, MonitorId string) (resp interface{}, err error) {
367 | resp, err = api.LoadBalancerMonitorDetails(MonitorId)
368 | return
369 | }
370 |
371 | func LoadBalancerPoolDetails(api *cloudflare.API, PoolId string) (resp interface{}, err error) {
372 | resp, err = api.LoadBalancerPoolDetails(PoolId)
373 | return
374 | }
375 |
376 | func OrganizationDetails(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
377 | resp, err = api.OrganizationDetails(OrganizationId)
378 | return
379 | }
380 |
381 | func OrganizationInvites(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
382 | resp, _, err = api.OrganizationInvites(OrganizationId)
383 | return
384 | }
385 |
386 | func OrganizationMembers(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
387 | resp, _, err = api.OrganizationMembers(OrganizationId)
388 | return
389 | }
390 |
391 | func OrganizationRoles(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
392 | resp, _, err = api.OrganizationRoles(OrganizationId)
393 | return
394 | }
395 |
396 | func OriginCertificates(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
397 | resp, err = api.OriginCertificates(cloudflare.OriginCACertificateListOptions{ZoneID: ZoneId})
398 | return
399 | }
400 |
401 | func OriginCertificate(api *cloudflare.API, CertificateId string) (resp interface{}, err error) {
402 | resp, err = api.OriginCertificate(CertificateId)
403 | return
404 | }
405 |
406 | func SSLDetails(api *cloudflare.API, CertificateId string, ZoneId string) (resp interface{}, err error) {
407 | resp, err = api.SSLDetails(ZoneId, CertificateId)
408 | return
409 | }
410 |
411 | func RailgunDetails(api *cloudflare.API, RailgunId string) (resp interface{}, err error) {
412 | resp, err = api.RailgunDetails(RailgunId)
413 | return
414 | }
415 |
416 | func RailgunZones(api *cloudflare.API, RailgunId string) (resp interface{}, err error) {
417 | resp, err = api.RailgunZones(RailgunId)
418 | return
419 | }
420 |
421 | func RateLimit(api *cloudflare.API, ZoneId string, RatelimitId string) (resp interface{}, err error) {
422 | resp, err = api.RateLimit(ZoneId, RatelimitId)
423 | return
424 | }
425 |
426 | func RevokeOriginCertificate(api *cloudflare.API, CertificateId string) (resp interface{}, err error) {
427 | resp, err = api.RevokeOriginCertificate(CertificateId)
428 | return
429 | }
430 |
431 | func TestRailgunConnection(api *cloudflare.API, ZoneId string, RailgunId string) (resp interface{}, err error) {
432 | resp, err = api.TestRailgunConnection(ZoneId, RailgunId)
433 | return
434 | }
435 |
436 | func ZoneRailgunDetails(api *cloudflare.API, ZoneId string, RailgunId string) (resp interface{}, err error) {
437 | resp, err = api.ZoneRailgunDetails(ZoneId, RailgunId)
438 | return
439 | }
440 |
441 | func CustomHostname(api *cloudflare.API, ZoneId string, CustomHostnameId string) (resp interface{}, err error) {
442 | resp, err = api.CustomHostname(ZoneId, CustomHostnameId)
443 | return
444 | }
445 |
446 | func CustomHostnameIDByName(api *cloudflare.API, ZoneId string, Name string) (resp interface{}, err error) {
447 | resp, err = api.CustomHostnameIDByName(ZoneId, Name)
448 | return
449 | }
450 |
451 | func ZoneSetPaused(api *cloudflare.API, ZoneId string, Paused bool) (resp interface{}, err error) {
452 | resp, err = api.ZoneSetPaused(ZoneId, Paused)
453 | return
454 | }
455 |
456 | func DeletePageRule(api *cloudflare.API, ZoneId string, PageruleId string) (resp interface{}, err error) {
457 | err = api.DeletePageRule(ZoneId, PageruleId)
458 | return
459 | }
460 |
461 | func DeleteRailgun(api *cloudflare.API, RailgunId string) (resp interface{}, err error) {
462 | err = api.DeleteRailgun(RailgunId)
463 | return
464 | }
465 |
466 | func DisableRailgun(api *cloudflare.API, RailgunId string) (resp interface{}, err error) {
467 | resp, err = api.DisableRailgun(RailgunId)
468 | return
469 | }
470 |
471 | func DisconnectZoneRailgun(api *cloudflare.API, RailgunId string, ZoneId string) (resp interface{}, err error) {
472 | resp, err = api.DisconnectZoneRailgun(ZoneId, RailgunId)
473 | return
474 | }
475 |
476 | func EnableRailgun(api *cloudflare.API, RailgunId string) (resp interface{}, err error) {
477 | resp, err = api.EnableRailgun(RailgunId)
478 | return
479 | }
480 |
481 | func DeleteRateLimit(api *cloudflare.API, ZoneId string, RatelimitId string) (resp interface{}, err error) {
482 | err = api.DeleteRateLimit(ZoneId, RatelimitId)
483 | return
484 | }
485 |
486 | func DeleteSSL(api *cloudflare.API, ZoneId string, CertificateId string) (resp interface{}, err error) {
487 | err = api.DeleteSSL(ZoneId, CertificateId)
488 | return
489 | }
490 |
491 | func DeleteCustomHostname(api *cloudflare.API, ZoneId string, CustomHostnameId string) (resp interface{}, err error) {
492 | err = api.DeleteCustomHostname(ZoneId, CustomHostnameId)
493 | return
494 | }
495 |
496 | func DeleteLoadBalancer(api *cloudflare.API, ZoneId string, LoadbalancerId string) (resp interface{}, err error) {
497 | err = api.DeleteLoadBalancer(ZoneId, LoadbalancerId)
498 | return
499 | }
500 |
501 | func DeleteLoadBalancerMonitor(api *cloudflare.API, MonitorId string) (resp interface{}, err error) {
502 | err = api.DeleteLoadBalancerMonitor(MonitorId)
503 | return
504 | }
505 |
506 | func DeleteLoadBalancerPool(api *cloudflare.API, PoolId string) (resp interface{}, err error) {
507 | err = api.DeleteLoadBalancerPool(PoolId)
508 | return
509 | }
510 |
511 | func DeleteOrganizationAccessRule(api *cloudflare.API, OrganizationId string, AccessRuleId string) (resp interface{}, err error) {
512 | resp, err = api.DeleteOrganizationAccessRule(OrganizationId, AccessRuleId)
513 | return
514 | }
515 |
516 | func CreateRailgun(api *cloudflare.API, Name string) (resp interface{}, err error) {
517 | resp, err = api.CreateRailgun(Name)
518 | return
519 | }
520 |
521 | func DeleteUserAccessRule(api *cloudflare.API, AccessRuleId string) (resp interface{}, err error) {
522 | resp, err = api.DeleteUserAccessRule(AccessRuleId)
523 | return
524 | }
525 |
526 | func DeleteUserAgentRule(api *cloudflare.API, UserAgentId string, ZoneId string) (resp interface{}, err error) {
527 | resp, err = api.DeleteUserAgentRule(ZoneId, UserAgentId)
528 | return
529 | }
530 |
531 | func DeleteZoneAccessRule(api *cloudflare.API, AccessRuleId string, ZoneId string) (resp interface{}, err error) {
532 | resp, err = api.DeleteZoneAccessRule(ZoneId, AccessRuleId)
533 | return
534 | }
535 |
536 | func DeleteZoneLockdown(api *cloudflare.API, ZoneId string, LockdownId string) (resp interface{}, err error) {
537 | resp, err = api.DeleteZoneLockdown(ZoneId, LockdownId)
538 | return
539 | }
540 |
541 | func ZoneAnalyticsByColocation(api *cloudflare.API, ZoneId string, Since string, Until string, Continuous bool) (resp interface{}, err error) {
542 | z := cloudflare.ZoneAnalyticsOptions{}
543 | if Since != "" {
544 | t, err := time.Parse(time.RFC3339, Since)
545 | if err != nil {
546 | log.Fatalf("Invalid timestamp passed to Since: %s", err)
547 | }
548 | z.Since = &t
549 | }
550 | if Until != "" {
551 | t, err := time.Parse(time.RFC3339, Until)
552 | if err != nil {
553 | log.Fatalf("Invalid timestamp passed to Until: %s", err)
554 | }
555 | z.Until = &t
556 | }
557 | z.Continuous = &Continuous
558 | resp, err = api.ZoneAnalyticsDashboard(ZoneId, z)
559 | return
560 | }
561 |
562 | func ZoneAnalyticsDashboard(api *cloudflare.API, ZoneId string, Since string, Until string, Continuous bool) (resp interface{}, err error) {
563 | z := cloudflare.ZoneAnalyticsOptions{}
564 | if Since != "" {
565 | t, err := time.Parse(time.RFC3339, Since)
566 | if err != nil {
567 | log.Fatalf("Invalid timestamp passed to Since: %s", err)
568 | }
569 | z.Since = &t
570 | }
571 | if Until != "" {
572 | t, err := time.Parse(time.RFC3339, Until)
573 | if err != nil {
574 | log.Fatalf("Invalid timestamp passed to Until: %s", err)
575 | }
576 | z.Until = &t
577 | }
578 | z.Continuous = &Continuous
579 | resp, err = api.ZoneAnalyticsDashboard(ZoneId, z)
580 | return
581 | }
582 |
583 | func UpdateUser(api *cloudflare.API, FirstName string, LastName string, Telephone string, Country string, Zipcode string) (resp interface{}, err error) {
584 | u := &cloudflare.User{}
585 | var setVar bool
586 | if FirstName != "" {
587 | u.FirstName = FirstName
588 | setVar = true
589 | }
590 | if LastName != "" {
591 | u.LastName = LastName
592 | setVar = true
593 | }
594 | if Telephone != "" {
595 | u.Telephone = Telephone
596 | setVar = true
597 | }
598 | if Country != "" {
599 | u.Country = Country
600 | setVar = true
601 | }
602 | if Zipcode != "" {
603 | u.Zipcode = Zipcode
604 | setVar = true
605 | }
606 | if setVar {
607 | resp, err = api.UpdateUser(u)
608 | } else {
609 | resp, err = api.UserDetails()
610 | }
611 | return
612 | }
613 |
614 | func CreateLoadBalancerPool(api *cloudflare.API, Name string, Origins string, Description string, Disabled bool, MinimumOrigins int, Monitor string, NotificationEmail string) (resp interface{}, err error) {
615 | var lbo []cloudflare.LoadBalancerOrigin
616 | err = json.Unmarshal([]byte(Origins), &lbo)
617 | if err != nil {
618 | return
619 | }
620 | l := cloudflare.LoadBalancerPool{
621 | Name: Name,
622 | Origins: lbo,
623 | }
624 | if Description != "" {
625 | l.Description = Description
626 | }
627 | if Disabled {
628 | l.Enabled = false
629 | }
630 | if MinimumOrigins > 0 {
631 | l.MinimumOrigins = MinimumOrigins
632 | }
633 | if Monitor != "" {
634 | l.Monitor = Monitor
635 | }
636 | if NotificationEmail != "" {
637 | l.NotificationEmail = NotificationEmail
638 | }
639 | resp, err = api.CreateLoadBalancerPool(l)
640 | return
641 | }
642 |
643 | func ModifyLoadBalancerPool(api *cloudflare.API, PoolId string, Name string, Origins string, Description string, Disabled bool, MinimumOrigins int, Monitor string, NotificationEmail string) (resp interface{}, err error) {
644 | var lbo []cloudflare.LoadBalancerOrigin
645 | err = json.Unmarshal([]byte(Origins), &lbo)
646 | if err != nil {
647 | return
648 | }
649 | l := cloudflare.LoadBalancerPool{
650 | ID: PoolId,
651 | Name: Name,
652 | Origins: lbo,
653 | }
654 | if Description != "" {
655 | l.Description = Description
656 | }
657 | if Disabled {
658 | l.Enabled = false
659 | }
660 | if MinimumOrigins > 0 {
661 | l.MinimumOrigins = MinimumOrigins
662 | }
663 | if Monitor != "" {
664 | l.Monitor = Monitor
665 | }
666 | if NotificationEmail != "" {
667 | l.NotificationEmail = NotificationEmail
668 | }
669 | resp, err = api.ModifyLoadBalancerPool(l)
670 | return
671 | }
672 |
673 | func UpdateZoneSettings(api *cloudflare.API, ZoneId string, ZoneSettings string) (resp interface{}, err error) {
674 | var zs []cloudflare.ZoneSetting
675 | err = json.Unmarshal([]byte(ZoneSettingsObject), &zs)
676 | if err != nil {
677 | return
678 | }
679 | resp, err = api.UpdateZoneSettings(ZoneId, zs)
680 | return
681 | }
682 |
683 | func UpdateZoneLockdown(api *cloudflare.API, ZoneId string, LockdownId string, Configuration string, Urls string, Paused bool, Description string) (resp interface{}, err error) {
684 | var c []cloudflare.ZoneLockdownConfig
685 | err = json.Unmarshal([]byte(Configuration), &c)
686 | if err != nil {
687 | return
688 | }
689 | urlList := strings.Split(Urls, ",")
690 | zl := cloudflare.ZoneLockdown{
691 | URLs: urlList,
692 | Paused: Paused,
693 | Configurations: c,
694 | }
695 | if Description != "" {
696 | zl.Description = Description
697 | }
698 | resp, err = api.UpdateZoneLockdown(ZoneId, LockdownId, zl)
699 | return
700 | }
701 |
702 | func CreateZoneLockdown(api *cloudflare.API, ZoneId string, Configuration string, Urls string, Paused bool, Description string) (resp interface{}, err error) {
703 | var c []cloudflare.ZoneLockdownConfig
704 | err = json.Unmarshal([]byte(Configuration), &c)
705 | if err != nil {
706 | return
707 | }
708 | urlList := strings.Split(Urls, ",")
709 | zl := cloudflare.ZoneLockdown{
710 | URLs: urlList,
711 | Paused: Paused,
712 | Configurations: c,
713 | }
714 | if Description != "" {
715 | zl.Description = Description
716 | }
717 | resp, err = api.CreateZoneLockdown(ZoneId, zl)
718 | return
719 | }
720 |
721 | func CreateVirtualDNS(api *cloudflare.API, Name string, OriginIps string, MinimumCacheTtl int, MaximumCacheTtl int, DeprecateAnyRequest bool) (resp interface{}, err error) {
722 | v := &cloudflare.VirtualDNS{}
723 | v.Name = Name
724 | v.OriginIPs = strings.Split(OriginIps, ",")
725 | if MinimumCacheTtl > 0 {
726 | v.MinimumCacheTTL = uint(MinimumCacheTtl)
727 | }
728 | if MaximumCacheTtl > 0 {
729 | v.MaximumCacheTTL = uint(MaximumCacheTtl)
730 | }
731 | v.DeprecateAnyRequests = DeprecateAnyRequest
732 | resp, err = api.CreateVirtualDNS(v)
733 | return
734 | }
735 |
736 | func UpdateVirtualDNS(api *cloudflare.API, VirtualDnsId string, OriginIps string, MinimumCacheTtl int, MaximumCacheTtl int, DeprecateAnyRequest bool) (resp interface{}, err error) {
737 | v := &cloudflare.VirtualDNS{}
738 | if Name != "" {
739 | v.Name = Name
740 | }
741 | if OriginIps != "" {
742 | v.OriginIPs = strings.Split(OriginIps, ",")
743 | }
744 | if MinimumCacheTtl > 0 {
745 | v.MinimumCacheTTL = uint(MinimumCacheTtl)
746 | }
747 | if MaximumCacheTtl > 0 {
748 | v.MaximumCacheTTL = uint(MaximumCacheTtl)
749 | }
750 | v.DeprecateAnyRequests = DeprecateAnyRequest
751 | err = api.UpdateVirtualDNS(VirtualDnsId, *v)
752 | return
753 | }
754 |
755 | func CreatePageRule(api *cloudflare.API, ZoneId string, Targets string, Actions string, Priority int, Status string) (resp interface{}, err error) {
756 | var (
757 | prt []cloudflare.PageRuleTarget
758 | pra []cloudflare.PageRuleAction
759 | r = cloudflare.PageRule{}
760 | )
761 |
762 | err = json.Unmarshal([]byte(Targets), &prt)
763 | if err != nil {
764 | return
765 | }
766 | err = json.Unmarshal([]byte(Actions), &pra)
767 | if err != nil {
768 | return
769 | }
770 | if Priority > 0 {
771 | r.Priority = Priority
772 | }
773 | r.Status = Status
774 | r.Actions = pra
775 | r.Targets = prt
776 | resp, err = api.CreatePageRule(ZoneId, r)
777 | return
778 | }
779 |
780 | func ChangePageRule(api *cloudflare.API, ZoneId string, PageruleId string, Targets string, Actions string, Priority int, Status string) (resp interface{}, err error) {
781 | var (
782 | prt []cloudflare.PageRuleTarget
783 | pra []cloudflare.PageRuleAction
784 | r = cloudflare.PageRule{}
785 | )
786 |
787 | err = json.Unmarshal([]byte(Targets), &prt)
788 | if err != nil {
789 | return
790 | }
791 | err = json.Unmarshal([]byte(Actions), &pra)
792 | if err != nil {
793 | return
794 | }
795 | if Priority > 0 {
796 | r.Priority = Priority
797 | }
798 | r.Status = Status
799 | r.Actions = pra
800 | r.Targets = prt
801 | err = api.ChangePageRule(ZoneId, PageruleId, r)
802 | return
803 | }
804 |
805 | func CreateOrganizationAccessRule(api *cloudflare.API, OrganizationId string, Mode string, Configuration string, Notes string) (resp interface{}, err error) {
806 | h := strings.Split(Hostnames, ",")
807 | c := cloudflare.OriginCACertificate{
808 | Hostnames: h,
809 | RequestValidity: RequestValidity,
810 | RequestType: RequestType,
811 | CSR: Csr,
812 | }
813 | resp, err = api.CreateOriginCertificate(c)
814 | return
815 | }
816 |
817 | func CreateOriginCertificate(api *cloudflare.API, Hostnames string, RequestValidity int, RequestType string, Csr string) (resp interface{}, err error) {
818 | h := strings.Split(Hostnames, ",")
819 | c := cloudflare.OriginCACertificate{
820 | Hostnames: h,
821 | RequestValidity: RequestValidity,
822 | RequestType: RequestType,
823 | CSR: Csr,
824 | }
825 | resp, err = api.CreateOriginCertificate(c)
826 | return
827 | }
828 |
829 | func CreateRateLimit(api *cloudflare.API, ZoneId string, Match string, Threshold int, Period int, Action string, Enabled bool, Description string, Bypass string) (resp interface{}, err error) {
830 | var (
831 | rlkv []cloudflare.RateLimitKeyValue
832 | m cloudflare.RateLimitTrafficMatcher
833 | a cloudflare.RateLimitAction
834 | )
835 | err = json.Unmarshal([]byte(Match), &m)
836 | if err != nil {
837 | return
838 | }
839 | err = json.Unmarshal([]byte(Action), &a)
840 | if err != nil {
841 | return
842 | }
843 | rl := cloudflare.RateLimit{
844 | Disabled: Enabled,
845 | Period: Period,
846 | Threshold: Threshold,
847 | Match: m,
848 | Action: a,
849 | }
850 | if Bypass != "" {
851 | err = json.Unmarshal([]byte(Bypass), &rlkv)
852 | if err != nil {
853 | return
854 | }
855 | rl.Bypass = rlkv
856 | }
857 | if Description != "" {
858 | rl.Description = Description
859 | }
860 | resp, err = api.CreateRateLimit(ZoneId, rl)
861 | return
862 | }
863 |
864 | func UpdateRateLimit(api *cloudflare.API, ZoneId string, LimitId string, Match string, Threshold int, Period int, Action string, Enabled bool, Description string, Bypass string) (resp interface{}, err error) {
865 | var (
866 | rlkv []cloudflare.RateLimitKeyValue
867 | m cloudflare.RateLimitTrafficMatcher
868 | a cloudflare.RateLimitAction
869 | )
870 | err = json.Unmarshal([]byte(Match), &m)
871 | if err != nil {
872 | return
873 | }
874 | err = json.Unmarshal([]byte(Action), &a)
875 | if err != nil {
876 | return
877 | }
878 | rl := cloudflare.RateLimit{
879 | ID: LimitId,
880 | Disabled: Enabled,
881 | Period: Period,
882 | Threshold: Threshold,
883 | Match: m,
884 | Action: a,
885 | }
886 | if Bypass != "" {
887 | err = json.Unmarshal([]byte(Bypass), &rlkv)
888 | if err != nil {
889 | return
890 | }
891 | rl.Bypass = rlkv
892 | }
893 | if Description != "" {
894 | rl.Description = Description
895 | }
896 | resp, err = api.CreateRateLimit(ZoneId, rl)
897 | return
898 | }
899 |
900 | func CreateUserAccessRule(api *cloudflare.API, Mode string, Configuration string, Notes string) (resp interface{}, err error) {
901 | var arc cloudflare.AccessRuleConfiguration
902 | err = json.Unmarshal([]byte(Configuration), &arc)
903 | if err != nil {
904 | return
905 | }
906 | ar := cloudflare.AccessRule{
907 | Configuration: arc,
908 | Mode: Mode,
909 | }
910 | if Notes != "" {
911 | ar.Notes = Notes
912 | }
913 | resp, err = api.CreateUserAccessRule(ar)
914 | return
915 | }
916 |
917 | func UpdateUserAccessRule(api *cloudflare.API, AccessRuleId string, Mode string, Configuration string, Notes string) (resp interface{}, err error) {
918 | var arc cloudflare.AccessRuleConfiguration
919 | err = json.Unmarshal([]byte(Configuration), &arc)
920 | if err != nil {
921 | return
922 | }
923 | ar := cloudflare.AccessRule{
924 | Configuration: arc,
925 | Mode: Mode,
926 | }
927 | if Notes != "" {
928 | ar.Notes = Notes
929 | }
930 | resp, err = api.UpdateUserAccessRule(AccessRuleId, ar)
931 | return
932 | }
933 |
934 | func UpdateZoneAccessRule(api *cloudflare.API, ZoneId string, AccessRuleId string, Mode string, Configuration string, Notes string) (resp interface{}, err error) {
935 | var arc cloudflare.AccessRuleConfiguration
936 | err = json.Unmarshal([]byte(Configuration), &arc)
937 | if err != nil {
938 | return
939 | }
940 | ar := cloudflare.AccessRule{
941 | Configuration: arc,
942 | Mode: Mode,
943 | }
944 | if Notes != "" {
945 | ar.Notes = Notes
946 | }
947 | resp, err = api.UpdateZoneAccessRule(OrganizationId, AccessRuleId, ar)
948 | return
949 | }
950 |
951 | func UpdateOrganizationAccessRule(api *cloudflare.API, OrganizationId string, AccessRuleId string, Mode string, Configuration string, Notes string) (resp interface{}, err error) {
952 | var arc cloudflare.AccessRuleConfiguration
953 | err = json.Unmarshal([]byte(Configuration), &arc)
954 | if err != nil {
955 | return
956 | }
957 | ar := cloudflare.AccessRule{
958 | Configuration: arc,
959 | Mode: Mode,
960 | }
961 | if Notes != "" {
962 | ar.Notes = Notes
963 | }
964 | resp, err = api.UpdateOrganizationAccessRule(OrganizationId, AccessRuleId, ar)
965 | return
966 | }
967 |
968 | func ListZoneAccessRules(api *cloudflare.API, ZoneId string, Notes string, Mode string, Page int) (resp interface{}, err error) {
969 | ar := cloudflare.AccessRule{}
970 | if Notes != "" {
971 | ar.Notes = Notes
972 | }
973 | if Mode != "" {
974 | ar.Mode = Mode
975 | }
976 | resp, err = api.ListOrganizationAccessRules(ZoneId, ar, Page)
977 | return
978 | }
979 |
980 | func CreateSSL(api *cloudflare.API, ZoneId string, Certificate string, PrivateKey string, BundleMethod string) (resp interface{}, err error) {
981 | z := cloudflare.ZoneCustomSSLOptions{
982 | Certificate: Certificate,
983 | PrivateKey: PrivateKey,
984 | }
985 | if BundleMethod != "" {
986 | z.BundleMethod = BundleMethod
987 | }
988 | resp, err = api.CreateSSL(ZoneId, z)
989 | return
990 | }
991 |
992 | func UpdateSSL(api *cloudflare.API, ZoneId string, CertificateId string, Certificate string, PrivateKey string, BundleMethod string) (resp interface{}, err error) {
993 | z := cloudflare.ZoneCustomSSLOptions{
994 | Certificate: Certificate,
995 | PrivateKey: PrivateKey,
996 | }
997 | if BundleMethod != "" {
998 | z.BundleMethod = BundleMethod
999 | }
1000 | resp, err = api.UpdateSSL(ZoneId, CertificateId, z)
1001 | return
1002 | }
1003 |
1004 | func Purge(api *cloudflare.API, ZoneId string, Files string, Tags string, Hosts string) (resp interface{}, err error) {
1005 | p := cloudflare.PurgeCacheRequest{}
1006 | if Files != "" {
1007 | p.Files = strings.Split(Files, ",")
1008 | }
1009 | if Hosts != "" {
1010 | p.Hosts = strings.Split(Hosts, ",")
1011 | }
1012 | if Tags != "" {
1013 | p.Tags = strings.Split(Tags, ",")
1014 | }
1015 | resp, err = api.PurgeCache(ZoneId, p)
1016 | return
1017 | }
1018 |
1019 | func CreateUserAgentRule(api *cloudflare.API, ZoneId string, Mode string, Configuration string, Description string, Paused bool) (resp interface{}, err error) {
1020 | var c cloudflare.UserAgentRuleConfig
1021 | u := cloudflare.UserAgentRule{
1022 | Mode: Mode,
1023 | Paused: Paused,
1024 | }
1025 | err = json.Unmarshal([]byte(Configuration), &c)
1026 | if err != nil {
1027 | return
1028 | }
1029 | u.Configuration = c
1030 | if Description != "" {
1031 | u.Description = Description
1032 | }
1033 | resp, err = api.CreateUserAgentRule(ZoneId, u)
1034 | return
1035 | }
1036 |
1037 | func UpdateUserAgentRule(api *cloudflare.API, ZoneId string, UserAgentId string, Mode string, Configuration string, Description string, Paused bool) (resp interface{}, err error) {
1038 | var c cloudflare.UserAgentRuleConfig
1039 | u := cloudflare.UserAgentRule{
1040 | Mode: Mode,
1041 | Paused: Paused,
1042 | }
1043 | err = json.Unmarshal([]byte(Configuration), &c)
1044 | if err != nil {
1045 | return
1046 | }
1047 | u.Configuration = c
1048 | if Description != "" {
1049 | u.Description = Description
1050 | }
1051 | resp, err = api.UpdateUserAgentRule(ZoneId, UserAgentId, u)
1052 | return
1053 | }
1054 |
1055 | func UpdateCustomHostnameSSL(api *cloudflare.API, ZoneId string, CustomHostnameId string, Method string, Type string) (resp interface{}, err error) {
1056 | h := cloudflare.CustomHostnameSSL{
1057 | Method: Method,
1058 | Type: Type,
1059 | }
1060 | resp, err = api.UpdateCustomHostnameSSL(ZoneId, CustomHostnameId, h)
1061 | return
1062 | }
1063 |
1064 | func CustomHostnames(api *cloudflare.API, ZoneId string, Hostname string, Page int) (resp interface{}, err error) {
1065 | page := 1
1066 | if Page > 0 {
1067 | page = Page
1068 | }
1069 | filter := cloudflare.CustomHostname{}
1070 | if Hostname != "" {
1071 | filter.Hostname = Hostname
1072 | }
1073 | resp, _, err = api.CustomHostnames(ZoneId, page, filter)
1074 | return
1075 | }
1076 |
1077 | func ReprioritizeSSL(api *cloudflare.API, ZoneId string, PriorityList string) (resp interface{}, err error) {
1078 |
1079 | var p []cloudflare.ZoneCustomSSLPriority
1080 | err = json.Unmarshal([]byte(PriorityList), &p)
1081 | if err != nil {
1082 | return
1083 | }
1084 | resp, err = api.ReprioritizeSSL(ZoneId, p)
1085 | return
1086 | }
1087 |
1088 | func ModifyLoadBalancerMonitor(api *cloudflare.API, MonitorId string, ExpectedCodes string, Method string, Header string, Timeout int, Path string, Interval int, Retries int, ExpectedBody string, Type string, Description string) (resp interface{}, err error) {
1089 | l := cloudflare.LoadBalancerMonitor{
1090 | ID: MonitorId,
1091 | ExpectedCodes: ExpectedCodes,
1092 | }
1093 | if Method != "" {
1094 | l.Method = Method
1095 | }
1096 | if Timeout > 0 {
1097 | l.Timeout = Timeout
1098 | }
1099 | if Header != "" {
1100 | h := make(map[string][]string)
1101 | err = json.Unmarshal([]byte(Header), &h)
1102 | if err != nil {
1103 | return nil, err
1104 | }
1105 | l.Header = h
1106 | }
1107 | if Path != "" {
1108 | l.Path = Path
1109 | }
1110 | if Interval > 0 {
1111 | l.Interval = Interval
1112 | }
1113 | if Retries > 0 {
1114 | l.Retries = Retries
1115 | }
1116 | if Type != "" {
1117 | l.Type = Type
1118 | }
1119 | if Description != "" {
1120 | l.Description = Description
1121 | }
1122 | resp, err = api.ModifyLoadBalancerMonitor(l)
1123 | return
1124 | }
1125 |
1126 | func ModifyLoadBalancer(api *cloudflare.API, ZoneId string, LoadbalancerId string, Name string, FallbackPool string, DefaultPools string, Proxied bool, Ttl int) (resp interface{}, err error) {
1127 | d := strings.Split(DefaultPools, ",")
1128 | l := cloudflare.LoadBalancer{
1129 | ID: LoadbalancerId,
1130 | Name: Name,
1131 | FallbackPool: FallbackPool,
1132 | DefaultPools: d,
1133 | Proxied: Proxied,
1134 | }
1135 | if Ttl > 0 {
1136 | l.TTL = Ttl
1137 | }
1138 | resp, err = api.ModifyLoadBalancer(ZoneId, l)
1139 | return
1140 | }
1141 |
1142 | func CreateWorkerRoute(api *cloudflare.API, ZoneId string, Pattern string, Disabled bool) (resp interface{}, err error) {
1143 | resp, err = api.CreateWorkerRoute(ZoneId, cloudflare.WorkerRoute{
1144 | Pattern: Pattern,
1145 | Enabled: !Disabled,
1146 | })
1147 | return
1148 | }
1149 |
1150 | func UpdateWorkerRoute(api *cloudflare.API, ZoneId string, RouteId string, Pattern string, Disabled bool) (resp interface{}, err error) {
1151 | resp, err = api.UpdateWorkerRoute(ZoneId, RouteId, cloudflare.WorkerRoute{
1152 | Pattern: Pattern,
1153 | Enabled: !Disabled,
1154 | })
1155 | return
1156 | }
1157 |
1158 | func ListWorkerRoutes(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
1159 | resp, err = api.ListWorkerRoutes(ZoneId)
1160 | return
1161 | }
1162 |
1163 | func UploadWorker(api *cloudflare.API, ZoneId, Script, ScriptName string) (resp interface{}, err error) {
1164 | s := Script
1165 | if len(Script) != 0 {
1166 | if Script[0] == '@' {
1167 | scriptFile := Script[1:]
1168 | fileScript, err := ioutil.ReadFile(scriptFile)
1169 | if err != nil {
1170 | return resp, err
1171 | }
1172 | s = string(fileScript)
1173 | } else if Script == "-" {
1174 | fileScript, err := ioutil.ReadAll(os.Stdin)
1175 | if err != nil {
1176 | return resp, err
1177 | }
1178 | s = string(fileScript)
1179 | }
1180 | }
1181 | wrp := &cloudflare.WorkerRequestParams{
1182 | ZoneID: ZoneId,
1183 | }
1184 | if ScriptName != "" {
1185 | wrp.ScriptName = ScriptName
1186 | }
1187 | resp, err = api.UploadWorker(wrp, s)
1188 | return
1189 | }
1190 |
1191 | func DeleteWorker(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
1192 | resp, err = api.DeleteWorker(&cloudflare.WorkerRequestParams{
1193 | ZoneID: ZoneId,
1194 | })
1195 | return
1196 | }
1197 |
1198 | func ListWorkerScripts(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
1199 | resp, err = api.ListWorkerScripts()
1200 | return
1201 | }
1202 |
1203 | func DownloadWorker(api *cloudflare.API, ZoneId string) (resp interface{}, err error) {
1204 | resp, err = api.DownloadWorker(&cloudflare.WorkerRequestParams{
1205 | ZoneID: ZoneId,
1206 | })
1207 | return
1208 | }
1209 |
1210 | func DownloadOrganizationWorker(api *cloudflare.API, OrganizationId string, Name string) (resp interface{}, err error) {
1211 | resp, err = api.DownloadWorker(&cloudflare.WorkerRequestParams{
1212 | ScriptName: Name,
1213 | })
1214 | return
1215 | }
1216 |
1217 | func DeleteOrganizationWorker(api *cloudflare.API, OrganizationId string, Name string) (resp interface{}, err error) {
1218 | resp, err = api.DeleteWorker(&cloudflare.WorkerRequestParams{
1219 | ScriptName: Name,
1220 | })
1221 | return
1222 | }
1223 |
1224 | func GetOrganizationAuditLogs(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
1225 | // api.GetOrganizationAuditLogs(OrganizationId)
1226 | // return
1227 | return
1228 | }
1229 | func GetUserAuditLogs(api *cloudflare.API, ActorIP string, ActorEmail string, ZoneName string, Since string, ID string, Direction string, Before string, Page int, PerPage int) (resp interface{}, err error) {
1230 | resp, err = api.GetUserAuditLogs(cloudflare.AuditLogFilter{
1231 | ID: ID,
1232 | ActorIP: ActorIP,
1233 | ActorEmail: ActorEmail,
1234 | Direction: Direction,
1235 | ZoneName: ZoneName,
1236 | Since: Since,
1237 | Before: Before,
1238 | PerPage: PerPage,
1239 | Page: Page,
1240 | })
1241 | return
1242 | }
1243 |
1244 | func ListWorkersKVNamespaces(api *cloudflare.API, OrganizationId string) (resp interface{}, err error) {
1245 | resp, err = api.ListWorkersKVNamespaces(context.TODO())
1246 | return
1247 | }
1248 |
1249 | func DeleteWorkersKVNamespace(api *cloudflare.API, OrganizationId string, NamespaceId string) (resp interface{}, err error) {
1250 | resp, err = api.DeleteWorkersKVNamespace(context.TODO(), NamespaceId)
1251 | return
1252 | }
1253 |
1254 | func ListWorkersKVs(api *cloudflare.API, OrganizationId string, NamespaceId string) (resp interface{}, err error) {
1255 | resp, err = api.ListWorkersKVs(context.TODO(), NamespaceId)
1256 | return
1257 | }
1258 |
1259 | func ReadWorkersKV(api *cloudflare.API, OrganizationId string, NamespaceId string, Key string) (resp interface{}, err error) {
1260 | resp, err = api.ReadWorkersKV(context.TODO(), NamespaceId, Key)
1261 | return
1262 | }
1263 |
1264 | func DeleteWorkersKV(api *cloudflare.API, OrganizationId string, NamespaceId string, Key string) (resp interface{}, err error) {
1265 | resp, err = api.DeleteWorkersKV(context.TODO(), NamespaceId, Key)
1266 | return
1267 | }
1268 |
1269 | func UpdateWorkersKVNamespace(api *cloudflare.API, OrganizationId string, NamespaceId string, Name string) (resp interface{}, err error) {
1270 | resp, err = api.UpdateWorkersKVNamespace(context.TODO(), NamespaceId, &cloudflare.WorkersKVNamespaceRequest{Title: Name})
1271 | return
1272 | }
1273 |
1274 | func CreateWorkersKVNamespace(api *cloudflare.API, OrganizationId string, Name string) (resp interface{}, err error) {
1275 | resp, err = api.CreateWorkersKVNamespace(context.TODO(), &cloudflare.WorkersKVNamespaceRequest{Title: Name})
1276 | return
1277 | }
1278 |
1279 | func WriteWorkersKV(api *cloudflare.API, OrganizationId string, NamespaceId string, Key string, Value string) (resp interface{}, err error) {
1280 | v := Value
1281 | if len(Value) != 0 {
1282 | if Value[0] == '@' {
1283 | valueFile := Value[1:]
1284 | fileValue, err := ioutil.ReadFile(valueFile)
1285 | if err != nil {
1286 | return resp, err
1287 | }
1288 | v = string(fileValue)
1289 | } else if Value == "-" {
1290 | fileValue, err := ioutil.ReadAll(os.Stdin)
1291 | if err != nil {
1292 | return resp, err
1293 | }
1294 | v = string(fileValue)
1295 | }
1296 | }
1297 | resp, err = api.WriteWorkersKV(context.TODO(), NamespaceId, Key, []byte(v))
1298 | return
1299 | }
1300 |
1301 | func UploadOrganizationWorker(api *cloudflare.API, ZoneId string, OrganizationId, Name string, Script string) (resp interface{}, err error) {
1302 | s := Script
1303 | if len(Script) != 0 {
1304 | if Script[0] == '@' {
1305 | scriptFile := Script[1:]
1306 | fileScript, err := ioutil.ReadFile(scriptFile)
1307 | if err != nil {
1308 | return resp, err
1309 | }
1310 | s = string(fileScript)
1311 | } else if Script == "-" {
1312 | fileScript, err := ioutil.ReadAll(os.Stdin)
1313 | if err != nil {
1314 | return resp, err
1315 | }
1316 | s = string(fileScript)
1317 | }
1318 | }
1319 | resp, err = api.UploadWorker(&cloudflare.WorkerRequestParams{
1320 | ScriptName: Name,
1321 | }, s)
1322 | return
1323 | }
1324 |
--------------------------------------------------------------------------------
/cmd/autogenerate/autogenerate.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os/exec"
6 |
7 | "github.com/ejcx/cf/definitions"
8 | )
9 |
10 | func main() {
11 | err := definitions.GenerateFile("definitions/definitions.toml", "cmd/autogenerated.go")
12 | if err != nil {
13 | log.Fatalf("Could not generate file: %s", err)
14 | }
15 | err = exec.Command("goimports", "-w", "cmd/autogenerated.go").Run()
16 | if err != nil {
17 | log.Fatalf("Could not run goimports on autogenerated file: %s", err)
18 | }
19 | err = exec.Command("go", "fmt", "cmd/autogenerated.go").Run()
20 | if err != nil {
21 | log.Fatalf("Could not run go fmt on autogenerated file: %s", err)
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/cmd/configure.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "log"
8 | "os"
9 |
10 | "github.com/99designs/keyring"
11 | cloudflare "github.com/cloudflare/cloudflare-go"
12 | cflib "github.com/ejcx/cf/lib"
13 | "github.com/segmentio/aws-okta/lib"
14 | "github.com/spf13/cobra"
15 | )
16 |
17 | var (
18 | ConfigureCmd = &cobra.Command{
19 | Use: "configure",
20 | Short: "A command for configuring your cloudflare api credentials",
21 | Run: func(cmd *cobra.Command, args []string) {
22 | err := Configure(cmd, args)
23 | if err != nil {
24 | log.Fatalf("Could not configure cf cli: %s", err)
25 | }
26 | },
27 | }
28 | noKeychain bool
29 | )
30 |
31 | func init() {
32 | ConfigureCmd.Flags().BoolVar(&noKeychain, "no-keychain", false, "Do not attempt to store cloudflare api credentials in the keychain. Just use plaintext file.")
33 | RootCmd.AddCommand(ConfigureCmd)
34 | }
35 |
36 | func Configure(cmd *cobra.Command, args []string) error {
37 | email, err := lib.Prompt("Cloudflare Email", false)
38 | if err != nil {
39 | return err
40 | }
41 |
42 | apiKey, err := lib.Prompt("Cloudflare APIKey", true)
43 | if err != nil {
44 | return err
45 | }
46 |
47 | // Add a newline at the beginning and end because sensitive
48 | // prompts all end up on one line.
49 | serviceKey, err := lib.Prompt("\nOrigin CA APIKey", true)
50 | if err != nil {
51 | return err
52 | }
53 | fmt.Println("")
54 |
55 | // Now that we have the credentials, validate that the apikey and the email
56 | // are real by calling the User Details API.
57 | creds := &cflib.Credentials{
58 | Email: email,
59 | Key: apiKey,
60 | UserServiceKey: serviceKey,
61 | }
62 | creds.SetEnv()
63 |
64 | api, err := cloudflare.New(os.Getenv("CF_API_KEY"), os.Getenv("CF_API_EMAIL"))
65 | if err != nil {
66 | return fmt.Errorf("Could not initialize api object: %s", err)
67 | }
68 |
69 | _, err = api.UserDetails()
70 | if err != nil {
71 | return fmt.Errorf("Invalid user credentials: %s", err)
72 | }
73 |
74 | if !noKeychain {
75 | // Now marshal the data to store in the keychain and set a cloudflare creds
76 | // file that has keychain set to true and nothing else
77 | encoded, err := json.Marshal(creds)
78 | if err != nil {
79 | return err
80 | }
81 | kr, err := cflib.GetKeyring()
82 | if err != nil {
83 | return err
84 | }
85 | err = kr.Set(keyring.Item{
86 | Key: "cloudflare-creds",
87 | Data: encoded,
88 | Label: "cloudflare credentials",
89 | KeychainNotTrustApplication: false,
90 | })
91 | if err != nil {
92 | return err
93 | }
94 | creds = &cflib.Credentials{
95 | Keychain: true,
96 | }
97 | }
98 |
99 | // Write a creds file. It can either be a dumby creds file that only
100 | // says to look in the keychain, or the real keychain file.
101 | buf, err := json.Marshal(creds)
102 | if err != nil {
103 | return err
104 | }
105 | home, err := cflib.GetHomeDir()
106 | if err != nil {
107 | return err
108 | }
109 | // Ignore the error. If it worked or didn't, both cases are already handled.
110 | os.Mkdir(home+"/.cf", 0755)
111 | outfile := home + "/.cf/credentials"
112 | err = ioutil.WriteFile(outfile, buf, 0600)
113 |
114 | return err
115 | }
116 |
--------------------------------------------------------------------------------
/cmd/root.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "log"
7 | "os"
8 |
9 | cloudflare "github.com/cloudflare/cloudflare-go"
10 | "github.com/ejcx/cf/lib"
11 | "github.com/spf13/cobra"
12 | )
13 |
14 | var cfgFile string
15 |
16 | type Credentials struct {
17 | Email string
18 | }
19 |
20 | var RootCmd = &cobra.Command{
21 | Use: "cf",
22 | Short: "A CLI for interacting with Cloudflare's V4 API",
23 | }
24 |
25 | func Execute() {
26 | if err := RootCmd.Execute(); err != nil {
27 | log.Fatal(err)
28 | }
29 | }
30 |
31 | // Main is where the high level program execution takes place.
32 | // The first thing that happens is the credentials are attempted
33 | // to be loaded from a file or your environment. If the creds are
34 | // loaded from a file then they are set as env vars to be used
35 | // by cloudflare-go.
36 | // Next, `root` is called, which is where API calls are made to
37 | // the cloudflare v4 API by using the `cloudflare-go` library.
38 | // Finally, the results are outputted to stdout (or stderr if
39 | // something disasterous happens).
40 | func Main(cmd *cobra.Command, args []string, name string) {
41 | err := lib.DefaultCredentialProvider.ConfigureEnvironment()
42 | if err != nil {
43 | log.Fatalf("No set of credentials to use: %s", err)
44 | }
45 |
46 | var (
47 | opts []cloudflare.Option
48 | )
49 | if OrganizationId != "" {
50 | opts = append(opts, cloudflare.UsingOrganization(OrganizationId))
51 | }
52 | api, err := cloudflare.New(os.Getenv("CF_API_KEY"), os.Getenv("CF_API_EMAIL"), opts...)
53 | if err != nil {
54 | log.Fatalf("Could not initialize api object: %s", err)
55 | }
56 | if serviceKey, ok := os.LookupEnv("CF_USER_SERVICE_KEY"); ok {
57 | api.APIUserServiceKey = serviceKey
58 | }
59 |
60 | r, err := Run(cmd, args, name, api)
61 | if err != nil {
62 | log.Fatalf("Could not make cloudflare request: %s", err)
63 | }
64 | buf, err := json.MarshalIndent(r, " ", " ")
65 | if err != nil {
66 | log.Fatalf("Could not make print resp: %s", err)
67 | }
68 | if string(buf) != "null" {
69 | fmt.Println(string(buf))
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/definitions/README.md:
--------------------------------------------------------------------------------
1 | # definitions
2 | Definitions is the guts and description of all commands and subcommands
3 | that are used in `cf`.
4 |
5 | ## Program Design
6 | ### Auto-generated Code
7 | It is important to understand the relationship between the `definitions.toml`
8 | file that resides in the `definitions` directory, and the `autogenerated.go`
9 | file that resides in the `cmd` directory.
10 |
11 | **definitions.toml** -- Contains a hand-written definition of each command-line command, their arguments, and their sub-commands.
12 |
13 | **autogenerated.go** -- Contains golang code that does two things. First, it creates all Variables passed to the program using the command-line. Second, it generates the command and subcommand structure of the CLI.
14 |
15 | **definitions.go** - Generates the go code using a series of templates. It is not pretty at all, but it converts the toml to definitions of [cobra](https://github.com/spf13/cobra), which provides a robust framework for CLI tools.
16 |
17 | ### Where are the API calls made?
18 | `cmd/root.go` has a large switch-statement where all API calls to `cloudflare-go` are made.
19 | When necessary, this switch statement does any massaging necessary to
20 | make the arguments from the command line fit in to the expected method signature.
21 |
22 |
23 |
--------------------------------------------------------------------------------
/definitions/definitions.go:
--------------------------------------------------------------------------------
1 | package definitions
2 |
3 | // definitions is used to auto-generate the cmd/autogenerated.go file.
4 | // It makes heavy use of Golang templates and uses the definitions.tom
5 | // file in order to generate the golang code.
6 |
7 | import (
8 | "bytes"
9 | "fmt"
10 | "io/ioutil"
11 | "strings"
12 | "text/template"
13 |
14 | "github.com/BurntSushi/toml"
15 | )
16 |
17 | const (
18 | // goTemplate is a high level template for the autogenerated.go file
19 | goTemplate = `
20 | package cmd
21 |
22 | var (
23 | {{ .Variables }}
24 | )
25 |
26 | func init() {
27 | {{ .Commands }}
28 | }
29 |
30 | func Run(cmd *cobra.Command, args []string, name string, api *cloudflare.API) (resp interface{}, err error) {
31 | {{ .SwitchList }}
32 | return
33 | }
34 | `
35 |
36 | switchTemplate = `switch name {
37 | {{ range . }}
38 | case "{{.Name}}":
39 | resp, err = {{.Name}}(api, {{.ArgList}}){{ end }}
40 | default:
41 | break
42 | }`
43 | // varTemplate is the template used by each subcommand to declare
44 | // their command line flags as Golang code.
45 | varTemplate = `{{ range .}}{{ .Name }} {{ .Type }}
46 | {{ end }}`
47 |
48 | // cmdTemplate is very hairy, and used to declare
49 | // top-level cli commands and their subcommands.
50 | // Top level commands are added to the root command
51 | // while subcommands will call the `Main` function
52 | // and pass their subcommand name, which is used
53 | // to route to the proper case within the switch.
54 | cmdTemplate = `var {{.VariableName}} = &cobra.Command{
55 | Use: "{{- .Name -}}",
56 | Short: "{{- .ShortDescription -}}",
57 | Long: ` + "`" + `{{- .Description -}}` + "`" + `,
58 | {{ if .V4APIName}}Run: func(cmd *cobra.Command, args []string) {
59 | Main(cmd, args, "{{- .V4APIName}}")
60 | },{{ end}}
61 | }
62 | {{- $varName := .VariableName }}
63 | {{range .Subcommands}}{{$varName}}.AddCommand({{.}})
64 | {{end}}
65 | {{ if .TopLevel }}RootCmd.AddCommand({{.VariableName}})
66 | {{ end }}
67 | {{range .Option}}
68 | {{$varName}}.Flags().{{.TypeCap}}Var(&{{.ArgName}}, "{{.Name}}", {{.Default}}, "{{.Description}}")
69 | {{if .Required}}{{$varName}}.MarkFlagRequired("{{.Name}}")
70 | {{end}}
71 | {{end}}
72 | `
73 | )
74 |
75 | var (
76 | // declaredVariables keeps track of which variables have already
77 | // been declared in our Go file. It will cause a compile time
78 | // issue if the same variable is declared twice.
79 | declaredVariables = make(map[string]bool)
80 | )
81 |
82 | // Option is a command line option that can be passed to
83 | // the program. Commands "have a" set of Options.
84 | type Option struct {
85 | Name string
86 | Type string
87 | Description string
88 | Required bool
89 | }
90 |
91 | type OptionTemplateValue struct {
92 | TypeCap string
93 | ArgName string
94 | Name string
95 | Default string
96 | Description string
97 | Required bool
98 | }
99 |
100 | type SwitchTemplateEntry struct {
101 | Name string
102 | ArgList string
103 | }
104 |
105 | // Command is a toplevel or subcommand.
106 | // They have a set of subcommands if they are toplevel
107 | // and V4APIName will be set to the name of the Switch
108 | // case that is associated with the subcommand name.
109 | // For Example: list-zones will have a switch case named
110 | // ListZones, and ListZones should call the cloudflare-go
111 | // method api.ListZones.
112 | type Command struct {
113 | Name string
114 | Description string
115 | ShortDescription string
116 | V4APIName string
117 | Option []Option
118 | Subcommands []string
119 | TopLevel bool
120 | }
121 |
122 | type CommandTemplateValues struct {
123 | Name string
124 | VariableName string
125 | V4APIName string
126 | Description string
127 | ShortDescription string
128 | Option []OptionTemplateValue
129 |
130 | Subcommands []string
131 | TopLevel bool
132 | }
133 |
134 | type FileTemplateValues struct {
135 | Commands string
136 | Variables string
137 | SwitchList string
138 | }
139 |
140 | func fileText(commands, variables, switchList string) (string, error) {
141 | var (
142 | buff bytes.Buffer
143 | )
144 | tmpl, err := template.New("gofile").Parse(goTemplate)
145 | if err != nil {
146 | return "", err
147 | }
148 | err = tmpl.Execute(&buff, &FileTemplateValues{
149 | Commands: commands,
150 | Variables: variables,
151 | SwitchList: switchList,
152 | })
153 | if err != nil {
154 | return "", err
155 | }
156 | return buff.String(), nil
157 | }
158 |
159 | func (o Option) ToOptionTemplateValue() OptionTemplateValue {
160 | // When declaring an int, bool, or string is golang it is
161 | // important to ensure that the data type default value
162 | // is initialized properly. An integer literal should not
163 | // be wrapped in quotes for example.
164 | defaultType := "\"\""
165 | if o.Type == "int" {
166 | defaultType = "0"
167 | } else if o.Type == "bool" {
168 | defaultType = "false"
169 | }
170 | return OptionTemplateValue{
171 | TypeCap: hyphenDelimToCamel(o.Type),
172 | ArgName: hyphenDelimToCamel(o.Name),
173 | Name: o.Name,
174 | Default: defaultType,
175 | Description: o.Description,
176 | Required: o.Required,
177 | }
178 | }
179 |
180 | func ToSwitch(cmds []*Command) (string, error) {
181 | var (
182 | switchList []SwitchTemplateEntry
183 | buff bytes.Buffer
184 | )
185 | for _, cmd := range cmds {
186 | if cmd.V4APIName == "" {
187 | continue
188 | }
189 | argList := cmd.ToArgList()
190 | switchList = append(switchList, SwitchTemplateEntry{
191 | Name: cmd.V4APIName,
192 | ArgList: argList,
193 | })
194 | }
195 | tmpl, err := template.New("switch").Parse(switchTemplate)
196 | if err != nil {
197 | return "", err
198 | }
199 | err = tmpl.Execute(&buff, switchList)
200 | if err != nil {
201 | return "", err
202 | }
203 | return buff.String(), nil
204 | }
205 |
206 | func (c *Command) ToVariables() (string, error) {
207 | var (
208 | buff bytes.Buffer
209 | options []Option
210 | )
211 |
212 | // We need to do a pass to convert the variable names from cmd flags
213 | // to Go variable names.
214 | for _, opt := range c.Option {
215 | if _, ok := declaredVariables[opt.Name]; ok {
216 | continue
217 | }
218 | options = append(options, Option{
219 | Name: hyphenDelimToCamel(opt.Name),
220 | Type: opt.Type,
221 | })
222 | declaredVariables[opt.Name] = true
223 | }
224 |
225 | tmpl, err := template.New("option").Parse(varTemplate)
226 | if err != nil {
227 | return "", err
228 | }
229 | err = tmpl.Execute(&buff, options)
230 | if err != nil {
231 | return "", err
232 | }
233 | return buff.String(), nil
234 | }
235 | func (c *Command) ToGo() (string, error) {
236 | var (
237 | buff bytes.Buffer
238 | subcommandVarNames []string
239 | )
240 | for _, subcmd := range c.Subcommands {
241 | subcommandVarNames = append(subcommandVarNames, hyphenDelimToCamel(subcmd))
242 | }
243 |
244 | // Convert the options to OptionTemplateValues
245 | var optionTemplateValueList []OptionTemplateValue
246 | for _, opt := range c.Option {
247 | optionTemplateValueList = append(optionTemplateValueList, opt.ToOptionTemplateValue())
248 | }
249 |
250 | tmpl, err := template.New("command").Parse(cmdTemplate)
251 | if err != nil {
252 | return "", err
253 | }
254 | err = tmpl.Execute(&buff, &CommandTemplateValues{
255 | Name: c.Name,
256 | TopLevel: c.TopLevel,
257 | Subcommands: subcommandVarNames,
258 | VariableName: hyphenDelimToCamel(c.Name),
259 | V4APIName: c.V4APIName,
260 | ShortDescription: c.ShortDescription,
261 | Description: c.Description,
262 | Option: optionTemplateValueList,
263 | })
264 | if err != nil {
265 | return "", err
266 | }
267 | return buff.String(), nil
268 | }
269 |
270 | func LoadDefinitions(fname string) ([]*Command, error) {
271 | c := map[string][]*Command{}
272 | _, err := toml.DecodeFile(fname, &c)
273 | if err != nil {
274 | return nil, err
275 | }
276 | return c["command"], nil
277 | }
278 |
279 | // hyphenDelimToCamel will convert names like
280 | // list-zones to ListZones, where the hyphen
281 | // is removed and the first letter of each word
282 | // is properly camel cased. Be aware that abbrvs
283 | // like 'ttl' will be transformmed to 'Ttl'.
284 | func hyphenDelimToCamel(s string) string {
285 | parts := strings.Split(s, "-")
286 |
287 | // Capitalize the first letter of each part and return the
288 | // concatenation of them.
289 | for i, part := range parts {
290 | parts[i] = strings.ToUpper(string(part[0])) + part[1:]
291 | }
292 | return strings.Join(parts, "")
293 | }
294 |
295 | func GenerateFile(fname string, outfile string) error {
296 | cmds, err := LoadDefinitions(fname)
297 | if err != nil {
298 | return err
299 | }
300 | commandsGo := ""
301 | variablesGo := ""
302 | // Do two passes. First we want to generate all code that is
303 | // not a top level command. Next we want to generate all top
304 | // level commands. This is because of the variable ordering
305 | // and avoiding undefined variable issues.
306 | for _, cmd := range cmds {
307 | if !cmd.TopLevel {
308 | s, err := cmd.ToGo()
309 | if err != nil {
310 | return err
311 | }
312 | commandsGo += s
313 | }
314 | }
315 |
316 | // While we do this second pass, create all the variables while
317 | // we are also creating all of the commands.
318 | for _, cmd := range cmds {
319 | v, err := cmd.ToVariables()
320 | if err != nil {
321 | return err
322 | }
323 | variablesGo += v
324 | if cmd.TopLevel {
325 | s, err := cmd.ToGo()
326 | if err != nil {
327 | return err
328 | }
329 | commandsGo += s
330 | }
331 | }
332 |
333 | switchList, err := ToSwitch(cmds)
334 | if err != nil {
335 | return err
336 | }
337 |
338 | t, err := fileText(commandsGo, variablesGo, switchList)
339 | if err != nil {
340 | return err
341 | }
342 | err = ioutil.WriteFile(outfile, []byte(t), 0644)
343 | if err != nil {
344 | return err
345 | }
346 | return nil
347 | }
348 |
349 | func (c *Command) ToArgList() string {
350 | s := ""
351 | for _, opt := range c.Option {
352 | if s == "" {
353 | s = hyphenDelimToCamel(opt.Name)
354 | } else {
355 | s += ", " + hyphenDelimToCamel(opt.Name)
356 | }
357 | }
358 | return s
359 | }
360 |
361 | func (c *Command) ToArgListWithTypes() string {
362 | s := ""
363 | for _, opt := range c.Option {
364 | s += ", " + hyphenDelimToCamel(opt.Name) + " " + opt.Type
365 | }
366 | return s
367 | }
368 |
369 | func ToFuncSigs(cmds []*Command) string {
370 | s := ""
371 | for _, cmd := range cmds {
372 | if cmd.TopLevel {
373 | continue
374 | }
375 | s += fmt.Sprintf("func %s(api *cloudflare.API%s) (resp interface{}, err error) {\nreturn}\n", hyphenDelimToCamel(cmd.V4APIName), cmd.ToArgListWithTypes())
376 | }
377 | return s
378 | }
379 |
--------------------------------------------------------------------------------
/definitions/definitions.toml:
--------------------------------------------------------------------------------
1 | [[command]]
2 | name = "zone"
3 | description = """
4 | A Zone is a domain name along with its subdomains and other identities. Using the zone command to interact with cloudflare zones"""
5 | subcommands = [
6 | "activation-check",
7 | "analytics-by-colo",
8 | "analytics-dashboard",
9 | "create-custom-hostname",
10 | "create-zone",
11 | "delete-custom-hostname",
12 | "delete-zone",
13 | "delete-zone-access-rule",
14 | "describe-zone",
15 | "edit-zone-paused",
16 | "edit-zone-vanity-ns",
17 | "describe-custom-hostname",
18 | "describe-custom-hostname-by-name",
19 | "get-id-by-name",
20 | "get-zone-settings",
21 | "list-available-rate-plans",
22 | "list-custom-hostnames",
23 | "list-zone-access-rules",
24 | "list-zones",
25 | "set-paused",
26 | "set-vanity-ns",
27 | "update-custom-hostname",
28 | "update-zone-access-rule",
29 | "update-zone-settings",
30 | ]
31 | toplevel = true
32 | shortdescription = "Interact with cloudflare zones"
33 |
34 | [[command]]
35 | name = "worker"
36 | description = """
37 | Manage your edge workers deployed to your account.
38 | """
39 | subcommands = [
40 | "create-worker-route",
41 | "create-kv-namespace",
42 | "delete-kv",
43 | "delete-kv-namespace",
44 | "delete-organization-worker",
45 | "delete-worker",
46 | "download-organization-worker",
47 | "download-worker",
48 | "get-kv",
49 | "list-kvs",
50 | "list-kv-namespaces",
51 | "list-worker-routes",
52 | "list-worker-scripts",
53 | "rename-kv-namespace",
54 | "update-worker-route",
55 | "upload-organization-worker",
56 | "upload-worker",
57 | "write-kv",
58 | ]
59 | toplevel = true
60 | shortdescription = "Interact with cloudflare workers api"
61 |
62 |
63 | [[command]]
64 | name = "dns"
65 | description = """
66 | Create, read, update, and delete cloudflare dns and virtual dns."""
67 | subcommands = [
68 | "create-dns-record",
69 | "create-virtual-dns",
70 | "delete-dns-record",
71 | "delete-virtual-dns",
72 | "describe-virtual-dns",
73 | "edit-dns-record",
74 | "list-dns-records",
75 | "list-virtual-dns",
76 | "show-dns-record",
77 | "update-virtual-dns",
78 | ]
79 | toplevel = true
80 | shortdescription = "Create, read, update, and delete your dns records."
81 |
82 | [[command]]
83 | name = "user"
84 | description = """
85 | The User subcommand will help you interact with your Cloudflare account."""
86 | subcommands = [
87 | "billing-profile",
88 | "create-user-access-rule",
89 | "delete-user-access-rule",
90 | "details",
91 | "edit-user",
92 | "get-user-audit-logs",
93 | "list-user-access-rules",
94 | "update-user-access-rule",
95 | ]
96 | toplevel = true
97 | shortdescription = "Interacting with your Cloudflare account"
98 |
99 | [[command]]
100 | name = "ssl"
101 | description = """
102 | Fine grained control and deep insights in to your zone's SSL stack, as well as the ability to order new certs."""
103 | subcommands = [
104 | "create-origin-cert",
105 | "describe-origin-cert",
106 | "describe-zone-origin-cert",
107 | "delete-custom-cert",
108 | "list-custom-certs",
109 | "list-origin-certs",
110 | "list-zone-ssl-settings",
111 | "reprioritize-certs",
112 | "revoke-origin-cert",
113 | "update-custom-cert",
114 | "upload-custom-cert",
115 | ]
116 | toplevel = true
117 | shortdescription = "Control and insight in to your zone's SSL stack "
118 |
119 |
120 | [[command]]
121 | name = "pagerule"
122 | description = """
123 | Gives you the ability to control how Cloudflare works on a URL or subdomain basis. Page Rules allow you to customize Cloudflare's functionality to match your domain's unique needs."""
124 | subcommands = [
125 | "create-pagerule",
126 | "list-pagerules",
127 | "delete-pagerule",
128 | "describe-pagerule",
129 | "update-pagerule",
130 | ]
131 | toplevel = true
132 | shortdescription = "Change how cloudflare works on a URL or subdomain basis."
133 |
134 | [[command]]
135 | name = "cache"
136 | description = """
137 | Commands for the management and description of cache technologies."""
138 | subcommands = [
139 | "connect-zone-railgun",
140 | "create-railgun",
141 | "delete-railgun",
142 | "describe-railgun",
143 | "describe-zone-railgun",
144 | "disable-railgun",
145 | "disconnect-railgun",
146 | "enable-railgun",
147 | "get-railgun-zones",
148 | "list-railguns",
149 | "list-zone-railguns",
150 | "purge",
151 | "purge-everything",
152 | "test-railgun-connection",
153 | ]
154 | toplevel = true
155 | shortdescription = "Commands for interacting with caching and railgun APIs"
156 |
157 | [[command]]
158 | name = "firewall"
159 | description = """
160 | The firewall subcommand is used to configure the WAF, user-agent rules, and zone-lockdowns."""
161 | subcommands = [
162 | "create-user-agent-rule",
163 | "create-zone-lockdown",
164 | "delete-user-agent-rule",
165 | "delete-zone-lockdown",
166 | "describe-zone-lockdown",
167 | "list-user-agent-rules",
168 | "list-waf-packages",
169 | "list-waf-rules",
170 | "list-zone-lockdowns",
171 | "update-user-agent-rule",
172 | "update-zone-lockdown",
173 | ]
174 | toplevel = true
175 | shortdescription = "Commands to interact with products that block access to your site"
176 |
177 | [[command]]
178 | name = "organization"
179 | description = """
180 | Organizztions show all information about the organizations and provides the ability to modify access and display information about your specific organizations."""
181 | subcommands = [
182 | "create-organization-access-rule",
183 | "delete-organization-access-rule",
184 | "describe-organization",
185 | "get-organization-invites",
186 | "get-organization-members",
187 | "get-organization-roles",
188 | "list-organization-access-rules",
189 | "list-organizations",
190 | "update-organization-access-rule",
191 | "get-organization-audit-logs"
192 | ]
193 | toplevel = true
194 | shortdescription = "Interact with the organizations you own and have access to"
195 |
196 | [[command]]
197 | name = "ratelimit"
198 | description = """
199 | Cloudflare ratelimits that ensure that the requests to your site are done at a rate you accept."""
200 | subcommands = [
201 | "create-ratelimit",
202 | "delete-ratelimit",
203 | "describe-ratelimit",
204 | "list-ratelimits",
205 | "update-ratelimit",
206 | ]
207 | toplevel = true
208 | shortdescription = "Configure, create, and view your zone's ratelimits."
209 |
210 | [[command]]
211 | name = "loadbalancer"
212 | description = """
213 | The Cloudflare loadbalancer product is an enterprise ready load balancing platform."""
214 | subcommands = [
215 | "create-loadbalancer",
216 | "create-loadbalancer-pool",
217 | "create-loadbalancer-monitor",
218 | "delete-loadbalancer",
219 | "delete-loadbalancer-monitor",
220 | "delete-loadbalancer-pool",
221 | "describe-loadbalancer",
222 | "describe-loadbalancer-pool",
223 | "describe-loadbalancer-monitor",
224 | "list-loadbalancer-monitors",
225 | "list-loadbalancer-pools",
226 | "list-loadbalancers",
227 | "update-loadbalancer",
228 | "update-loadbalancer-monitor",
229 | "update-loadbalancer-pool",
230 | ]
231 | toplevel = true
232 | shortdescription = "Manage, create, and describe your loadbalancers, pools, and monitor"
233 |
234 | [[command]]
235 | name = "list-zones"
236 | description = """
237 | This is a meaty description of the list-zones"""
238 | shortdescription = "Command for listing zones"
239 | v4apiname = "ListZones"
240 | [[command.option]]
241 | name = "zone-name-filter"
242 | type = "string"
243 | description = "string for filtering by name"
244 | required = false
245 |
246 | [[command]]
247 | name = "list-dns-records"
248 | description = """
249 | List DNS Records associated with a given zone-id"""
250 | shortdescription = "Command for listing dns-records"
251 | v4apiname = "ListDnsRecords"
252 |
253 | [[command.option]]
254 | name = "zone-id"
255 | type = "string"
256 | description = "zone id used for filtering"
257 | required = true
258 |
259 | [[command.option]]
260 | name = "type"
261 | type = "string"
262 | description = "DNS Record type used for filter"
263 | required = false
264 |
265 | [[command.option]]
266 | name = "name"
267 | type = "string"
268 | description = "DNS Record name used for filter"
269 | required = false
270 |
271 | [[command.option]]
272 | name = "content"
273 | type = "string"
274 | description = "DNS Record content used for filter"
275 | required = false
276 |
277 | [[command]]
278 | name = "create-dns-record"
279 | description = """Create DNS record associated with a given zone."""
280 | shortdescription = "Command DNS Record"
281 | v4apiname = "CreateDnsRecord"
282 |
283 | [[command.option]]
284 | name = "zone-id"
285 | type = "string"
286 | description = "The zone id associated with the new dns record"
287 | required = true
288 |
289 | [[command.option]]
290 | name = "type"
291 | type = "string"
292 | description = "valid values: A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI read only"
293 | required = true
294 |
295 | [[command.option]]
296 | name = "name"
297 | type = "string"
298 | description = "DNS Record name (example: example.com), max length: 255"
299 | required = true
300 |
301 | [[command.option]]
302 | name = "content"
303 | type = "string"
304 | description = "DNS Record content used for filter"
305 | required = true
306 |
307 | [[command.option]]
308 | name = "ttl"
309 | type = "int"
310 | description = "Time to live for DNS record. Value of 1 is 'automatic', min value:120 max value:2147483647"
311 | required = false
312 |
313 | [[command.option]]
314 | name = "not-proxied"
315 | type = "bool"
316 | description = "Whether the record is receiving the performance and security benefits of Cloudflare"
317 | required = false
318 |
319 | [[command.option]]
320 | name = "priority"
321 | type = "int"
322 | description = "Used with some records like MX and SRV to determine priority. If you do not supply a priority for an MX record, a default value of 0 will be set. min value:0 max value:65535."
323 | required = false
324 |
325 | [[command]]
326 | name = "delete-dns-record"
327 | description = """Delete DNS record associated with a given zone."""
328 | shortdescription = "Delete DNS Record"
329 | v4apiname = "DeleteDnsRecord"
330 |
331 | [[command.option]]
332 | name = "zone-id"
333 | type = "string"
334 | description = "The zone id associated with the record you wish to delete"
335 | required = true
336 |
337 | [[command.option]]
338 | name = "record-id"
339 | type = "string"
340 | description = "The record id associated with the dns record you wish to delete"
341 | required = true
342 |
343 | [[command]]
344 | name = "delete-zone"
345 | description = """Delete a zone associated with your account."""
346 | shortdescription = "Delete zone"
347 | v4apiname = "DeleteZone"
348 |
349 | [[command.option]]
350 | name = "zone-id"
351 | type = "string"
352 | description = "The zone id that will be deleted"
353 | required = true
354 |
355 | [[command]]
356 | name = "create-zone"
357 | description = """Create a zone associated with your account."""
358 | shortdescription = "Create zone"
359 | v4apiname = "CreateZone"
360 |
361 | [[command.option]]
362 | name = "name"
363 | type = "string"
364 | description = "The zone name that will be added to your account"
365 | required = true
366 |
367 | [[command.option]]
368 | name = "jumpstart"
369 | type = "bool"
370 | description = "Should the zone DNS be pre-populated"
371 | required = false
372 |
373 | [[command.option]]
374 | name = "organization-id"
375 | type = "string"
376 | description = "The organizationID associated with the zone"
377 | required = false
378 |
379 | [[command]]
380 | name = "show-dns-record"
381 | description = """Show a single DNS record associated with a zone ID and record ID."""
382 | shortdescription = "Show DNS Record"
383 | v4apiname = "DNSRecord"
384 |
385 | [[command.option]]
386 | name = "zone-id"
387 | type = "string"
388 | description = "The zone ID associated with the DNS Record"
389 | required = true
390 |
391 | [[command.option]]
392 | name = "record-id"
393 | type = "string"
394 | description = "*Required:* The recordID associated with the DNS Record"
395 | required = true
396 |
397 | [[command]]
398 | name = "list-ratelimits"
399 | description = """Returns all Rate Limits for a zone"""
400 | shortdescription = "Show Ratelimits"
401 | v4apiname = "ListAllRateLimits"
402 |
403 | [[command.option]]
404 | name = "zone-id"
405 | type = "string"
406 | description = "The zone ID associated with the Ratelimits"
407 | required = true
408 |
409 | [[command]]
410 | name = "list-loadbalancers"
411 | description = """Returns all LoadBalancers for a zone"""
412 | shortdescription = "Show LoadBalancers"
413 | v4apiname = "ListLoadBalancers"
414 | [[command.option]]
415 | name = "zone-id"
416 | type = "string"
417 | description = "The zone ID associated with the Ratelimits"
418 | required = true
419 |
420 | [[command]]
421 | name = "list-organizations"
422 | description = """Returns all Organizations associated with your account"""
423 | shortdescription = "Show Organizations"
424 | v4apiname = "ListOrganizations"
425 |
426 | [[command]]
427 | name = "list-pagerules"
428 | description = """Returns all page rules associated with a given zone ID"""
429 | shortdescription = "Show Page Rules"
430 | v4apiname = "ListPageRules"
431 | [[command.option]]
432 | name = "zone-id"
433 | type = "string"
434 | description = "The zone ID associated with the pagerules"
435 | required = true
436 |
437 | [[command]]
438 | name = "list-custom-certs"
439 | description = """Returns all custom certs for a given zone ID"""
440 | shortdescription = "Show Custom Certs"
441 | v4apiname = "ListCustomCerts"
442 | [[command.option]]
443 | name = "zone-id"
444 | type = "string"
445 | description = "The zone ID associated with the custom certs"
446 | required = true
447 |
448 | [[command]]
449 | name = "list-user-agent-rules"
450 | description = """Returns all User-Agent rules for a specific zone ID"""
451 | shortdescription = "List User-Agent rules"
452 | v4apiname = "ListUserAgentRules"
453 | [[command.option]]
454 | name = "zone-id"
455 | type = "string"
456 | description = "The zone ID associated with the user-agent rule."
457 | required = true
458 |
459 | [[command.option]]
460 | name = "page"
461 | type = "int"
462 | description = "Pagination for user-agent rules"
463 |
464 | [[command]]
465 | name = "list-waf-packages"
466 | description = """Return the WAF Packages associated with a given zone."""
467 | shortdescription = "List WAF Packages"
468 | v4apiname = "ListWAFPackages"
469 | [[command.option]]
470 | name = "zone-id"
471 | type = "string"
472 | description = "The zone ID associated with the WAF packages."
473 | required = true
474 |
475 | [[command]]
476 | name = "list-waf-rules"
477 | description = """Return the WAF Rules associated with a given zone."""
478 | shortdescription = "List WAF Rules"
479 | v4apiname = "ListWAFRules"
480 | [[command.option]]
481 | name = "zone-id"
482 | type = "string"
483 | description = "The zone ID associated with the WAF configuration."
484 | required = true
485 | [[command.option]]
486 | name = "package-id"
487 | type = "string"
488 | description = "The package ID associated with the displayed WAF rules."
489 | required = true
490 |
491 | [[command]]
492 | name = "list-zone-lockdowns"
493 | description = """Return the lockdowns associated with a given zone."""
494 | shortdescription = "List Zone Lockdowns"
495 | v4apiname = "ListZoneLockdowns"
496 | [[command.option]]
497 | name = "zone-id"
498 | type = "string"
499 | description = "The zone ID associated with the WAF configuration."
500 | required = true
501 | [[command.option]]
502 | name = "page"
503 | type = "int"
504 | description = "Pagination for zone lockdowns."
505 |
506 | [[command]]
507 | name = "describe-zone-lockdown"
508 | description = """Return the detailed information about a lockdown associated with a given zone."""
509 | shortdescription = "Get detailed zone lockdown information"
510 | v4apiname = "ZoneLockdown"
511 | [[command.option]]
512 | name = "zone-id"
513 | type = "string"
514 | description = "The zone ID associated with the zone lockdown."
515 | required = true
516 | [[command.option]]
517 | name = "lockdown-id"
518 | type = "string"
519 | description = "The lockdown ID associated with the lockdown"
520 | required = true
521 |
522 | [[command]]
523 | name = "edit-zone-paused"
524 | description = """Edit a given zone's properties."""
525 | shortdescription = "Edit a given zone"
526 | v4apiname = "EditZonePaused"
527 | [[command.option]]
528 | name = "zone-id"
529 | type = "string"
530 | description = "The zone ID associated with the zone being updated"
531 | required = true
532 | [[command.option]]
533 | name = "paused"
534 | type = "bool"
535 | description = "Set to pause the zone while editing the zone"
536 |
537 | [[command]]
538 | name = "edit-zone-vanity-ns"
539 | description = """Edit a given zone's properties."""
540 | shortdescription = "Edit a given zone"
541 | v4apiname = "EditZoneVanityNS"
542 | [[command.option]]
543 | name = "zone-id"
544 | type = "string"
545 | description = "The zone ID associated with the zone being updated"
546 | required = true
547 | [[command.option]]
548 | name = "vanity-ns"
549 | type = "string"
550 | required = true
551 | description = "Comma delimited list of vanity nameservers"
552 |
553 | [[command]]
554 | name = "set-vanity-ns"
555 | description = """Set a given zone's vanity nameservers."""
556 | shortdescription = "Set zone's vanity nameservers"
557 | v4apiname = "ZoneSetVanityNS"
558 | [[command.option]]
559 | name = "zone-id"
560 | type = "string"
561 | description = "The zone ID associated with the zone being updated"
562 | required = true
563 | [[command.option]]
564 | name = "vanity-ns"
565 | type = "string"
566 | required = true
567 | description = "Comma delimited list of vanity nameservers"
568 |
569 | [[command]]
570 | name = "edit-dns-record"
571 | description = """Edit an individual dns record's proxied status."""
572 | shortdescription = "Edit proxy status for dns record"
573 | v4apiname = "EditDNSRecord"
574 | [[command.option]]
575 | name = "proxied"
576 | type = "bool"
577 | description = "Set this flag is you wish to proxy through Cloudflare, otherwise do not set"
578 | [[command.option]]
579 | name = "zone-id"
580 | type = "string"
581 | required = true
582 | description = "The zone ID associated with the dns record"
583 | [[command.option]]
584 | name = "record-id"
585 | type = "string"
586 | required = true
587 | description = "The record ID that indicates the dns record"
588 | [[command.option]]
589 | name = "type"
590 | type = "string"
591 | description = "valid values: A, AAAA, CNAME, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY, DS, NAPTR, SMIMEA, SSHFP, TLSA, URI read only"
592 | required = true
593 | [[command.option]]
594 | name = "name"
595 | type = "string"
596 | description = "DNS Record name (example: example.com), max length: 255"
597 | required = true
598 | [[command.option]]
599 | name = "content"
600 | type = "string"
601 | description = "DNS Record content used for filter"
602 | required = true
603 | [[command.option]]
604 | name = "ttl"
605 | type = "int"
606 | description = "Time to live for DNS record. Value of 1 is 'automatic', min value:120 max value:2147483647"
607 | required = false
608 |
609 | [[command]]
610 | name = "list-loadbalancer-monitors"
611 | description = """Returns all LoadBalancer Monitors. Not specific to a zone"""
612 | shortdescription = "Show LoadBalancer Monitors"
613 | v4apiname = "ListLoadBalancerMonitors"
614 | [[command]]
615 | name = "list-loadbalancer-pools"
616 | description = """Returns all LoadBalancer Pools. Not specific to a zone"""
617 | shortdescription = "Show LoadBalancer Pools"
618 | v4apiname = "ListLoadBalancerPools"
619 |
620 | [[command]]
621 | name = "list-organization-access-rules"
622 | description = """Returns all Organizations associated with your account"""
623 | shortdescription = "List Organization Access Rules"
624 | v4apiname = "ListOrganizationAccessRules"
625 | [[command.option]]
626 | name = "organization-id"
627 | type = "string"
628 | description = "The Organization ID"
629 | required = true
630 | [[command.option]]
631 | name = "notes"
632 | type = "string"
633 | description = "Matching any string within previously created access rules with the notes"
634 | required = false
635 | [[command.option]]
636 | name = "mode"
637 | type = "string"
638 | description = "valid values: block, challenge, whitelist, js_challenge"
639 | required = false
640 | [[command.option]]
641 | name = "page"
642 | type = "int"
643 | description = "Requested page within paginated list of results"
644 | required = false
645 |
646 | [[command]]
647 | name = "list-railguns"
648 | description = """Returns all Railguns associated with your account"""
649 | shortdescription = "List Railguns associated with the account"
650 | v4apiname = "ListRailguns"
651 |
652 | [[command]]
653 | name = "list-zone-railguns"
654 | description = """Returns all Railguns associated with a given zone"""
655 | shortdescription = "List all Railguns associated with a zone"
656 | v4apiname = "ListZoneRailguns"
657 |
658 | [[command]]
659 | name = "list-user-access-rules"
660 | description = """Returns all access rules associated with your account"""
661 | shortdescription = "List User Access Rules"
662 | v4apiname = "ListUserAccessRules"
663 | [[command.option]]
664 | name = "notes"
665 | type = "string"
666 | description = "Matching any string within previously created access rules with the notes"
667 | required = false
668 | [[command.option]]
669 | name = "mode"
670 | type = "string"
671 | description = "valid values: block, challenge, whitelist, js_challenge"
672 | required = false
673 | [[command.option]]
674 | name = "page"
675 | type = "int"
676 | description = "Requested page within paginated list of results"
677 | required = false
678 |
679 | [[command]]
680 | name = "list-virtual-dns"
681 | description = """Returns all Virtual DNS clusters associated with an account"""
682 | shortdescription = "List Virtual DNS clusters"
683 | v4apiname = "ListVirtualDns"
684 |
685 | [[command]]
686 | name = "list-available-rate-plans"
687 | description = """List all rate plans the zone can subscribe to."""
688 | shortdescription = "List all available zone rate plans"
689 | v4apiname = "AvailableZoneRatePlans"
690 | [[command.option]]
691 | name = "zone-id"
692 | type = "string"
693 | description = "The zone ID associated with the rate plans"
694 | required = true
695 |
696 | [[command]]
697 | name = "connect-zone-railgun"
698 | description = """Connect or disconnect a Railgun"""
699 | shortdescription = "Connect or disconnect a Railgun"
700 | v4apiname = "ConnectZoneRailgun"
701 | [[command.option]]
702 | name = "zone-id"
703 | type = "string"
704 | description = "The zone ID to be associated with the railgun"
705 | required = true
706 | [[command.option]]
707 | name = "railgun-id"
708 | type = "string"
709 | description = "The railgun ID to be associated with the zone"
710 | required = true
711 |
712 | [[command]]
713 | name = "create-custom-hostname"
714 | description = """Add a new custom hostname and request that an SSL certificate be issued for it. One of three validation methods—http, cname, email—should be used, with 'http' recommended if the CNAME is already in place (or will be soon). Specifying 'email' will send an email to the WHOIS contacts on file for the base domain plus hostmaster, postmaster, webmaster, admin, administrator. Specifying 'cname' will return a CNAME that needs to be placed. If http is used and the domain is not already pointing to the Managed CNAME host, the PATCH method must be used once it is (to complete validation)."""
715 | shortdescription = "Create a custom hostname for an associated zone."
716 | v4apiname = "CreateCustomHostname"
717 | [[command.option]]
718 | name = "zone-id"
719 | type = "string"
720 | description = "The zone ID associated with the custom hostname"
721 | required = true
722 | [[command.option]]
723 | name = "hostname"
724 | type = "string"
725 | description = "The custom hostname that will point to your hostname via CNAME."
726 | required = true
727 | [[command.option]]
728 | name = "method"
729 | type = "string"
730 | description = "The SSL Verification method. valid values: http, email, cname."
731 | required = true
732 | [[command.option]]
733 | name = "type"
734 | type = "string"
735 | description = "The type of SSL certificate valid values: dv only"
736 | required = true
737 |
738 | [[command]]
739 | name = "create-loadbalancer-monitor"
740 | description = """Create a configured monitor"""
741 | shortdescription = "Create a configured monitor"
742 | v4apiname = "CreateLoadBalancerMonitor"
743 | [[command.option]]
744 | name = "expected-codes"
745 | type = "string"
746 | description = "The expected http response code in the healthcheck"
747 | required = true
748 | [[command.option]]
749 | name = "method"
750 | type = "string"
751 | description = "The HTTP method to use for the health check. default value: GET"
752 | required = false
753 | [[command.option]]
754 | name = "header"
755 | type = "string"
756 | description = "The HTTP request headers to send in the health check. It is recommended you set a Host header by default. The User-Agent header cannot be overridden. Example: {\\\"Host\\\": [\\\"example.com\\\"],\\\"X-App-ID\\\": [\\\"abc123\\\"]}"
757 | required = false
758 | [[command.option]]
759 | name = "timeout"
760 | type = "int"
761 | description = "The timeout (in seconds) before marking the health check as failed. default value: 5"
762 | required = true
763 | [[command.option]]
764 | name = "path"
765 | type = "string"
766 | description = "The endpoint path to health check against. default value: /"
767 | required = true
768 | [[command.option]]
769 | name = "interval"
770 | type = "int"
771 | description = "The interval between each health check. Shorter intervals may improve failover time, but will increase load. default value 60"
772 | required = true
773 | [[command.option]]
774 | name = "retries"
775 | type = "int"
776 | description = "The number of retries to attempt in case of a timeout before marking the origin as unhealthy. default value 2"
777 | required = true
778 | [[command.option]]
779 | name = "expected-body"
780 | type = "string"
781 | description = "A case-insensitive sub-string to look for in the response body. If this string is not found, the origin will be marked as unhealthy."
782 | required = false
783 | [[command.option]]
784 | name = "type"
785 | type = "string"
786 | description = "The protocol to use for the healthcheck. Currently supported protocols are 'HTTP' and 'HTTPS'. default value: http"
787 | required = true
788 | [[command.option]]
789 | name = "description"
790 | type = "string"
791 | description = "Object description"
792 | required = true
793 |
794 | [[command]]
795 | name = "create-loadbalancer"
796 | description = """Create a configured monitor"""
797 | shortdescription = "Create a configured monitor"
798 | v4apiname = "CreateLoadBalancer"
799 | [[command.option]]
800 | name = "zone-id"
801 | type = "string"
802 | description = "The zoneID associated with the loadbalancer"
803 | required = true
804 | [[command.option]]
805 | name = "name"
806 | type = "string"
807 | description = "The DNS hostname to associate with your Load Balancer. If this hostname already exists as a DNS record in Cloudflare's DNS, the Load Balancer will take precedence and the DNS record will not be used."
808 | required = true
809 | [[command.option]]
810 | name = "fallback-pool"
811 | type = "string"
812 | description = "The pool ID to use when all other pools are detected as unhealthy. max length: 32"
813 | required = true
814 | [[command.option]]
815 | name = "default-pools"
816 | type = "string"
817 | description = "A comma separated list of pool IDs ordered by their failover priority. Pools defined here are used by default, or when region_pools are not configured for a given region."
818 | required = true
819 | [[command.option]]
820 | name = "proxied"
821 | type = "bool"
822 | description = "Whether the hostname should be gray clouded (false) or orange clouded (true). default value: false"
823 | required = false
824 | [[command.option]]
825 | name = "ttl"
826 | type = "int"
827 | description = "Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This only applies to gray-clouded (unproxied) load balancers."
828 | required = false
829 |
830 | [[command]]
831 | name = "purge-everything"
832 | description = """Purge all items in this zones cache."""
833 | shortdescription = "Purge Everything"
834 | v4apiname = "PurgeEverything"
835 | [[command.option]]
836 | name = "zone-id"
837 | type = "string"
838 | description = "The zoneID that will be purged."
839 | required = true
840 |
841 | [[command]]
842 | name = "activation-check"
843 | description = """Initiates another zone activation check for newly-created zones"""
844 | shortdescription = "Initiate another zone activation check"
845 | v4apiname = "ActivationCheck"
846 | [[command.option]]
847 | name = "zone-id"
848 | type = "string"
849 | description = "The zoneID associated with the activation check"
850 | required = true
851 |
852 | [[command]]
853 | name = "describe-zone"
854 | description = """Fetches information about a zone."""
855 | shortdescription = "Fetches information about a zone."
856 | v4apiname = "ZoneDetails"
857 | [[command.option]]
858 | name = "zone-id"
859 | type = "string"
860 | description = "The zoneID that will be purged."
861 | required = true
862 |
863 | [[command]]
864 | name = "get-id-by-name"
865 | description = """Get the zone id by the zone name."""
866 | shortdescription = "Get the zone id by name"
867 | v4apiname = "GetIDByName"
868 | [[command.option]]
869 | name = "zone-name"
870 | type = "string"
871 | description = "The zoneName that you want the ID of"
872 | required = true
873 |
874 | [[command]]
875 | name = "list-zone-ssl-settings"
876 | description = """Get the ssl settings associated with a zone."""
877 | shortdescription = "Fetch zone ssl settings"
878 | v4apiname = "ZoneSSLSettings"
879 | [[command.option]]
880 | name = "zone-id"
881 | type = "string"
882 | description = "The zoneID you wish to fetch the SSL settings for"
883 | required = true
884 |
885 | [[command]]
886 | name = "get-zone-settings"
887 | description = """Get zone specific settings."""
888 | shortdescription = "Get zone specific settings"
889 | v4apiname = "ZoneSettings"
890 | [[command.option]]
891 | name = "zone-id"
892 | type = "string"
893 | description = "The zoneID you wish to fetch the zone settings for"
894 | required = true
895 |
896 | [[command]]
897 | name = "details"
898 | description = """Get user specific settings."""
899 | shortdescription = "Get user specific settings"
900 | v4apiname = "UserDetails"
901 |
902 | [[command]]
903 | name = "billing-profile"
904 | description = """Get the user billing profile."""
905 | shortdescription = "Get the billing profile"
906 | v4apiname = "UserBillingProfile"
907 |
908 | [[command]]
909 | name = "describe-virtual-dns"
910 | description = """Get the details about a virtual dns instance."""
911 | shortdescription = "Get virtual dns details"
912 | v4apiname = "VirtualDNS"
913 | [[command.option]]
914 | name = "virtual-dns-id"
915 | type = "string"
916 | description = "The virtualDNS ID you wish to fetch the details of."
917 | required = true
918 |
919 | [[command]]
920 | name = "delete-virtual-dns"
921 | description = """Delete a specific virtual dns instance."""
922 | shortdescription = "Delete virtual dns instance"
923 | v4apiname = "DeleteVirtualDNS"
924 | [[command.option]]
925 | name = "virtual-dns-id"
926 | type = "string"
927 | description = "The virtualDNS ID you wish to delete."
928 | required = true
929 |
930 | [[command]]
931 | name = "describe-pagerule"
932 | description = """Get the details of a specific page rule"""
933 | shortdescription = "Get page rule details"
934 | v4apiname = "PageRule"
935 | [[command.option]]
936 | name = "zone-id"
937 | type = "string"
938 | description = "The zone ID associated with the page rule"
939 | required = true
940 | [[command.option]]
941 | name = "pagerule-id"
942 | type = "string"
943 | description = "The pagerule ID you wish to fetch the details of."
944 | required = true
945 |
946 | [[command]]
947 | name = "describe-loadbalancer"
948 | description = """Get loadbalancer details."""
949 | shortdescription = "Get loadbalancer details"
950 | v4apiname = "LoadBalancerDetails"
951 | [[command.option]]
952 | name = "zone-id"
953 | type = "string"
954 | description = "The zone ID associated with the page rule"
955 | required = true
956 | [[command.option]]
957 | name = "loadbalancer-id"
958 | type = "string"
959 | description = "The loadbalancer id that you wish to view the details of."
960 | required = true
961 |
962 | [[command]]
963 | name = "describe-loadbalancer-monitor"
964 | description = """Get loadbalancer monitor details."""
965 | shortdescription = "Get loadbalancer monitor details"
966 | v4apiname = "LoadBalancerMonitorDetails"
967 | [[command.option]]
968 | name = "monitor-id"
969 | type = "string"
970 | description = "The loadbalancer monitor id that you wish to view the details of."
971 | required = true
972 |
973 | [[command]]
974 | name = "describe-loadbalancer-pool"
975 | description = """Get loadbalancer pool details."""
976 | shortdescription = "Get loadbalancer pool details"
977 | v4apiname = "LoadBalancerPoolDetails"
978 | [[command.option]]
979 | name = "pool-id"
980 | type = "string"
981 | description = "The loadbalancer pool id that you wish to view the details of."
982 | required = true
983 |
984 | [[command]]
985 | name = "describe-organization"
986 | description = """Get organization details."""
987 | shortdescription = "Get organization details"
988 | v4apiname = "OrganizationDetails"
989 | [[command.option]]
990 | name = "organization-id"
991 | type = "string"
992 | description = "The organization id that you wish to view the details of."
993 | required = true
994 |
995 | [[command]]
996 | name = "get-organization-invites"
997 | description = """Get organization invites."""
998 | shortdescription = "Get organization invites"
999 | v4apiname = "OrganizationInvites"
1000 | [[command.option]]
1001 | name = "organization-id"
1002 | type = "string"
1003 | description = "The organization id that you wish to view the invites for."
1004 | required = true
1005 |
1006 | [[command]]
1007 | name = "get-organization-members"
1008 | description = """Get organization members."""
1009 | shortdescription = "Get organization members"
1010 | v4apiname = "OrganizationMembers"
1011 | [[command.option]]
1012 | name = "organization-id"
1013 | type = "string"
1014 | description = "The organization id that you wish to view the members of"
1015 | required = true
1016 |
1017 | [[command]]
1018 | name = "get-organization-roles"
1019 | description = """Get organization roles."""
1020 | shortdescription = "Get organization roles"
1021 | v4apiname = "OrganizationRoles"
1022 | [[command.option]]
1023 | name = "organization-id"
1024 | type = "string"
1025 | description = "The organization id that you wish to view the member roles of"
1026 | required = true
1027 |
1028 | [[command]]
1029 | name = "list-origin-certs"
1030 | description = """List Origin Certificates associated with a given zone ID"""
1031 | shortdescription = "List origin certificates"
1032 | v4apiname = "OriginCertificates"
1033 | [[command.option]]
1034 | name = "zone-id"
1035 | type = "string"
1036 | description = "The zone id that you wish to view the origin certs of"
1037 | required = true
1038 |
1039 | [[command]]
1040 | name = "describe-origin-cert"
1041 | description = """Get detailed information about a specific origin certificate"""
1042 | shortdescription = "Get origin cert details"
1043 | v4apiname = "OriginCertificate"
1044 | [[command.option]]
1045 | name = "certificate-id"
1046 | type = "string"
1047 | description = "The origin certificate id that you wish to view detailed information about"
1048 | required = true
1049 |
1050 | [[command]]
1051 | name = "describe-zone-origin-cert"
1052 | description = """Get detailed information about a specific zone's origin certificate"""
1053 | shortdescription = "Get zone's origin cert details"
1054 | v4apiname = "SSLDetails"
1055 | [[command.option]]
1056 | name = "certificate-id"
1057 | type = "string"
1058 | description = "The zone's certificate id that you wish to view detailed information about"
1059 | required = true
1060 | [[command.option]]
1061 | name = "zone-id"
1062 | type = "string"
1063 | description = "The zone id that you wish to view detailed information about"
1064 | required = true
1065 |
1066 | [[command]]
1067 | name = "describe-railgun"
1068 | description = """Get detailed information about a specific railgun"""
1069 | shortdescription = "Get railgun instance details"
1070 | v4apiname = "RailgunDetails"
1071 | [[command.option]]
1072 | name = "railgun-id"
1073 | type = "string"
1074 | description = "The railgun id that you wish to view detailed information about"
1075 | required = true
1076 |
1077 | [[command]]
1078 | name = "get-railgun-zones"
1079 | description = """Get detailed information about a specific railgun's zones"""
1080 | shortdescription = "Get railgun instance zone details"
1081 | v4apiname = "RailgunZones"
1082 | [[command.option]]
1083 | name = "railgun-id"
1084 | type = "string"
1085 | description = "The railgun id that you wish to view associated zones"
1086 | required = true
1087 |
1088 | [[command]]
1089 | name = "describe-ratelimit"
1090 | description = """Get detailed information about a specific zone's ratelimits"""
1091 | shortdescription = "Get detailed information about a zone"
1092 | v4apiname = "RateLimit"
1093 | [[command.option]]
1094 | name = "zone-id"
1095 | type = "string"
1096 | description = "The zone id associated with the ratelimit"
1097 | required = true
1098 | [[command.option]]
1099 | name = "ratelimit-id"
1100 | type = "string"
1101 | description = "The ratelimit id that you wish to view detailed information about"
1102 | required = true
1103 |
1104 | [[command]]
1105 | name = "revoke-origin-cert"
1106 | description = """Revoke a specific origin certificate"""
1107 | shortdescription = "Revoke origin certificate"
1108 | v4apiname = "RevokeOriginCertificate"
1109 | [[command.option]]
1110 | name = "certificate-id"
1111 | type = "string"
1112 | description = "The certificate id that is being revoked"
1113 | required = true
1114 |
1115 | [[command]]
1116 | name = "test-railgun-connection"
1117 | description = """Returns all access rules associated with your account"""
1118 | shortdescription = "List User Access Rules"
1119 | v4apiname = "TestRailgunConnection"
1120 | [[command.option]]
1121 | name = "zone-id"
1122 | type = "string"
1123 | description = "The zone id associated with the railgun connection you wish to test"
1124 | required = true
1125 | [[command.option]]
1126 | name = "railgun-id"
1127 | type = "string"
1128 | description = "The railgun id associated with the railgun connection you wish to test"
1129 | required = true
1130 |
1131 | [[command]]
1132 | name = "describe-zone-railgun"
1133 | description = """Returns all railgun details for an associated zone"""
1134 | shortdescription = "Get zone railgun details"
1135 | v4apiname = "ZoneRailgunDetails"
1136 | [[command.option]]
1137 | name = "zone-id"
1138 | type = "string"
1139 | description = "The zone id associated with the railguns you wish to get"
1140 | required = true
1141 | [[command.option]]
1142 | name = "railgun-id"
1143 | type = "string"
1144 | description = "The railgun id associated with the railguns you wish to get"
1145 | required = true
1146 |
1147 | [[command]]
1148 | name = "describe-custom-hostname"
1149 | description = """Returns details associated with the custom hostname id"""
1150 | shortdescription = "Custom hostname details"
1151 | v4apiname = "CustomHostname"
1152 | [[command.option]]
1153 | name = "zone-id"
1154 | type = "string"
1155 | description = "The zone id associated with the custom hostname being returned"
1156 | required = true
1157 | [[command.option]]
1158 | name = "custom-hostname-id"
1159 | type = "string"
1160 | description = "The custom hostname id associated with the custom hostname you wish to describe"
1161 | required = true
1162 |
1163 | [[command]]
1164 | name = "describe-custom-hostname-by-name"
1165 | description = """Returns details associated with the custom hostname id"""
1166 | shortdescription = "Custom hostname details"
1167 | v4apiname = "CustomHostnameIDByName"
1168 | [[command.option]]
1169 | name = "zone-id"
1170 | type = "string"
1171 | description = "The zone id associated with the custom hostname id being returned"
1172 | required = true
1173 | [[command.option]]
1174 | name = "name"
1175 | type = "string"
1176 | description = "The custom hostname associated with the custom hostname id you wish to return"
1177 | required = true
1178 |
1179 | [[command]]
1180 | name = "set-paused"
1181 | description = """Set or unset a zone from being paused"""
1182 | shortdescription = "Pause or unpause a zone"
1183 | v4apiname = "ZoneSetPaused"
1184 | [[command.option]]
1185 | name = "zone-id"
1186 | type = "string"
1187 | description = "The zone id to either pause or unpause"
1188 | required = true
1189 | [[command.option]]
1190 | name = "paused"
1191 | type = "bool"
1192 | description = "This flag is unset for unpaused. Set for paused."
1193 | required = false
1194 |
1195 | [[command]]
1196 | name = "delete-pagerule"
1197 | description = """Delete a page rule associated with a specific zone and pagerule id"""
1198 | shortdescription = "Delete a specific page rule"
1199 | v4apiname = "DeletePageRule"
1200 | [[command.option]]
1201 | name = "zone-id"
1202 | type = "string"
1203 | description = "The zone ID associated with the page rule"
1204 | required = true
1205 | [[command.option]]
1206 | name = "pagerule-id"
1207 | type = "string"
1208 | description = "The pagerule ID associated with the pagerule you wish to delete"
1209 | required = true
1210 |
1211 | [[command]]
1212 | name = "delete-railgun"
1213 | description = """Delete a railgun associated with a specific railgun id"""
1214 | shortdescription = "Delete a specific railgun by its id"
1215 | v4apiname = "DeleteRailgun"
1216 | [[command.option]]
1217 | name = "railgun-id"
1218 | type = "string"
1219 | description = "The railgun ID associated with the railgun being deleted"
1220 | required = true
1221 |
1222 | [[command]]
1223 | name = "disable-railgun"
1224 | description = """Disable a railgun associated with a specific railgun id"""
1225 | shortdescription = "Delete a specific railgun by its id"
1226 | v4apiname = "DisableRailgun"
1227 | [[command.option]]
1228 | name = "railgun-id"
1229 | type = "string"
1230 | description = "The railgun ID associated with the railgun being disabled"
1231 | required = true
1232 |
1233 | [[command]]
1234 | name = "disconnect-railgun"
1235 | description = """Disconnect a railgun associated with a specific zone"""
1236 | shortdescription = "Disconnect a railgun from a zone"
1237 | v4apiname = "DisconnectZoneRailgun"
1238 | [[command.option]]
1239 | name = "railgun-id"
1240 | type = "string"
1241 | description = "The railgun ID associated with the railgun being disconnected"
1242 | required = true
1243 | [[command.option]]
1244 | name = "zone-id"
1245 | type = "string"
1246 | description = "The zone ID that the railgun instance is being disconnected from"
1247 | required = true
1248 |
1249 | [[command]]
1250 | name = "enable-railgun"
1251 | description = """Enable a railgun associated with a specific railgun id"""
1252 | shortdescription = "Enable a specific disabled railgun by its id"
1253 | v4apiname = "EnableRailgun"
1254 | [[command.option]]
1255 | name = "railgun-id"
1256 | type = "string"
1257 | description = "The railgun ID associated with the railgun being enabled "
1258 | required = true
1259 |
1260 | [[command]]
1261 | name = "delete-ratelimit"
1262 | description = """Delete a ratelimit associated with a specific ratelimit id"""
1263 | shortdescription = "Delete a specific ratelimit by its id"
1264 | v4apiname = "DeleteRateLimit"
1265 | [[command.option]]
1266 | name = "zone-id"
1267 | type = "string"
1268 | description = "The zone ID associated with the ratelimit being deleted"
1269 | required = true
1270 | [[command.option]]
1271 | name = "ratelimit-id"
1272 | type = "string"
1273 | description = "The ratelimit ID associated with the ratelimit being deleted"
1274 | required = true
1275 |
1276 | [[command]]
1277 | name = "delete-custom-cert"
1278 | description = """Delete a custom certificate associated with a specific certificate id"""
1279 | shortdescription = "Delete a specific certificate by its id"
1280 | v4apiname = "DeleteSSL"
1281 | [[command.option]]
1282 | name = "zone-id"
1283 | type = "string"
1284 | description = "The zone ID associated with the certificate being deleted"
1285 | required = true
1286 | [[command.option]]
1287 | name = "certificate-id"
1288 | type = "string"
1289 | description = "The certificate ID associated with the certificate being deleted"
1290 | required = true
1291 |
1292 | [[command]]
1293 | name = "delete-custom-hostname"
1294 | description = """Delete a custom hostname associated with a specific zone id"""
1295 | shortdescription = "Delete a specific custom hostname"
1296 | v4apiname = "DeleteCustomHostname"
1297 | [[command.option]]
1298 | name = "zone-id"
1299 | type = "string"
1300 | description = "The zone ID associated with the custom hostname being deleted"
1301 | required = true
1302 | [[command.option]]
1303 | name = "custom-hostname-id"
1304 | type = "string"
1305 | description = "The custom hostname ID associated with the custom hostname being deleted"
1306 | required = true
1307 |
1308 | [[command]]
1309 | name = "delete-loadbalancer"
1310 | description = """Delete a loadbalancer associated with a specific zone"""
1311 | shortdescription = "Delete a specific loadbalancer"
1312 | v4apiname = "DeleteLoadBalancer"
1313 | [[command.option]]
1314 | name = "zone-id"
1315 | type = "string"
1316 | description = "The zone ID associated with the loadbalancer"
1317 | required = true
1318 | [[command.option]]
1319 | name = "loadbalancer-id"
1320 | type = "string"
1321 | description = "The loadbalancer-id associated with the custom hostname being deleted"
1322 | required = true
1323 |
1324 | [[command]]
1325 | name = "delete-loadbalancer-monitor"
1326 | description = """Delete a specific loadbalancer monitor"""
1327 | shortdescription = "Delete a specific loadbalancer monitor"
1328 | v4apiname = "DeleteLoadBalancerMonitor"
1329 | [[command.option]]
1330 | name = "monitor-id"
1331 | type = "string"
1332 | description = "The load balancer monitor ID associated with the monitor being deleted"
1333 | required = true
1334 |
1335 | [[command]]
1336 | name = "delete-loadbalancer-pool"
1337 | description = """Delete a specific loadbalancer pool"""
1338 | shortdescription = "Delete a specific loadbalancer pool"
1339 | v4apiname = "DeleteLoadBalancerPool"
1340 | [[command.option]]
1341 | name = "pool-id"
1342 | type = "string"
1343 | description = "The load balancer pool ID associated with the pool being deleted"
1344 | required = true
1345 |
1346 | [[command]]
1347 | name = "delete-organization-access-rule"
1348 | description = """Delete an access rule associated with a specific organization"""
1349 | shortdescription = "Delete a specific access rule"
1350 | v4apiname = "DeleteOrganizationAccessRule"
1351 | [[command.option]]
1352 | name = "organization-id"
1353 | type = "string"
1354 | description = "The organization ID associated with the access rule being deleted"
1355 | required = true
1356 | [[command.option]]
1357 | name = "access-rule-id"
1358 | type = "string"
1359 | description = "The access rule ID associated with the access rule being deleted"
1360 | required = true
1361 |
1362 | [[command]]
1363 | name = "create-railgun"
1364 | description = """Create a railgun"""
1365 | shortdescription = "Create a railgun"
1366 | v4apiname = "CreateRailgun"
1367 | [[command.option]]
1368 | name = "name"
1369 | type = "string"
1370 | description = "The name you are assigning to the newly created railgun"
1371 | required = true
1372 |
1373 | [[command]]
1374 | name = "delete-user-access-rule"
1375 | description = """Delete a specific user access rule"""
1376 | shortdescription = "Delete a user access rule"
1377 | v4apiname = "DeleteUserAccessRule"
1378 | [[command.option]]
1379 | name = "access-rule-id"
1380 | type = "string"
1381 | description = "The access rule id associated with the user access rule you are deleting"
1382 | required = true
1383 |
1384 | [[command]]
1385 | name = "delete-user-agent-rule"
1386 | description = """Delete a specific user agent rule"""
1387 | shortdescription = "Delete a user agent rule"
1388 | v4apiname = "DeleteUserAgentRule"
1389 | [[command.option]]
1390 | name = "user-agent-id"
1391 | type = "string"
1392 | description = "The user agent rule id associated with the user agent rule being deleted"
1393 | required = true
1394 | [[command.option]]
1395 | name = "zone-id"
1396 | type = "string"
1397 | description = "The zone id associated with the user agent rule being deleted"
1398 | required = true
1399 |
1400 | [[command]]
1401 | name = "delete-zone-access-rule"
1402 | description = """Delete a specific zone access rule"""
1403 | shortdescription = "Delete a zone access rule"
1404 | v4apiname = "DeleteZoneAccessRule"
1405 | [[command.option]]
1406 | name = "access-rule-id"
1407 | type = "string"
1408 | description = "The zone access rule id associated with the zone access rule being deleted"
1409 | required = true
1410 | [[command.option]]
1411 | name = "zone-id"
1412 | type = "string"
1413 | description = "The zone id associated with the zone access rule being deleted"
1414 | required = true
1415 |
1416 | [[command]]
1417 | name = "delete-zone-lockdown"
1418 | description = """Delete a specific zone lockdown"""
1419 | shortdescription = "Delete a zone lockdown"
1420 | v4apiname = "DeleteZoneLockdown"
1421 | [[command.option]]
1422 | name = "zone-id"
1423 | type = "string"
1424 | description = "The zone id associated with the specific zone lockdown rule"
1425 | required = true
1426 | [[command.option]]
1427 | name = "lockdown-id"
1428 | type = "string"
1429 | description = "The zone lockdown id associated with the zone lockdown being deleted"
1430 | required = true
1431 |
1432 | [[command]]
1433 | name = "analytics-by-colo"
1434 | description = """Retrieve zone analytics structured by colocation"""
1435 | shortdescription = "Get analytics by colo"
1436 | v4apiname = "ZoneAnalyticsByColocation"
1437 | [[command.option]]
1438 | name = "zone-id"
1439 | type = "string"
1440 | description = "The zone id that analytics are being retreived for"
1441 | required = true
1442 | [[command.option]]
1443 | name = "since"
1444 | type = "string"
1445 | description = "String timestamp of the analytics start time"
1446 | required = false
1447 | [[command.option]]
1448 | name = "until"
1449 | type = "string"
1450 | description = "String timestamp of the analytics end time"
1451 | required = false
1452 | [[command.option]]
1453 | name = "continuous"
1454 | type = "bool"
1455 | description = "When continuous is true and since or until is set, the api will only return completely aggregated results"
1456 | required = false
1457 |
1458 | [[command]]
1459 | name = "analytics-dashboard"
1460 | description = """Retrieve zone analytics overview"""
1461 | shortdescription = "Get an analytics overview by zone"
1462 | v4apiname = "ZoneAnalyticsDashboard"
1463 | [[command.option]]
1464 | name = "zone-id"
1465 | type = "string"
1466 | description = "The zone id that analytics are being retreived for"
1467 | required = true
1468 | [[command.option]]
1469 | name = "since"
1470 | type = "string"
1471 | description = "String timestamp of the analytics start time"
1472 | required = false
1473 | [[command.option]]
1474 | name = "until"
1475 | type = "string"
1476 | description = "String timestamp of the analytics end time"
1477 | required = false
1478 | [[command.option]]
1479 | name = "continuous"
1480 | type = "bool"
1481 | description = "When continuous is true and since or until is set, the api will only return completely aggregated results"
1482 | required = false
1483 |
1484 | [[command]]
1485 | name = "edit-user"
1486 | description = """Edit user account details"""
1487 | shortdescription = "Edit user account details"
1488 | v4apiname = "UpdateUser"
1489 | [[command.option]]
1490 | name = "first-name"
1491 | type = "string"
1492 | description = "User's first name, max length 60"
1493 | required = false
1494 | [[command.option]]
1495 | name = "last-name"
1496 | type = "string"
1497 | description = "User's last name, max length 60"
1498 | required = false
1499 | [[command.option]]
1500 | name = "telephone"
1501 | type = "string"
1502 | description = "User's telephone number, max length 20"
1503 | required = false
1504 | [[command.option]]
1505 | name = "country"
1506 | type = "string"
1507 | description = "The country in which the user lives, example US. max length 30"
1508 | required = false
1509 | [[command.option]]
1510 | name = "zipcode"
1511 | type = "string"
1512 | description = "The zip code or postal code in which the user lives, max length 20"
1513 | required = false
1514 |
1515 | [[command]]
1516 | name = "create-loadbalancer-pool"
1517 | description = """Create a new loadbalancer pool"""
1518 | shortdescription = "Create a loadbalancer pool"
1519 | v4apiname = "CreateLoadBalancerPool"
1520 | [[command.option]]
1521 | name = "name"
1522 | type = "string"
1523 | description = "The name of the loadbalancer pool"
1524 | required = true
1525 | [[command.option]]
1526 | name = "origins"
1527 | type = "string"
1528 | description = "The list of origins Example: [{\\\"name\\\": \\\"app-server-1\\\", \\\"address\\\": \\\"0.0.0.0\\\", \\\"enabled\\\": true, \\\"weight\\\": 0.56}]"
1529 | required = true
1530 | [[command.option]]
1531 | name = "description"
1532 | type = "string"
1533 | description = "A human-readable description of the pool."
1534 | [[command.option]]
1535 | name = "disabled"
1536 | type = "bool"
1537 | description = "By default, the pool will be enabled. Specify disabled in order to modify this default"
1538 | [[command.option]]
1539 | name = "minimum-origins"
1540 | type = "int"
1541 | description = "The minimum number of origins that must be healthy for this pool to serve traffic. "
1542 | [[command.option]]
1543 | name = "monitor"
1544 | type = "string"
1545 | description = "The ID of the Monitor to use for health checking origins within this pool."
1546 | [[command.option]]
1547 | name = "notification-email"
1548 | type = "string"
1549 | description = "The email address to send health status notifications to. This can be an individual mailbox or a mailing list."
1550 |
1551 | [[command]]
1552 | name = "update-loadbalancer-pool"
1553 | description = """Edit an existing loadbalancer pool"""
1554 | shortdescription = "Edit an existing loadbalancer pool"
1555 | v4apiname = "ModifyLoadBalancerPool"
1556 | [[command.option]]
1557 | name = "pool-id"
1558 | type = "string"
1559 | description = "The name of the loadbalancer pool"
1560 | required = true
1561 | [[command.option]]
1562 | name = "name"
1563 | type = "string"
1564 | description = "The name of the loadbalancer pool"
1565 | required = true
1566 | [[command.option]]
1567 | name = "origins"
1568 | type = "string"
1569 | description = "The list of origins Example: [{\\\"name\\\": \\\"app-server-1\\\", \\\"address\\\": \\\"0.0.0.0\\\", \\\"enabled\\\": true, \\\"weight\\\": 0.56}]"
1570 | required = true
1571 | [[command.option]]
1572 | name = "description"
1573 | type = "string"
1574 | description = "A human-readable description of the pool."
1575 | [[command.option]]
1576 | name = "disabled"
1577 | type = "bool"
1578 | description = "By default, the pool will be enabled. Specify disabled in order to modify this default"
1579 | [[command.option]]
1580 | name = "minimum-origins"
1581 | type = "int"
1582 | description = "The minimum number of origins that must be healthy for this pool to serve traffic. "
1583 | [[command.option]]
1584 | name = "monitor"
1585 | type = "string"
1586 | description = "The ID of the Monitor to use for health checking origins within this pool."
1587 | [[command.option]]
1588 | name = "notification-email"
1589 | type = "string"
1590 | description = "The email address to send health status notifications to. This can be an individual mailbox or a mailing list."
1591 |
1592 | [[command]]
1593 | name = "update-zone-settings"
1594 | description = """Edit a zones settings"""
1595 | shortdescription = "Edit a zones settings"
1596 | v4apiname = "UpdateZoneSettings"
1597 | [[command.option]]
1598 | name = "zone-id"
1599 | type = "string"
1600 | description = "The zone id associated with the settings being modified"
1601 | required = true
1602 | [[command.option]]
1603 | name = "zone-settings-object"
1604 | type = "string"
1605 | description = "One or more zone setting objects. Must contain an ID and a value. Example: [{\\\"id\\\": \\\"always_online\\\",\\\"value\\\": \\\"on\\\"}]"
1606 | required = true
1607 |
1608 | [[command]]
1609 | name = "update-zone-lockdown"
1610 | description = """Edit an existing zone lockdown"""
1611 | shortdescription = "Edit an existing zone lockdown"
1612 | v4apiname = "UpdateZoneLockdown"
1613 | [[command.option]]
1614 | name = "zone-id"
1615 | type = "string"
1616 | description = "The zone id associated with the zone lockdown"
1617 | required = true
1618 | [[command.option]]
1619 | name = "lockdown-id"
1620 | type = "string"
1621 | description = "The lockdown id associated with the zone lockdown"
1622 | required = true
1623 | [[command.option]]
1624 | name = "configuration"
1625 | type = "string"
1626 | description = "The new configuration associated with the lockdown - Example: [{\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}]"
1627 | required = true
1628 | [[command.option]]
1629 | name = "urls"
1630 | type = "string"
1631 | description = "Comma delimited list of URLs associated with the zone lockdown"
1632 | required = true
1633 | [[command.option]]
1634 | name = "paused"
1635 | type = "bool"
1636 | description = "Whether this zone lockdown is currently paused"
1637 | required = false
1638 | [[command.option]]
1639 | name = "description"
1640 | type = "string"
1641 | description = "A note that you can use to describe the reason for a Lockdown rule"
1642 | required = false
1643 |
1644 | [[command]]
1645 | name = "create-zone-lockdown"
1646 | description = """Create a new zone lockdown"""
1647 | shortdescription = "Create a new zone lockdown"
1648 | v4apiname = "CreateZoneLockdown"
1649 | [[command.option]]
1650 | name = "zone-id"
1651 | type = "string"
1652 | description = "The zone id associated with the zone lockdown"
1653 | required = true
1654 | [[command.option]]
1655 | name = "configuration"
1656 | type = "string"
1657 | description = "The new configuration associated with the lockdown - Example: [{\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}]"
1658 | required = true
1659 | [[command.option]]
1660 | name = "urls"
1661 | type = "string"
1662 | description = "Comma delimited list of URLs associated with the zone lockdown"
1663 | required = true
1664 | [[command.option]]
1665 | name = "paused"
1666 | type = "bool"
1667 | description = "Whether this zone lockdown is currently paused"
1668 | required = false
1669 | [[command.option]]
1670 | name = "description"
1671 | type = "string"
1672 | description = "A note that you can use to describe the reason for a Lockdown rule"
1673 | required = false
1674 |
1675 | [[command]]
1676 | name = "create-virtual-dns"
1677 | description = """Create a new virtual dns cluster"""
1678 | shortdescription = "Create a new virtual dns cluster"
1679 | v4apiname = "CreateVirtualDNS"
1680 | [[command.option]]
1681 | name = "name"
1682 | type = "string"
1683 | description = "Virtual DNS Cluster Name, max length: 160 characters"
1684 | required = true
1685 | [[command.option]]
1686 | name = "origin-ips"
1687 | type = "string"
1688 | description = "Comma delimited list of origin IP addresses - Example: [\\\"192.0.2.1\\\",\\\"198.51.100.1\\\",\\\"2001:DB8:100::CF\\\"]"
1689 | required = true
1690 | [[command.option]]
1691 | name = "minimum-cache-ttl"
1692 | type = "int"
1693 | description = "Minimum DNS Cache TTL. default value: 60, min value:30, max value:36000"
1694 | required = false
1695 | [[command.option]]
1696 | name = "maximum-cache-ttl"
1697 | type = "int"
1698 | description = "Maximum DNS Cache TTL. default value: 900, min value:30, max value:36000"
1699 | required = false
1700 | [[command.option]]
1701 | name = "deprecate-any-request"
1702 | type = "bool"
1703 | description = "Deprecate the response to ANY requests"
1704 | required = false
1705 |
1706 | [[command]]
1707 | name = "update-virtual-dns"
1708 | description = """Update a virtual dns cluster"""
1709 | shortdescription = "Update a virtual dns cluster"
1710 | v4apiname = "UpdateVirtualDNS"
1711 | [[command.option]]
1712 | name = "virtual-dns-id"
1713 | type = "string"
1714 | description = "The virtual DNS id being modified"
1715 | required = true
1716 | [[command.option]]
1717 | name = "origin-ips"
1718 | type = "string"
1719 | description = "Comma delimited list of origin IP addresses - Example: [\\\"192.0.2.1\\\",\\\"198.51.100.1\\\",\\\"2001:DB8:100::CF\\\"]"
1720 | required = false
1721 | [[command.option]]
1722 | name = "minimum-cache-ttl"
1723 | type = "int"
1724 | description = "Minimum DNS Cache TTL. default value: 60, min value:30, max value:36000"
1725 | required = false
1726 | [[command.option]]
1727 | name = "maximum-cache-ttl"
1728 | type = "int"
1729 | description = "Maximum DNS Cache TTL. default value: 900, min value:30, max value:36000"
1730 | required = false
1731 | [[command.option]]
1732 | name = "deprecate-any-request"
1733 | type = "bool"
1734 | description = "Deprecate the response to ANY requests"
1735 | required = false
1736 |
1737 | [[command]]
1738 | name = "create-pagerule"
1739 | description = """Create a new page rule associated with a zone"""
1740 | shortdescription = "Create a new page rule"
1741 | v4apiname = "CreatePageRule"
1742 | [[command.option]]
1743 | name = "zone-id"
1744 | type = "string"
1745 | description = "The zone id associated with the new page rule"
1746 | required = true
1747 | [[command.option]]
1748 | name = "targets"
1749 | type = "string"
1750 | description = "List of page rule targets. Examples: '[{\\\"target\\\": \\\"url\\\",\\\"constraint\\\": {\\\"operator\\\": \\\"matches\\\",\\\"value\\\": \\\"*example.com/images/*\\\"}}]'"
1751 | required = true
1752 | [[command.option]]
1753 | name = "actions"
1754 | type = "string"
1755 | description = "List of page rule actions. Examples: '[{\\\"id\\\": \\\"always_online\\\",\\\"value\\\": \\\"on\\\"}]'"
1756 | required = true
1757 | [[command.option]]
1758 | name = "priority"
1759 | type = "int"
1760 | description = "A number that indicates the preference for a page rule over another. default value: 1"
1761 | required = false
1762 | [[command.option]]
1763 | name = "status"
1764 | type = "string"
1765 | description = "Status of the page rule. default value: disabled valid values: active, disabled required = false"
1766 | required = true
1767 |
1768 | [[command]]
1769 | name = "update-pagerule"
1770 | description = """Update a new page rule associated with a zone and page rule"""
1771 | shortdescription = "Update a new page rule"
1772 | v4apiname = "ChangePageRule"
1773 | [[command.option]]
1774 | name = "zone-id"
1775 | type = "string"
1776 | description = "The zone id associated with the updated page rule"
1777 | required = true
1778 | [[command.option]]
1779 | name = "pagerule-id"
1780 | type = "string"
1781 | description = "The pagerule id associated with the updated page rule"
1782 | required = true
1783 | [[command.option]]
1784 | name = "targets"
1785 | type = "string"
1786 | description = "List of page rule targets. Examples: '[{\\\"target\\\": \\\"url\\\",\\\"constraint\\\": {\\\"operator\\\": \\\"matches\\\",\\\"value\\\": \\\"*example.com/images/*\\\"}}]'"
1787 | required = true
1788 | [[command.option]]
1789 | name = "actions"
1790 | type = "string"
1791 | description = "List of page rule actions. Examples: '[{\\\"id\\\": \\\"always_online\\\",\\\"value\\\": \\\"on\\\"}]'"
1792 | required = true
1793 | [[command.option]]
1794 | name = "priority"
1795 | type = "int"
1796 | description = "A number that indicates the preference for a page rule over another. default value: 1"
1797 | required = false
1798 | [[command.option]]
1799 | name = "status"
1800 | type = "string"
1801 | description = "Status of the page rule. default value: disabled valid values: active, disabled required = false"
1802 | required = true
1803 |
1804 | [[command]]
1805 | name = "create-organization-access-rule"
1806 | description = """Make a new IP, IP range, or country access rule for all zones owned by the organization. Note: If you would like to create an access rule that applies to a specific zone only, use the zone firewall endpoints."""
1807 | shortdescription = "Create an organization access rule"
1808 | v4apiname = "CreateOrganizationAccessRule"
1809 | [[command.option]]
1810 | name = "organization-id"
1811 | type = "string"
1812 | description = "The organization id associated with the new access rule"
1813 | required = true
1814 | [[command.option]]
1815 | name = "mode"
1816 | type = "string"
1817 | description = "The action to apply to a matched request valid values: block, challenge, whitelist, js_challenge"
1818 | required = true
1819 | [[command.option]]
1820 | name = "configuration"
1821 | type = "string"
1822 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
1823 | required = true
1824 | [[command.option]]
1825 | name = "notes"
1826 | type = "string"
1827 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
1828 | required = false
1829 |
1830 | [[command]]
1831 | name = "create-origin-cert"
1832 | description = """Create a Cloudflare-signed certificate."""
1833 | shortdescription = "Create a Cloudflare-signed certificate"
1834 | v4apiname = "CreateOriginCertificate"
1835 | [[command.option]]
1836 | name = "hostnames"
1837 | type = "string"
1838 | description = "Comma-delimited list of hostnames or wildcard names (e.g., *.example.com) bound to the certificate"
1839 | required = true
1840 | [[command.option]]
1841 | name = "request-validity"
1842 | type = "int"
1843 | description = "The number of days for which the certificate should be valid. default value: 5475, valid values: 7, 30, 90, 365, 730, 1095, 5475"
1844 | required = true
1845 | [[command.option]]
1846 | name = "request-type"
1847 | type = "string"
1848 | description = "Signature type desired on certificate (\\\"origin-rsa\\\" (rsa), \\\"origin-ecc\\\" (ecdsa), or \\\"keyless-certificate\\\" (for Keyless SSL servers) valid values: origin-rsa, origin-ecc, keyless-certificate"
1849 | required = true
1850 | [[command.option]]
1851 | name = "csr"
1852 | type = "string"
1853 | description = "The Certificate Signing Request (CSR). Must be newline-encoded. -----BEGIN CERTIFICATE REQUEST-----\\nMIICxzCCA...\\n-----END CERTIFICATE REQUEST-----"
1854 | required = true
1855 |
1856 | [[command]]
1857 | name = "create-ratelimit"
1858 | description = """Create a new rate limit for a zone. See the record object definitions for required attributes for each record type"""
1859 | shortdescription = "Creates a new rate limit for a zone."
1860 | v4apiname = "CreateRateLimit"
1861 | [[command.option]]
1862 | name = "zone-id"
1863 | type = "string"
1864 | description = "The zone id associated with the newly created ratelimit"
1865 | required = true
1866 | [[command.option]]
1867 | name = "match"
1868 | type = "string"
1869 | description = "The match object described by https://api.cloudflare.com/#rate-limits-for-a-zone-create-rate-limit"
1870 | required = true
1871 | [[command.option]]
1872 | name = "threshold"
1873 | type = "int"
1874 | description = "The threshold that triggers the rate limit mitigations, combine with period. i.e. threshold per period min value:2 max value:1000000"
1875 | required = true
1876 | [[command.option]]
1877 | name = "period"
1878 | type = "int"
1879 | description = "The time in seconds to count matching traffic. If the count exceeds threshold within this period the action will be performed. min value:1 max value:86400"
1880 | required = true
1881 | [[command.option]]
1882 | name = "action"
1883 | type = "string"
1884 | description = "The action to be performed when the threshold of matched traffic within the period defined is exceeded '{\\\"mode\\\": \\\"challenge\\\",\\\"timeout\\\": 86400,\\\"response\\\": {\\\"content_type\\\": \\\"text/xml\\\",\\\"body\\\": \\\"This request has been rate-limited.\\\"}}'"
1885 | required = true
1886 | [[command.option]]
1887 | name = "enabled"
1888 | type = "bool"
1889 | description = "Whether this ratelimit is currently enabled or not."
1890 | required = false
1891 | [[command.option]]
1892 | name = "description"
1893 | type = "string"
1894 | description = "A note that you can use to describe the reason for a rate limit. This value is sanitized and all tags are removed max length: 1024"
1895 | required = false
1896 | [[command.option]]
1897 | name = "bypass"
1898 | type = "string"
1899 | description = "Criteria that would allow the rate limit to be bypassed, for example to express that you shouldn't apply a rate limit to a given set of URLs '[{\\\"name\\\": \\\"url\\\",\\\"value\\\": \\\"api.example.com/*\\\"}]'"
1900 | required = false
1901 |
1902 | [[command]]
1903 | name = "update-ratelimit"
1904 | description = """Update a specific rate limit."""
1905 | shortdescription = "Update a rate limit for a zone."
1906 | v4apiname = "UpdateRateLimit"
1907 | [[command.option]]
1908 | name = "zone-id"
1909 | type = "string"
1910 | description = "The zone id associated with the newly created ratelimit"
1911 | required = true
1912 | [[command.option]]
1913 | name = "limit-id"
1914 | type = "string"
1915 | description = "The ratelimit id associated with the newly created ratelimit"
1916 | required = true
1917 | [[command.option]]
1918 | name = "match"
1919 | type = "string"
1920 | description = "The match object described by https://api.cloudflare.com/#rate-limits-for-a-zone-create-rate-limit"
1921 | required = true
1922 | [[command.option]]
1923 | name = "threshold"
1924 | type = "int"
1925 | description = "The threshold that triggers the rate limit mitigations, combine with period. i.e. threshold per period min value:2 max value:1000000"
1926 | required = true
1927 | [[command.option]]
1928 | name = "period"
1929 | type = "int"
1930 | description = "The time in seconds to count matching traffic. If the count exceeds threshold within this period the action will be performed. min value:1 max value:86400"
1931 | required = true
1932 | [[command.option]]
1933 | name = "action"
1934 | type = "string"
1935 | description = "The action to be performed when the threshold of matched traffic within the period defined is exceeded '{\\\"mode\\\": \\\"challenge\\\",\\\"timeout\\\": 86400,\\\"response\\\": {\\\"content_type\\\": \\\"text/xml\\\",\\\"body\\\": \\\"This request has been rate-limited.\\\"}}'"
1936 | required = true
1937 | [[command.option]]
1938 | name = "enabled"
1939 | type = "bool"
1940 | description = "Whether this ratelimit is currently enabled or not."
1941 | required = false
1942 | [[command.option]]
1943 | name = "description"
1944 | type = "string"
1945 | description = "A note that you can use to describe the reason for a rate limit. This value is sanitized and all tags are removed max length: 1024"
1946 | required = false
1947 | [[command.option]]
1948 | name = "bypass"
1949 | type = "string"
1950 | description = "Criteria that would allow the rate limit to be bypassed, for example to express that you shouldn't apply a rate limit to a given set of URLs '[{\\\"name\\\": \\\"url\\\",\\\"value\\\": \\\"api.example.com/*\\\"}]'"
1951 | required = false
1952 |
1953 | [[command]]
1954 | name = "create-user-access-rule"
1955 | description = """Make a new IP, IP range, or country access rule for all zones owned by the user. Note: If you would like to create an access rule that applies to a specific zone only, use the zone firewall endpoints."""
1956 | shortdescription = "Create a user access rule"
1957 | v4apiname = "CreateUserAccessRule"
1958 | [[command.option]]
1959 | name = "mode"
1960 | type = "string"
1961 | description = "The action to apply to a matched request valid values: block, challenge, whitelist, js_challenge"
1962 | required = true
1963 | [[command.option]]
1964 | name = "configuration"
1965 | type = "string"
1966 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
1967 | required = true
1968 | [[command.option]]
1969 | name = "notes"
1970 | type = "string"
1971 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
1972 | required = false
1973 |
1974 | [[command]]
1975 | name = "update-user-access-rule"
1976 | description = """Update an IP, IP range, or country access rule for all zones owned by the user. Note: If you would like to create an access rule that applies to a specific zone only, use the zone firewall endpoints."""
1977 | shortdescription = "Create a user access rule"
1978 | v4apiname = "UpdateUserAccessRule"
1979 | [[command.option]]
1980 | name = "access-rule-id"
1981 | type = "string"
1982 | description = "The access rule id associated with the rule being updated"
1983 | required = true
1984 | [[command.option]]
1985 | name = "mode"
1986 | type = "string"
1987 | description = "The action to apply to a matched request valid values: block, challenge, whitelist, js_challenge"
1988 | required = true
1989 | [[command.option]]
1990 | name = "configuration"
1991 | type = "string"
1992 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
1993 | required = true
1994 | [[command.option]]
1995 | name = "notes"
1996 | type = "string"
1997 | description = "Set the access rule's human readable note"
1998 | required = false
1999 |
2000 | [[command]]
2001 | name = "update-zone-access-rule"
2002 | description = """Update an IP, IP range, or country access rule for all zones owned by the user. Note: If you would like to create an access rule that applies to a specific zone only, use the zone firewall endpoints."""
2003 | shortdescription = "Create a user access rule"
2004 | v4apiname = "UpdateZoneAccessRule"
2005 | [[command.option]]
2006 | name = "zone-id"
2007 | description = "The zone id associated with the rule being updated"
2008 | type = "string"
2009 | required = true
2010 | [[command.option]]
2011 | name = "access-rule-id"
2012 | type = "string"
2013 | description = "The access rule id associated with the rule being updated"
2014 | required = true
2015 | [[command.option]]
2016 | name = "mode"
2017 | type = "string"
2018 | description = "The action to apply to a matched request valid values: block, challenge, whitelist, js_challenge"
2019 | required = true
2020 | [[command.option]]
2021 | name = "configuration"
2022 | type = "string"
2023 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
2024 | required = true
2025 | [[command.option]]
2026 | name = "notes"
2027 | type = "string"
2028 | description = "Set the access rule's human readable note"
2029 | required = false
2030 |
2031 | [[command]]
2032 | name = "update-organization-access-rule"
2033 | description = """Update an IP, IP range, or country access rule for all zones owned by the user. Note: If you would like to create an access rule that applies to a specific zone only, use the zone firewall endpoints."""
2034 | shortdescription = "Create a user access rule"
2035 | v4apiname = "UpdateOrganizationAccessRule"
2036 | [[command.option]]
2037 | name = "organization-id"
2038 | description = "The organization id associated with the rule being updated"
2039 | type = "string"
2040 | required = true
2041 | [[command.option]]
2042 | name = "access-rule-id"
2043 | type = "string"
2044 | description = "The access rule id associated with the rule being updated"
2045 | required = true
2046 | [[command.option]]
2047 | name = "mode"
2048 | type = "string"
2049 | description = "The action to apply to a matched request valid values: block, challenge, whitelist, js_challenge"
2050 | required = true
2051 | [[command.option]]
2052 | name = "configuration"
2053 | type = "string"
2054 | description = "Rule configuration. Example {\\\"target\\\": \\\"ip\\\",\\\"value\\\": \\\"198.51.100.4\\\"}"
2055 | required = true
2056 | [[command.option]]
2057 | name = "notes"
2058 | type = "string"
2059 | description = "Set the access rule's human readable note"
2060 | required = false
2061 |
2062 | [[command]]
2063 | name = "list-zone-access-rules"
2064 | description = """Returns all access rules associated with the zone"""
2065 | shortdescription = "List Zone Access Rules"
2066 | v4apiname = "ListZoneAccessRules"
2067 | [[command.option]]
2068 | name = "zone-id"
2069 | type = "string"
2070 | description = "The zone ID associated with the access rule"
2071 | required = true
2072 | [[command.option]]
2073 | name = "notes"
2074 | type = "string"
2075 | description = "Matching any string within previously created access rules with the notes"
2076 | required = false
2077 | [[command.option]]
2078 | name = "mode"
2079 | type = "string"
2080 | description = "valid values: block, challenge, whitelist, js_challenge"
2081 | required = false
2082 | [[command.option]]
2083 | name = "page"
2084 | type = "int"
2085 | description = "Requested page within paginated list of results"
2086 | required = false
2087 |
2088 | [[command]]
2089 | name = "upload-custom-cert"
2090 | description = """Upload a new SSL certificate for a zone"""
2091 | shortdescription = "Upload a custom SSL cert"
2092 | v4apiname = "CreateSSL"
2093 | [[command.option]]
2094 | name = "zone-id"
2095 | type = "string"
2096 | description = "The zone-id associated with the custom cert"
2097 | required = true
2098 | [[command.option]]
2099 | name = "certificate"
2100 | type = "string"
2101 | description = "The zone's SSL certificate or certificate and the intermediate(s)"
2102 | required = true
2103 | [[command.option]]
2104 | name = "private-key"
2105 | type = "string"
2106 | description = "The zone's private key. Example -----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----"
2107 | required = true
2108 | [[command.option]]
2109 | name = "bundle-method"
2110 | type = "string"
2111 | description = "A ubiquitous bundle is a bundle that has a higher probability of being verified everywhere, even by clients using outdated or unusual trust stores. default value: ubiquitous; valid values: ubiquitous, optimal, force required = false"
2112 |
2113 | [[command]]
2114 | name = "update-custom-cert"
2115 | description = """Update a new SSL certificate for a zone"""
2116 | shortdescription = "Upload a custom SSL cert"
2117 | v4apiname = "UpdateSSL"
2118 | [[command.option]]
2119 | name = "zone-id"
2120 | type = "string"
2121 | description = "The zone-id associated with the custom cert"
2122 | required = true
2123 | [[command.option]]
2124 | name = "certificate-id"
2125 | type = "string"
2126 | description = "The certificate id associated with the custom cert"
2127 | required = true
2128 | [[command.option]]
2129 | name = "certificate"
2130 | type = "string"
2131 | description = "The zone's SSL certificate or certificate and the intermediate(s)"
2132 | required = true
2133 | [[command.option]]
2134 | name = "private-key"
2135 | type = "string"
2136 | description = "The zone's private key. Example -----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----"
2137 | required = true
2138 | [[command.option]]
2139 | name = "bundle-method"
2140 | type = "string"
2141 | description = "A ubiquitous bundle is a bundle that has a higher probability of being verified everywhere, even by clients using outdated or unusual trust stores. default value: ubiquitous; valid values: ubiquitous, optimal, force required = false"
2142 |
2143 | [[command]]
2144 | name = "purge"
2145 | description = """Purge specific items in the cache"""
2146 | shortdescription = "Purge specific items"
2147 | v4apiname = "Purge"
2148 | [[command.option]]
2149 | name = "zone-id"
2150 | type = "string"
2151 | description = "The zone ID that will be purged."
2152 | required = true
2153 | [[command.option]]
2154 | name = "files"
2155 | type = "string"
2156 | description = "The files that will be purged."
2157 | required = false
2158 | [[command.option]]
2159 | name = "tags"
2160 | type = "string"
2161 | description = "The tags that will be purged."
2162 | required = false
2163 | [[command.option]]
2164 | name = "hosts"
2165 | type = "string"
2166 | description = "The hosts that will be purged."
2167 | required = false
2168 |
2169 | [[command]]
2170 | name = "create-user-agent-rule"
2171 | description = """Creates a new User-Agent rule for a specific zone"""
2172 | shortdescription = "Creates a new User-Agent rule"
2173 | v4apiname = "CreateUserAgentRule"
2174 | [[command.option]]
2175 | name = "zone-id"
2176 | type = "string"
2177 | description = "The zone ID associated with the user-agent rule."
2178 | required = true
2179 | [[command.option]]
2180 | name = "mode"
2181 | type = "string"
2182 | description = "The type of action to perform. max length: 12 valid values: block, challenge, js_challenge"
2183 | required = true
2184 | [[command.option]]
2185 | name = "configuration"
2186 | type = "string"
2187 | description = "Target/Value pair to use for this rule. The value is the exact UserAgent to match {\\\"target\\\": \\\"ua\\\", \\\"value\\\": \\\"Mozilla/5.0\\\"}"
2188 | required = true
2189 | [[command.option]]
2190 | name = "description"
2191 | type = "string"
2192 | description = "Some useful information about this rule to help identify the purpose of it."
2193 | required = false
2194 | [[command.option]]
2195 | name = "paused"
2196 | type = "bool"
2197 | description = "Whether this UA rule is currently paused"
2198 | required = false
2199 |
2200 | [[command]]
2201 | name = "update-user-agent-rule"
2202 | description = """Updates a new User-Agent rule for a specific zone"""
2203 | shortdescription = "Updates a new User-Agent rule"
2204 | v4apiname = "UpdateUserAgentRule"
2205 | [[command.option]]
2206 | name = "zone-id"
2207 | type = "string"
2208 | description = "The zone ID associated with the user-agent rule."
2209 | required = true
2210 | [[command.option]]
2211 | name = "user-agent-id"
2212 | type = "string"
2213 | description = "The user agent ID associated with the user-agent rule."
2214 | required = true
2215 | [[command.option]]
2216 | name = "mode"
2217 | type = "string"
2218 | description = "The type of action to perform. max length: 12 valid values: block, challenge, js_challenge"
2219 | required = true
2220 | [[command.option]]
2221 | name = "configuration"
2222 | type = "string"
2223 | description = "Target/Value pair to use for this rule. The value is the exact UserAgent to match {\\\"target\\\": \\\"ua\\\", \\\"value\\\": \\\"Mozilla/5.0\\\"}"
2224 | required = true
2225 | [[command.option]]
2226 | name = "description"
2227 | type = "string"
2228 | description = "Some useful information about this rule to help identify the purpose of it."
2229 | required = false
2230 | [[command.option]]
2231 | name = "paused"
2232 | type = "bool"
2233 | description = "Whether this UA rule is currently paused"
2234 | required = false
2235 |
2236 | [[command]]
2237 | name = "update-custom-hostname"
2238 | description = """Modify SSL configuration for a custom hostname. When sent with SSL config that matches existing config, used to indicate that hostname should pass domain control validation (DCV). Can also be used to change validation type, e.g., from 'http' to 'email'."""
2239 | shortdescription = "Create a custom hostname for an associated zone."
2240 | v4apiname = "UpdateCustomHostnameSSL"
2241 | [[command.option]]
2242 | name = "zone-id"
2243 | type = "string"
2244 | description = "The zone ID associated with the custom hostname"
2245 | required = true
2246 | [[command.option]]
2247 | name = "custom-hostname-id"
2248 | type = "string"
2249 | description = "The custom hostname id associated with the custom hostname being modified"
2250 | required = true
2251 | [[command.option]]
2252 | name = "method"
2253 | type = "string"
2254 | description = "The SSL Verification method. valid values: http, email, cname."
2255 | required = true
2256 | [[command.option]]
2257 | name = "type"
2258 | type = "string"
2259 | description = "The type of SSL certificate valid values: dv only"
2260 | required = true
2261 |
2262 |
2263 | [[command]]
2264 | name = "list-custom-hostnames"
2265 | description = """List Custom Hostnames fetches custom hostnames for the given zone, by applying filter.Hostname if not empty and scoping the result to page'th 50 items."""
2266 | shortdescription = "List custom hostnames"
2267 | v4apiname = "CustomHostnames"
2268 | [[command.option]]
2269 | name = "zone-id"
2270 | type = "string"
2271 | description = "The zone ID associated with the custom hostname"
2272 | required = true
2273 | [[command.option]]
2274 | name = "hostname"
2275 | type = "string"
2276 | description = "The custom hostname that you wish to filter by"
2277 | required = false
2278 | [[command.option]]
2279 | name = "page"
2280 | type = "int"
2281 | description = "API supports pagination. Up to 50 results per page. Default is page 1"
2282 | required = false
2283 |
2284 | [[command]]
2285 | name = "reprioritize-certs"
2286 | description = """If a zone has multiple SSL certificates, you can set the order in which they should be used during a request. Higher priority numbers will be tried first."""
2287 | shortdescription = "Reprioritize SSL certs"
2288 | v4apiname = "ReprioritizeSSL"
2289 | [[command.option]]
2290 | name = "zone-id"
2291 | type = "string"
2292 | description = "The zone ID associated with the certs"
2293 | required = true
2294 | [[command.option]]
2295 | name = "priority-list"
2296 | description = "Array of ordered certificates. [{\\\"id\\\": \\\"5a7805061c76ada191ed06f989cc3dac\\\",\\\"priority\\\": 2},{\\\"id\\\": \\\"9a7806061c88ada191ed06f989cc3dac\\\",\\\"priority\\\": 1}]"
2297 | type = "string"
2298 | required = true
2299 |
2300 | [[command]]
2301 | name = "update-loadbalancer-monitor"
2302 | description = """Update an existing monitor"""
2303 | shortdescription = "Update a configured monitor"
2304 | v4apiname = "ModifyLoadBalancerMonitor"
2305 | [[command.option]]
2306 | name = "monitor-id"
2307 | type = "string"
2308 | description = "The monitor id associated with the existing loadbalancer monitor"
2309 | required = true
2310 | [[command.option]]
2311 | name = "expected-codes"
2312 | type = "string"
2313 | description = "The expected http response code in the healthcheck"
2314 | required = true
2315 | [[command.option]]
2316 | name = "method"
2317 | type = "string"
2318 | description = "The HTTP method to use for the health check. default value: GET"
2319 | required = false
2320 | [[command.option]]
2321 | name = "header"
2322 | type = "string"
2323 | description = "The HTTP request headers to send in the health check. It is recommended you set a Host header by default. The User-Agent header cannot be overridden. Example: {\\\"Host\\\": [\\\"example.com\\\"],\\\"X-App-ID\\\": [\\\"abc123\\\"]}"
2324 | required = false
2325 | [[command.option]]
2326 | name = "timeout"
2327 | type = "int"
2328 | description = "The timeout (in seconds) before marking the health check as failed. default value: 5"
2329 | required = true
2330 | [[command.option]]
2331 | name = "path"
2332 | type = "string"
2333 | description = "The endpoint path to health check against. default value: /"
2334 | required = true
2335 | [[command.option]]
2336 | name = "interval"
2337 | type = "int"
2338 | description = "The interval between each health check. Shorter intervals may improve failover time, but will increase load. default value 60"
2339 | required = true
2340 | [[command.option]]
2341 | name = "retries"
2342 | type = "int"
2343 | description = "The number of retries to attempt in case of a timeout before marking the origin as unhealthy. default value 2"
2344 | required = true
2345 | [[command.option]]
2346 | name = "expected-body"
2347 | type = "string"
2348 | description = "A case-insensitive sub-string to look for in the response body. If this string is not found, the origin will be marked as unhealthy."
2349 | required = false
2350 | [[command.option]]
2351 | name = "type"
2352 | type = "string"
2353 | description = "The protocol to use for the healthcheck. Currently supported protocols are 'HTTP' and 'HTTPS'. default value: http"
2354 | required = true
2355 | [[command.option]]
2356 | name = "description"
2357 | type = "string"
2358 | description = "Object description"
2359 | required = true
2360 |
2361 | [[command]]
2362 | name = "update-loadbalancer"
2363 | description = """Update an existing loadbalancer"""
2364 | shortdescription = "Update an existing loadbalancer"
2365 | v4apiname = "ModifyLoadBalancer"
2366 | [[command.option]]
2367 | name = "zone-id"
2368 | type = "string"
2369 | description = "The zoneID associated with the loadbalancer"
2370 | required = true
2371 | [[command.option]]
2372 | name = "loadbalancer-id"
2373 | type = "string"
2374 | description = "The loadbalancer id associated with the loadbalancer being modified"
2375 | required = true
2376 | [[command.option]]
2377 | name = "name"
2378 | type = "string"
2379 | description = "The DNS hostname to associate with your Load Balancer. If this hostname already exists as a DNS record in Cloudflare's DNS, the Load Balancer will take precedence and the DNS record will not be used."
2380 | required = true
2381 | [[command.option]]
2382 | name = "fallback-pool"
2383 | type = "string"
2384 | description = "The pool ID to use when all other pools are detected as unhealthy. max length: 32"
2385 | required = true
2386 | [[command.option]]
2387 | name = "default-pools"
2388 | type = "string"
2389 | description = "A comma separated list of pool IDs ordered by their failover priority. Pools defined here are used by default, or when region_pools are not configured for a given region."
2390 | required = true
2391 | [[command.option]]
2392 | name = "proxied"
2393 | type = "bool"
2394 | description = "Whether the hostname should be gray clouded (false) or orange clouded (true). default value: false"
2395 | required = false
2396 | [[command.option]]
2397 | name = "ttl"
2398 | type = "int"
2399 | description = "Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This only applies to gray-clouded (unproxied) load balancers."
2400 | required = false
2401 |
2402 | [[command]]
2403 | name = "create-worker-route"
2404 | description = """Create a new Edge Worker Route Filter"""
2405 | shortdescription = "Create Worker Router"
2406 | v4apiname = "CreateWorkerRoute"
2407 | [[command.option]]
2408 | name = "zone-id"
2409 | type = "string"
2410 | description = "The zoneID associated with the worker route"
2411 | required = true
2412 | [[command.option]]
2413 | name = "pattern"
2414 | type = "string"
2415 | description = "The url pattern for the route, example: example.net/*"
2416 | required = true
2417 | [[command.option]]
2418 | name = "disable"
2419 | type = "bool"
2420 | description = "Set this flag to disable the worker on a given route"
2421 | required = false
2422 |
2423 | [[command]]
2424 | name = "update-worker-route"
2425 | description = """Create a new Edge Worker Route Filter"""
2426 | shortdescription = "Update Worker Route Filter"
2427 | v4apiname = "UpdateWorkerRoute"
2428 | [[command.option]]
2429 | name = "zone-id"
2430 | type = "string"
2431 | description = "The zoneID associated with the worker route"
2432 | required = true
2433 | [[command.option]]
2434 | name = "route-id"
2435 | type = "string"
2436 | description = "The routeId associated with the worker route"
2437 | required = true
2438 | [[command.option]]
2439 | name = "pattern"
2440 | type = "string"
2441 | description = "The url pattern for the route, example: example.net/*"
2442 | required = true
2443 | [[command.option]]
2444 | name = "disable"
2445 | type = "bool"
2446 | description = "Set this flag to disable the worker on a given route"
2447 | required = false
2448 |
2449 | [[command]]
2450 | name = "list-worker-routes"
2451 | description = """List all a new Edge Worker Route Filter"""
2452 | shortdescription = "List Worker Route Filters"
2453 | v4apiname = "ListWorkerRoutes"
2454 | [[command.option]]
2455 | name = "zone-id"
2456 | type = "string"
2457 | description = "The zoneID associated with the worker route filters"
2458 | required = true
2459 |
2460 | [[command]]
2461 | name = "upload-worker"
2462 | description = """Upload a cloudflare worker for your zone"""
2463 | shortdescription = "Upload a Cloudflare Worker for your zone"
2464 | v4apiname = "UploadWorker"
2465 | [[command.option]]
2466 | name = "zone-id"
2467 | type = "string"
2468 | description = "The zoneID associated with the worker"
2469 | required = true
2470 | [[command.option]]
2471 | name = "script"
2472 | type = "string"
2473 | description = "The raw worker code to run at the edge. @ to read code from a file. - to read from stdin"
2474 | required = true
2475 | [[command.option]]
2476 | name = "script-name"
2477 | type = "string"
2478 | description = "The worker script name associated with the worker"
2479 | required = false
2480 |
2481 | [[command]]
2482 | name = "upload-organization-worker"
2483 | description = """Upload an organization's cloudflare worker"""
2484 | shortdescription = "Upload a Cloudflare Worker associated with your Organization"
2485 | v4apiname = "UploadOrganizationWorker"
2486 | [[command.option]]
2487 | name = "zone-id"
2488 | type = "string"
2489 | description = "The zoneID associated with the worker"
2490 | required = false
2491 | [[command.option]]
2492 | name = "organization-id"
2493 | type = "string"
2494 | description = "The organization id associated with the worker"
2495 | required = true
2496 | [[command.option]]
2497 | name = "name"
2498 | type = "string"
2499 | description = "The worker's name"
2500 | required = true
2501 | [[command.option]]
2502 | name = "script"
2503 | type = "string"
2504 | description = "The raw worker code to run at the edge. @ to read code from a file. - to read from stdin"
2505 | required = true
2506 |
2507 | [[command]]
2508 | name = "delete-worker"
2509 | description = """Delete a cloudflare worker"""
2510 | shortdescription = "Delete Worker"
2511 | v4apiname = "DeleteWorker"
2512 | [[command.option]]
2513 | name = "zone-id"
2514 | type = "string"
2515 | description = "The zoneID associated with the worker"
2516 | required = true
2517 |
2518 | [[command]]
2519 | name = "delete-organization-worker"
2520 | description = """Delete an organization's cloudflare worker"""
2521 | shortdescription = "Delete Organization Worker"
2522 | v4apiname = "DeleteOrganizationWorker"
2523 | [[command.option]]
2524 | name = "organization-id"
2525 | type = "string"
2526 | description = "The organization id associated with the worker"
2527 | required = true
2528 | [[command.option]]
2529 | name = "name"
2530 | type = "string"
2531 | description = "The worker's name"
2532 | required = true
2533 |
2534 | [[command]]
2535 | name = "list-worker-scripts"
2536 | description = """List your cloudflare worker scripts"""
2537 | shortdescription = "List your worker scripts"
2538 | v4apiname = "ListWorkerScripts"
2539 | [[command.option]]
2540 | name = "organization-id"
2541 | type = "string"
2542 | description = "The organization id associated with the workers"
2543 | required = true
2544 |
2545 | [[command]]
2546 | name = "download-worker"
2547 | description = """Download your cloudflare worker script"""
2548 | shortdescription = "Download your worker script"
2549 | v4apiname = "DownloadWorker"
2550 | [[command.option]]
2551 | name = "zone-id"
2552 | type = "string"
2553 | description = "The zone id associated with the workers"
2554 | required = true
2555 |
2556 | [[command]]
2557 | name = "download-organization-worker"
2558 | description = """Download a worker associated with your organization"""
2559 | shortdescription = "Download your worker script"
2560 | v4apiname = "DownloadOrganizationWorker"
2561 | [[command.option]]
2562 | name = "organization-id"
2563 | type = "string"
2564 | description = "The organization id associated with the workers"
2565 | required = true
2566 | [[command.option]]
2567 | name = "name"
2568 | type = "string"
2569 | description = "The worker's name"
2570 | required = true
2571 |
2572 | [[command]]
2573 | name = "get-organization-audit-logs"
2574 | description = """Get an organization's audit logs"""
2575 | shortdescription = "Get Organization audit logs"
2576 | v4apiname = "GetOrganizationAuditLogs"
2577 | [[command.option]]
2578 | name = "organization-id"
2579 | type = "string"
2580 | description = "The organization id associated with audit logs you wish to read"
2581 | required = true
2582 |
2583 | [[command]]
2584 | name = "get-user-audit-logs"
2585 | description = """Get a user's audit logs"""
2586 | shortdescription = "Get audit logs associated with a user"
2587 | v4apiname = "GetUserAuditLogs"
2588 | [[command.option]]
2589 | name = "actor-ip"
2590 | type = "string"
2591 | description = "Filter to search by a specific actor ip"
2592 | required = false
2593 | [[command.option]]
2594 | name = "actor-email"
2595 | type = "string"
2596 | description = "Filter by the email address of the actor that made the change 'alice@example.com'"
2597 | required = false
2598 | [[command.option]]
2599 | name = "zone-name"
2600 | type = "string"
2601 | description = "Filter by the name of the zone associated to the change"
2602 | required = false
2603 | [[command.option]]
2604 | name = "since"
2605 | type = "string"
2606 | description = "Limit the returned results to logs newer than the specified date '2017-04-28'"
2607 | required = false
2608 | [[command.option]]
2609 | name = "id"
2610 | type = "string"
2611 | description = "Find a specific log by its ID. Example: 'f174be97-19b1-40d6-954d-70cd5fbd52db'"
2612 | required = false
2613 | [[command.option]]
2614 | name = "direction"
2615 | type = "string"
2616 | description = "Change the direction of the chronological sorting. Must be: 'asc' or 'desc'"
2617 | required = false
2618 | [[command.option]]
2619 | name = "before"
2620 | type = "string"
2621 | description = "Limit the returned results to logs older than the specified date"
2622 | required = false
2623 | [[command.option]]
2624 | name = "page"
2625 | type = "int"
2626 | description = "Which page of results to return"
2627 | required = false
2628 | [[command.option]]
2629 | name = "per_page"
2630 | type = "int"
2631 | description = "How many results to return per page"
2632 | required = false
2633 |
2634 | [[command]]
2635 | name = "list-kv-namespaces"
2636 | description = """Get your account's kv namespaces"""
2637 | shortdescription = "Get account's kv namespaces"
2638 | v4apiname = "ListWorkersKVNamespaces"
2639 | [[command.option]]
2640 | name = "organization-id"
2641 | type = "string"
2642 | description = "The user's organization id"
2643 | required = true
2644 |
2645 | [[command]]
2646 | name = "delete-kv-namespace"
2647 | description = """Get your account's kv namespaces"""
2648 | shortdescription = "Get account's kv namespaces"
2649 | v4apiname = "DeleteWorkersKVNamespace"
2650 | [[command.option]]
2651 | name = "organization-id"
2652 | type = "string"
2653 | description = "The user's organization id"
2654 | required = true
2655 | [[command.option]]
2656 | name = "namespace-id"
2657 | type = "string"
2658 | description = "The namespace id associated with the kv store"
2659 | required = true
2660 |
2661 | [[command]]
2662 | name = "list-kvs"
2663 | description = """List a specific namespaces keys"""
2664 | shortdescription = "List a specific namespaces keys"
2665 | v4apiname = "ListWorkersKVs"
2666 | [[command.option]]
2667 | name = "organization-id"
2668 | type = "string"
2669 | description = "The user's organization id"
2670 | required = true
2671 | [[command.option]]
2672 | name = "namespace-id"
2673 | type = "string"
2674 | description = "The namespace id associated with the kv store"
2675 | required = true
2676 |
2677 | [[command]]
2678 | name = "get-kv"
2679 | description = """Get a specific value given a key"""
2680 | shortdescription = "Get a specific value given a key"
2681 | v4apiname = "ReadWorkersKV"
2682 | [[command.option]]
2683 | name = "organization-id"
2684 | type = "string"
2685 | description = "The user's organization id"
2686 | required = true
2687 | [[command.option]]
2688 | name = "namespace-id"
2689 | type = "string"
2690 | description = "The namespace id associated with the kv store"
2691 | required = true
2692 | [[command.option]]
2693 | name = "key"
2694 | type = "string"
2695 | description = "The key associated with the value you want returned"
2696 | required = true
2697 |
2698 | [[command]]
2699 | name = "delete-kv"
2700 | description = """Delete a specific key value pair"""
2701 | shortdescription = "Delete a specific key value pair"
2702 | v4apiname = "DeleteWorkersKV"
2703 | [[command.option]]
2704 | name = "organization-id"
2705 | type = "string"
2706 | description = "The user's organization id"
2707 | required = true
2708 | [[command.option]]
2709 | name = "namespace-id"
2710 | type = "string"
2711 | description = "The namespace id associated with the kv store"
2712 | required = true
2713 | [[command.option]]
2714 | name = "key"
2715 | type = "string"
2716 | description = "The key associated with the value you to deleted"
2717 | required = true
2718 |
2719 | [[command]]
2720 | name = "write-kv"
2721 | description = """Write a key value pair"""
2722 | shortdescription = "Write a key value pair"
2723 | v4apiname = "WriteWorkersKV"
2724 | [[command.option]]
2725 | name = "organization-id"
2726 | type = "string"
2727 | description = "The user's organization id"
2728 | required = true
2729 | [[command.option]]
2730 | name = "namespace-id"
2731 | type = "string"
2732 | description = "The namespace id associated with the kv store"
2733 | required = true
2734 | [[command.option]]
2735 | name = "key"
2736 | type = "string"
2737 | description = "The key associated with the kv pair"
2738 | required = true
2739 | [[command.option]]
2740 | name = "value"
2741 | type = "string"
2742 | description = "The value associated with the kv pair"
2743 | required = true
2744 |
2745 | [[command]]
2746 | name = "rename-kv-namespace"
2747 | description = """Rename kv namespace"""
2748 | shortdescription = "Rename a kv namespace"
2749 | v4apiname = "UpdateWorkersKVNamespace"
2750 | [[command.option]]
2751 | name = "organization-id"
2752 | type = "string"
2753 | description = "The user's organization id"
2754 | required = true
2755 | [[command.option]]
2756 | name = "namespace-id"
2757 | type = "string"
2758 | description = "The namespace id associated with the kv store"
2759 | required = true
2760 | [[command.option]]
2761 | name = "name"
2762 | type = "string"
2763 | description = "The namespace's new name"
2764 | required = true
2765 |
2766 | [[command]]
2767 | name = "create-kv-namespace"
2768 | description = """Create a kv namespace"""
2769 | shortdescription = "Create a kv namespace"
2770 | v4apiname = "CreateWorkersKVNamespace"
2771 | [[command.option]]
2772 | name = "organization-id"
2773 | type = "string"
2774 | description = "The user's organization id"
2775 | required = true
2776 | [[command.option]]
2777 | name = "name"
2778 | type = "string"
2779 | description = "The namespace's name"
2780 | required = true
2781 |
--------------------------------------------------------------------------------
/definitions/definitions_test.go:
--------------------------------------------------------------------------------
1 | package definitions
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestLoadConfiguration(t *testing.T) {
8 | cmds, err := LoadDefinitions("definitions.toml")
9 | if err != nil {
10 | t.Fatalf("Could not load configuration file: %s", err)
11 | }
12 | if cmds[0].Subcommands[0] == "" {
13 | t.Fatalf("Subcommand value is empty")
14 | }
15 | }
16 |
17 | func TestHyphenToCamel(t *testing.T) {
18 | l := "list-zones"
19 | out := hyphenDelimToCamel(l)
20 | if out != "ListZones" {
21 | t.Fatalf("Unexpected camelcase for list-zones: %s", out)
22 | }
23 | }
24 |
25 | func TestRunTemplate(t *testing.T) {
26 | cmds, err := LoadDefinitions("definitions.toml")
27 | if err != nil {
28 | t.Fatalf("Could not load configuration file: %s", err)
29 | }
30 | _, err = cmds[1].ToGo()
31 | if err != nil {
32 | t.Fatalf("Could not convert command to golang: %s", err)
33 | }
34 | _, err = cmds[0].ToGo()
35 | if err != nil {
36 | t.Fatalf("Could not convert command to golang: %s", err)
37 | }
38 | }
39 |
40 | func TestRunVarTemplate(t *testing.T) {
41 | cmds, err := LoadDefinitions("definitions.toml")
42 | if err != nil {
43 | t.Fatalf("Could not load configuration file: %s", err)
44 | }
45 | _, err = cmds[1].ToVariables()
46 | if err != nil {
47 | t.Fatalf("Could not convert command to golang: %s", err)
48 | }
49 | }
50 |
51 | func TestRunSwitch(t *testing.T) {
52 | cmds, err := LoadDefinitions("definitions.toml")
53 | if err != nil {
54 | t.Fatalf("Could not load configuration file: %s", err)
55 | }
56 | _, err = ToSwitch(cmds)
57 | if err != nil {
58 | t.Fatalf("Could not convert command list to switch: %s", err)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lib/.cf/credentials:
--------------------------------------------------------------------------------
1 | {
2 | "Email":"evan@twiinsen.com",
3 | "Key":"AKIAXXX"
4 | }
5 |
--------------------------------------------------------------------------------
/lib/creds.go:
--------------------------------------------------------------------------------
1 | package lib
2 |
3 | import (
4 | "encoding/json"
5 | "io/ioutil"
6 | "os"
7 | "os/user"
8 |
9 | "github.com/99designs/keyring"
10 | "github.com/segmentio/aws-okta/lib"
11 | )
12 |
13 | var (
14 | DefaultCredentialProvider = &CredProvider{}
15 | )
16 |
17 | type CredProvider struct {
18 | HomeDir string
19 | }
20 |
21 | type Credentials struct {
22 | Email string `json:"Email"`
23 | Key string `json:"Key"`
24 | UserServiceKey string `json:"UserServiceKey"`
25 | Keychain bool `json:"Keychain"`
26 | }
27 |
28 | func GetKeyring() (keyring.Keyring, error) {
29 | var allowedBackends []keyring.BackendType
30 | return keyring.Open(keyring.Config{
31 | AllowedBackends: allowedBackends,
32 | KeychainTrustApplication: true,
33 | ServiceName: "cloudflare-credentials",
34 | LibSecretCollectionName: "cloudflare",
35 | FileDir: "~/.cf/",
36 | FilePasswordFunc: func(prompt string) (string, error) {
37 | return lib.Prompt("\n"+prompt, true)
38 | },
39 | })
40 | }
41 |
42 | func GetHomeDir() (string, error) {
43 | usr, err := user.Current()
44 | if err != nil {
45 | return "", err
46 | }
47 | return usr.HomeDir, nil
48 | }
49 |
50 | func readConfigFile(homedir string) (*Credentials, error) {
51 | filename := homedir + "/.cf/credentials"
52 | buf, err := ioutil.ReadFile(filename)
53 | if err != nil {
54 | return nil, err
55 | }
56 | c := &Credentials{}
57 | err = json.Unmarshal(buf, c)
58 | return c, err
59 | }
60 |
61 | func (c *Credentials) SetEnv() {
62 | os.Setenv("CF_API_KEY", c.Key)
63 | os.Setenv("CF_API_EMAIL", c.Email)
64 | os.Setenv("CF_USER_SERVICE_KEY", c.UserServiceKey)
65 | }
66 |
67 | func isEnvSet() bool {
68 | // If we already have the cloudflare environment variables set that
69 | // are used by the cloudflare-go library then we should just return.
70 | _, keyOk := os.LookupEnv("CF_API_KEY")
71 | _, emailOk := os.LookupEnv("CF_API_EMAIL")
72 | _, serviceOk := os.LookupEnv("CF_USER_SERVICE_KEY")
73 | return keyOk || emailOk || serviceOk
74 | }
75 |
76 | func (c *CredProvider) ConfigureEnvironment() error {
77 | // Nothing to do
78 | if isEnvSet() {
79 | return nil
80 | }
81 |
82 | homedir := c.HomeDir
83 |
84 | // Otherwise, we need to read the ~/.cf/credentials file in the users
85 | // home directory. It would also be nice to store this in the keychain
86 | if c.HomeDir == "" {
87 | h, err := GetHomeDir()
88 | if err != nil {
89 | return err
90 | }
91 | homedir = h
92 | }
93 |
94 | creds, err := readConfigFile(homedir)
95 | if err != nil {
96 | return err
97 | }
98 |
99 | if creds.Keychain {
100 | kr, err := GetKeyring()
101 | if err != nil {
102 | return err
103 | }
104 | keychainCreds, err := kr.Get("cloudflare-creds")
105 | if err != nil {
106 | return err
107 | }
108 | if err = json.Unmarshal(keychainCreds.Data, &creds); err != nil {
109 | return err
110 | }
111 | }
112 |
113 | creds.SetEnv()
114 | return nil
115 | }
116 |
--------------------------------------------------------------------------------
/lib/creds_test.go:
--------------------------------------------------------------------------------
1 | package lib
2 |
3 | import (
4 | "errors"
5 | "log"
6 | "os"
7 | "strings"
8 | "testing"
9 | )
10 |
11 | func getCredDir() (string, error) {
12 | var (
13 | gopath string
14 | )
15 | if p, ok := os.LookupEnv("GOPATH"); ok {
16 | gopath = p
17 | } else {
18 | return "", errors.New("Could not find GOPATH. GOPATH must be set to test.")
19 | }
20 | return gopath + "/src/github.com/ejcx/cf/lib", nil
21 | }
22 |
23 | func TestGetHomeDir(t *testing.T) {
24 | if _, err := getHomeDir(); err != nil {
25 | t.Fatalf("Could not get home dir: %s", err)
26 | }
27 | }
28 |
29 | func TestLoadCredsFile(t *testing.T) {
30 | testPath, err := getCredDir()
31 | if err != nil {
32 | t.Fatalf("Could not load cred dir: %s", err)
33 | }
34 | credentials, err := readConfigFile(testPath)
35 | if err != nil {
36 | t.Fatalf("Could not read file %s: %s", testPath, err)
37 | }
38 | if credentials.Email == "" {
39 | t.Fatal("Unexpected test credential file result")
40 | }
41 | }
42 |
43 | func TestLoadToEnv(t *testing.T) {
44 | var (
45 | foundKey bool
46 | )
47 | testPath, err := getCredDir()
48 | if err != nil {
49 | log.Fatalf("Could not load cred dir: %s", err)
50 | }
51 | c := &CredProvider{
52 | HomeDir: testPath,
53 | }
54 | err = c.ConfigureEnvironment()
55 | if err != nil {
56 | log.Fatalf("Error while configuring env: %s", err)
57 | }
58 | env := os.Environ()
59 | for _, kv := range env {
60 | envParts := strings.Split(kv, "=")
61 | if len(envParts) != 2 {
62 | t.Fatalf("Unexpected result from env %s", kv)
63 | }
64 | if envParts[0] == "CF_API_KEY" {
65 | foundKey = true
66 | if envParts[1] != "AKIAXXX" {
67 | t.Fatalf("Unexpected value loaded from config")
68 | }
69 | }
70 | }
71 | if !foundKey {
72 | t.Fatal("Never found loaded key")
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ejcx/cf/5abf1c03aac87dbb69d1089de7aa1e2f51428a2a/logo.png
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/ejcx/cf/cmd"
4 |
5 | func main() {
6 | cmd.Execute()
7 | }
8 |
--------------------------------------------------------------------------------