ConfigLMM 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.yardopts +4 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Examples/Android.mm.yaml +8 -0
  6. data/Examples/Apps/Blog.mm.yaml +7 -0
  7. data/Examples/Apps/Jellyfin.mm.yaml +3 -0
  8. data/Examples/Implemented.mm.yaml +155 -0
  9. data/Examples/Keys.ini +7 -0
  10. data/Examples/Linux.mm.yaml +16 -0
  11. data/Examples/Windows.mm.yaml +11 -0
  12. data/Examples/configlmmAuth.sh +26 -0
  13. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +38 -0
  14. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +19 -0
  15. data/Plugins/Apps/IPFS/IPFS.conf.erb +44 -0
  16. data/Plugins/Apps/IPFS/IPFS.lmm.rb +23 -0
  17. data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +34 -0
  18. data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +19 -0
  19. data/Plugins/Apps/Jackett/Jackett.conf.erb +38 -0
  20. data/Plugins/Apps/Jackett/Jackett.lmm.rb +19 -0
  21. data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +59 -0
  22. data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +23 -0
  23. data/Plugins/Apps/Mastodon/Mastodon.conf.erb +81 -0
  24. data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +23 -0
  25. data/Plugins/Apps/Matrix/Matrix.conf.erb +36 -0
  26. data/Plugins/Apps/Matrix/Matrix.lmm.rb +23 -0
  27. data/Plugins/Apps/Netdata/Netdata.conf.erb +37 -0
  28. data/Plugins/Apps/Netdata/Netdata.lmm.rb +23 -0
  29. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +165 -0
  30. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +23 -0
  31. data/Plugins/Apps/Nginx/config-lmm/errors.conf +31 -0
  32. data/Plugins/Apps/Nginx/config-lmm/private.conf +6 -0
  33. data/Plugins/Apps/Nginx/config-lmm/proxy.conf +15 -0
  34. data/Plugins/Apps/Nginx/config-lmm/public.conf +3 -0
  35. data/Plugins/Apps/Nginx/config-lmm/ssl.conf +18 -0
  36. data/Plugins/Apps/Nginx/main.conf +30 -0
  37. data/Plugins/Apps/Nginx/nginx.conf +90 -0
  38. data/Plugins/Apps/Nginx/nginx.lmm.rb +62 -0
  39. data/Plugins/Apps/Nginx/proxy.conf.erb +31 -0
  40. data/Plugins/Apps/Odoo/Odoo.conf.erb +44 -0
  41. data/Plugins/Apps/Odoo/Odoo.lmm.rb +23 -0
  42. data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +50 -0
  43. data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +30 -0
  44. data/Plugins/Apps/Pterodactyl/Wings.conf.erb +38 -0
  45. data/Plugins/Apps/Sunshine/Sunshine.conf.erb +31 -0
  46. data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +21 -0
  47. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +48 -0
  48. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +25 -0
  49. data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +35 -0
  50. data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +19 -0
  51. data/Plugins/Apps/gollum/config.ru +11 -0
  52. data/Plugins/Apps/gollum/gollum.conf.erb +41 -0
  53. data/Plugins/Apps/gollum/gollum.lmm.rb +52 -0
  54. data/Plugins/OS/Linux.lmm.rb +64 -0
  55. data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +144 -0
  56. data/Plugins/Platforms/GitHub.lmm.rb +57 -0
  57. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +83 -0
  58. data/Plugins/Platforms/GoDaddy/zone.txt.erb +13 -0
  59. data/Plugins/Platforms/porkbun.lmm.rb +129 -0
  60. data/Plugins/Platforms/porkbun_spec.rb +110 -0
  61. data/Plugins/Services/DNS/AmberBit.lmm.rb +14 -0
  62. data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +14 -0
  63. data/Plugins/Services/DNS/NICLV.lmm.rb +18 -0
  64. data/Plugins/Services/DNS/PowerDNS.lmm.rb +261 -0
  65. data/Plugins/Services/DNS/tonic.lmm.rb +126 -0
  66. data/README.md +337 -0
  67. data/Rakefile +15 -0
  68. data/UNLICENSE +24 -0
  69. data/bin/configlmm +7 -0
  70. data/bin/console +11 -0
  71. data/bin/setup +8 -0
  72. data/lib/ConfigLMM/Framework/plugins/dns.rb +63 -0
  73. data/lib/ConfigLMM/Framework/plugins/errors.rb +23 -0
  74. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +55 -0
  75. data/lib/ConfigLMM/Framework/plugins/plugin.rb +167 -0
  76. data/lib/ConfigLMM/Framework/plugins/ssh.rb +37 -0
  77. data/lib/ConfigLMM/Framework/plugins/store.rb +57 -0
  78. data/lib/ConfigLMM/Framework/plugins.rb +5 -0
  79. data/lib/ConfigLMM/Framework/registrator.rb +32 -0
  80. data/lib/ConfigLMM/Framework.rb +9 -0
  81. data/lib/ConfigLMM/LMM/plugins.rb +5 -0
  82. data/lib/ConfigLMM/LMM.rb +8 -0
  83. data/lib/ConfigLMM/cli.rb +161 -0
  84. data/lib/ConfigLMM/command.rb +53 -0
  85. data/lib/ConfigLMM/commands/build.rb +41 -0
  86. data/lib/ConfigLMM/commands/cleanup.rb +30 -0
  87. data/lib/ConfigLMM/commands/configsCommand.rb +167 -0
  88. data/lib/ConfigLMM/commands/deploy.rb +39 -0
  89. data/lib/ConfigLMM/commands/diff.rb +45 -0
  90. data/lib/ConfigLMM/commands/list.rb +15 -0
  91. data/lib/ConfigLMM/commands/refresh.rb +46 -0
  92. data/lib/ConfigLMM/commands/types.rb +35 -0
  93. data/lib/ConfigLMM/commands/validate.rb +49 -0
  94. data/lib/ConfigLMM/context.rb +52 -0
  95. data/lib/ConfigLMM/io/configList.rb +98 -0
  96. data/lib/ConfigLMM/io/path.rb +48 -0
  97. data/lib/ConfigLMM/io/source.rb +47 -0
  98. data/lib/ConfigLMM/io.rb +2 -0
  99. data/lib/ConfigLMM/state.rb +78 -0
  100. data/lib/ConfigLMM/utils/filters.rb +126 -0
  101. data/lib/ConfigLMM/version.rb +5 -0
  102. data/lib/ConfigLMM.rb +6 -0
  103. data/sig/ConfigLMM.rbs +4 -0
  104. metadata +485 -0
data/README.md ADDED
@@ -0,0 +1,337 @@
1
+ # ConfigLMM - Large Configuration Management Manager
2
+
3
+ ## Manage The Management with ease!
4
+
5
+ You define how you want your applications/systems/containers/services/servers
6
+ to work without being vendor locked into any particular implementation or provider.
7
+
8
+ *ConfigLMM* will materialize this into whichever implementation you feel like using that day :)
9
+
10
+ **One Config to Rule Them All**:
11
+
12
+ * [Nginx](https://nginx.org/)
13
+ * [NGINX Unit](https://unit.nginx.org/)
14
+ * [Apache](https://apache.org/)
15
+ * [Docker](https://www.docker.com/)
16
+ * [Podman](https://podman.io/)
17
+ * [Kubernetes](https://kubernetes.io/)
18
+ * [Ansible](https://www.ansible.com/)
19
+ * [Chef](https://www.chef.io/)
20
+ * [Fluxcd](https://fluxcd.io/)
21
+ * [GitLab CI/CD](https://helm.sh/)
22
+ * [Helm](https://helm.sh/)
23
+ * [Puppet](https://www.puppet.com/)
24
+ * [Salt](https://saltproject.io/)
25
+ * [Spinnaker](https://spinnaker.io/)
26
+ * [Terraform](https://www.terraform.io/)
27
+ * [Amazon Web Services (AWS)](https://aws.amazon.com/)
28
+ * [DigitalOcean](https://www.digitalocean.com/)
29
+ * [Google Cloud](https://cloud.google.com/)
30
+ * [Microsoft Azure](https://azure.microsoft.com/)
31
+ * [Oracle Cloud Infrastructure (OCI)](https://www.oracle.com/cloud/)
32
+ * [OpenStack](https://www.openstack.org/)
33
+ * [VirtualBox](https://www.virtualbox.org/)
34
+ * [Chaos Monkey](https://github.com/Netflix/chaosmonkey)
35
+ * [Chaos Mesh](https://chaos-mesh.org/)
36
+ * [Cypress](https://www.cypress.io/)
37
+ * [Puppeteer](https://pptr.dev/)
38
+ * [Testsigma](https://testsigma.com/)
39
+ * [Selenium](https://www.selenium.dev/)
40
+ * [Greenbone Vulnerability Management (GVM/OpenVAS)](https://community.greenbone.net/)
41
+ * [Grype](https://github.com/anchore/grype)
42
+ * [Metasploit](https://www.metasploit.com/)
43
+ * [OpenCost](https://www.opencost.io/)
44
+ * [MSYS2](https://www.msys2.org/)
45
+ * [libvirt](https://libvirt.org/)
46
+ * [systemd](https://systemd.io/)
47
+ * [Wine](https://www.winehq.org/)
48
+ * [OpenEmbedded](https://www.openembedded.org/)
49
+ * [Yocto Project](https://www.yoctoproject.org/)
50
+ * [Nix](https://nixos.org/)
51
+ * [FreeBSD](https://www.freebsd.org/)
52
+ * [LineageOS](https://lineageos.org/)
53
+ * Any Cloud Provider
54
+ * Any kind of software (eg. [KDE](https://kde.org/), )
55
+ * Baremetal - your own host/VMs/VPS
56
+ * And everything else
57
+
58
+ The true [GitOps](https://en.wikipedia.org/wiki/DevOps#GitOps)/DevOps/DevSecOps/[TestOps](https://en.wikipedia.org/wiki/TestOps)/SysOps/[AIOps](https://en.wikipedia.org/wiki/Artificial_Intelligence_for_IT_Operations)[DataOps](https://en.wikipedia.org/wiki/DataOps) which I call AllTheOps :)
59
+
60
+ ## Benefits
61
+
62
+ * Compare performance and price among different providers
63
+ * Host different services on different providers
64
+ * Migrate from local Docker to AWS Lambda and back to on-premises Kubernetes :)
65
+ * Move your applications across operating systems (eg. Windows to Linux etc)
66
+ * Easily and quickly switch between different implementations like from Apache to Nginx and so on
67
+ * Try out and compare different software easily (eg. reverse proxies, configuration management software etc)
68
+ * Provision new baremetal host with several VMs where each host bunch of Docker containers with multiple services inside
69
+ * Configure different devices (eg. IoT, routers, smartphones, coffee machines, fridges) and environments (eg. Wine, MSYS2, WSL, chroot, raw images) and a lot of other things
70
+ * Reuse configuration among different services
71
+ * Automatically follow best practises and secure by default without having to know anything about that
72
+ * Fully test (functionality/integration/end-to-end, load/performance and alerts/monitoring) all deployed infrastructure and applications
73
+ * Scan all your infrastructure for vulnerabilities and insecure configuration
74
+ * Practise [chaos engineering](https://en.wikipedia.org/wiki/Chaos_engineering) by testing how well systems handle various faults (eg. you have RAID1 does dropping a disk really doesn't affect applications? or terminating one application instance or database or even whole region)
75
+ * Automatically cleanup unused resources and other unneeded things
76
+ * Don't be limited with what your Platform Provider tools (CLIs/SDKs/APIs) support (eg. configure things thru Web UI portal if there's no other option)
77
+ * Anything else you can think of
78
+
79
+ Are you wondering if so many features won't make this unbearably complicated and unmaintainable?
80
+
81
+ I don't think so and this project will try to show that :) In fact I think most of existing
82
+ tools are overly complex. Think about Helm Charts/CloudFormation/Kubernetes/Puppet and such.
83
+
84
+ While most tools use declarative configuration I think they still got it wrong
85
+ because they are too low level by asking you to define *HOW* to accomplish target state while I think
86
+ configuration should just describe what you *WANT* the target state to be :)
87
+
88
+ So with *ConfigLMM* you only define what you *WANT* but don't describe *HOW* to accomplish that.
89
+
90
+ Some examples with idea of defining "*WHAT I WANT*":
91
+
92
+ * I need "*THESE*" files to be at "*MYDOMAIN*" (I don't even care where it runs just make it happen)
93
+ * "*THIS*" software hosted on "*MY*" VPS using "nginx" and "Puma" (yes I do have some preferences)
94
+ * run "*THIS*" container on "*FRIENDS*" Google Cloud account in "*THOSE*" regions
95
+ * I need "*THESE*" fonts on "*ALL*" my machines
96
+
97
+ I call this intention based configuration which is used by *ConfigLMM* and it also follows convention over configuration paradigm.
98
+
99
+ PS. Looks like I'm not only one thinking this way, see [RFC 9315 - Intent-Based Networking](https://www.ietf.org/rfc/rfc9315.html).
100
+ So essentially you can think of *ConfigLMM* as loose implementation of that RFC but even more because not only Networking part.
101
+
102
+ ### Still not sold?
103
+
104
+ Then consider this scenario:
105
+
106
+ * Your brother who is a gamer bought new laptop which came with pre-installed Ubuntu
107
+ * Your mom bought Android smartphone which is her first one ever
108
+ * Your dad wants to start writing a blog and he cares deeply about his data and privacy
109
+ * Your friend who works at IoT company is looking into how to optimize company's infrastructure/software stack
110
+
111
+ So currently how would you make life easier/better for your family and friends(s)?
112
+
113
+ * Let them struggle on their own?
114
+ * Install and configure everything yourself? If so are you following best practices, with security and backups in mind? How sad your dad would be if blog stopped working? How much of your time this would take?
115
+
116
+ Let's have a meeting and find out what they actually want to do with their devices.
117
+
118
+ * Brother: I want to play Fortnite.
119
+ * Mom: Oh I don't know anything about this.
120
+ * Dad: I want to share some private articles with few friends but I don't want to give my data to [Big Tech](https://en.wikipedia.org/wiki/Big_Tech)!
121
+ * Friend: So my company has thousands of IoT devices that need firmware updates and we want to modernize/optimize our homegrown solution/control plane that has grown over many years to unimaginable complexity and has become quite fragile and thus making any changes is very risky/hard/slow.
122
+
123
+ Okay so now that we have an idea what we need we can start making it happen.
124
+ But do you know all the things that are needed to accomplish these goals? Your friend???
125
+
126
+ For brother:
127
+
128
+ * Fortnite - uses [kernel-level anti-cheat](https://lutris.net/games/fortnite/) so this rules out all non-Windows OS'es
129
+ * Need to install Windows, [Steam](https://store.steampowered.com/about/), Fortnite and his other favorite games
130
+ * You might not want ads/telemetry enabled on his Windows so need to disable those aswell
131
+ * Probably best to use privacy respecting browser
132
+ * Configure and install bunch of other things
133
+
134
+ For mom:
135
+
136
+ * You know she'll struggle with finding and installing her favorite apps so you want to preinstall those
137
+ * You might want to remove/uninstall some of already preinstalled apps because they might confuse her
138
+ * There are some settings that are not good preference for her so you want to change those aswell
139
+
140
+ For dad:
141
+
142
+ * Need some place to host blog that is not Big Tech
143
+ * Need authentication (maybe with user management?) so that he can share his private articles to friends
144
+ * For blog:
145
+
146
+ * Secure configuration and keeping up with new vulnerabilities (very common for blog software)
147
+ * Automatic backups
148
+ * Monitoring/Alerts
149
+ * Intrusion detection? What if someone gains access and posts bunch of spam there?
150
+
151
+ For friend:
152
+
153
+ *Uhm...* Yeah unless you've spent years working with IoT it's unlikely that you can help him there much.
154
+
155
+ I don't know about you but for me this all looks like *A LOT* of work.
156
+
157
+ So let's just move to the future and use *ConfigLMM* to solve all these problems :)
158
+
159
+ By using *ConfigLMM* you can create a configuration (even work together on it with family) that will satisfy everyone's needs and then make it all happen like *MAGIC* (just what they think it is)
160
+
161
+ So let's take a look at it:
162
+
163
+ ```yaml
164
+ BrotherComputer:
165
+ Type: Windows
166
+ Managed: yes
167
+ Apps:
168
+ - Steam
169
+ - Fortnite
170
+ - Roblox
171
+ - Minecraft
172
+ - Firefox
173
+
174
+ MomPhone:
175
+ Type: Android
176
+ Settings:
177
+ HomeScreen: With App drawer
178
+ Apps:
179
+ - Duolingo
180
+ Remove:
181
+ - CandyCrush
182
+
183
+ DadBlog:
184
+ # In separate context file, there is specified "Dislikes: Big Tech"
185
+ Type: Blog
186
+ Feature: User Management
187
+
188
+ Friend:
189
+ # Omitted for brevity but yes ConfigLMM would be able to configure even that
190
+ ```
191
+
192
+ Q: Wait what, is this all, *the WHOLE* config? *Yep, exactly like it should be, no more, no less :)*
193
+
194
+ Q: Then *WHY* have I been writing gazillion of bash scripts and thousands of Puppet/Kubernetes/[CDK](https://aws.amazon.com/cdk/) code lines? *For years I have been wondering the same*
195
+
196
+ Q: But what about friend how will I know how to write such config? You don't need to know how but just tell him to use *ConfigLMM* and his company's development team will spend some time creating it.
197
+
198
+ Q: How is this even possible? *MAGIC! See Implementation section for more details but generally you don't even need to care how*
199
+
200
+ ## Back to The Reality
201
+
202
+ Well unfortunately what I just described is not really implemented yet.
203
+
204
+ This is a massive project and no matter how much I want to build it - it's not realistic that I can implement it all on my own.
205
+
206
+ And this is why I'm proposing this to be a community driven project where all of us help each other by implementing some parts of it.
207
+
208
+ When thinking about all of us together then it will save a lot of time for many of us. Especially as new Apps we want to host and configure just keeps growing.
209
+
210
+ Also maybe things you want to configure are already implemented so take a look at [Examples/Implemented.mm.yaml](/Examples/Implemented.mm.yaml) and see what we already have! :)
211
+
212
+ So I ask you to try it out (you can run `confilmm types` to see what is implemented), submit your issues and Pull Requests. I definitely need your and everyone's help to achieve this project's goal.
213
+
214
+ ## Installation
215
+
216
+ First you need to have Ruby and RubyGems. Then you can install it with:
217
+
218
+ $ gem install ConfigLMM
219
+
220
+ ## Usage
221
+
222
+ Create yaml file with desired config, eg.
223
+ ```yaml
224
+ Wiki:
225
+ Type: Gollum
226
+ Domain: wiki.example.to
227
+ CertName: Gollum
228
+ Resources:
229
+ NS:
230
+ Type: TonicDNS
231
+ Domain: example.to
232
+ Nameservers:
233
+ ns.example.to: 192.168.5.5
234
+ DNS:
235
+ Type: PowerDNS
236
+ DNS:
237
+ example.to:
238
+ wiki: CNAME=@ # `@` means point it to the domain root
239
+ '@': A=@me # first `@` means domain root and `@me` means current external IP
240
+ ```
241
+
242
+ Then deploy it and let the magic happen!
243
+ ```
244
+ $ configlmm help
245
+ Commands:
246
+ configlmm build [CONFIGS...] # Build configuration in deployable form
247
+ configlmm deploy [CONFIGS...] # Deploy configuration
248
+ configlmm diff [CONFIGS...] # Show changes that will be applied with next deploy
249
+ configlmm help [COMMAND] # Describe available commands or one specific command
250
+ configlmm list [CONFIGS...] # List things
251
+ configlmm refresh [CONFIGS...] # Update local state to match deployed things
252
+ configlmm validate [CONFIGS...] # Check whether the configuration is valid
253
+ configlmm version # Show program's version
254
+
255
+ Options:
256
+ [--level=LEVEL] # Logging level to use
257
+ # Default: info
258
+ # Possible values: debug, info, warn, error
259
+ -n, [--dry], [--no-dry], [--skip-dry] # Only show actions without performing
260
+
261
+ $ configlmm deploy config.mm.yaml
262
+ Deploying...
263
+ Deploying NS: TonicDNS
264
+ Tonic - Successful DNS Change
265
+ Deploying DNS: PowerDNS
266
+ Deploying Wiki: Gollum
267
+ Deploy successful!
268
+ ```
269
+
270
+ ## FAQ
271
+
272
+ **Q: Why name it "*Large*"? Why "*L*" is after Config in *ConfigLMM*?**
273
+
274
+ To be a pun of [LLM](https://en.wikipedia.org/wiki/Large_language_model) and like with a language model you don't need to write down every single detail. Also *ConfigLMM* is definitely smarter than LLMs :)
275
+
276
+ Another thing is that it really is quite *Large*/big project to accomplish this goal with so many features.
277
+
278
+ **Q: I already have infrastructure deployer/orchestrator that I love and don't want to change so this is useless for me?**
279
+
280
+ Not necessarily, for example you can use `configlmm build` feature to create configs and then use your own orchestrator to do actual provisioning/deployment (and even do additional customization on built configs).
281
+
282
+ **Q: Aren't this many features a bit too much?**
283
+
284
+ No :)
285
+
286
+ **Q: Is this actually doable?**
287
+
288
+ Yes :)
289
+
290
+ **Q: Are you crazy/insane?**
291
+
292
+ Yes :) But maybe everyone/whole world is by learning hundreds of different tools with different versions each with dozens of incompatible/conflicting options/flags and some with couple of configuration files aswell.
293
+
294
+ I think the complexity of that is insane and the amount of different tools only keeps growing.
295
+
296
+ Can you count how many different tools/programs have you used today/this week/month? What about in a year or in your whole life together?
297
+
298
+
299
+ ## Implementation
300
+
301
+ To accomplish this functionality *ConfigLMM* consists of 3 main parts:
302
+
303
+ 1. High level configuration file format (superset/abstraction) that describes your infrastructure intentions
304
+ 2. Core Framework that holds *ConfigLMM* together
305
+ 2. Plugins for different apps/services/systems which implement build/deploy logic using provided configuration
306
+
307
+ Note that this project is in very early development stage and so there won't really be API/spec stability for some while.
308
+ You might need to update your configuration as new versions are released and design iterated and improved with time.
309
+ Unfortunately that's the sad reality we live in and things can't always be perfect from the start :)
310
+
311
+ ## Development
312
+
313
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
314
+
315
+ To install this gem onto your local machine, run `bundle exec rake install`.
316
+
317
+ ## Contributing
318
+
319
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ConfigLMM/ConfigLMM.
320
+ Pretty Please! :)
321
+
322
+ ### Implement a new Plugin
323
+
324
+ To implement a new Plugin, simply create a file with name `$pluginName.lmm.rb` and put it in respective category in `Plugins` folder.
325
+
326
+ Then in that file create a method with name `action#{pluginName}Deploy` and implement logic there. It will be loaded automatically so you don't need any other changes.
327
+
328
+ I highly recommend looking at existing plugins. Also you can copy and rename `porkbun.lmm.rb` to use as a base.
329
+
330
+ ### Model Configuration for App/Service/System
331
+
332
+ Try to model your existing infrastructure with high level YAML and submit those under Examples folder.
333
+
334
+ This will allow us to come up with best design for configuration file format even before we start implementing such configuration.
335
+
336
+ And you never know, maybe someone will love it so much he'll implement necessary Plugins so then others and you will be able to use *configlmm* to deploy such infrastructure.
337
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'yard'
6
+
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.pattern = 'spec/**/*_spec.rb,Plugins/**/*_spec.rb'
9
+ end
10
+
11
+ YARD::Rake::YardocTask.new(:doc) do |t|
12
+ t.files = ['**/*.rb', '*.rb', '-', '*.md']
13
+ end
14
+
15
+ task default: :spec
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
data/bin/configlmm ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # frozen_string_literal: true
4
+
5
+ require_relative '../lib/ConfigLMM/cli'
6
+
7
+ ConfigLMM::CLI.start
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'ConfigLMM'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require 'irb'
11
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,63 @@
1
+
2
+ # frozen_string_literal: true
3
+ require_relative 'plugin'
4
+
5
+ module ConfigLMM
6
+ module Framework
7
+
8
+ class DNS < Framework::Plugin
9
+ DEFAULT_TTL = 600
10
+
11
+ def processDNS(domain, items)
12
+ records = {}
13
+
14
+ if items.is_a?(Hash)
15
+ # More complicated structure with Hash
16
+ # TODO Implement TTL
17
+ raise 'Hash object not implemented!'
18
+ end
19
+
20
+ if items.is_a?(String)
21
+ items = items.split(';')
22
+ end
23
+
24
+ items.each do |item|
25
+ type, content = item.strip.split('=')
26
+ content += '.' if type == 'CNAME' || type == 'ALIAS'
27
+ content = domain + '.' if content == '@' || content == '@.'
28
+ content = self.class.externalIp if content == '@me'
29
+ records[type] ||= []
30
+ records[type] << { type: type, content: content, ttl: DEFAULT_TTL }
31
+ end
32
+
33
+ records
34
+ end
35
+
36
+ def showManualDNSSteps(target, message)
37
+ if !target['DNS'].to_h.empty?
38
+ target['DNS'].each do |domain, data|
39
+ yield(domain)
40
+ prompt.say(message, :color => :magenta) if message
41
+ data.each do |name, data|
42
+ self.processDNS(domain, data).each do |type, records|
43
+ records.each do |record|
44
+ prompt.say(" * Type: #{record[:type]}\n Name: #{name}\n Content: #{record[:content]}", :color => :bold)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def self.externalIp
53
+ return @ExternalIp if @ExternalIp
54
+ @ExternalIp = HTTP.get('https://api.ipify.org').body.to_s
55
+ end
56
+
57
+ def self.externalIp=(ip)
58
+ @ExternalIp = ip
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ module Framework
5
+ PluginMissingError = Class.new(RuntimeError)
6
+
7
+ class PluginError < RuntimeError
8
+ def initialize(message, cause = nil)
9
+ super(message)
10
+ @cause = cause
11
+ end
12
+
13
+ def cause
14
+ @cause
15
+ end
16
+ end
17
+
18
+ PluginLoadError = Class.new(PluginError)
19
+ PluginProcessError = Class.new(PluginError)
20
+ PluginAuthError = Class.new(PluginError)
21
+ PluginPrerequisite = Class.new(PluginError)
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'plugin'
5
+ require_relative 'errors'
6
+ require_relative 'store'
7
+ require 'addressable/idna'
8
+ require 'http'
9
+ require 'fileutils'
10
+
11
+ module ConfigLMM
12
+ module Framework
13
+
14
+ class NginxApp < Framework::Plugin
15
+
16
+ def writeNginxConfig(dir, name, id, target, activeState, context, options)
17
+ outputFolder = options['output']
18
+
19
+ updateTargetConfig(target)
20
+
21
+ template = ERB.new(File.read(dir + '/' + name + '.conf.erb'))
22
+ renderTemplate(template, target, outputFolder + '/nginx/servers-lmm/' + name + '.conf', options)
23
+ plugins[:Nginx].actionNginxBuild(id, target, activeState, context, options)
24
+ end
25
+
26
+ def deployNginxConfig(id, target, activeState, context, options)
27
+ outputFolder = options['output']
28
+
29
+ if !target['Location'] || target['Location'] == '@me'
30
+ copy(outputFolder + '/nginx/servers-lmm', '/etc/nginx/', options['dry'])
31
+ end
32
+
33
+ plugins[:Nginx].actionNginxDeploy(id, target, activeState, context, options)
34
+ end
35
+
36
+ def cleanupNginxConfig(name, id, state, context, options)
37
+ rm('/etc/nginx/servers-lmm/' + name + '.conf', options['dry'])
38
+ end
39
+
40
+ private
41
+
42
+ def updateTargetConfig(target)
43
+ target['TLS'] = true if target['TLS'].nil?
44
+
45
+ if !target['Port']
46
+ target['Port'] = target['TLS'] ? 443 : 80
47
+ end
48
+ if target['Domain']
49
+ target['Domain'] = Addressable::IDNA.to_ascii(target['Domain'])
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end