how to set configurations variables and access it in rails controller - ruby-on-rails-3

I have a set of parameters that needs to be initialized for elasticMQ sqs. Right now I have added in the controller as below.
sqs = RightAws::SqsGen2.new("ABCD","DEFG",{:server=>"localhost",:port=>9324,:protocol=>"http"})
what is the better way to set it in config folder and access it in controller and how to do it. Please help

Create a config file config/config.yml that will store the config variables for the different environments and load it in config/application.rb.
development:
elasticmq:
server: localhost
port: 9324
protocol: 'http'
production:
elasticmq:
server:
port:
protocol:
test:
In config/application.rb:
CONFIG = YAML.load_file("config/config.yml")[Rails.env]
The CONFIG variable is now available in the controller.So now you can do the following:
sqs = RightAws::SqsGen2.new("ABCD","DEFG",{:server=>"#{CONFIG['elasticmq']['server']}",:port=> "#{CONFIG['elasticmq']['port']}",:protocol=>"#{CONFIG['elasticmq']['protocol']}"})

Related

How to pass environment array configuration properties with docker-compose dynamically?

I have an ASP .NET Core Web API app that is deployed on a docker linux container.
Now I need to upgrade my app configuration including an emails array, it is not a problem until I need to pass this array using docker-compose.yml.
This is the C# code I use to retrieve the configuration:
List<string> emails = _config.GetSection("Checker:EMails").Get<List<string>>();
These are my linux environments variables as explained by microsoft:
export Checker__RefreshTime="86400000"
export Checker__DaysToCheck="15"
#emails array
export Checker__EMails__0="my_email1#my.com"
export Checker__EMails__1="my_email2p#my.com"
docker-compose.yml file:
environment:
# the following line passes the host environment var to the container created from the image
# Checker configuration
- Checker__RefreshTime=${Checker__RefreshTime}
- Checker__DaysToCheck=${Checker__DaysToCheck}
How can I include the emails array dynamically without the necessity to change docker-compose.yml file every time? Because now I need to do something like:
environment:
# the following line passes the host environment var to the container created from the image
# Checker configuration
- Checker__RefreshTime=${Checker__RefreshTime}
- Checker__DaysToCheck=${Checker__DaysToCheck}
- Checker__EMails__0=${Checker__EMails__0}
- Checker__EMails__1=${Checker__EMails__1}
# etc..
You can use an file to store the environment variables and call the file from your docker-compose file.
Instead of:
environment:
- Checker__RefreshTime=${Checker__RefreshTime}
- Checker__DaysToCheck=${Checker__DaysToCheck}
- Checker__EMails__0=${Checker__EMails__0}
- Checker__EMails__1=${Checker__EMails__1}
use:
env_file: filename.env

Traefik 2 set passHostHeader globally and not per service?

I'm using traefik internally as a gateway and thus want to always have passtHostHeader: false for default as to not always have it repeatedly set on each service.
I looked through the
ENVs
cli arguments &
dynamic configuration reference
but to no avail.
Is there a way to achieve this?
my dynamic-file.yml
routers:
ext-service-router:
rule: "PathPrefix(`/ext-service`)
service: ext-service-service
services:
ext-service-service:
loadBalancer:
passHostHeader: false # I want this to be the default and not need to set it
servers:
- URL: "https://my-ext-service.example.com"

Traefik v2 as a reverse proxy without docker

I have read the documentation but I can not figure out how to configure Traefik v2 to replace Nginx as a reverse proxy for web sites (virtual hosts) without involving Docker. Ideally there would be let'sencrypt https as well.
I have a service running at http://127.0.0.1:4000 which I would like to reverse proxy to from http://myhost.com:80
This is the configuration i've come up with so far:
[Global]
checkNewVersion = true
[log]
level = "DEBUG"
filePath = "log-file.log"
[accessLog]
filePath = "log-access.log"
bufferingSize = 100
[entrypoints]
[entrypoints.http]
address = ":80"
[http]
[http.routers]
[http.routers.my-router]
rule = "Host(`www.myhost.com`)"
service = "http"
entrypoint=["http"]
[http.services]
[http.services.http.loadbalancer]
[[http.services.http.loadbalancer.servers]]
url = "http://127.0.0.1:4000"
I figured it out,
the first part to note is that in traefik v2 there are two types of configuration, static and dynamic. So I created two files, traefik.toml and traefik-dynamic.toml.
contents of traefik.toml:
[log]
level = "DEBUG"
filePath = "log-file.log"
[accessLog]
filePath = "log-access.log"
bufferingSize = 100
[providers]
[providers.file]
filename = "traefik-dynamic.toml"
[api]
dashboard = true
debug = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web-secure]
address = ":443"
[entryPoints.dashboard]
address = ":8080"
[certificatesResolvers.sample.acme]
email = "myemail#example.com"
storage = "acme.json"
[certificatesResolvers.sample.acme.httpChallenge]
# used during the challenge
entryPoint = "web"
traefik-dynamic.toml:
[http]
# Redirect to https
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
scheme = "https"
[http.routers]
[http.routers.my-router]
rule = "Host(`www.example.com`)"
service = "phx"
entryPoints = ["web-secure"]
[http.routers.my-router.tls]
certResolver = "sample"
[http.services]
[http.services.phx.loadbalancer]
[[http.services.phx.loadbalancer.servers]]
url = "http://127.0.0.1:4000"
You can also use Traefik v2 to reverse proxy to a service running on the localhost without using Nginx as explained here using File (and not Docker provider) for Traefik.
First, route calls to myhost.com through localhost by updating /etc/hosts like:
127.0.0.1 myhost.com
Create a minimal docker-compose.yml like:
version: "3.7"
services:
proxy:
image: traefik:2.0
command:
- "--providers.file.filename=/etc/traefik/proxy-config.toml"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- ./proxy-config.toml:/etc/traefik/proxy-config.toml:ro
This Compose file creates a read-only volume containing the dynamic configuration for the Traefik reverse proxy standing in for Nginx as requested. It uses the File provider for Traefik and not Docker and a blank HTTP address mapped to port 80 for the entrypoint. This is a complete Compose file in itself. Beyond that all that's needed is the reverse proxy configuration for Traefik.
Configure the Traefik reverse proxy proxy-config.toml in the same directory:
[http.routers.test-streamrouter]
rule = "Host(`myhost.com`)"
service = "test-loadbalancer"
entryPoints = ["web"]
[[http.services.test-loadbalancer.loadBalancer.servers]]
url = "http://host.docker.internal:4000"
This is a sample reverse proxy in its entirety. It can be enhanced with middlewares to perform URL rewriting, update domain names or even redirect users if that's your aim. A single load balancer is used as shown in this answer. And host.docker.internal is used to return the host's internal networking address.
Note: At time of writing "host.docker.internal" only works with Docker for Mac and will fail on Linux. However, you may be able to use the Compose service name instead (i.e. "proxy").
Once you get this working you can set up the Let's Encrypt stuff or swap between development and production configurations using the TRAEFIK_PROVIDERS_FILE_FILENAME environment variable.
You can
use container names within the same bridged network instead of localhost
link middlewares and services without #file suffix
Please mind, that in the yaml and toml file, you need to pay attention to lower-uppercase of the properties. Whereas in docker it is loadbalancer, you need to write loadBalencer in the config file.
http:
middlewares:
docs:
stripPrefix:
prefixes:
- "/docs"
restapi:
stripPrefix:
prefixes:
- "/api/v1"
routers:
restapi:
rule: "PathPrefix(`/api/v1`)"
middlewares:
- "restapi"
service: "restapi"
entryPoints:
- http
docs:
rule: "PathPrefix(`/docs`)"
middlewares:
- "docs"
service: "docs"
entryPoints:
- http
client:
rule: "PathPrefix(`/`)"
service: "client"
entryPoints:
- http
help:
rule: "PathPrefix(`/server/sicon/help`)"
services:
restapi:
loadBalancer:
servers:
- url: "http://sicon_backend:1881"
docs:
loadBalancer:
servers:
- url: "http://sicon_backend:1882"
client:
loadBalancer:
servers:
- url: "http://sicon_client"

Spring cloud config git refreshRate behaviour

I am trying to setup Spring Cloud Config Server and want to enable auto refresh of properties based on changes to the backing git repository.
Below is the bootstrap.yml of the server.
server:
port: 8080
spring:
application:
name: my-configserver
cloud:
config:
server:
bootstrap: true
git:
uri: /Users/anoop/Documents/centralconfig
refreshRate: 15
searchPaths: {application}/properties
bus:
enabled: true
As per the documentation spring.cloud.config.server.git.refreshRate determines
how often the config server will fetch updated configuration data from
your Git backend
I see that the config clients are not notified of changes, when the configuration changes. I have not configured a git hook for this and was hoping that just setting the property would do the job.
Anoop
Since you have configured the refreshRate property, whenever config client (other applications) call config server to fetch properties (this happens when either the application starts or application calls /actuator/refresh endpoint), they will get properties which were fetched 15 seconds (your refreshRate) old.
By default the refreshRate property is set to 0, meaning any time client applications ask for property config server will fetch latest from GIT.
I don't think there is any property which lets your client apps get notified in case of change/commits in the GIT. This is something your app needs to do by calling actuator/refresh endpoint. This can be done programmatically using some scheduler (though I wouldn't recommend that).
By default, the config client just reads the properties in git repo at startup and not again.
You can actually have a way to workaround by force bean to refresh its configuration from the config server.
First, you need to add #RefreshScope annotation in the bean where config needs to be reloaded.
Second, enable spring boot actuator in application.yml of config client.
# enable dynamic configuration changes using spring boot actuator
management:
endpoints:
web:
exposure:
include: '*'
And then config a scheduled job (by using #Scheduled annotation with fixedRate,...). Of course, fixedRate should conform with refreshRate from config server.
And inside that job, it will execute the request as below:
curl -X POST http://username:password#localhost:8888/refresh
Then your config client will be notified changes in config repo every fixRate interval.
The property spring.cloud.config.server.git.refreshRate is configured in the Config Server and controls how frequently it is going to pull updates, if any, from Git. Otherwise, the Config Server's default behaviour is to connect to the Git repo only when some client requests its configuration.
Git Repo -> Config Server
It has no effect in the communication between the Config Server and its clients.
Config Server -> Spring Boot app (Config Server clients)
Spring Boot apps built with Config Server clients pull all configuration from the Config Server during their startup. To enable them to dynamically change the initially loaded configuration, you need to perform the following steps in your Spring Boot apps aka Config Server clients:
Include Spring Boot Actuator in the classpath, for example using Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Enable the actuator refresh endpoint via the management.endpoints.web.exposure.include=refresh property
Annotate the Beans holding the properties in your code with #RefreshScope, for example:
#RefreshScope
#Service
public class BookService {
#Value("${book.default-page-size:20}")
private int DEFAULT_PAGE_SIZE;
//...
}
With the application running, commit some property change into the repo:
git commit -am "Testing property changes"
Trigger the updating process by sending a HTTP POST request to the refresh endpoint, for example (using httpie and assuming your app is running locally at the port 8080:
http post :8080/actuator/refresh
and the response should be something like below indicating which properties, if any, have changed
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/vnd.spring-boot.actuator.v3+json
Date: Wed, 30 Jun 2021 10:18:48 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
[
"config.client.version",
"book.default-page-size"
]

how to set local path in yaml configuration file in microservice

Here all the properties file are in github location,so that I am able to read using uri path ,how I will read if It's in my local system.Can anybody please guide ?
server:
port: 8888
eureka:
instance:
hostname: configserver
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://discovery:8761/eureka/
spring:
cloud:
config:
server:
git:
uri: https://github.com/****/******
You need to use spring cloud config in native mode, e.g.
spring:
cloud:
config:
server:
bootstrap: true
native:
search-locations: file:///C:/ConfigData
See the following link for more information:
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_file_system_backend