I am developing a Rails application for AWS and would like to create drop down menu for region names, like "us-east-1" etc.
If someone already created gem to get them, I want to use it. Does anyone know such a gem or useful API?
The AWS SDK for Ruby (aws-sdk gem) supports enumerating region names:
require 'aws-sdk'
ec2 = AWS::EC2.new(:access_key_id => '...', :secret_access_key => '...')
ec2.regions.map(&:name)
=> ["eu-west-1", "sa-east-1", "us-east-1", "ap-northeast-1", "us-west-2", "us-west-1", "ap-southeast-1"]
You can also use a client interface to the DescribeRegions call:
ec2.client.describe_regions
=> { :region_info=>[
{:region_name=>"eu-west-1", :region_endpoint=>"ec2.eu-west-1.amazonaws.com"},
{:region_name=>"sa-east-1", :region_endpoint=>"ec2.sa-east-1.amazonaws.com"},
{:region_name=>"us-east-1", :region_endpoint=>"ec2.us-east-1.amazonaws.com"},
{:region_name=>"ap-northeast-1", :region_endpoint=>"ec2.ap-northeast-1.amazonaws.com"},
{:region_name=>"us-west-2", :region_endpoint=>"ec2.us-west-2.amazonaws.com"},
{:region_name=>"us-west-1", :region_endpoint=>"ec2.us-west-1.amazonaws.com"},
{:region_name=>"ap-southeast-1", :region_endpoint=>"ec2.ap-southeast-1.amazonaws.com"}
],
:request_id=>"04458cac-bdf2-4847-bf1f-c7ea65813777"
}
You can view the gem docs here: http://docs.amazonwebservices.com/AWSRubySDK/latest/frames.html
On mine I can do:
>> `ec2-describe-regions`.scan(/REGION\s+(\S+)/).flatten
=> ["eu-west-1", "sa-east-1", "us-east-1", "ap-northeast-1", "us-west-2", "us-west-1", "ap-southeast-1"]
I found the Gem!
http://rubydoc.info/gems/aws/2.5.6/Aws/Ec2:describe_regions
Related
I am trying to use a gem called RubyPress which allows to use Wordpress' xml-rpc api from ruby. But it always gives me this error:
getaddrinfo: No such host is known. (SocketError)
Here's my code:
require 'rubypress'
wp = Rubypress::Client.new(:host => "localhost/wordpress",
:username => "admin",
:password => "admin")
p wp.getOptions
I am able to connect fine using another gem called wp_rpc but rubypress doesn't seem to work. Rubypress seems to be maintained so i want to use it, it also seems to have more features.
Also, even when i try connecting to a real site, it gives a 403 error which is very strange.
I am running the server using XAMPP on Windows 7. How can I get it to work?
UPDATE:
Here's the code i used for posting, now it doesn't seem to post. Not sure where i went wrong.
wp.newPost( :blog_id => 0, # 0 unless using WP Multi-Site, then use the blog id
:content => {
:post_status => "publish",
:post_date => Time.now,
:post_content => "This is the body",
:post_title => "RubyPress is the best!",
:post_name => "/rubypress-is-the-best",
:post_author => 1, # 1 if there is only the admin user, otherwise the user's id
:terms_names => {
:category => ['Category One','Category Two','Category Three'],
:post_tag => ['Tag One','Tag Two', 'Tag Three']
}
}
)
Note: This is from the rubypress github page. Those categories and tags are not present on the blog, is that the reason?
host must be a host name (e.g. "localhost" in this particular case, or, say, "google.com"):
require 'rubypress'
wp = Rubypress::Client.new(host: "localhost",
username: "admin",
password: "admin",
path: "/wordpress/xmlrpc.php")
Probably, you might need to tune the path parameter up to point exactly to where WP’s RPC endpoint is to be found.
I'm building a cli tool in ruby, and I need to take config from different sources: environment variable, dotfile, arguments or hardcoded values. (with a precedence system)
In node.js I would have used nconf.js, to do this.
Is there some configuration gem in ruby that enable to do such a thing?
The actual answer is this:
updated: 2020-02-26
https://github.com/infochimps-labs/configliere
to quote the author:
Be willing to sit down with the Five Families. Takes settings from (at your option):
Pre-defined defaults from constants
Simple config files
Environment variables
Commandline options and git-style command runners
Ruby block (called when all other options are in place)
put simply. just like nconf.
require 'configliere'
Settings.use :commandline
Settings({
:dest_time => '11-05-1955',
:fluxcapacitor => {
:speed => 88,
},
:delorean => {
:power_source => 'plutonium',
:roads_needed => true,
},
:username => 'marty',
:password => '',
})
#set a value to possibly also come from env
Settings.define :dest_time, :env_var => 'DEST_TIME'
Settings.read "#{__dir__}/config.yml"
Settings.read "#{Dir.pwd()}/config.yml"
Settings.resolve!
old answer:
https://github.com/rubyconfig/config#working-with-environment-variables
it doesn't do argv, but it lets you layer various yaml files and then override with ENV just like nconf lets you.
I am having a struggle getting this to work so I've created a hell-world Rails app to try and get this to work.
Here's the repo with the code that is not working: https://github.com/pitosalas/shibtry
Here's what I've done starting from an empty Rails application:
I've added two gems to gem files:
gem 'omniauth-shibboleth'
gem 'rack-saml'
I got the shibboleth meta data from my university's web site and converted it using shib_conv.rb into the corresponding YAML: ./config.yml
I've updated routes adding get '/auth/:provider/callback', to: 'sessions#create'
I've put a breakpoint at SessionController#create
I've added initializers: omniauth.rb:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :shibboleth, {
:shib_session_id_field => "Shib-Session-ID",
:shib_application_id_field => "Shib-Application-ID",
:debug => true,
:extra_fields => [
:"unscoped-affiliation",
:entitlement
]
}
end
I've added rack_sam.rb initializer:
Rails.application.config.middleware.insert_after Rack::ETag, Rack::Saml,
{ :metadata => "#{Rails.root}/config/metadata.yml"}
Now, run the server and go to http://0.0.0.0:3000/auth/shibboleth and I get an error:
undefined method `[]' for nil:NilClass'
which is traced back to this line in rack-saml/misc/onelogin_setting.rb line 13 which is:
settings.idp_sso_target_url = #metadata['saml2_http_redirect']
in other words, looking for the metadata hash for that key. It happens that in my metadata.yml file that key is present, but by the time I get to this onelogin_setting.rb line 13, #metadata is nil (it should contain the contents of the file) and consequently that key doesn't exist.
And that's where, for now, the trail dries up.
I bypassed Shibboleth totally. My goal was to allow login to my universities authentication system specifically to allow students to log in with their student login, which is fronted by google apps. So this was much easier: https://developers.google.com/identity/sign-in/web/
Looks like you forgot to add your config file to the initializer:
Rails.application.config.middleware.insert_after Rack::ETag, Rack::Saml,
{
:metadata => "#{Rails.root}/config/metadata.yml",
:config => "#{Rails.root}/config/rack-saml.yml"
}
And the saml_idp setting in the rack-saml.yml must match the key for the idp_lists entry in your metadata.yml
I am trying to figure out what is the best way to get a list of ec2 instances with a certain tag for example "testing" using the ruby aws sdk.
ec2 = AWS::EC2.new(:access_key_id => "XXXXXXXXXXXXX", :secret_access_key => "YYYYYYYYY")
ec2list = ec2.instances.filter("Name", "testing)
This does not seem to work for some reason. It was thinking it will filter out the collection and just give me instances with tag testing. Is there a way to do this using the ruby sdk? thank you.
If you want the tag "Name" with the value of "testing" use:
instances = resource.instances(
filters: [
{
name: 'tag:Name',
values: ["testing"]
}
]
)
For all instances with a tag key of "testing" the following is used.
instances = resource.instances(
filters: [
{
name: 'tag:Key',
values: ["testing"]
}
]
)
See the #instances docs for more filter options.
This worked for me:
ec2.instances.tagged("testing")
None of the above worked, but this one worked for me:
ec2.instances.with_tag("Environment","Integration")
Hi I think you could get what you want using filter on the tags of the instances:
ec2 = AWS::EC2.new(:access_key_id => "XXXXXXXXXXXXX", :secret_access_key => "YYYYYYYYY")
ec2list = ec2.instances.tags.filter("Name", "testing)
CF:
http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/AutoScaling/TagCollection.html#filter-instance_method
http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2.html#tags-instance_method
I am used to doing it this way
require 'aws-sdk'
ec2 = AWS::EC2.new(
:region => cluster_region,
:access_key_id => key_id,
:secret_access_key => access_key)
instances = ec2.instances
instances = instances.filter("filter-key", "filter-value")
One can find the available filters at
http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-DescribeInstances.html
EC2 gives instances a new IP address when they're stopped then restarted, so I need to be able to automatically manage a route53 record set so that I can access things consistently. Sadly the documentation for the route53 portion of the sdk is not nearly as robust as it is for ec2 (understandably) and so I'm a bit stuck. From what I've seen so far, it seems like change_resource_record_sets (link) is the way to go, but I'm confused as to what needs go into :chages since it mentions a Change object but fails to provide a link to a description of said object.
Here's what my code currently looks like for a creation:
r53.client.change_resource_record_sets(:hosted_zone_id => 'MY_ID', :change_batch => {
:changes => 'I DONT KNOW WHAT GOES HERE',
:action => 'CREATE',
:resource_record_set => {
:name => #instance.instance_name,
:type => 'CNAME',
:ttl => 330,
:value => #instance.ip_address
}})
EDIT: Okay, since I haven't had any help either here or on the official forums I've been messing around with it myself. So it turns out that the documentation is just plain awful. All of the values are stored in a Change object, and not given there. So it actually looks more like this:
some_change = AWS::Route53::CreateRequest.new(#instance.instance_name,
'CNAME',
:ttl => 330,
:resource_records => [
{:value => #instance.ip_address}
])
r53.client.change_resource_record_sets(:hosted_zone_id => 'MY_ZONE', :change_batch => {
:changes => [some_change],
})
The documentation is pretty poor, though it does contain a few examples. I initially had the impression that it was necessary to create requests (and use the client object) per your solution, but there are alternatives.
An example of creating a record can be found in the ResourceRecordSetCollection reference, but it's only a little more concise than your answer:
rrsets = AWS::Route53::HostedZone.new(hosted_zone_id).rrsets
rrset = rrsets.create('foo.example.com.', 'A', :ttl => 300, :resource_records => [{:value => '127.0.0.1'}])
I wanted to update an existing record, and didn't have the hosted_zone_id to hand. It took far too long to figure out how best to do this, so I'm offering the following example in the hope it saves someone else some time:
r53 = AWS::Route53.new
domain = "example.com."
fqdn = "host." + domain
zone = r53.hosted_zones.select { |z| z.name == domain }.first
rrset = zone.rrsets[fqdn, 'A']
rrset.resource_records = [ { :value => "1.2.3.4" } ]
rrset.update
Note that that assumes you only have a single zone with that name in Route53.
The method that zts posted seems to be a much better way of updating records. However, if you're updating an alias record then you have to use DeleteRequest/CreateRequest as the alias_target instance attribute on ResourceRecordSet seems to be readonly, even though the docs don't list it as so.
Here's one way to do it. Note that the hosted zone id for the alias target (region in the code below) should not be a personal zone ID, it is actually an encrypted region ID. This doesn't seem to be documented anywhere, and the only reference for these IDs that I could find was in the source of the fog gem.
Edit: This has now moved to a separate module called fog-aws and is more up to date.
{
"ap-northeast-1" => "Z2YN17T5R711GT",
"ap-southeast-1" => "Z1WI8VXHPB1R38",
"ap-southeast-2" => "Z2999QAZ9SRTIC",
"eu-west-1" => "Z3NF1Z3NOM5OY2",
"eu-central-1" => "Z215JYRZR1TBD5",
"sa-east-1" => "Z2ES78Y61JGQKS",
"us-east-1" => "Z3DZXE0Q79N41H",
"us-west-1" => "Z1M58G0W56PQJA",
"us-west-2" => "Z33MTJ483KN6FU",
}
And the code:
change_request = {
hosted_zone_id: zone.id,
change_batch: { changes: [] }
}
alias_target = {
hosted_zone_id: region,
evaluate_target_health: false
}
# Delete the record if it already exists
if rrset.exists?
alias_target[:dns_name] = rrset.alias_target[:dns_name]
delete_request = AWS::Route53::DeleteRequest.new(fqdn, 'A', alias_target: alias_target)
change_request[:change_batch][:changes][0] = delete_request
r53.client.change_resource_record_sets(change_request)
end
# Create the new record
alias_target[:dns_name] = new_alias
create_request = AWS::Route53::CreateRequest.new(fqdn, 'A', alias_target: alias_target)
change_request[:change_batch][:changes][0] = create_request
r53.client.change_resource_record_sets(change_request)
I hacked it until it worked, and here are my results:
Don't look at the ruby route53 documentation for anything but method/object/attribute names. It is misleading, if not outright wrong. Instead, check out the rest documentation since the client just builds up a standard xml request anyway. My example of creating a simple record is as follows:
some_change = AWS::Route53::CreateRequest.new("foo.bar.com",
'CNAME', # the type of the resource record set
:ttl => 330, # The cache time to live for the current resource record set
:resource_records => [
{:value => "0.0.0.0"} # dependent on type
])
r53.client.change_resource_record_sets(:hosted_zone_id => 'MY_ZONE', :change_batch => {
:changes => [some_change],
})
I initially worked with what #slippery John did, but that proved problematic for spot instances that reclaim certain dns names often.
I found a solution I think is better, almost I identical to his:
some_change = AWS::Route53::ChangeRequest.new("UPSERT","foo.bar.com",
'CNAME', # the type of the resource record set
:ttl => 330, # The cache time to live for the current resource record set
:resource_records => [
{:value => "0.0.0.0"} # dependent on type
])
r53.client.change_resource_record_sets(:hosted_zone_id => 'MY_ZONE', :change_batch => {
:changes => [some_change],
})
it is intentionally copied from his solution with a slight modification.
For aws-sdk v2 it is like this:
[72] pry(main)> r53 = Aws::Route53::Client.new
[73] pry(main)> change
=> {:action=>"UPSERT",
:resource_record_set=>
{:name=>"myhost.example.com",
:resource_records=>[{:value=>"192.0.2.44"}],
:ttl=>60,
:type=>"A"}}
[44] pry(main)> res = r53.change_resource_record_sets(hosted_zone_id: my_zone_id, change_batch: {changes: [change]})
=> #<struct Aws::Route53::Types::ChangeResourceRecordSetsResponse
change_info=
#<struct Aws::Route53::Types::ChangeInfo
id="/change/C02195391TWJO1GT9KVRV",
status="PENDING",
submitted_at=2020-11-03 21:39:09.41 UTC,
comment=nil>>
For more info see https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Aws/Route53/Client.html#change_resource_record_sets-instance_method