fastlyctl 1.0.15 → 1.0.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d56f375e7f8e4c2105efabf9b224428666fe432702c0a259a6da21d816409a3
4
- data.tar.gz: b509f52f29c1a5dbb5a5d5f39ad42aa3f0c8701835c368d810d119487b64a665
3
+ metadata.gz: c53f586abe251025a9bd645fcf0ebffc7054424d09d9db8b114e7392e9568477
4
+ data.tar.gz: bbe5746a703ce8c051e8cd98fa63405b6d33da3e77794ed5099d13b0acad5767
5
5
  SHA512:
6
- metadata.gz: cf19cda3f417d5063fd29729ed80c10688cb9d9eb3e93ce16409c3a06d02dc641495710d38a085922d059ed5292e5713724a9769d2af75f773227eaece4c3c2c
7
- data.tar.gz: 4192c6bec0a62011d77d7e0e25362a55563ac7ec8a65e4278a23715e2a75abd031a755091fb51749b127e6f2998a6a20c3255a925553f3981de803164aa77a8f
6
+ metadata.gz: 1fb81e003390783de19f713bc6443272d9d84d03ded47c6a4a4aef0cf381724633e2524aeac22c3dfd8578cf91db42185da20daa74fede3189f24f3ffeb50daa
7
+ data.tar.gz: 7d261f97f4ecd5f17958b1e6b5a323f6375561565771319a3ee35a9869e74b4d910ff4be01dacd721b31c73c7d4752651cdd61a40932ec1140085d1f6f99f329
data/README.md CHANGED
@@ -321,6 +321,22 @@ Flags:
321
321
  * --d: When used with the create command, specifies that the snippet should be dynamic.
322
322
  * --y: Answer yes to all prompts
323
323
 
324
+ ### tls
325
+
326
+ #### managed
327
+
328
+ Usage:
329
+
330
+ ```
331
+ fastlyctl tls managed [subcommand] [domain]
332
+ ```
333
+
334
+ Available Subcommands:
335
+ * create: Create a Managed TLS Subscription for `[domain]`
336
+ * status: Print the status of all Managed TLS Subscriptions
337
+ * challenges: Print the challenges available for the verification of a certificate for `[domain]`
338
+ * delete: Delete a Managed TLS Subscription for `[domain]`
339
+
324
340
  ### token
325
341
 
326
342
  Manipulate tokens for an account.
@@ -371,10 +387,6 @@ Flags:
371
387
 
372
388
  The `--debug` flag is available on any command. Using it will cause fastlyctl to print the libcurl output for any requests it makes.
373
389
 
374
- ## Contributing
375
-
376
- Submit a pull request. Don't break anything.
377
-
378
390
  ## License
379
391
 
380
392
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/fastlyctl.gemspec CHANGED
@@ -34,4 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_runtime_dependency "thor", "~> 0.19.4"
35
35
  spec.add_runtime_dependency 'diffy', '~> 3.2.1'
36
36
  spec.add_runtime_dependency 'launchy', '~> 2.4.3', '>= 2.4.3'
37
+ spec.add_runtime_dependency 'openssl', '~> 2.1.2', '>= 2.1.2'
37
38
  end
data/lib/fastlyctl.rb CHANGED
@@ -6,11 +6,13 @@ require "uri"
6
6
  require "launchy"
7
7
  require "erb"
8
8
  require "pp"
9
+ require "openssl"
9
10
 
10
11
  require "fastlyctl/version"
11
12
  require "fastlyctl/fetcher"
12
13
  require "fastlyctl/clone_utils"
13
14
  require "fastlyctl/utils"
15
+ require "fastlyctl/subcommand_patch"
14
16
  require "fastlyctl/cli"
15
17
 
16
18
  include ERB::Util
data/lib/fastlyctl/cli.rb CHANGED
@@ -17,6 +17,7 @@ require "fastlyctl/commands/acl"
17
17
  require "fastlyctl/commands/copy"
18
18
  require "fastlyctl/commands/logging"
19
19
  require "fastlyctl/commands/condition"
20
+ require "fastlyctl/commands/tls"
20
21
 
21
22
 
22
23
  module FastlyCTL
@@ -59,12 +59,12 @@ module FastlyCTL
59
59
 
60
60
  if main === true
61
61
  # the "main-ness" of the vcl does not get carried over during creation. must explicitly set main
62
- FastlyCTL::Fetcher.api_request(:put, "/service/#{sid}/version/#{version}/vcl/#{URI.escape(obj["name"])}/main")
62
+ FastlyCTL::Fetcher.api_request(:put, "/service/#{sid}/version/#{version}/vcl/#{FastlyCTL::Utils.percent_encode(obj["name"])}/main")
63
63
  end
64
64
 
65
65
  if type == "director"
66
66
  backends.each do |b|
67
- FastlyCTL::Fetcher.api_request(:post, "/service/#{sid}/version/#{version}/director/#{URI.escape(obj["name"])}/backend/#{b}", body: obj )
67
+ FastlyCTL::Fetcher.api_request(:post, "/service/#{sid}/version/#{version}/director/#{FastlyCTL::Utils.percent_encode(obj["name"])}/backend/#{b}", body: obj )
68
68
  end
69
69
  end
70
70
 
@@ -20,7 +20,7 @@ module FastlyCTL
20
20
  version = FastlyCTL::Fetcher.get_writable_version(id) unless options[:version]
21
21
  version ||= options[:version]
22
22
 
23
- encoded_name = URI.escape(name) if name
23
+ encoded_name = FastlyCTL::Utils.percent_encode(name) if name
24
24
 
25
25
  case action
26
26
  when "create"
@@ -32,7 +32,7 @@ module FastlyCTL
32
32
  version = FastlyCTL::Fetcher.get_writable_version(id) unless options[:version]
33
33
  version ||= options[:version].to_i
34
34
 
35
- encoded_name = URI.escape(name) if name
35
+ encoded_name = FastlyCTL::Utils.percent_encode(name) if name
36
36
 
37
37
  case action
38
38
  when "list"
@@ -19,7 +19,7 @@ module FastlyCTL
19
19
  path += "/#{obj_name}" unless obj_type == "settings"
20
20
  obj = FastlyCTL::Fetcher.api_request(:get, path)
21
21
 
22
- encoded_name = URI.escape(obj_name)
22
+ encoded_name = FastlyCTL::Utils.percent_encode(obj_name)
23
23
 
24
24
  if (obj_type == "settings")
25
25
  puts "Copying settings from #{id} version #{source_version} to #{target_id} version #{target_version}..."
@@ -20,7 +20,7 @@ module FastlyCTL
20
20
  version = FastlyCTL::Fetcher.get_writable_version(id) unless options[:version]
21
21
  version ||= options[:version]
22
22
 
23
- encoded_name = URI.escape(name) if name
23
+ encoded_name = FastlyCTL::Utils.percent_encode(name) if name
24
24
 
25
25
  case action
26
26
  when "create"
@@ -49,14 +49,14 @@ module FastlyCTL
49
49
  abort "Must specify name for dictionary" unless name
50
50
  abort "Must specify key and value for dictionary item" unless (key && value)
51
51
  dict = FastlyCTL::Fetcher.api_request(:get, "/service/#{id}/version/#{version}/dictionary/#{encoded_name}")
52
- FastlyCTL::Fetcher.api_request(:put, "/service/#{id}/dictionary/#{dict["id"]}/item/#{key}", params: { item_value: value })
52
+ FastlyCTL::Fetcher.api_request(:put, "/service/#{id}/dictionary/#{dict["id"]}/item/#{FastlyCTL::Utils.percent_encode(key)}", params: { item_value: value })
53
53
 
54
54
  say("Dictionary item #{key} set to #{value}.")
55
55
  when "remove"
56
56
  abort "Must specify name for dictionary" unless name
57
57
  abort "Must specify key for dictionary item" unless key
58
58
  dict = FastlyCTL::Fetcher.api_request(:get, "/service/#{id}/version/#{version}/dictionary/#{encoded_name}")
59
- FastlyCTL::Fetcher.api_request(:delete, "/service/#{id}/dictionary/#{dict["id"]}/item/#{key}")
59
+ FastlyCTL::Fetcher.api_request(:delete, "/service/#{id}/dictionary/#{dict["id"]}/item/#{FastlyCTL::Utils.percent_encode(key)}")
60
60
 
61
61
  say("Item #{key} removed from dictionary #{name}.")
62
62
  when "list_items"
@@ -3,11 +3,10 @@ module FastlyCTL
3
3
  desc "purge_all", "Purge all content from a service."
4
4
  method_option :service, :aliases => ["--s"]
5
5
  def purge_all
6
- parsed_id = FastlyCTL::Utils.parse_directory
6
+ id = FastlyCTL::Utils.parse_directory unless options[:service]
7
+ id ||= options[:service]
7
8
 
8
- id = FastlyCTL::Utils.parse_directory
9
-
10
- abort "Could not parse service id from directory. Use --s <service> to specify, vcl download, then try again." unless (id || options[:service])
9
+ abort "Could not parse service id from directory. Use --s <service> to specify, vcl download, then try again." unless id
11
10
 
12
11
  FastlyCTL::Fetcher.api_request(:post, "/service/#{id}/purge_all")
13
12
 
@@ -18,7 +18,7 @@ module FastlyCTL
18
18
  version = FastlyCTL::Fetcher.get_writable_version(id) unless options[:version]
19
19
  version ||= options[:version].to_i
20
20
 
21
- encoded_name = URI.escape(name) if name
21
+ encoded_name = FastlyCTL::Utils.percent_encode(name) if name
22
22
 
23
23
  filename = options.key?(:filename) ? options[:filename] : "#{name}.snippet"
24
24
 
@@ -0,0 +1,70 @@
1
+ require "fastlyctl/commands/tls/managed"
2
+
3
+ module FastlyCTL
4
+ class TLSSubCmd < SubCommandBase
5
+ SubcommandPrefix = "tls"
6
+
7
+ desc "managed SUBCOMMAND ...ARGS", "Interface with Fastly Managed TLS Subscriptions (lets-encrypt)"
8
+ subcommand "managed", TLSManagedSubCmd
9
+ end
10
+
11
+ class CLI < Thor
12
+ desc "tls SUBCOMMAND ...ARGS", "Interface with Fastly TLS"
13
+ subcommand "tls", TLSSubCmd
14
+ end
15
+
16
+ module TLSUtils
17
+ def self.get_tls_configs
18
+ data = FastlyCTL::Fetcher.api_request(:get,"/tls/configurations",{use_vnd:true})["data"]
19
+ if data.length == 0
20
+ thor = Thor::Shell::Basic.new
21
+ thor.say "No TLS Configurations found. You may need to upgrade to a paid account if you are using a free account."
22
+ thor.say "If you need assistance, please contact support@fastly.com."
23
+ if (thor.yes?("Would you like to open the TLS configuration page in the Fastly app?"))
24
+ FastlyCTL::Utils.open_app_path("/network/domains")
25
+ end
26
+ abort
27
+ end
28
+
29
+ return data
30
+ end
31
+
32
+ def self.select_tls_config(configs)
33
+ thor = Thor::Shell::Basic.new
34
+ if configs.length == 1
35
+ thor.say "Using TLS Configuration #{configs[0]["id"]} - #{configs[0]["name"]}"
36
+ return configs[0]
37
+ end
38
+
39
+ loop do
40
+ i = 1
41
+ configs.each do |c|
42
+ bulk = c["attributes"]["bulk"] ? " [Platform TLS]" : ""
43
+ thor.say("[#{i}]#{bulk} #{c["id"]} - #{c["name"]}\n")
44
+ i += 1
45
+ end
46
+
47
+ selected = thor.ask("Which TLS Configuration would you like to use? Please type the number next to the configuration(s) above.").to_i
48
+ if selected > 0 && selected <= (configs.length+1)
49
+ selected -= 1
50
+ thor.say "Using TLS Configuration #{configs[selected]["id"]} - #{configs[selected]["name"]}"
51
+ return configs[selected]
52
+ end
53
+
54
+ thor.say "#{selcted} is in invalid selection. Please try again."
55
+ end
56
+ end
57
+
58
+ def self.print_challenges(tls_authorization)
59
+ thor = Thor::Shell::Basic.new
60
+ thor.say "\nIn order to verify your ownership of the domain, the Certificate Authority provided the following challenges:"
61
+ tls_authorization["attributes"]["challenges"].each do |challenge|
62
+ thor.say("\n#{challenge["type"]}: Create #{challenge["record_type"]} record for #{challenge["record_name"]} with value(s) of:")
63
+ challenge["values"].each do |val|
64
+ thor.say(" #{val}")
65
+ end
66
+ end
67
+ thor.say("\nNote: If you don't want to move all traffic to Fastly right now, use the managed-dns option. The other options result in traffic for that hostname being directed to Fastly.")
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,119 @@
1
+ module FastlyCTL
2
+ class TLSManagedSubCmd < SubCommandBase
3
+ SubcommandPrefix = "tls managed"
4
+ DomainRegex = /(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/
5
+
6
+ desc "create <domain>", "Create a Fastly Managed TLS Subscription for [domain]. A Certificate will be requested from lets-encrypt once you satisfy one of the challenges. You can learn more about the challenge types here: https://letsencrypt.org/docs/challenge-types/ and Fastly's API documentation here: https://docs.fastly.com/api/tls-subscriptions."
7
+ def create(domain)
8
+ abort "Must specify valid domain name" unless domain =~ DomainRegex
9
+
10
+ tls_configs = FastlyCTL::TLSUtils.get_tls_configs
11
+ tls_config = FastlyCTL::TLSUtils.select_tls_config(tls_configs)
12
+
13
+ payload = {
14
+ data: {
15
+ type: "tls_subscription",
16
+ attributes: {
17
+ certificate_authority: "lets-encrypt"
18
+ },
19
+ relationships: {
20
+ tls_domains: {
21
+ data: [
22
+ {
23
+ type: "tls_domain",
24
+ id: domain
25
+ }
26
+ ]
27
+ },
28
+ tls_configuration: {
29
+ data: {
30
+ type: "tls_configuration",
31
+ id: tls_config["id"]
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ subscription = FastlyCTL::Fetcher.api_request(:post,"/tls/subscriptions", {
39
+ body: payload.to_json,
40
+ use_vnd: true
41
+ })
42
+
43
+ tls_authorization = FastlyCTL::Utils.filter_vnd(subscription["included"],"tls_authorization")
44
+ abort "Unable to fetch TLS Authorization for the domain." unless tls_authorization.length > 0
45
+ FastlyCTL::TLSUtils.print_challenges(tls_authorization[0])
46
+ end
47
+
48
+ desc "status", "Print status of Fastly Managed TLS Subscriptions"
49
+ def status
50
+ subscriptions = FastlyCTL::Fetcher.api_request(:get,"/tls/subscriptions", {
51
+ use_vnd: true
52
+ })
53
+
54
+ if subscriptions["data"].length == 0
55
+ say("No Fastly Managed TLS Subscriptions found.")
56
+ abort
57
+ end
58
+
59
+ subscriptions["data"].each do |subscription|
60
+ output = subscription["relationships"]["tls_domains"]["data"][0]["id"]
61
+ output += " - " + subscription["attributes"]["certificate_authority"]
62
+ output += " - " + subscription["attributes"]["state"]
63
+ say(output)
64
+ end
65
+ end
66
+
67
+ desc "challenges", "Print challenges available for a domain's verification."
68
+ def challenges(domain)
69
+ abort "Must specify valid domain name" unless domain =~ DomainRegex
70
+
71
+ domains = FastlyCTL::Fetcher.api_request(:get,"/tls/domains?include=tls_subscriptions.tls_authorizations", {
72
+ use_vnd: true
73
+ })
74
+
75
+ tls_authorizations = FastlyCTL::Utils.filter_vnd(domains["included"],"tls_authorization")
76
+
77
+ tls_authorizations.each do |tls_authorization|
78
+ tls_authorization["attributes"]["challenges"].each do |challenge|
79
+ if challenge["record_name"] == domain
80
+ FastlyCTL::TLSUtils.print_challenges(tls_authorization)
81
+ abort
82
+ end
83
+ end
84
+ end
85
+
86
+ say("#{domain} not found in domain list.")
87
+ end
88
+
89
+ desc "delete", "Delete a Fastly Managed TLS Subscription"
90
+ def delete(domain)
91
+ abort "Must specify valid domain name" unless domain =~ DomainRegex
92
+
93
+ activation = FastlyCTL::Fetcher.api_request(:get,"/tls/activations?filter[tls_domain.id]=#{domain}", {use_vnd: true})
94
+
95
+ if activation["data"].length >= 1
96
+ say("TLS is currently active for #{domain}. If you proceed, Fastly will no longer be able to serve TLS requests to clients for #{domain}.")
97
+ answer = ask("Please type the name of the domain to confirm deactivation and deletion of the Fastly Managed TLS subscription: ")
98
+ abort "Supplied domain does not match the domain requested for deletion--aborting." unless answer == domain
99
+
100
+ FastlyCTL::Fetcher.api_request(:delete,"/tls/activations/#{activation["data"][0]["id"]}",{use_vnd:true})
101
+ end
102
+
103
+ subscriptions = FastlyCTL::Fetcher.api_request(:get,"/tls/subscriptions", {
104
+ use_vnd: true
105
+ })
106
+
107
+ subscriptions["data"].each do |subscription|
108
+ next unless subscription["relationships"]["tls_domains"]["data"][0]["id"] == domain
109
+
110
+ FastlyCTL::Fetcher.api_request(:delete,"/tls/subscriptions/#{subscription["id"]}",{use_vnd:true})
111
+
112
+ say("TLS Subscription for #{domain} has been deleted.")
113
+ abort
114
+ end
115
+
116
+ say("No TLS Subscription found for #{domain}...")
117
+ end
118
+ end
119
+ end
@@ -33,7 +33,8 @@ module FastlyCTL
33
33
  # gbps
34
34
  uncacheable = agg["pass"] + agg["synth"] + agg["errors"]
35
35
  bw = ((agg["resp_header_bytes"] + agg["resp_body_bytes"]).to_f * 8.0) / 1000000000.0
36
- hit_rate = (1.0 - ((agg["miss"] - agg["shield"]).to_f / ((agg["requests"] - uncacheable).to_f))) * 100.0
36
+ shield = agg["shield"] || 0
37
+ hit_rate = (1.0 - ((agg["miss"] - shield).to_f / ((agg["requests"] - uncacheable).to_f))) * 100.0
37
38
  passes = agg["pass"]
38
39
  miss_time = agg["miss"] > 0 ? ((agg["miss_time"] / agg["miss"]) * 1000).round(0) : 0
39
40
  synth = agg["synth"]
@@ -7,6 +7,7 @@ module FastlyCTL
7
7
  options[:body] ||= nil
8
8
  options[:force_session] ||= false
9
9
  options[:expected_responses] ||= [200]
10
+ options[:use_vnd] ||= false
10
11
 
11
12
  headers = {"Accept" => "application/json", "Connection" => "close", "User-Agent" => "FastlyCTL: https://github.com/fastly/fastlyctl"}
12
13
 
@@ -27,6 +28,15 @@ module FastlyCTL
27
28
 
28
29
  headers["Content-Type"] = "application/x-www-form-urlencoded" if (method == :post || method == :put)
29
30
 
31
+ if options[:use_vnd]
32
+ headers["Accept"] = "application/vnd.api+json"
33
+
34
+ if (method == :post || method == :put)
35
+ headers["Content-Type"] = "application/vnd.api+json"
36
+ end
37
+ options[:expected_responses].push(*[201,202,203,204])
38
+ end
39
+
30
40
  headers.merge!(options[:headers]) if options[:headers].count > 0
31
41
 
32
42
  # dont allow header splitting on anything
@@ -54,25 +64,41 @@ module FastlyCTL
54
64
  end
55
65
  else
56
66
  case response.response_code
57
- when 400
58
- error = "400: Bad API request--got bad request response."
59
- when 403
60
- error = "403: Access Denied by API. Run login command to authenticate."
61
- when 404
62
- error = "404: Service does not exist or bad path requested."
63
- when 503
64
- error = "503: API is offline."
65
- else
66
- error = "API responded with status #{response.response_code}."
67
+ when 400
68
+ error = "400: Bad API request--something was wrong with the request made by FastlyCTL."
69
+ when 403
70
+ error = "403: Access Denied by API. Run login command to authenticate."
71
+ when 404
72
+ error = "404: Service does not exist or bad path requested."
73
+ when 503
74
+ error = "503: Error from Fastly API--see details below."
75
+ when 0
76
+ error = "0: Network connection error occurred."
77
+ else
78
+ error = "API responded with status #{response.response_code}."
67
79
  end
68
80
 
69
81
  error += " Method: #{method.to_s.upcase}, Path: #{path}\n"
70
- error += "Message from API: #{response.response_body}"
82
+
83
+ if (options[:use_vnd])
84
+ begin
85
+ error_resp = JSON.parse(response.response_body)
86
+ rescue JSON::ParserError
87
+ error_resp = {"errors" => [{"title" => "Error parsing response JSON","details" => "No further information available. Please file a github issue at https://github.com/fastly/fastlyctl"}]}
88
+ end
89
+
90
+ error_resp["errors"].each do |e|
91
+ next unless e.key?("title") && e.key?("detail")
92
+ error += e["title"] + " --- " + e["detail"] + "\n"
93
+ end
94
+ else
95
+ error += "Message from API: #{response.response_body}"
96
+ end
71
97
 
72
98
  abort error
73
99
  end
74
100
 
75
- return response.response_body if (response.headers["Content-Type"] != "application/json")
101
+ return response.response_body unless (response.headers["Content-Type"] =~ /json$/)
76
102
 
77
103
  if response.response_body.length > 1
78
104
  begin
@@ -161,7 +187,7 @@ module FastlyCTL
161
187
  end
162
188
 
163
189
  def self.upload_snippet(service,version,content,name)
164
- return FastlyCTL::Fetcher.api_request(:put, "/service/#{service}/version/#{version}/snippet/#{name}", {:endpoint => :api, body: {
190
+ return FastlyCTL::Fetcher.api_request(:put, "/service/#{service}/version/#{version}/snippet/#{FastlyCTL::Utils.percent_encode(name)}", {:endpoint => :api, body: {
165
191
  content: content
166
192
  }
167
193
  })
@@ -178,7 +204,7 @@ module FastlyCTL
178
204
  end
179
205
  end
180
206
 
181
- response = FastlyCTL::Fetcher.api_request(:put, "/service/#{service}/version/#{version}/vcl/#{name}", {:endpoint => :api, body: params, expected_responses: [200,404]})
207
+ response = FastlyCTL::Fetcher.api_request(:put, "/service/#{service}/version/#{version}/vcl/#{FastlyCTL::Utils.percent_encode(name)}", {:endpoint => :api, body: params, expected_responses: [200,404]})
182
208
 
183
209
  # The VCL got deleted so recreate it.
184
210
  if response["msg"] == "Record not found"
@@ -0,0 +1,5 @@
1
+ class SubCommandBase < Thor
2
+ def self.banner(command, namespace = nil, subcommand = false)
3
+ basename + " " + self::SubcommandPrefix + " " + command.usage
4
+ end
5
+ end
@@ -4,6 +4,10 @@ module FastlyCTL
4
4
  Launchy.open(FastlyCTL::FASTLY_APP + FastlyCTL::TANGO_PATH + id)
5
5
  end
6
6
 
7
+ def self.open_app_path(path)
8
+ Launchy.open(FastlyCTL::FASTLY_APP + path)
9
+ end
10
+
7
11
  def self.parse_directory(path=false)
8
12
  directory = Dir.pwd unless path
9
13
  directory = path if path
@@ -68,5 +72,21 @@ module FastlyCTL
68
72
 
69
73
  return diff
70
74
  end
75
+
76
+ def self.percent_encode(string)
77
+ # CGI.escape replace whitespace to "+" which is "%20" in a percent-encoding manner
78
+ CGI.escape(string).gsub('+', '%20')
79
+ end
80
+
81
+ def self.filter_vnd(haystack,needle)
82
+ results = []
83
+ haystack.each do |i|
84
+ next unless i["type"] == needle
85
+
86
+ results.push(i)
87
+ end
88
+
89
+ return results
90
+ end
71
91
  end
72
92
  end
@@ -1,3 +1,3 @@
1
1
  module FastlyCTL
2
- VERSION = "1.0.15"
2
+ VERSION = "1.0.16"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlyctl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.15
4
+ version: 1.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Basile
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-06 00:00:00.000000000 Z
11
+ date: 2020-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -72,6 +72,26 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: 2.4.3
75
+ - !ruby/object:Gem::Dependency
76
+ name: openssl
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 2.1.2
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: 2.1.2
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 2.1.2
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: 2.1.2
75
95
  description: This gem provides a CLI for managing Fastly configurations
76
96
  email:
77
97
  - stephen@fastly.com
@@ -111,10 +131,13 @@ files:
111
131
  - lib/fastlyctl/commands/purge_all.rb
112
132
  - lib/fastlyctl/commands/skeleton.rb
113
133
  - lib/fastlyctl/commands/snippet.rb
134
+ - lib/fastlyctl/commands/tls.rb
135
+ - lib/fastlyctl/commands/tls/managed.rb
114
136
  - lib/fastlyctl/commands/token.rb
115
137
  - lib/fastlyctl/commands/upload.rb
116
138
  - lib/fastlyctl/commands/watch.rb
117
139
  - lib/fastlyctl/fetcher.rb
140
+ - lib/fastlyctl/subcommand_patch.rb
118
141
  - lib/fastlyctl/utils.rb
119
142
  - lib/fastlyctl/version.rb
120
143
  homepage: http://www.github.com/fastly/fastlyctl