How to setup basic ManageIQ automate environment in Rails console? - ruby-on-rails

I used to run some operations in ManageIQ through automate simulation, which is available from UI.
I'd like to find a way to reproduce these operations from rails console.
For example operations for Instance management - migrate, evacuate or relocate instance.
How do I make it?

There's the common way to do this:
Set up a basic $evm context in a Rails console
# rails c
# $evm = MiqAeMethodService::MiqAeService.new(MiqAeEngine::MiqAeWorkspaceRuntime.new)
For example you can find any VM in vmdb and define it into a variable:
# vm = $evm.vmdb('vm').find('some_id')
Similar with other objects, e.g.
flavor = $evm.vmdb('flavor').find(flavor_id)

Related

Is there a way to find current environment in a Ruby application similar to rails.env?

I need to implement a feature that sets some Env vars conditionally based on current environment(dev,test,prod). I know in rails this can be accomplished with rails.env. Is there a similar method for Ruby?
No, vanilla ruby doesn't have a concept of "environment". You will have to build this yourself. One simple way is to use an environment variable and read it.
For example, you can require a MYAPP_ENVIRONMENT environment variable. Then you read it with myapp_environment = ENV['MYAPP_ENVIRONMENT']. Then you might have hashes or some other data structure to determine values that are specific to that environment:
ENDPOINT_A = {
prod: 'https://prod.my_company.com',
stage: 'https://stage.my_company.com'
}
Similarly for other variables. Note that the endpoint string is a ruby variable, not an environment variable. You should NOT set environment variables from the ruby code that uses them. The whole point of environment variables is that they are set externally to your app and your app takes them as input to configure how it behaves.
If you want to specify the endpoint through an environment variable, you should set it in the operating system where your ruby app runs. You can do this manually on the machine or through a deployment pipeline or script.

Scope of Models(?) in Rails

I'm new to Ruby on Rails and am trying to access my site's database. I generated and set up a model and controller called Machine, and noticed that in places like the Machine view I could iterate through all the machines in my database simply using #machines.each. However, this doesn't appear to be universal, as when I created a new Ruby file directly in my project's outermost directory, both #machines.each and the attempted assignment #machines = Machine.all threw errors (a NoMethodError and NameError respectively). Here's an example of code I could try to run:
#machines = Machine.all
#machines.each do |machine|
puts machine.created_at
end
Perhaps I need some kind of import statement?
If you are writing a script in plain Ruby -- then yes, you'll have to import everything manually, establish a connection to the DB, etc.
The code would roughly look like this:
require 'active_support'
require 'active_record'
your_db_config = {
# your DB config goes here
}
ActiveSupport::Dependencies.autoload_paths += File.join(__dir__, "app/models")
ActiveRecord::Base.establish_connection(your_db_config)
machines = Machine.all
Consider creating a task if you want Rails to take care of all that and don't want to be doing all that stuff manually.
When you start a rails server (or a rails console) it preloads your Rails application so that your models, constants, etc. are automatically in scope. If you want to access your application's resources from a separate script you still need to load the app. The simplest way to do that is with the rails runner command, which loads your app and then executes a script. So if your script above is in lib/show_machines you'd run:
$ bin/rails runner lib/show_machines
If you like self-executing scripts you can also use runner as a 'shebang' line:
#!/usr/bin/env <your_project_path>/rails/runner
#machines = Machine.all
#machines.each do |machine|
puts machine.created_at
end

Configuring Neo4j with rails for different environments

I have configured Neo4j in development environment using neo4j core gem.
To create a new connection, i have used the below code in application.rb
Application.rb
neo4j_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://localhost:7474')
neo4j_session = Neo4j::Core::CypherSession.new(neo4j_adaptor)
How to configure the neo4j so that development environment and test environment uses different database.
eg: for development sample_development and for running rspec sample_test.
I don't know how much experience you have with Rails. But in rails you mainly have 3 environments be default:
1- development
2- test
3- production
You can have different configs for different environments as shown in this SO question:
Best way to create custom config options for my Rails app?
Last thing, I would not recommend to use the Neo4j adapter directly unless you are really experienced and need direct access to it because of business requirements.
I'd recommend to use Neo4jrb wrapper around the core adapter as shown here:
https://neo4jrb.readthedocs.io/en/9.2.x/Setup.html#generating-a-new-app
UPDATE
Create a file called neo4j.yml inside config directory in your project with following code:
development:
neo4j_api: http://localhost:7474
test:
neo4j_api: http://something_else:7474
production:
neo4j_api: http://maybe_something_else:7474
then create an initializer in your project lets call it neo4j.rb so its path should be: config/initializers/neo4j.rb.
Inside this initializer put the following code:
NEO4J_CONFIG = YAML.load_file(Rails.root.join('config/neo4j.yml'))[Rails.env]
Then you will have the NEO4J_CONFIG accessible at any part of your rails application like:
NEO4J_CONFIG['neo4j_api']
and your code should look like:
neo4j_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new(NEO4J_CONFIG['neo4j_api'])
neo4j_session = Neo4j::Core::CypherSession.new(neo4j_adaptor)

How to avoid passing environment variables to puppet agent

I am trying to use a 3rd party puppet module which relies on the fact the puppet agent which will run has the JAVA_HOME correctly set.
The JAVA_HOME is required because there is a command defined in a provider (see here).
I have 2 options which I can use now:
Pass the variable when executing the puppet agent (but works only in interactive)
Put in place a file to be sourced by the user executing puppet with the cron (self managed by puppet)
My question is: is it possible to pass the environment to a provider?
POSSIBLE SOLUTION
Taking inspiration from the following post
I created a new type and a provider for it which inside sets the ENV[myvar] = myvalue. Note that the type is not ensurable.
The variable will "leak" and will allow other modules relying on it to work properly.
E.g.
### ... Provider code
def ensure
if value = ENV[resource[:name]]
value
else
:absent
end
end
def ensure=(new_value)
if new_value == :absent
ENV.delete(resource[:name])
else
ENV[resource[:name]] = new_value
end
end
### Usage in puppet code
mytype { 'MYVAR':
ensure => 'MYVAL',
}
Note that puppet will report at each run the value has changed from absent to a specific value. To avoid so, I think it is enough to always return :absent (I must verify that).
is it possible to pass the environment to a provider?
No, Puppet has no mechanism for customizing the environment for external commands on a per-provider basis. I think you have more options than those you've enumerated, however. Among them:
wrap the puppet command in a shell script that sets the environment variables you want
if you are indeed using cron to schedule agent runs, then use cron's built-in support for setting environment variables for the commands it runs.
The latter seems a promising alternative.

Run script in Rails console and have access to objects created?

I recently found you can run an arbitrary Ruby file in the Rails console using load or require, as in:
load 'test_code.rb'
This is great as far as it goes, but using either load or require (what's the difference?) I don't seem to have access to the objects created in the script after it completes.
For example, in my script I might have something like:
u = User.where('last_name = ?', 'Spock').first
If I start rails console and run that script using load or require, I see it working, I see the query happen, and I can 'put' attributes from the object inside the script and see them in the console output. But once the script is done, the variable u is undefined.
I'd like to run some code to set up a few objects and then explore them interactively. Can this be done? Am I doing something wrong or missing something obvious?
Variables defined in your script will go out of scope once the file is loaded. If you want to use the variables in console, define them as instance variables or constants
#u = User.where('last_name = ?', 'Spock').first
or
USER = User.where('last_name = ?', 'Spock').first
As explained in http://www.ruby-doc.org/core-2.1.2/Kernel.html#method-i-load:
In no circumstance will any local variables in the loaded file be propagated to the loading environment.
An option is to eval the file:
eval(File.read 'your_script.rb')
and the local variables will be there afterwards.

Resources