Passing values from Capistrano deploy.rb file to app - ruby

In my Capistrano's deploy.rb file, I set up different environments such as server names, ports, etc. I also require the users to send a callback to another server, also defined in the deploy.rb. How do I cleanly pass this value to my app?
Something to this effect:
config/deploy.rb:
set :callback_url, "http://somecallbackurl.com:12345/bla"
app/controllers/myapp.rb:
def get_callback_url
???
end
I'm using Sinatra.

I found a solution, and that is to use the environment variables.
Set it from deploy.rb
run "export CALLBACK_URL=#{callback_url}"
From app:
def get_callback_url
ENV['CALLBACK_URL']
end
I wouldn't say it's the cleanest solution, but it works.

I'd probably recommend using a shared YAML file to store this kind of configuration, and loading it separately. For example, have a file named something like config/settings.yml, containing something like:
:callback_url: "http://somecallbackurl.com:12345/bla"
In config/deploy.rb, you could have:
settings = YAML.load_file('config/settings.yml')
set :callback_url, settings[:callback_url]
And in config/initializers/settings.rb, you could have:
settings = YAML.load_file('config/settings.yml')
CALLBACK_URL = settings[:callback_url]
Finally, in app/controllers/myapp.rb, you would do:
def get_callback_url
CALLBACK_URL
end
Using a shared YAML file is just the first thing I thought of. Another approach would be defining some constants in a ruby file, and requiring that file both in an initializer, and in deploy.rb. The basic idea is that you don't really want your app to depend on your capistrano environment, so you should find a way to separate the shared configuration.

Related

Setting path to custom .irbrc using IRB.conf

I want to invoke irb dynamically from my Ruby program, but have it not to load the default ~/.irbrc, but a file ./custom_irbrc instead. I can do it like this:
require 'irb'
ENV['IRBRC'] = './custom_irbrc'
IRB.setup(nil)
# My configurations follow here
IRB.conf[...]=...
IRB.start
I wonder whether I can set my custom irbrc also via .conf instead of polluting the environment. I didn't find a really comprehensive description of the possible conf-settings, but from what I found, I tried as educated guess:
IRB.conf[:IRB_RC] = './custom_irbrc'
IRB.conf[:RC] = './custom_irbrc'
but neither one seems to have any effect.
The desired effect can be achieved, although by using an undocumented feature, and there is no guarantee that it will be available in future Ruby versions too:
IRB.conf[:RC_NAME_GENERATOR] = proc { './custom_irbrc' }
This has to be done before IRB.setup is called.

How do I programmatically set a content_security_policy?

I'm configuring the Content Security Policy for our Rails 5.2 app. I need to whitelist some domains in our CSP. I'd like to put the list of domains elsewhere so I can reference them in other places in the application, then generate the CSP headers programmatically from that list.
Looking at the source code for the Content Security Policy configuration mechanisms in Rails 5, it looks like there's some magic metaprogramming going on, so it's not clear to me how to accomplish what I need to do. It looks like the functions I need to call to set headers might be picky about how exactly they want to be called. In particular, it's not clear to me if I can pass them arrays or safely call them multiple times, or if they do some metaprogramming magic that only works if the domains are passed in as individual function arguments.
Can I pass in an array to the header I want to set, like this?
whitelisted_domains = ['https://example.com', 'self']
Rails.application.configure do
config.content_security_policy do |csp|
csp.child_src whitelisted_domains
end
end
Or can I call the same function multiple times, like this?
whitelisted_domains = ['https://example.com', 'self']
Rails.application.configure do
config.content_security_policy do |csp|
whitelisted_domains.each {|domain| csp.child_src domain}
end
end
If neither of those will work, what's the best way of accomplishing what I want to do?
From what I can tell from sourcecode and documentation, it takes an array. From the edgeguides at rails, posting following
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
...
end
and the sourcecode, using *sources as param; it believe it takes any number of arguments, meaning you could do something along the lines of;
whitelisted_domains = ['https://example.com', 'self']
Rails.application.configure do
config.content_security_policy do |csp|
csp.child_src(*whitelisted_domains)
end
end
https://blog.sqreen.io/integrating-content-security-policy-into-your-rails-applications-4f883eed8f45/
https://edgeguides.rubyonrails.org/security.html#content-security-policy
Sourcecode of define_method for each directive
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/content_security_policy.rb#L151
(note: None of this has been tested in a Rails app, simple looking guides and source code of Rails)

Conditional routes and bot name in Lita

I am trying to develop a simple Lita chat bot with more flexible command routing.
There are a couple of issues I am having difficulties with.
1. Conditional routing
How can I use config values before or inside route definitions?
For example, instead of this definition that needs a "run" prefix:
route(/^\s*run\s+(\S*)\s*(.*)$/, :cmd, command: true)
I would like to use something like this, with a flexible, config-based prefix:
route(/^\s*#{config.prefix}\s+(\S*)\s*(.*)$/, :cmd, command: true)
Which fails. So I also tried something like this:
if config.use_prefix
route(/^\s*run\s+(\S*)\s*(.*)$/, :cmd, command: true)
else
route(/^\s*(\S*)\s*(.*)$/, :cmd, command: true)
end
Which also fails with a not very helpful error.
In both cases, I defined the proper config key with config :prefix and config :use_prefix.
2. Showing the bot name in the help
I know there is a robot.name property available for me inside the executed command, but I was unable to use it inside of the help string. I was trying to achieve something like this:
route(/^\s*run\s+(\S*)\s*(.*)$/, :cmd, command: true, help: {
"run SCRIPT" => "run the specified SCRIPT. use `#{robot.name} run list` for a list of available scripts."
})
but it just printed something unexpected.
Any help is appreciated.
The issue is that you're confusing the config class method and the config instance method. config at the class level (code in the class body but not inside an instance method definition) defines a new configuration attribute for the plugin. config at the instance level (inside an instance method or in an inline callback provided to route using a block) accesses the values of the plugin's own configuration at runtime.
In the current version of Lita, there isn't a pretty way to use runtime configuration in class-level definitions like chat routes. The workaround I've used myself is to register an event listener for the :loaded event, which triggers when the Lita::Robot has been initialized. At this point, configuration has been finalized, and you can use it to define more routes.
For example:
class MyHandler < Lita::Handler
on :loaded, :define_dynamic_routes
def define_dynamic_routes(payload)
if config.some_setting
self.class.route(/foo/, :callback)
else
self.class.route(/bar/, :callback)
end
end
end
You can look at the code for lita-karma for a more detailed example, as it uses this pattern.
The next major version of Lita is going to include an overhaul to the plugin system which will make this pattern much easier. For now, this is what I'd recommend, though.

chef cookbook lwrp, easiest way to use new_resource.updated_by_last_action(true)

I'm writing a LWRP for chef 10.
And when that resource is run in other recipes it should be marked as "updated_by_last_action" if something has changed. But if nothing has changed. updated_by_last_action should be false.
So as example I have chef documentation http://docs.opscode.com/lwrp_custom_provider.html#updated-by-last-action. That example the resource template is wrapped inside an variable to test if it's been changed, and then set the updated_by_last_action status.
So my code should look something like this
f = file new_resource.filename do
xxx
end
new_resource.updated_by_last_action(f.updated_by_last_action?)
t = template new_resource.templatename do
xxx
end
new_resource.updated_by_last_action(t.updated_by_last_action?)
m mount new_resource.mountpoint do
xxx
end
new_resource.updated_by_last_action(m.updated_by_last_action?)
But if a provider gets bigger and uses a lot of resources like template, file, directory, mount, etc..
Should all those resource be wrapped inside variables like the example to find out if a resource have been updated, so to then further send a status that this provider have been updated.
I'm wondering if there is a simpler and cleaner way to run new_resource.updated_by_last_action(true) other then to wrap all resources inside variables. Cause if I just put a new_resource.updated_by_last_action(true) inside action before end the LWRP is marked as being updated every chef run, which is not optimal.
You can add use_inline_resources at the top of your LWRP, which delegates the updated_by_last_action to the inline resources.

Passing options and parameters to Test/Unit via Rake::TestTask

So I've been trying to figure this out, and the best solution I can came up with his global variables - but that seems so dirty and 1974 - Am I missing a feature of Rake/ Test::Unit?
I have a Rake file in which I'm running tests:
Rake::TestTask.new(:test) do |t|
t.test_files = FileList['test_*.rb']
end
and test_1.rb has something like this:
require "test/unit"
class TestStuff < Test::Unit::TestCase
def setup
#thingy = Thing.New(parameter1, parameter2)
end
def test_this_thing
#thing.do()
end
end
My problem is, Thing.new() requires arguments, and those arguments are specific to my environment. In reality, I'm running Selenium-WebDriver, and I want to pass in a browser type, and a url, etc... sometimes I want ff, othertimes I want chrome... sometimes this URL, sometimes that... depending on the day, etc.
The simplest thing seems to do something like:
#all that rake stuff
$parameter1 = x
$parameter2 = y
and then make Thing.new() look up my global vars:
#thingy = Thing.New($parameter1, $parameter2)
This seems sloppy.. and it just doesn't feel right to me. I'm still trying to get this 'test harness' up and running, and want to do it right the first time. That's why I chose Rake, based on a lot of other feedback.
Keep in mind, I'll probably have 100's of tests, ultimately, and they'll all need to do get this information... I thought Rake was good at making sure all of this was easy, but it doesn't seem to be.
Where did I go wrong?
I have used YAML files to store my configuration (browser config, environments including URLs, etc).
You can also use an environmental variable to define simple configurations. You can access environmental variables via ENV['foobar'] in Ruby.
So, for example, my browser call might look like this inside my setup method:
driver = Selenium::WebDriver.for (ENV['SWD_BROWSER'] || "firefox").to_sym
and in my Rake file (or in the shell console) define the environmental variable to use.

Resources