cfer 0.5.0.pre.rc4 → 0.5.0

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
  SHA1:
3
- metadata.gz: 920b540c1393d65eca22f5058ef46209581064a3
4
- data.tar.gz: 305ea70aebc10866edf04d318581002a0d6d23ed
3
+ metadata.gz: 78cb715113442fbbec2fa9c33e2e243bd048960c
4
+ data.tar.gz: f48b5126eebba1e069e2a26f8de51d9fc5f49d80
5
5
  SHA512:
6
- metadata.gz: a0641e4b71578c1eca5891ceeff60caa79a065462627efc8abd44ae9065b7ec71024c1f4f8f811efb709f06bccd95128a9aa2e3f289dcd8ed042a06d3f6fc46b
7
- data.tar.gz: 44f48d246f170fb5f6af197c606fdc40927de89c858ae83577ddb35260e5307975b2e59df80acbc146ba454693924708d6c3cb8ec253c9970acbe5bd5f70cd1d
6
+ metadata.gz: 16f2f7eec9dab63812568214952a1aee5668a9553c4c9156346f9a8dffe43e07a6a63e0667bb8491ce9d225493a631c5132af794afb5679bb43afd69896bfa9d
7
+ data.tar.gz: c4978b1220c8ce036a6fb4b2b96d695af2cd39b79a18e50371a58434102c8803df735ca18c0625a494c6d58bd798a6de0a82c855c6ce42bdd3fc89ae251319a5
@@ -12,6 +12,8 @@ engines:
12
12
  enabled: true
13
13
  rubocop:
14
14
  enabled: true
15
+ exclude_fingerprints:
16
+ - 9d7be17b9e5e786560cf0df662f55736
15
17
  ratings:
16
18
  paths:
17
19
  - "**.inc"
@@ -14,6 +14,7 @@ branches:
14
14
  - develop
15
15
  script:
16
16
  - bundle exec rspec
17
+ - bundle exec codeclimate-test-reporter
17
18
  - bundle exec yard
18
19
  addons:
19
20
  code_climate:
data/Gemfile CHANGED
@@ -7,8 +7,9 @@ group :test do
7
7
  gem 'rspec'
8
8
  gem 'rspec-mocks'
9
9
  gem 'guard-rspec'
10
- gem 'coveralls', require: false
11
- gem "codeclimate-test-reporter", require: nil
10
+ gem 'simplecov'
11
+ gem 'rubocop', '~> 0.47.1'
12
+ gem "codeclimate-test-reporter", "~> 1.0.0"
12
13
  end
13
14
 
14
15
  group :debug do
data/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  Cfer is a lightweight toolkit for managing CloudFormation templates.
11
11
 
12
- Read about Cfer [here](http://tilmonedwards.com/2015/07/28/cfer.html).
12
+ Read about Cfer [here](https://github.com/seanedwards/cfer/blob/master/examples/vpc.md).
13
13
 
14
14
  ## Support
15
15
 
@@ -247,5 +247,5 @@ This project also contains a [Code of Conduct](https://github.com/seanedwards/cf
247
247
 
248
248
  # Release Notes
249
249
 
250
- [Change Log](https://github.com/seanedwards/cfer/CHANGELOG.md)
250
+ [Change Log](https://github.com/seanedwards/cfer/blob/master/CHANGELOG.md)
251
251
 
data/bin/cfer CHANGED
@@ -6,7 +6,7 @@ module Cfer
6
6
  DEBUG = false
7
7
  end
8
8
 
9
- require 'cfer'
9
+ require 'cfer/cli'
10
10
 
11
11
 
12
12
  Cfer::Cli::main(ARGV)
@@ -0,0 +1,194 @@
1
+ When I first encountered AWS CloudFormation, I was appalled by the format for about ten minutes. This is the criticism of it that I've heard most often: the unwieldy syntax makes it unapproachable. Writing it by hand is worse than lunch meetings. I don't disagree.
2
+
3
+ However, I think CloudFormation makes a pretty decent intermediate language. Users of Elasic Beanstalk might notice a bunch of CloudFormation stacks in their account, all containing some kind of Amazon-produced EB magic. This is where CloudFormation excels: Machine-generated infrastructure.
4
+
5
+ To that end, I took a couple weekends and wrote [Cfer](https://github.com/seanedwards/cfer), a DSL for generating CloudFormation templates in Ruby. [I'm](http://chrisfjones.github.io/coffin/) [not](https://github.com/bazaarvoice/cloudformation-ruby-dsl) [the](https://github.com/stevenjack/cfndsl) [only](https://github.com/Optaros/cloud_builder) [one](https://github.com/rapid7/convection) [doing](https://github.com/cloudtools/troposphere) [this](https://cfn-pyplates.readthedocs.org/en/latest/). But I'll run through an example template, which will help you build a basic VPC in AWS, and at the same time, address some of the features of Cfer that might make CloudFormation a little more appealing to you.
6
+
7
+ If you find the format of this post difficult to follow, you can see this same example as a fully functional template in [examples/vpc.rb](https://github.com/seanedwards/cfer/blob/develop/examples/vpc.rb)
8
+
9
+
10
+ This template creates the following resources for a basic beginning AWS VPC setup:
11
+
12
+ 1. A VPC
13
+ 2. A route table to control network routing
14
+ 3. An Internet gateway to route traffic to the public internet
15
+ 4. 3 subnets, one in each of the account's first 3 availability zones
16
+ 5. A default network route to the IGW
17
+ 6. Associated plumbing resources to link it all together
18
+
19
+ ## Template Parameters
20
+
21
+ Template parameters allow you to use the same template to build multiple similar instances of parts of your infrastructure. Parameters may be defined using the `parameter` function:
22
+
23
+ ```ruby
24
+ parameter :VpcName, default: 'Example VPC'
25
+ ```
26
+
27
+ Resources are created using the `resource` function, accepting the following arguments:
28
+
29
+ 1. The resource name (string or symbol)
30
+ 2. The resource type. See the AWS CloudFormation docs for the [available resource types](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html).
31
+
32
+
33
+ ## The VPC Resource
34
+
35
+ The VPC is the foundation of your private network in AWS.
36
+
37
+ ```ruby
38
+ resource :vpc, 'AWS::EC2::VPC' do
39
+ ```
40
+
41
+ Each line within the resource block sets a single property. These properties are simply camelized using the ActiveSupport gem's `camelize` function. This means that the `cidr_block` function will set the `CidrBlock` property.
42
+
43
+ ```ruby
44
+ cidr_block '172.42.0.0/16'
45
+ ```
46
+
47
+ Following this pattern, `enable_dns_support` sets the `EnableDnsSupport` property.
48
+
49
+ ```ruby
50
+ enable_dns_support true
51
+ enable_dns_hostnames true
52
+ instance_tenancy 'default'
53
+ ```
54
+
55
+ The `tag` function is available on all resources, and adds keys to the resource's `Tags` property. It accepts the following arguments:
56
+
57
+ 1. Tag name (symbol or string)
58
+ 2. Tag value
59
+
60
+ ```ruby
61
+ tag :DefaultVpc, true
62
+ ```
63
+
64
+ Parameters are required at template generation time, and therefore may be referenced using the `parameters` hash anywhere in a template. This will render the parameter value as a string constant in the CloudFormation JSON output.
65
+
66
+ ```ruby
67
+ tag :Name, parameters[:VpcName]
68
+ ```
69
+
70
+ Finally, we can finish this resource by closing the block that we started when we called the `resource` function.
71
+
72
+ ```ruby
73
+ end
74
+ ```
75
+
76
+ ## The Internet Gateway
77
+
78
+ Instances in your VPC will need to be able to access the internet somehow, and an internet gateway is the mechanism for making this happen. Let's create one.
79
+
80
+ If there are no properties to set on a resource, the `do..end` block may be omitted entirely
81
+
82
+ ```ruby
83
+ resource :defaultigw, 'AWS::EC2::InternetGateway'
84
+ ```
85
+
86
+ ## Attaching the Gateway
87
+
88
+ For a gateway to be routable, it needs to be attached to a specific VPC using a "VPC Gateway Attachment" resource.
89
+
90
+ `Fn::ref` serves the same purpose as CloudFormation's `{"Ref": ""}` intrinsic function.
91
+
92
+ ```ruby
93
+ resource :vpcigw, 'AWS::EC2::VPCGatewayAttachment' do
94
+ vpc_id Fn::ref(:vpc)
95
+ internet_gateway_id Fn::ref(:defaultigw)
96
+ end
97
+ ```
98
+
99
+ ## The Route Table
100
+
101
+ A VPC also needs a route table. Every VPC comes with a default route table, but I like to create my own resources so that they're all expressed in the template.
102
+
103
+ ```ruby
104
+ resource :routetable, 'AWS::EC2::RouteTable' do
105
+ vpc_id Fn::ref(:vpc)
106
+ end
107
+ ```
108
+
109
+ ## The Default Route
110
+
111
+ We also have to set up a default route, so that any traffic that the VPC doesn't recognize gets routed off to the internet gateway.
112
+
113
+ The `resource` function accepts one additional parameter that was not addressed above: the options hash. Additional options passed here will be placed inside the resource, but outside the `Properties` block. In this case, we've specified that the default route explicitly depends on the VPC Internet Gateway.
114
+
115
+ As of this writing, this is actually a required workaround for this template. The gateway must be attached to the VPC before a route can be created to it, but since the gateway attachment isn't actually referenced anywhere in this resource, we need to explicitly declare that dependency.
116
+
117
+ ```ruby
118
+ resource :defaultroute, 'AWS::EC2::Route', DependsOn: [:vpcigw] do
119
+ route_table_id Fn::ref(:routetable)
120
+ gateway_id Fn::ref(:defaultigw)
121
+ destination_cidr_block '0.0.0.0/0'
122
+ end
123
+ ```
124
+
125
+ ## The Subnets
126
+
127
+ Naturally, you'll also need networks. Like the route table, I like to create my own so that I have control of their configuration inside the template.
128
+
129
+ Notice `Fn::select`, `Fn::get_azs` and `AWS::region` in this snippet. These all map to the CloudFormation functions and variables of the same name.
130
+
131
+ We'll use Ruby to create three identical subnets:
132
+
133
+ ```ruby
134
+ (1..3).each do |i|
135
+ ```
136
+
137
+ The subnets themselves will be in the first three availability zones of the account. A more sophisticated template might want to handle this differently.
138
+
139
+ ```ruby
140
+ resource "subnet#{i}", 'AWS::EC2::Subnet' do
141
+ availability_zone Fn::select(i, Fn::get_azs(AWS::region))
142
+ cidr_block "172.42.#{i}.0/24"
143
+ vpc_id Fn::ref(:vpc)
144
+ end
145
+ ```
146
+
147
+ Now the subnet needs to be associated with the route table, so that hosts in the subnet are able to access the rest of the network and the internet.
148
+
149
+ ```ruby
150
+ resource "srta#{i}".to_sym, 'AWS::EC2::SubnetRouteTableAssociation' do
151
+ subnet_id Fn::ref("subnet#{i}")
152
+ route_table_id Fn::ref(:routetable)
153
+ end
154
+ ```
155
+
156
+ We can use the `output` function to output the subnet IDs we've just created. We'll go over how Cfer makes this useful in part 2 of this post.
157
+
158
+ ```ruby
159
+ output "subnetid#{i}", Fn::ref("subnet#{i}")
160
+ ```
161
+
162
+ And of course, end the iteration block.
163
+
164
+ ```ruby
165
+ end
166
+ ```
167
+
168
+
169
+ Finally, let's output the VPC ID too, since we'll probably need that in other templates.
170
+
171
+ ```ruby
172
+ output :vpcid, Fn::ref(:vpc)
173
+ ```
174
+
175
+ ## Converging the Stack
176
+
177
+ Now that you have your template ready, you'll be able to use Cfer to create or update a CloudFormation stack:
178
+
179
+ {% highlight bash %}
180
+ cfer converge vpc -t examples/vpc.rb --profile ${AWS_PROFILE} --region ${AWS_REGION}
181
+ ```
182
+
183
+ Which should produce something like this.
184
+
185
+ ![Cfer Demo]({{ site.url }}/images/cfer/cfer-demo.gif)
186
+
187
+ Use `cfer help` to get more usage information, or check `README.md` and `Rakefile` in the source repository to see how to embed Cfer into your own projects.
188
+
189
+ ## In Part 2...
190
+
191
+ In part 2, we'll go over some additional features of Cfer. If you want a preview, you can check out the [instance.rb](https://github.com/seanedwards/cfer/blob/develop/examples/instance.rb) example, which covers how you can use Cfer to create security groups, instances with automated provisioning, and how to automatically look up outputs from other stacks.
192
+
193
+ Cfer can be found on [GitHub](https://github.com/seanedwards/cfer) and [RubyGems](https://rubygems.org/gems/cfer) and is MIT licensed. Pull requests are welcome.
194
+
@@ -64,7 +64,7 @@ module Cfer
64
64
  cfn = options[:aws_options] || {}
65
65
 
66
66
  cfn_stack = options[:cfer_client] || Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
67
- raise Cfer::Util::CferError, "No such template file: #{tmpl}" unless File.exists?(tmpl) || options[:cfer_stack]
67
+ raise Cfer::Util::CferError, "No such template file: #{tmpl}" unless File.exist?(tmpl) || options[:cfer_stack]
68
68
  stack =
69
69
  options[:cfer_stack] ||
70
70
  Cfer::stack_from_file(tmpl,
@@ -126,7 +126,7 @@ module Cfer
126
126
  when 'table', nil
127
127
  puts "Status: #{cfn_stack[:stack_status]}"
128
128
  puts "Description: #{cfn_stack[:description]}" if cfn_stack[:description]
129
- puts "Created with Cfer version: #{Semantic::Version.new(cfer_version_str).to_s} (current: #{Cfer::SEMANTIC_VERSION.to_s})" if cfer_version
129
+ puts "Created with Cfer version: #{Semantic::Version.new(cfer_version_str)} (current: #{Cfer::SEMANTIC_VERSION.to_s})" if cfer_version
130
130
  puts ""
131
131
  def tablify(list, type)
132
132
  list ||= []
@@ -165,7 +165,7 @@ module Cfer
165
165
  cfn = options[:aws_options] || {}
166
166
 
167
167
  cfn_stack = options[:cfer_client] || Cfer::Cfn::Client.new(cfn)
168
- raise Cfer::Util::CferError, "No such template file: #{tmpl}" unless File.exists?(tmpl) || options[:cfer_stack]
168
+ raise Cfer::Util::CferError, "No such template file: #{tmpl}" unless File.exist?(tmpl) || options[:cfer_stack]
169
169
  stack = options[:cfer_stack] || Cfer::stack_from_file(tmpl,
170
170
  options.merge(client: cfn_stack, parameters: generate_final_parameters(options))).to_h
171
171
  puts render_json(stack, options)
@@ -333,7 +333,6 @@ end
333
333
  %w{
334
334
  version.rb
335
335
  block.rb
336
- cli.rb
337
336
  config.rb
338
337
 
339
338
  util/error.rb
@@ -36,7 +36,7 @@ module Cfer
36
36
 
37
37
  def include_file(file)
38
38
  Preconditions.check(file).is_not_nil
39
- raise Cfer::Util::FileDoesNotExistError, "#{file} does not exist." unless File.exists?(file)
39
+ raise Cfer::Util::FileDoesNotExistError, "#{file} does not exist." unless File.exist?(file)
40
40
 
41
41
  case File.extname(file)
42
42
  when '.json'
@@ -121,7 +121,6 @@ module Cfer::Cfn
121
121
  stack_options[:timeout_in_minutes] = options[:timeout] if options[:timeout]
122
122
 
123
123
  stack_options.merge! parse_stack_policy(:stack_policy, options[:stack_policy])
124
- stack_options.merge! parse_stack_policy(:stack_policy_during_update, options[:stack_policy_during_update])
125
124
 
126
125
  stack_options.merge! template_options
127
126
 
@@ -133,6 +132,7 @@ module Cfer::Cfn
133
132
  if options[:change]
134
133
  create_change_set stack_options.merge change_set_name: options[:change], description: options[:change_description], parameters: update_params
135
134
  else
135
+ stack_options.merge! parse_stack_policy(:stack_policy_during_update, options[:stack_policy_during_update])
136
136
  update_stack stack_options.merge parameters: update_params
137
137
  end
138
138
  :updated
@@ -1,3 +1,4 @@
1
+ require 'cfer'
1
2
  require 'cri'
2
3
  require 'rainbow'
3
4
  require 'table_print'
@@ -5,7 +5,7 @@ module Cfer
5
5
  DEBUG = true
6
6
  end
7
7
 
8
- require "cfer"
8
+ require "cfer/cli"
9
9
 
10
10
  Cfer::LOGGER.level = Logger::DEBUG
11
11
 
@@ -20,14 +20,6 @@ module Cfer::Core::Functions
20
20
  {"Fn::Select" => [i, o]}
21
21
  end
22
22
 
23
- def base64(v)
24
- {"Fn::Base64" => v}
25
- end
26
-
27
- def condition(cond)
28
- {"Condition" => cond}
29
- end
30
-
31
23
  def and(*conds)
32
24
  {"Fn::And" => conds}
33
25
  end
@@ -52,35 +44,31 @@ module Cfer::Core::Functions
52
44
  {"Fn::GetAZs" => region}
53
45
  end
54
46
 
55
- def account_id
56
- Fn::ref 'AWS::AccountId'
47
+ def sub(str, vals = {})
48
+ {"Fn::Sub" => [str, vals]}
57
49
  end
58
50
 
59
51
  def notification_arns
60
- Fn::ref 'AWS::NotificationARNs'
61
- end
62
-
63
- def no_value
64
- Fn::ref 'AWS::NoValue'
65
- end
66
-
67
- def region
68
- Fn::ref 'AWS::Region'
69
- end
70
-
71
- def stack_id
72
- Fn::ref 'AWS::StackId'
73
- end
74
-
75
- def stack_name
76
- Fn::ref 'AWS::StackName'
52
+ ref 'AWS::NotificationARNs'
77
53
  end
78
54
  end
79
55
 
80
56
  module Cfer::Core::Functions::AWS
81
57
  extend Cfer::Core::Functions
58
+
59
+ def self.method_missing(sym, *args)
60
+ method = sym.to_s.camelize
61
+ raise "AWS::#{method} does not accept arguments" unless args.empty?
62
+ ref "AWS::#{method}"
63
+ end
82
64
  end
83
65
 
84
66
  module Cfer::Core::Functions::Fn
85
67
  extend Cfer::Core::Functions
68
+
69
+ def self.method_missing(sym, *args)
70
+ method = sym.to_s.camelize
71
+ raise "Fn::#{method} requires one argument" unless args.size == 1
72
+ { "Fn::#{method}" => args.first }
73
+ end
86
74
  end
@@ -2,14 +2,14 @@ module Cfer::Core
2
2
  # Provides support for hooking into resource types, and evaluating code before or after properties are set
3
3
  module Hooks
4
4
  def pre_block
5
- self.class.pre_hooks.each do |hook|
6
- instance_eval &hook
5
+ self.class.pre_hooks.sort { |a, b| (a[:nice] || 0) <=> (b[:nice] || 0) }.each do |hook|
6
+ Docile.dsl_eval(self, &hook[:block])
7
7
  end
8
8
  end
9
9
 
10
10
  def post_block
11
- self.class.post_hooks.each do |hook|
12
- instance_eval &hook
11
+ self.class.post_hooks.sort { |a, b| (a[:nice] || 0) <=> (b[:nice] || 0) }.each do |hook|
12
+ Docile.dsl_eval(self, &hook[:block])
13
13
  end
14
14
  end
15
15
 
@@ -18,12 +18,12 @@ module Cfer::Core
18
18
  end
19
19
 
20
20
  module ClassMethods
21
- def before(&block)
22
- self.pre_hooks << block
21
+ def before(options = {}, &block)
22
+ self.pre_hooks << options.merge(block: block)
23
23
  end
24
24
 
25
- def after(&block)
26
- self.post_hooks << block
25
+ def after(options = {}, &block)
26
+ self.post_hooks << options.merge(block: block)
27
27
  end
28
28
 
29
29
  def pre_hooks
@@ -22,6 +22,7 @@ module Cfer::Core
22
22
  # @param options [Hash] An arbitrary set of additional properties to be added to this tag, for example `PropagateOnLaunch` on `AWS::AutoScaling::AutoScalingGroup`
23
23
  def tag(k, v, **options)
24
24
  self[:Properties][:Tags] ||= []
25
+ self[:Properties][:Tags].delete_if { |kv| kv["Key"] == k }
25
26
  self[:Properties][:Tags].unshift({"Key" => k, "Value" => v}.merge(options))
26
27
  end
27
28
 
@@ -53,14 +54,14 @@ module Cfer::Core
53
54
 
54
55
  # Registers a hook that will be run before properties are set on a resource
55
56
  # @param type [String] The type of resource, for example `AWS::EC2::Instance`
56
- def before(type, &block)
57
- resource_class(type).pre_hooks << block
57
+ def before(type, options = {}, &block)
58
+ resource_class(type).pre_hooks << options.merge(block: block)
58
59
  end
59
60
 
60
61
  # Registers a hook that will be run after properties have been set on a resource
61
62
  # @param type [String] The type of resource, for example `AWS::EC2::Instance`
62
- def after(type, &block)
63
- resource_class(type).post_hooks << block
63
+ def after(type, options = {}, &block)
64
+ resource_class(type).post_hooks << options.merge(block: block)
64
65
  end
65
66
  end
66
67
  end
@@ -1,5 +1,5 @@
1
1
  module Cfer
2
- VERSION = "0.5.0-rc4"
2
+ VERSION = "0.5.0"
3
3
 
4
4
  begin
5
5
  require 'semantic'
@@ -26,6 +26,10 @@ module CferExt
26
26
  end
27
27
 
28
28
  module WithPolicyDocument
29
+ def policy_document(doc = nil, &block)
30
+ doc = CferExt::AWS::IAM.generate_policy(&block) if doc == nil
31
+ self[:Properties][:PolicyDocument] = doc
32
+ end
29
33
  end
30
34
 
31
35
  module WithPolicies
@@ -0,0 +1,11 @@
1
+ require 'docile'
2
+
3
+ Cfer::Core::Resource.extend_resource "AWS::Route53::RecordSetGroup" do
4
+ %w{a aaaa cname mx ns ptr soa spf srv txt}.each do |type|
5
+ define_method type.to_sym do |name, records, options = {}|
6
+ self[:Properties][:RecordSets] ||= []
7
+ self[:Properties][:RecordSets] << options.merge(Type: type.upcase, Name: name, ResourceRecords: [ records ].flatten)
8
+ end
9
+ end
10
+ end
11
+
@@ -38,7 +38,7 @@ Cfer::Core::Stack.extend_stack do
38
38
  end
39
39
  end
40
40
 
41
- Cfer::Core::Stack.after do
41
+ Cfer::Core::Stack.after(nice: 100) do
42
42
  begin
43
43
  validate_stack!(self)
44
44
  rescue Cfer::Util::CferValidationError => e
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.pre.rc4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Edwards
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2017-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
@@ -223,6 +223,7 @@ files:
223
223
  - doc/cfer-demo.gif
224
224
  - examples/common/instance_deps.rb
225
225
  - examples/instance.rb
226
+ - examples/vpc.md
226
227
  - examples/vpc.rb
227
228
  - lib/cfer.rb
228
229
  - lib/cfer/block.rb
@@ -244,6 +245,7 @@ files:
244
245
  - lib/cferext/aws/iam/policy_generator.rb
245
246
  - lib/cferext/aws/kms/key.rb
246
247
  - lib/cferext/aws/rds/db_instance.rb
248
+ - lib/cferext/aws/route53/record_dsl.rb
247
249
  - lib/cferext/cfer/stack_validation.rb
248
250
  homepage: https://github.com/seanedwards/cfer
249
251
  licenses:
@@ -263,9 +265,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
263
265
  version: 2.2.5
264
266
  required_rubygems_version: !ruby/object:Gem::Requirement
265
267
  requirements:
266
- - - ">"
268
+ - - ">="
267
269
  - !ruby/object:Gem::Version
268
- version: 1.3.1
270
+ version: '0'
269
271
  requirements: []
270
272
  rubyforge_project:
271
273
  rubygems_version: 2.5.1