waylon 0.1.9 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +64 -27
- data/README.md +115 -7
- data/examples/deploying/helm/waylon/.helmignore +16 -0
- data/examples/deploying/helm/waylon/Chart.yaml +5 -0
- data/examples/deploying/helm/waylon/README.md +71 -0
- data/examples/deploying/helm/waylon/templates/_helpers.tpl +7 -0
- data/examples/deploying/helm/waylon/templates/redis-pv.yaml +19 -0
- data/examples/deploying/helm/waylon/templates/redis-pvc.yaml +18 -0
- data/examples/deploying/helm/waylon/templates/redis-statefulset.yaml +107 -0
- data/examples/deploying/helm/waylon/templates/web-deployment.yaml +99 -0
- data/examples/deploying/helm/waylon/templates/web-ingress.yaml +48 -0
- data/examples/deploying/helm/waylon/templates/web-service.yaml +26 -0
- data/examples/deploying/helm/waylon/templates/worker-deployment.yaml +101 -0
- data/examples/deploying/helm/waylon/values.yaml +50 -0
- data/examples/deploying/k8s/README.md +11 -0
- data/examples/deploying/k8s/redis-statefulset.yaml +86 -0
- data/examples/deploying/k8s/web-deployment.yaml +85 -0
- data/examples/deploying/k8s/web-ingress.yaml +32 -0
- data/examples/deploying/k8s/web-service.yaml +18 -0
- data/examples/deploying/k8s/worker-deployment.yaml +87 -0
- data/exe/waylon +284 -0
- data/scripts/test.sh +2 -0
- data/waylon.gemspec +2 -1
- metadata +34 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb325165305f7aa6a4fd6aa4884d83271ab6e80b6723a23dd9ab8807639da527
|
4
|
+
data.tar.gz: 0f2a970931faa5b246fd914fd6a489b1155db761d4f6a65e84f4db4f9c8ac211
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b8a3c3f75ba31787d6d331128c8186968d9986add25396f956a946842793d541d4a3ca5e1c10f5c29fae102c4262c7086f131256cd2438e8b2229815e781e13
|
7
|
+
data.tar.gz: f00d14c4f34bab4ed359240664ad2eefcf6a5ba90563c519f4d86026e50c1b16d3ce7228ef18662aac5d8a744e702b0999574aa170c83fd70169f030a5c234f5
|
data/Gemfile.lock
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
waylon (0.
|
4
|
+
waylon (0.2.4)
|
5
5
|
rake (~> 13.0)
|
6
6
|
waylon-core
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.8.
|
12
|
-
public_suffix (>= 2.0.2, <
|
11
|
+
addressable (2.8.1)
|
12
|
+
public_suffix (>= 2.0.2, < 6.0)
|
13
13
|
ast (2.4.2)
|
14
|
+
backport (1.2.0)
|
15
|
+
benchmark (0.2.0)
|
14
16
|
concurrent-ruby (1.1.10)
|
17
|
+
connection_pool (2.2.5)
|
15
18
|
diff-lcs (1.5.0)
|
16
19
|
docile (1.4.0)
|
17
|
-
|
20
|
+
e2mmap (0.1.0)
|
21
|
+
faraday (1.10.2)
|
18
22
|
faraday-em_http (~> 1.0)
|
19
23
|
faraday-em_synchrony (~> 1.0)
|
20
24
|
faraday-excon (~> 1.1)
|
@@ -38,38 +42,53 @@ GEM
|
|
38
42
|
faraday-rack (1.0.0)
|
39
43
|
faraday-retry (1.0.3)
|
40
44
|
ffi (1.15.5)
|
41
|
-
i18n (1.
|
45
|
+
i18n (1.12.0)
|
42
46
|
concurrent-ruby (~> 1.0)
|
47
|
+
jaro_winkler (1.5.4)
|
43
48
|
json (2.6.2)
|
49
|
+
kramdown (2.4.0)
|
50
|
+
rexml
|
51
|
+
kramdown-parser-gfm (1.1.0)
|
52
|
+
kramdown (~> 2.0)
|
44
53
|
moneta (1.5.1)
|
45
54
|
mono_logger (1.1.1)
|
46
55
|
multi_json (1.15.0)
|
47
56
|
multipart-post (2.2.3)
|
48
|
-
mustermann (
|
57
|
+
mustermann (2.0.2)
|
49
58
|
ruby2_keywords (~> 0.0.1)
|
50
59
|
nio4r (2.5.8)
|
60
|
+
nokogiri (1.13.8-arm64-darwin)
|
61
|
+
racc (~> 1.4)
|
62
|
+
nokogiri (1.13.8-x86_64-linux)
|
63
|
+
racc (~> 1.4)
|
51
64
|
parallel (1.22.1)
|
52
|
-
parser (3.1.2.
|
65
|
+
parser (3.1.2.1)
|
53
66
|
ast (~> 2.4.1)
|
54
|
-
public_suffix (
|
55
|
-
puma (5.6.
|
67
|
+
public_suffix (5.0.0)
|
68
|
+
puma (5.6.5)
|
56
69
|
nio4r (~> 2.0)
|
57
|
-
|
58
|
-
rack
|
70
|
+
racc (1.6.0)
|
71
|
+
rack (2.2.4)
|
72
|
+
rack-protection (2.2.2)
|
59
73
|
rack
|
60
74
|
rainbow (3.1.1)
|
61
75
|
rake (13.0.6)
|
62
76
|
rbnacl (7.1.1)
|
63
77
|
ffi
|
64
|
-
redis (
|
65
|
-
|
66
|
-
|
78
|
+
redis (5.0.1)
|
79
|
+
redis-client (~> 0.7)
|
80
|
+
redis-client (0.7.1)
|
81
|
+
connection_pool
|
82
|
+
redis-namespace (1.9.0)
|
83
|
+
redis (>= 4)
|
67
84
|
regexp_parser (2.5.0)
|
68
|
-
resque (2.
|
85
|
+
resque (2.3.0)
|
69
86
|
mono_logger (~> 1.0)
|
70
87
|
multi_json (~> 1.0)
|
71
88
|
redis-namespace (~> 1.6)
|
72
89
|
sinatra (>= 0.9.2)
|
90
|
+
reverse_markdown (2.1.1)
|
91
|
+
nokogiri
|
73
92
|
rexml (3.2.5)
|
74
93
|
rspec (3.11.0)
|
75
94
|
rspec-core (~> 3.11.0)
|
@@ -84,21 +103,22 @@ GEM
|
|
84
103
|
diff-lcs (>= 1.2.0, < 2.0)
|
85
104
|
rspec-support (~> 3.11.0)
|
86
105
|
rspec-support (3.11.0)
|
87
|
-
rubocop (1.
|
106
|
+
rubocop (1.35.1)
|
107
|
+
json (~> 2.3)
|
88
108
|
parallel (~> 1.10)
|
89
|
-
parser (>= 3.1.
|
109
|
+
parser (>= 3.1.2.1)
|
90
110
|
rainbow (>= 2.2.2, < 4.0)
|
91
111
|
regexp_parser (>= 1.8, < 3.0)
|
92
112
|
rexml (>= 3.2.5, < 4.0)
|
93
|
-
rubocop-ast (>= 1.
|
113
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
94
114
|
ruby-progressbar (~> 1.7)
|
95
115
|
unicode-display_width (>= 1.4.0, < 3.0)
|
96
|
-
rubocop-ast (1.
|
116
|
+
rubocop-ast (1.21.0)
|
97
117
|
parser (>= 3.1.1.0)
|
98
118
|
rubocop-rake (0.6.0)
|
99
119
|
rubocop (~> 1.0)
|
100
|
-
rubocop-rspec (2.
|
101
|
-
rubocop (~> 1.
|
120
|
+
rubocop-rspec (2.12.1)
|
121
|
+
rubocop (~> 1.31)
|
102
122
|
ruby-progressbar (1.11.0)
|
103
123
|
ruby2_keywords (0.0.5)
|
104
124
|
simplecov (0.21.2)
|
@@ -107,14 +127,30 @@ GEM
|
|
107
127
|
simplecov_json_formatter (~> 0.1)
|
108
128
|
simplecov-html (0.12.3)
|
109
129
|
simplecov_json_formatter (0.1.4)
|
110
|
-
sinatra (2.2.
|
111
|
-
mustermann (~>
|
130
|
+
sinatra (2.2.2)
|
131
|
+
mustermann (~> 2.0)
|
112
132
|
rack (~> 2.2)
|
113
|
-
rack-protection (= 2.2.
|
133
|
+
rack-protection (= 2.2.2)
|
114
134
|
tilt (~> 2.0)
|
115
|
-
|
116
|
-
|
117
|
-
|
135
|
+
solargraph (0.46.0)
|
136
|
+
backport (~> 1.2)
|
137
|
+
benchmark
|
138
|
+
bundler (>= 1.17.2)
|
139
|
+
diff-lcs (~> 1.4)
|
140
|
+
e2mmap
|
141
|
+
jaro_winkler (~> 1.5)
|
142
|
+
kramdown (~> 2.3)
|
143
|
+
kramdown-parser-gfm (~> 1.1)
|
144
|
+
parser (~> 3.0)
|
145
|
+
reverse_markdown (>= 1.0.5, < 3)
|
146
|
+
rubocop (>= 0.52)
|
147
|
+
thor (~> 1.0)
|
148
|
+
tilt (~> 2.0)
|
149
|
+
yard (~> 0.9, >= 0.9.24)
|
150
|
+
thor (1.2.1)
|
151
|
+
tilt (2.0.11)
|
152
|
+
unicode-display_width (2.2.0)
|
153
|
+
waylon-core (0.2.4)
|
118
154
|
addressable (~> 2.8)
|
119
155
|
faraday (~> 1.8)
|
120
156
|
i18n (~> 1.8)
|
@@ -139,6 +175,7 @@ DEPENDENCIES
|
|
139
175
|
rubocop-rake (~> 0.6)
|
140
176
|
rubocop-rspec (~> 2.6)
|
141
177
|
simplecov (~> 0.21)
|
178
|
+
solargraph (~> 0.45)
|
142
179
|
waylon!
|
143
180
|
yard (~> 0.9, >= 0.9.27)
|
144
181
|
|
data/README.md
CHANGED
@@ -1,10 +1,122 @@
|
|
1
1
|
# Waylon
|
2
2
|
|
3
|
-
This is a convenience gem for making the installation of [Waylon::Core](https://github.com/jgnagy/waylon-core) easier.
|
3
|
+
This is a convenience gem for making the installation of [Waylon::Core](https://github.com/jgnagy/waylon-core) easier. As a framework, Waylon is inspired by [Lita](https://www.lita.io/) and should be intuitive for anyone familiar with it. Waylon is built to make creating bots of many different kinds easy, fun, and flexible.
|
4
4
|
|
5
|
-
|
5
|
+
It supports different kinds of sensory inputs (chat platforms, web endpoints, and more), as well as easy to build Skills, built-in and extensible permissions, modern JSON logging, and more.
|
6
6
|
|
7
|
-
|
7
|
+
## Why Call it 'Waylon'?
|
8
|
+
|
9
|
+
Waylon just seemed like a good name for a bot. Plus, the gem name was available. That's really all there is to it.
|
10
|
+
|
11
|
+
Also, the author of the Waylon framework is a fan of The Simpsons, so it is a bit of a bonus that there is a character on that show called "Waylon Smithers, Jr." that is a faithful assistant to "Mr. Burns". Note that while it is a nice coincidence that Waylon shares its name with "Smithers" from that show, neither this framework nor any code within it is inspired by, related to, associated with, or endorsed by that show. Any similarity is entirely coincidental and unintentional.
|
12
|
+
|
13
|
+
## Why Make a New Bot Framework?
|
14
|
+
|
15
|
+
As a framework, Waylon was designed with several features in mind:
|
16
|
+
|
17
|
+
* Scalability
|
18
|
+
* Using a pub-sub model and workers based on a queue, scaling up workers is fast and simple
|
19
|
+
* Using a shared cache and shared storage, worker instances are completely stateless
|
20
|
+
* Support for more than just chat-based features
|
21
|
+
* Simple Webhook-based Senses
|
22
|
+
* Senses that route based on more than just regex
|
23
|
+
* Advanced chat-based features
|
24
|
+
* Built-in concepts like threaded-replies, reactions, and more
|
25
|
+
* Support for complex responses using cards, blocks, etc. (based on the Sense's capabilities)
|
26
|
+
* Security
|
27
|
+
* Storage is automatically encrypted
|
28
|
+
* Groups (and permissions) are a first-class concept, though user and group implementations are modular
|
29
|
+
* Dedicated inbound server process for webhooks that can be locked down (e.g, read-only and very limited capabilities)
|
30
|
+
|
31
|
+
This is all while staying familiar to users of Lita. The goal is to make it simple to build powerful bot features while also making it straightforward to migrate existing ones.
|
32
|
+
|
33
|
+
Many of these features would be difficult to port to existing frameworks.
|
34
|
+
|
35
|
+
## Getting Started
|
36
|
+
|
37
|
+
### Creating A New Skill
|
38
|
+
|
39
|
+
Waylon's abilities, usually for responding to input (things like replying to a chat message or responding to a webhook) are packaged in plugins called `Skills`. These Skills use what are called `Routes` to determine what to do with input (and whether or not input can be handled by a particular Skill).
|
40
|
+
|
41
|
+
In most cases, a route needs to be defined that matches some text. Waylon supports [Regular Expressions](https://www.rubyguides.com/2015/06/ruby-regex/) to perform this matching, though other forms of `Conditions` can easily be implemented (we'll save that for another time).
|
42
|
+
|
43
|
+
Finally, we'll need to define an _action_ that is performed when input matches a Route. This is usually just a standard method in Ruby.
|
44
|
+
|
45
|
+
Let's start with a very basic example. We can create a Skill that allows Waylon to perform simple a simple "echo" function, meaning Waylon will just reply with whatever we tell him to.
|
46
|
+
|
47
|
+
Install the `waylon` gem:
|
48
|
+
|
49
|
+
$ gem install waylon
|
50
|
+
|
51
|
+
Then, create a new skill gem:
|
52
|
+
|
53
|
+
$ waylon skill echo
|
54
|
+
|
55
|
+
This will create a gem for you in a directory called `waylon-echo`. You'll need to edit `waylon-echo/waylon-echo.gemspec` and fill in a few important details.
|
56
|
+
|
57
|
+
First, find any line containing `TODO` and fill in actual values. Remove `spec.metadata["allowed_push_host"]` unless you have your own private gem server. Remove any other `spec.metadata` lines you don't need.
|
58
|
+
|
59
|
+
Toward the end of the file (but before the final `end`), add a line like this:
|
60
|
+
|
61
|
+
spec.add_dependency "waylon-core", "~> 0.2"
|
62
|
+
|
63
|
+
You'll also need to add a few development dependencies:
|
64
|
+
|
65
|
+
spec.add_development_dependency "pry"
|
66
|
+
spec.add_development_dependency "yard"
|
67
|
+
|
68
|
+
Now you should be able to start development. Take a look at `lib/waylon/skills/echo.rb`. Delete the `route()` at the beginning of the file and replace it with this:
|
69
|
+
|
70
|
+
route(/^say\s+(.+)/, :do_the_thing)
|
71
|
+
|
72
|
+
This simple route will look for text beginning with "say" and capture any words after it. This captured content will be available in `tokens[0]` (or `tokens.last`).
|
73
|
+
|
74
|
+
Now, we can use this to respond. Edit the `do_the_thing` method so it looks like this:
|
75
|
+
|
76
|
+
def do_the_thing
|
77
|
+
react :speech_balloon
|
78
|
+
|
79
|
+
reply "echo: #{tokens.last}"
|
80
|
+
end
|
81
|
+
|
82
|
+
That's it! Save the file and now you have an echo plugin. You can even demo it with:
|
83
|
+
|
84
|
+
$ bundle exec rake demo
|
85
|
+
|
86
|
+
You'll be presented with a REPL interface. You can type `say something` and you should get a response back from Waylon that looks something like this:
|
87
|
+
|
88
|
+
(@homer) << say something
|
89
|
+
(@waylon) >> :speech_balloon:
|
90
|
+
echo: 'something'
|
91
|
+
|
92
|
+
From here, you'll want to do all the typical ruby things like writing tests, updating the README.md, etc., but that's the easy stuff.
|
93
|
+
|
94
|
+
To actually use this with a real chat platform, you'll need to build and release your new gem. This is beyond the scope of this short guide, but [RubyGems.org](https://rubygems.org/) has a great [guide for publishing a gem](https://guides.rubygems.org/publishing/) that is worth reading.
|
95
|
+
|
96
|
+
After you've published your gem, you can use it in your own bot. Keep reading to see how that works!
|
97
|
+
### Creating Your Own Bot
|
98
|
+
|
99
|
+
To create a new bot using the Waylon bot framework, you can install the `waylon` gem:
|
100
|
+
|
101
|
+
$ gem install waylon
|
102
|
+
|
103
|
+
Then you can use these Waylon executable to create the basics:
|
104
|
+
|
105
|
+
$ waylon init mybot
|
106
|
+
|
107
|
+
This creates a directory in your current working directory called `mybot` and populates it with the files needed to get started.
|
108
|
+
|
109
|
+
From there, edit the `plugins.rb` file and add some plugins. Check out [this list](https://github.com/search?q=waylon-*+language%3ARuby+user%3Ajgnagy+language%3ARuby+language%3ARuby&type=Repositories&ref=advsearch&l=Ruby&l=Ruby) to see some options.
|
110
|
+
|
111
|
+
### Building a Docker Image
|
112
|
+
|
113
|
+
Assuming you used `waylon init` from above, you'll have a `Dockerfile` in your repo ready to go. In most cases, you just need to use `docker build -t waylon .` to build an image that can be used in a container environment (such as Kubernetes). You'll likely need to push this to a registry. Waylon and its open-source plugins should never cause sensitive information to be embedded within your image, but if you're using proprietary plugins, you'll want to avoid pushing your built image to a public registry.
|
114
|
+
|
115
|
+
For examples on how to deploy your Waylon image to Kubernetes, see the [`helm` example](examples/deploying/helm/waylon/) or the [pure Kubernetes example](examples/deploying/k8s/).
|
116
|
+
|
117
|
+
### Other Custom Ruby Projects
|
118
|
+
|
119
|
+
For something custom, add this line to your application's Gemfile:
|
8
120
|
|
9
121
|
```ruby
|
10
122
|
gem 'waylon'
|
@@ -14,10 +126,6 @@ And then execute:
|
|
14
126
|
|
15
127
|
$ bundle install
|
16
128
|
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
|
-
$ gem install waylon
|
20
|
-
|
21
129
|
## Contributing
|
22
130
|
|
23
131
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jgnagy/waylon.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Patterns to ignore when building packages.
|
2
|
+
# This supports shell glob matching, relative path matching, and
|
3
|
+
# negation (prefixed with !). Only one pattern per line.
|
4
|
+
.DS_Store
|
5
|
+
.git/
|
6
|
+
.gitignore
|
7
|
+
# Common backup files
|
8
|
+
*.swp
|
9
|
+
*.bak
|
10
|
+
*.tmp
|
11
|
+
*~
|
12
|
+
# Various IDEs
|
13
|
+
.project
|
14
|
+
.idea/
|
15
|
+
*.tmproj
|
16
|
+
.vscode/
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Waylon Helm Chart
|
2
|
+
|
3
|
+
This is an example (though fairly complete) Helm chart for running a [Waylon](https://github.com/jgnagy/waylon) chat bot.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
* Review the list of parameters and decide what needs to be changed. You'll need _at least_ to have previously built and published a Waylon Docker image and you'll need to decide on a domain name. You'll provide these values when you render the template.
|
8
|
+
|
9
|
+
* Render the template to a file:
|
10
|
+
|
11
|
+
```sh
|
12
|
+
$ helm template ./waylon --set common.waylonImage="some.docker.registry/project/mywaylon:1.2.3" --set web.ingress.hostname="foo.bar.com" > /tmp/waylon.yaml
|
13
|
+
```
|
14
|
+
|
15
|
+
* Deploy your rendered template:
|
16
|
+
|
17
|
+
```sh
|
18
|
+
$ kubectl -n some-namespace apply -f /tmp/waylon.yaml
|
19
|
+
```
|
20
|
+
|
21
|
+
## Parameters
|
22
|
+
|
23
|
+
| Setting | Default Value | Description |
|
24
|
+
| --- | --- | --- |
|
25
|
+
| `common.strictSecrurity` | `true` | Should stricter security controls be enabled? |
|
26
|
+
| `common.waylonImage` | _none_ | The full docker image to pull for your Waylon deployment |
|
27
|
+
| `common.imagePullSecret` | _none_ | Completely optional secret to use when pulling images from private repos |
|
28
|
+
| `redis.enabled` | `true` | Should a dedicated Redis be deployed for alongside Waylon? |
|
29
|
+
| `redis.annotations` | `{}` | Optionally list any additional annotations for the Redis StatefulSet. **Note:** these are not passed-through to the Pods. |
|
30
|
+
| `redis.labels` | `{}` | Optionally list any additional labels for the Redis StatefulSet. **Note:** these are not passed-through to the Pods. |
|
31
|
+
| `redis.hostAndPort` | `redis:6379` | Tells Waylon how to find Redis. If `redis.enabled` is `false`, be sure to update this, otherwise it can be left alone. |
|
32
|
+
| `redis.image` | `redis:6-alpine` | The full docker image to use for Redis |
|
33
|
+
| `redis.imagePullPolicy` | `Always` | How often to try pulling the Redis docker image |
|
34
|
+
| `redis.command` | `["redis-server", "--appendonly yes"]` | Usually best to leave this alone, but it allows setting more advanced Redis settings |
|
35
|
+
| `redis.cpuLimit` | `200m` | How much CPU can Redis use? |
|
36
|
+
| `redis.memoryLimit` | `512Mi` | How much memory can Redis use? |
|
37
|
+
| `redis.storage.capacity` | `5Gi` | How much disk space can Redis use? It shouldn't need much given how it is used but adjust based on your plugins and expected load. |
|
38
|
+
| `redis.storage.class` | `longhorn` | What [Kubernetes StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) should Redis use? |
|
39
|
+
| `web.deployment.annotations` | `{}` | Optionally list any additional annotations for the Waylon web Deployment. **Note:** these are not passed-through to the Pods. |
|
40
|
+
| `web.deployment.imagePullPolicy` | `IfNotPresent` | How often to try pulling the Waylon image for the Web deployment |
|
41
|
+
| `web.deployment.labels` | `{}` | Optionally list any additional labels for the Waylon web Deployment. **Note:** these are not passed-through to the Pods. |
|
42
|
+
| `web.deployment.logLevel` | `DEBUG` | What log level should the Waylon web component use? |
|
43
|
+
| `web.deployment.maxSurge` | `2` | How many _additional_ Pods can the deployment create to handle a rollout/update? |
|
44
|
+
| `web.deployment.maxUnavailable` | `0` | How many Pods can be unavailble during a deployment rollout? |
|
45
|
+
| `web.deployment.replicas` | `1` | How many Pods do want to run for Waylon's web component? |
|
46
|
+
| `web.deployment.cpuLimit` | `250m` | How much CPU can Redis use? |
|
47
|
+
| `web.deployment.memoryLimit` | `256Mi` | How much memory can Redis use? |
|
48
|
+
| `web.ingress.enabled` | `true` | Should Waylon have an Ingress for its web component? |
|
49
|
+
| `web.ingress.class` | `nginx` | What [Ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) will be use for `kubernetes.io/ingress.class`? |
|
50
|
+
| `web.ingress.hostname` | _none_ | What hostname will the Web component use (also used for TLS) |
|
51
|
+
| `web.ingress.tls.enabled` | `true` | Should the Ingress use TLS (HTTPS)? |
|
52
|
+
| `web.ingress.tls.issuer` | `letsencrypt` | What is the name of the [Issuer/ClusterIssuer](https://cert-manager.io/docs/concepts/issuer/) that will be used for provisioning TLS secrets? |
|
53
|
+
| `web.ingress.tls.issuerClass` | `ClusterIssuer` | Is the TLS issuer a `ClusterIssuer` or an `Issuer`? You can usually ignore this setting. |
|
54
|
+
| `web.service.port` | `80` | The port that the Service listens on |
|
55
|
+
| `web.service.type` | `ClusterIP` | The Service type |
|
56
|
+
| `worker.deployment.annotations` | `{}` | Optionally list any additional annotations for the Waylon worker Deployment. **Note:** these are not passed-through to the Pods. |
|
57
|
+
| `worker.deployment.imagePullPolicy` | `IfNotPresent` | How often to try pulling the Waylon image for the worker Deployment |
|
58
|
+
| `worker.deployment.labels` | `{}` | Optionally list any additional labels for the Waylon worker Deployment. **Note:** these are not passed-through to the Pods. |
|
59
|
+
| `worker.deployment.logLevel` | `DEBUG` | What log level should the Waylon worker component use? |
|
60
|
+
| `worker.deployment.maxSurge` | `2` | How many _additional_ Pods can the deployment create to handle a rollout/update? |
|
61
|
+
| `worker.deployment.maxUnavailable` | `0` | How many Pods can be unavailble during a deployment rollout? |
|
62
|
+
| `worker.deployment.replicas` | `1` | How many Pods do want to run for Waylon's web component? |
|
63
|
+
| `worker.deployment.cpuLimit` | `250m` | How much CPU can Redis use? |
|
64
|
+
| `worker.deployment.memoryLimit` | `256Mi` | How much memory can Redis use? |
|
65
|
+
|
66
|
+
See the [default `values.yaml`](values.yaml) for a full view of the default settings.
|
67
|
+
|
68
|
+
### Some Gotchas
|
69
|
+
|
70
|
+
* You **MUST** set `common.waylonImage` and, if you plan on using an Ingress for Waylon, `web.ingress.hostname`.
|
71
|
+
* If your TLS issuer is not named `letsencrypt` but uses the ACMEv2 protocol via cert-manager, you might need to add to `web.ingress.annotations` so it contains an entry like `cert-manager.io/acme-challenge-type: http01`. This is only _automatically_ added if your issuer is called `letsencrypt`.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{{- if and .Values.redis.enabled .Values.redis.storage.hostPath }}
|
2
|
+
apiVersion: v1
|
3
|
+
kind: PersistentVolume
|
4
|
+
metadata:
|
5
|
+
name: redis-data-pv
|
6
|
+
labels:
|
7
|
+
type: local
|
8
|
+
app.kubernetes.io/name: redis-data-pv
|
9
|
+
app.kubernetes.io/component: redis-data-pv
|
10
|
+
{{- include "waylon.commonLabels" . | nindent 4 }}
|
11
|
+
spec:
|
12
|
+
storageClassName: manual
|
13
|
+
capacity:
|
14
|
+
storage: {{ .Values.redis.storage.capacity }}
|
15
|
+
accessModes:
|
16
|
+
- ReadWriteOnce
|
17
|
+
hostPath:
|
18
|
+
path: {{ .Values.redis.storage.hostPath }}
|
19
|
+
{{- end -}}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{{- if and .Values.redis.enabled .Values.redis.storage.hostPath }}
|
2
|
+
apiVersion: v1
|
3
|
+
kind: PersistentVolumeClaim
|
4
|
+
metadata:
|
5
|
+
labels:
|
6
|
+
app.kubernetes.io/name: redis-data-pvc
|
7
|
+
app.kubernetes.io/component: redis-data-pvc
|
8
|
+
{{- include "waylon.commonLabels" . | nindent 4 }}
|
9
|
+
name: redis-data-pvc
|
10
|
+
spec:
|
11
|
+
storageClassName: manual
|
12
|
+
accessModes:
|
13
|
+
- ReadWriteOnce
|
14
|
+
resources:
|
15
|
+
requests:
|
16
|
+
storage: {{ .Values.redis.storage.capacity }}
|
17
|
+
volumeName: redis-data-pv
|
18
|
+
{{- end -}}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
{{- if .Values.redis.enabled -}}
|
2
|
+
apiVersion: apps/v1
|
3
|
+
kind: StatefulSet
|
4
|
+
metadata:
|
5
|
+
name: redis
|
6
|
+
labels:
|
7
|
+
app.kubernetes.io/name: redis
|
8
|
+
app.kubernetes.io/component: redis
|
9
|
+
{{- include "waylon.commonLabels" . | nindent 4 }}
|
10
|
+
{{- with .Values.redis.labels }}
|
11
|
+
{{- toYaml . | nindent 4 }}
|
12
|
+
{{- end }}
|
13
|
+
{{- if .Values.redis.annotations }}
|
14
|
+
annotations:
|
15
|
+
{{- toYaml .Values.redis.annotations | nindent 4 }}
|
16
|
+
{{- end }}
|
17
|
+
spec:
|
18
|
+
serviceName: redis
|
19
|
+
# hardcoded to 1 because we're not configuring clustering
|
20
|
+
replicas: 1
|
21
|
+
selector:
|
22
|
+
matchLabels:
|
23
|
+
app.kubernetes.io/name: redis
|
24
|
+
app.kubernetes.io/component: redis
|
25
|
+
{{- include "waylon.commonLabels" . | nindent 6 }}
|
26
|
+
template:
|
27
|
+
metadata:
|
28
|
+
labels:
|
29
|
+
app.kubernetes.io/name: redis
|
30
|
+
app.kubernetes.io/component: redis
|
31
|
+
{{- include "waylon.commonLabels" . | nindent 8 }}
|
32
|
+
spec:
|
33
|
+
{{- if .Values.redis.storage.hostPath }}
|
34
|
+
volumes:
|
35
|
+
- name: datadir
|
36
|
+
persistentVolumeClaim:
|
37
|
+
claimName: redis-data-pvc
|
38
|
+
{{- end }}
|
39
|
+
{{- if .Values.common.imagePullSecret -}}
|
40
|
+
imagePullSecrets:
|
41
|
+
- name: {{ .Values.common.imagePullSecret }}
|
42
|
+
{{- end }}
|
43
|
+
containers:
|
44
|
+
- name: redis
|
45
|
+
image: {{ .Values.redis.image }}
|
46
|
+
imagePullPolicy: {{ .Values.redis.imagePullPolicy }}
|
47
|
+
stdin: true
|
48
|
+
tty: true
|
49
|
+
command: {{ toYaml .Values.redis.command | nindent 8 }}
|
50
|
+
{{- if .Values.common.strictSecurity }}
|
51
|
+
securityContext:
|
52
|
+
readOnlyRootFilesystem: true
|
53
|
+
allowPrivilegeEscalation: false
|
54
|
+
privileged: false
|
55
|
+
runAsNonRoot: true
|
56
|
+
runAsUser: 999
|
57
|
+
runAsGroup: 999
|
58
|
+
capabilities:
|
59
|
+
drop:
|
60
|
+
- ALL
|
61
|
+
{{- end }}
|
62
|
+
resources:
|
63
|
+
limits:
|
64
|
+
memory: {{ .Values.redis.memoryLimit }}
|
65
|
+
cpu: {{ .Values.redis.cpuLimit }}
|
66
|
+
requests:
|
67
|
+
memory: 8Mi
|
68
|
+
cpu: 20m
|
69
|
+
ports:
|
70
|
+
- containerPort: 6379
|
71
|
+
protocol: TCP
|
72
|
+
name: redis
|
73
|
+
readinessProbe:
|
74
|
+
exec:
|
75
|
+
command:
|
76
|
+
- sh
|
77
|
+
- -c
|
78
|
+
- "/usr/local/bin/redis-cli -h $(hostname) ping"
|
79
|
+
initialDelaySeconds: 15
|
80
|
+
timeoutSeconds: 5
|
81
|
+
livenessProbe:
|
82
|
+
exec:
|
83
|
+
command:
|
84
|
+
- sh
|
85
|
+
- -c
|
86
|
+
- "/usr/local/bin/redis-cli -h $(hostname) ping"
|
87
|
+
initialDelaySeconds: 30
|
88
|
+
periodSeconds: 2
|
89
|
+
successThreshold: 1
|
90
|
+
failureThreshold: 3
|
91
|
+
timeoutSeconds: 5
|
92
|
+
volumeMounts:
|
93
|
+
- name: datadir
|
94
|
+
mountPath: /data
|
95
|
+
{{- if not .Values.redis.storage.hostPath }}
|
96
|
+
volumeClaimTemplates:
|
97
|
+
- metadata:
|
98
|
+
name: datadir
|
99
|
+
spec:
|
100
|
+
accessModes:
|
101
|
+
- "ReadWriteOnce"
|
102
|
+
resources:
|
103
|
+
requests:
|
104
|
+
storage: {{ .Values.redis.storage.capacity }}
|
105
|
+
storageClassName: {{ .Values.redis.storage.class | quote }}
|
106
|
+
{{- end -}}
|
107
|
+
{{- end -}}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
apiVersion: apps/v1
|
2
|
+
kind: Deployment
|
3
|
+
metadata:
|
4
|
+
name: web
|
5
|
+
labels:
|
6
|
+
app.kubernetes.io/name: web
|
7
|
+
app.kubernetes.io/component: web
|
8
|
+
{{- include "waylon.commonLabels" . | nindent 4 }}
|
9
|
+
{{- with .Values.web.deployment.labels }}
|
10
|
+
{{- toYaml . | nindent 4 }}
|
11
|
+
{{- end }}
|
12
|
+
{{- if .Values.web.deployment.annotations }}
|
13
|
+
annotations:
|
14
|
+
{{- toYaml .Values.web.deployment.annotations | nindent 4 }}
|
15
|
+
{{- end }}
|
16
|
+
spec:
|
17
|
+
replicas: {{ .Values.web.deployment.replicas }}
|
18
|
+
strategy:
|
19
|
+
type: RollingUpdate
|
20
|
+
rollingUpdate:
|
21
|
+
maxSurge: {{ .Values.web.deployment.maxSurge }}
|
22
|
+
maxUnavailable: {{ .Values.web.deployment.maxUnavailable }}
|
23
|
+
selector:
|
24
|
+
matchLabels:
|
25
|
+
app.kubernetes.io/component: web
|
26
|
+
{{- include "waylon.commonLabels" . | nindent 6 }}
|
27
|
+
template:
|
28
|
+
metadata:
|
29
|
+
labels:
|
30
|
+
app.kubernetes.io/name: web
|
31
|
+
app.kubernetes.io/component: web
|
32
|
+
{{- include "waylon.commonLabels" . | nindent 8 }}
|
33
|
+
spec:
|
34
|
+
{{- if .Values.common.strictSecurity }}
|
35
|
+
securityContext:
|
36
|
+
runAsUser: 1000
|
37
|
+
runAsGroup: 1000
|
38
|
+
{{- end }}
|
39
|
+
{{- if .Values.common.imagePullSecret }}
|
40
|
+
imagePullSecrets:
|
41
|
+
- name: {{ .Values.common.imagePullSecret }}
|
42
|
+
{{- end }}
|
43
|
+
volumes:
|
44
|
+
- name: tmpvol
|
45
|
+
emptyDir: {}
|
46
|
+
containers:
|
47
|
+
- name: web
|
48
|
+
image: {{ .Values.common.waylonImage }}
|
49
|
+
imagePullPolicy: {{ .Values.web.deployment.imagePullPolicy }}
|
50
|
+
stdin: true
|
51
|
+
tty: true
|
52
|
+
args: ["web"]
|
53
|
+
env:
|
54
|
+
- name: REDIS
|
55
|
+
value: {{ .Values.redis.hostAndPort }}
|
56
|
+
- name: LOG_LEVEL
|
57
|
+
value: {{ .Values.web.deployment.logLevel }}
|
58
|
+
envFrom:
|
59
|
+
- secretRef:
|
60
|
+
name: waylon-secret
|
61
|
+
resources:
|
62
|
+
limits:
|
63
|
+
memory: {{ .Values.web.deployment.memoryLimit }}
|
64
|
+
cpu: {{ .Values.web.deployment.cpuLimit }}
|
65
|
+
requests:
|
66
|
+
memory: 64Mi
|
67
|
+
cpu: 10m
|
68
|
+
livenessProbe:
|
69
|
+
tcpSocket:
|
70
|
+
port: waylon
|
71
|
+
timeoutSeconds: 2
|
72
|
+
initialDelaySeconds: 2
|
73
|
+
periodSeconds: 2
|
74
|
+
failureThreshold: 3
|
75
|
+
readinessProbe:
|
76
|
+
httpGet:
|
77
|
+
path: /ping
|
78
|
+
port: waylon
|
79
|
+
timeoutSeconds: 6
|
80
|
+
initialDelaySeconds: 2
|
81
|
+
periodSeconds: 10
|
82
|
+
failureThreshold: 3
|
83
|
+
ports:
|
84
|
+
- name: waylon
|
85
|
+
containerPort: 9292
|
86
|
+
protocol: TCP
|
87
|
+
volumeMounts:
|
88
|
+
- mountPath: /tmp
|
89
|
+
name: tmpvol
|
90
|
+
{{- if .Values.common.strictSecurity }}
|
91
|
+
securityContext:
|
92
|
+
allowPrivilegeEscalation: false
|
93
|
+
privileged: false
|
94
|
+
runAsNonRoot: true
|
95
|
+
readOnlyRootFilesystem: true
|
96
|
+
capabilities:
|
97
|
+
drop:
|
98
|
+
- all
|
99
|
+
{{- end }}
|