ruby gem to auto reload config files during runtime - ruby

I am looking for a ruby gem ( or a idea to develop one) which can refresh config files(yaml) during runtime. So that I can store in variable and use them.

There's a config object in Configurabilty (disclosure: I'm the author) which you can use either on its own, or as part of the Configurability mixin. From the documentation:
Configurability also includes Configurability::Config, a fairly simple
configuration object class that can be used to load a YAML configuration file,
and then present both a Hash-like and a Struct-like interface for reading
configuration sections and values; it's meant to be used in tandem with Configurability, but it's also useful on its own.
Here's a quick example to demonstrate some of its features. Suppose you have a
config file that looks like this:
---
database:
development:
adapter: sqlite3
database: db/dev.db
pool: 5
timeout: 5000
testing:
adapter: sqlite3
database: db/testing.db
pool: 2
timeout: 5000
production:
adapter: postgres
database: fixedassets
pool: 25
timeout: 50
ldap:
uri: ldap://ldap.acme.com/dc=acme,dc=com
bind_dn: cn=web,dc=acme,dc=com
bind_pass: Mut#ge.Mix#ge
branding:
header: "#333"
title: "#dedede"
anchor: "#9fc8d4"
You can load this config like so:
require 'configurability/config'
config = Configurability::Config.load( 'examples/config.yml' )
# => #<Configurability::Config:0x1018a7c7016 loaded from
examples/config.yml; 3 sections: database, ldap, branding>
And then access it using struct-like methods:
config.database
# => #<Configurability::Config::Struct:101806fb816
{:development=>{:adapter=>"sqlite3", :database=>"db/dev.db", :pool=>5,
:timeout=>5000}, :testing=>{:adapter=>"sqlite3",
:database=>"db/testing.db", :pool=>2, :timeout=>5000},
:production=>{:adapter=>"postgres", :database=>"fixedassets",
:pool=>25, :timeout=>50}}>
config.database.development.adapter
# => "sqlite3"
config.ldap.uri
# => "ldap://ldap.acme.com/dc=acme,dc=com"
config.branding.title
# => "#dedede"
or using a Hash-like interface using either Symbols, Strings, or a mix of
both:
config[:branding][:title]
# => "#dedede"
config['branding']['header']
# => "#333"
config['branding'][:anchor]
# => "#9fc8d4"
You can install it via the Configurability interface:
config.install
Check to see if the file it was loaded from has changed since you
loaded it:
config.changed?
# => false
# Simulate changing the file by manually changing its mtime
File.utime( Time.now, Time.now, config.path )
config.changed?
# => true
If it has changed (or even if it hasn't), you can reload it, which automatically re-installs it via the Configurability interface:
config.reload
You can make modifications via the same Struct- or Hash-like interfaces and write the modified config back out to the same file:
config.database.testing.adapter = 'mysql'
config[:database]['testing'].database = 't_fixedassets'
then dump it to a YAML string:
config.dump
# => "--- \ndatabase: \n development: \n adapter: sqlite3\n
database: db/dev.db\n pool: 5\n timeout: 5000\n testing: \n
adapter: mysql\n database: t_fixedassets\n pool: 2\n timeout:
5000\n production: \n adapter: postgres\n database:
fixedassets\n pool: 25\n timeout: 50\nldap: \n uri:
ldap://ldap.acme.com/dc=acme,dc=com\n bind_dn:
cn=web,dc=acme,dc=com\n bind_pass: Mut#ge.Mix#ge\nbranding: \n
header: \"#333\"\n title: \"#dedede\"\n anchor: \"#9fc8d4\"\n"
or write it back to the file it was loaded from:
config.write

Using for example Watchr or Guard you can monitor files and act on changes to them.
The actual action to take when a file changes depends entirely on your specific setup and situation, so you're on your own there. Or you need to provide more information.

Related

After upgrading SpringBoot 2.5.3, replacing spring.datasource. Schema to spring.sql.init.schema-locations is failed

How do I use spring.sql.init.schema-locations
Spring-boot version 2.5.3 failed
my spring.sql.inti.schema-locations and spring.datasource.schema
spring:
sql:
init:
schema-locations: classpath:sql/create_table_h2.sql
main:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
# 数据源配置项
datasource:
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1 # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
initial-size: 1 # 单元测试,配置为 1,提升启动速度
# schema: classpath:sql/create_table_h2.sql
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper
mapperPackage: com.ruoyi.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.ruoyi.**.domain
spring-boot version 2.4.10 succeeded
spring.datasource.schema = classpath:sql/create_table_h2.sql
I think some other related factors may interfere with the project, or you can try to lower the version, which may be the best way. In projects with new features, I prefer to use spring-boot, which may be more Good way to upgrade.

How do you set the deployment configuration when using the Google API for Deployment Manager?

I am trying to use the Ruby Google API Client to create a deployment on the Google Compute Platform (GCP).
I have a YAML file for the configuation:
resources:
- name: my-vm
type: compute.v1.instance
properties:
zone: europe-west1-b
machineType: zones/europe-west1-b/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: global/images/myvm-1487178154
networkInterfaces:
- network: $(ref.my-subnet.selfLink)
networkIP: 172.31.54.11
# Create the network for the machines
- name: my-subnet
type: compute.v1.network
properties:
IPv4Range: 172.31.54.0/24
I have tested that this works using the gcloud command line tool.
I now want to do this in Ruby using the API. I have the following code:
require 'google/apis/deploymentmanager_v2'
require 'googleauth'
require 'googleauth/stores/file_token_store'
SCOPE = Google::Apis::DeploymentmanagerV2::AUTH_CLOUD_PLATFORM
PROJECT_ID = "my-project"
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = "./service_account.json"
deployment_manager = Google::Apis::DeploymentmanagerV2::DeploymentManagerService.new
deployment_manager.authorization = Google::Auth.get_application_default([SCOPE])
All of this is working in that I am authenticated and I have a deployment_manager object I can work with.
I want to use the insert_deployment method which has the following signature:
#insert_deployment(project, deployment_object = nil, preview: nil, fields: nil, quota_user: nil, user_ip: nil, options: nil) {|result, err| ... } ⇒ Google::Apis::DeploymentmanagerV2::Operation
The deployment_object type is 'Google::Apis::DeploymentmanagerV2::Deployment'. I can create this object but then I am do not know how to import the YAML file I have into this to be able to programtically perform the deployment.
There is another class called ConfigFile which seems akin to the command line option of specifying the --config but again I do not know how to load the file into this nor then turn it into the correct object for the insert_deployment.
I have worked this out.
Different classes need to be nested so that the configuration is picked up. For example:
require 'google/apis/deploymentmanager_v2'
require 'googleauth'
SCOPE = Google::Apis::DeploymentmanagerV2::AUTH_CLOUD_PLATFORM
PROJECT_ID = "my-project"
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = "./service_account.json"
# Create a target configuration
target_configuration = Google::Apis::DeploymentmanagerV2::TargetConfiguration.new(config: {content: File.read('gcp.yaml')})
# Now create a deployment object
deployment = Google::Apis::DeploymentmanagerV2::Deployment.new(target: target_configuration, name: 'ruby-api-deployment')
# Attempt the deployment
response = deployment_manager.insert_deployment(PROJECT_ID, deployment)
Hope this helps someone

Getting the correct class when reading in ruby object from safe_yaml

I have a yaml file that stores the OAuth::AccessToken value returned by authenticating with the oauth gem. I read this file in to save myself authenticating each time.
:access_token: !ruby/object:OAuth::AccessToken
token: 0fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
secret: eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
consumer: !ruby/object:OAuth::Consumer
key: 2aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
secret: 181XXXXXXXXXXXXXXXXXXXXX
options:
:signature_method: HMAC-SHA1
:request_token_path: /oauth/request_token/
:authorize_path: /oauth/authorize
:access_token_path: /oauth/access_token/
:proxy:
:scheme: :header
:http_method: :get
:oauth_version: '1.0'
:site: http://api.mendeley.com
http_method: :get
http: !ruby/object:Net::HTTP
address: api.mendeley.com
port: 80
curr_http_version: '1.1'
no_keepalive_server: false
close_on_empty_response: false
socket:
started: false
open_timeout: 30
read_timeout: 30
continue_timeout:
debug_output:
use_ssl: false
ssl_context:
enable_post_connection_check: true
compression:
sspi_enabled: false
ssl_version:
key:
cert:
ca_file: /etc/ssl/certs/ca-certificates.crt
ca_path:
cert_store:
ciphers:
verify_mode: 1
verify_callback:
verify_depth: 5
ssl_timeout:
params:
:oauth_token: 0fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
oauth_token: 0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
:oauth_token_secret: efXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
oauth_token_secret: eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
When I read this file in using the yaml gem, everything works fine. But I'm using Jekyll and have to read this in with safe_yaml gem, and even though the yaml appears to correctly dictate the class, when I do:
auth_contents = YAML::load(File.open("auth.yaml"))
$access_token = auth_contents[":access_token"]
I get $access_token back as a hash; the class declaration is lost. This means that of course I cannot apply methods like $access_token.get, etc. How can I work around this? Any way to persuade ruby to recognize the correct class?
First of all: Make sure that you actually want to load in the class. It appears to me like you control the YAML file, but if it for some reason is loaded from somewhere you don't trust, you probably want to manually deserialize the hash.
That said, you can whitelist trusted types with safe_yaml:
SafeYAML.whitelist!(OAuth::AccessToken, OAuth::Consumer, Net::HTTP)

Mongoid: (Replication) configuration file yml not loaded

development:
hosts: [[database_1.mongolab.com, 12345], [database_2.mongolab.com, 12345]]
database: database_name
username: database_user
password: database_pass
persist_in_safe_mode: true
raise_not_found_error: false
This configuration file (config/mongoid.yml) is loaded using :
Mongoid.load!("config/mongoid.yml")
But I get this error :
Mongo::ConnectionFailure at /
Failed to connect to a master node at localhost:27017
You can create your mongoid.yml and place it anywhere you like. But be sure that on application path (config/initialization) under that you do the following:
Mongoid.load!("path/to/your/mongoid.yml")
Update
To use mongoid master in your project, set this in your Gemfile
gem "mongoid", :git => "git#github.com:durran/mongoid.git"
You are using the Sinatra configuration scheme when using Mongoid with Rails.
Try this:
development:
hosts:
- - database_1.mongolab.com
- 12345
- - database_2.mongolab.com
- 12345
database: database_name
username: database_user
password: database_pass
persist_in_safe_mode: true
raise_not_found_error: false

Mapping many-to-one in YAML

I'm trying to introduce a many-to-one kind of mapping inside a YAML configuration file for rake.
That is, I have something like:
- server: address
and I'd like to have something like:
- server: {1, 3, 5: address1; 2, 8, 12: address2}
of course, this is not the correct syntax.
This because I need a different address according to a given ID.
CONFIG['server'][3] # this should return 'address1'
CONFIG['server'][5] # this should return 'address1' too
CONFIG['server'][12] # and this should return 'address2'
Is this feasibile in some way?
Thank you in advance
It should work this way:
create a file in config called server_config.yml:
common: &common
common_stuff_foo: foo
common_stuff_bar: bar
server:
1:
<<: *common
adress: adress_for_server1
2:
<<: *common
adress: adress_for_server2
... #some other servers
12:
<<: *common
adress: adress_for_server12
put a file to config/initializers like config_servers.rb with the content
CONFIG = YAML.load_file("#{RAILS_ROOT}/config/server_config.yml")
and you might get your address via
CONFIG['server'][1]['address'] in your application
It's not tested, but I think it will work. I'm just a little bit uncertain about those numbers in the yaml-file

Resources