-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#2756] Apply config through the airy controller #3176
[#2756] Apply config through the airy controller #3176
Conversation
@@ -1,15 +1,18 @@ | |||
load("@com_github_airyhq_bazel_tools//lint:buildifier.bzl", "check_pkg") | |||
load("@io_bazel_rules_go//go:def.bzl", "go_library") | |||
# gazelle:prefix github.com/airyhq/airy/lib/go/httpclient/payloads | |||
# gazelle:prefix github.com/airyhq/airy/lib/go/payloads |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved the payloads
outside of the httpclient
package, because they are also used by the controller.
type ConfigComponent struct { | ||
Removed bool `json:"removed"` | ||
Component string `json:"component"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently only used by the ConfigApplyResponsePayload, so not sure if it should be here or in payloads
. Also Removed
is just to be in line with the current concept (when a configuration is applied without a component - that component is removed).
I'd be happy to remove this and add a separate endpoint for removing a component.
namespace := "default" | ||
responseConfigComponents := payloads.ConfigApplyResponsePayload{} | ||
|
||
err = json.Unmarshal(body, &conf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned I would suggest that we nest the config inside a data
field. This will make the API more maintainable as we can add more options to the request body later when needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe having everything inside components
. Also if we add more options specially mandatory options. That will create a breaking change anyway. Not sure having a nested value will be necessary
if len(secData) != 0 { | ||
applyErr := k8s.ApplyConfigMap("security", namespace, secData, map[string]string{}, s.clientSet) | ||
if applyErr != nil { | ||
klog.Error("Unable to apply configuration for \"security\"\nError:\n" + err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the request should fail and terminate early (same below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the request should fail and terminate early (same below)
I am not sure about this. The components are independent from each-other, so an error in deploying one component/configMap should not impact the ones that follow after.
We can return perhaps a list of failed components
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that we could do that but for clients, a completely failed state is easier to recover from than a state that is half failed.
What do you return for a request that only did 50% of what you asked it to? 200
aka "success"? In that case, clients may not be aware that anything failed at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I get it 👍 We can return the failed-components
in a separate list, but I think as it is very unlikely that only one configMap fails - I will set it to return a 500
- InternalServerError
.
From the UI I assume it will mostly be used for applying a single component at a time anyway.
db4db7d
to
537a769
Compare
537a769
to
0c62e5c
Compare
|
||
```json | ||
{ | ||
"Security": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Payload needs to follow our snake_case
convention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Payload needs to follow our
snake_case
convention
Thanks 👍. I changed it for security
and data
. For the values which were in the airy.yaml
(allowedOrigins
, systemToken
, jwtSecret
, ...) I suggest we do it in a subsequent PR, as it has lots of changes across almost all components.
```json5 | ||
{ | ||
"security": { | ||
"systemToken": "token", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to make this API the new source of truth for interacting with Airy. Therefore I'd argue that as with all other endpoints we also convert these keys into snake_case
so that the interface is uniform.
The list of the deleted components is returned. | ||
|
||
```json5 | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete outer {}
since this isn't valid json
} | ||
|
||
var conf payloads.ComponentsUpdateRequestPayload | ||
namespace := os.Getenv("NAMESPACE") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can use the variable that's already stored in s.namespace
here
{ | ||
"name": "security", | ||
"enabled": true, | ||
"data": null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can data ever be non-null
? If no, then I'd remove it.
Also: security isn't a component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need another endpoint for applying the configuration forsecurity
?
I changed the cli part to use |
} | ||
|
||
res := payloads.ComponentsUpdateResponsePayload{} | ||
e := c.post("components.update", payload, &res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will fix this in my PR #3221
…iryhq/airy into feature/2756-config-through-controller
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look good. Juste some small things to adresse and it will be good to merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some minor changes it looks good now to me
@@ -17,7 +17,7 @@ type ClusterGet struct { | |||
} | |||
|
|||
func (s *ClusterGet) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||
components, err := configmaps.GetComponentsConfigMaps(r.Context(), s.namespace, s.clientSet, maskSecrets) | |||
components, err := k8s.GetComponentsConfigMaps(r.Context(), s.namespace, s.clientSet, maskSecrets) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually work yet? 🤔 When I run the image in my local cluster this endpoint returns:
{"components":{}}
Or perhaps there is something more than add the image that I have to do :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually work yet? thinking When I run the image in my local cluster this endpoint returns:
{"components":{}}Or perhaps there is something more than add the image that I have to do :)
You would also need to add the ingress rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This request is directly from within the cluster. If it was a networking issue the response would be a 404
. Will do more testing later
Co-authored-by: Christoph Proeschel <chris@airy.co>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect. great work!! Thanks for adding the label everywhere
addresses #2756
A draft PR for proof of concept and also to get some feedback 🙏 .
The CLI returns this:
The endpoint accepts
json
and also the legacy
yaml
format of theairy.yaml
file.