https://github.com/swisscom/hfc
https://github.com/swisscom/hfc
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/swisscom/hfc
- Owner: swisscom
- License: mit
- Created: 2019-03-25T12:43:04.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-08-22T15:33:06.000Z (almost 7 years ago)
- Last Synced: 2025-03-04T22:02:06.027Z (over 1 year ago)
- Language: Ruby
- Size: 35.2 KB
- Stars: 1
- Watchers: 14
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# (H)ierarchical(F)acts(C)onfig
## Installation
### Gem
Add this line to your application's Gemfile:
```ruby
gem 'hfc'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install hfc
### config
download the example config from the "config" directory and store it at /opt/hfc/ or set ``env HFC=/my/path
Setup the hierarchy according to your preference and start generating the config based on the facts you give it.
### Supported extensions
- .rb
- .yaml
- .yml
- .json
### Versioning
You can either version your own config folder using git or you can gemify it:
```
bundle exec gem Company-Config
```
```ruby
# company-config/lib/company/config.rb
require 'hfc'
module Company
module Config
def self.dir
File.join(__dir__,"..","..","hfc")
end
Dir = File.join(__dir__,"..","..","hfc")
end
class HFC
include ::HFC_Base
def initialize(lookup_paths: [::Company::Config::Dir, File.join(ENV['HOME'].to_s, '.config', 'hfc')], **opts)
super(lookup_paths: lookup_paths, **opts)
end
end
end
```
```ruby
require 'company/config'
company_hfc = Company::Config.new
```
Now you have your own config gem which includes your config data. You can version it and include it in any project.
The biggest advantage is the semantic versioningi. You can declare now breaking changes of your config.
## Idea
(H)ierarchical (F)acts (C)onfiguration
### Facts
In HFC, the facts decide which files get deep-merged into one giant configuration. For every Fact it will try to find the corresponding file in the fact-folder.
No facts:
```
|
|- {}
|- merge: config/common.(yaml|rb|*)
|- {...}
```
Facts: {domain: "com"}
```
|
|- {}
|- merge: common.(yaml|rb|*)
|- merge: domain/com.(yaml|rb|*)
|- merge: domain/com/*.(yaml|rb|*)
|- {...}
```
Facts: {hostname: "localhost", domain: "com"}
```
|
|- {}
|- merge: common.(yaml|rb|*)
|- merge: domain/com.(yaml|rb|*)
|- merge: domain/com/*.(yaml|rb|*)
|- merge: hostname/localhost.(yaml|rb|*)
|- merge: hostname/localhost/*(yaml|rb|*)
|- {...}
```
You can build up this hierarchy of facts with as many facts as you wish.
### Facts Hierachy
The lookup order of facts itself can defined in hfc.yaml, but can be also set anywhere else.
See `config/hfc.yaml` for example.
```yaml
---
hfc:
hierarchy:
- :domain
- :hostname
```
### Facts by name
Facts can also be extracted by using named matches of a regex.
```yaml
hfc:
by_name:
hostname: !ruby/regexp '/(?(?[a-z0-9]+)\.?(?.*))/i'
```
```ruby
facts = HFC.facts_by_name("gitlab.com")
# => {fqdn: "gitlab.com", hostname: "gitlab", domain: "com"}
```
### Join Facts
It's also possible to join facts to create a new fact.
```yaml
hfc:
join_facts:
reverse-hostname:
- :domain
- :hostname
```
```
reverse-hostname = "#{domain}-#{hostname}"
```
### Facts by Facts
Facts can also create new facts
```yaml
hfc:
by_facts:
fqdn:
"127.0.0.1":
hostname: "localhost"
```
If the fact "fqdn" equals to "127.0.0.1", then the fact "hostname" will be set to "localhost"
## Usage
```
hfc --name gitlab.com
```
```ruby
facts = HFC.facts_by_name("gitlab.com")
config = HFC.lookup(facts)
```
### HFC#fetch
```ruby
facts = HFC.facts_by_name("127.0.0.1")
config = HFC.lookup(facts: facts)
config.fetch()
# => {my: {nested: {setting: true}}}
config.fetch(:my)
# => {nested: {setting: true}}
config.fetch(:my, "nested")
# => {setting: true}
config.fetch(:my, :nested, :setting)
# => true
```
### HFC#fetch uses internally HashWithIndifferentAccess
```ruby
config.fetch(:my, "nested")
# => {setting: true}
```
```ruby
config.fetch(:my, :nested)
# => {setting: true}
```
### HFC#[]
hfc#`[]` is an alias of hfc#`fetch`
```ruby
config[:my, :nested]
# => {setting: true}
```
## Why not use ___ ?
This gem is inspired by
- hiera https://github.com/puppetlabs/hiera
- tty-config https://github.com/piotrmurach/tty-config
## Development
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/swisscom/hfc.