-
Notifications
You must be signed in to change notification settings - Fork 20
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
Feature/admission controller #226
Conversation
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
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.
interesting... some clarifications needed, but overall good
did you follow any example for the admission controller that you could document?
admissionController := webhook.New(addr, "/etc/certs/tls.crt", "/etc/certs/tls.key", runtime.NewScheme(), webhook.NewAdmissionValidator(k8sApi, exporter)) | ||
// Start HTTP REST server for webhook | ||
waitGroup.Add(1) | ||
go func() { |
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 saw that @kooomix used https://pkg.go.dev/golang.org/x/sync/errgroup#Group.Go in the backend and I found it super elegant... consider it here maybe?
main.go
Outdated
@@ -136,6 +142,36 @@ func main() { | |||
}(mainHandler) | |||
} | |||
|
|||
if operatorConfig.AdmissionControllerEnabled() { | |||
// Handle SIGINT and SIGTERM by cancelling the root context | |||
admissionContext, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) |
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 we can move this outside of the flag? why only SIGINT with admission 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.
done
return | ||
} | ||
|
||
// discard the body |
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 am still not convinced this is needed... do you have some pointers (I know we do it in different places, just curious)?
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.
see golang/go#60240
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 prefer to do it anyway to avoid potential leaks.
admission/webhook/validator.go
Outdated
return true | ||
} | ||
|
||
func (av *AdmissionValidator) validateAdminRoleBinding(attrs admission.Attributes) 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.
I think at some point these will reside as separate rules, such as in node-agent?
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 at some point but not now.
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
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 added some comments.
Here are my overall comments:
- What are the 'rules'? Why are they not defined as rules, but rather as "if" statements in a large function?
- How can the user interact with this system?
- This code is missing unit tests.
- Some conditions, such as capabilities, are hard-coded. Consider implementing a more flexible solution.
I don't know the full context, but if this is just a POC, I don't see a reason to merge it into the main branch. You should continue working on it, and once it is more complete (at least the basics), we can consider merging it into the main branch.
main.go
Outdated
}() | ||
|
||
cancellationReason := admissionController.Run(serverContext) | ||
logger.L().Ctx(ctx).Error("server stopped", helpers.Error(cancellationReason)) |
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.
logger.L().Ctx(ctx).Error("server stopped", helpers.Error(cancellationReason)) | |
logger.L().Ctx(ctx).Fatal("server stopped", helpers.Error(cancellationReason)) |
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.
done
main.go
Outdated
waitGroup.Done() | ||
}() | ||
|
||
cancellationReason := admissionController.Run(serverContext) |
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.
cancellationReason := admissionController.Run(serverContext) | |
err := admissionController.Run(serverContext) |
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.
done
main.go
Outdated
admissionContext, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) | ||
defer stop() | ||
|
||
waitGroup := sync.WaitGroup{} |
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 should "kill" the main process if there is an issue initializing the admission controller.
This being said, I don't think we need here a waiting group.
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.
Removed it but I think it's good to have for scaling.
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'm not sure what you mean by the "scaling", what is the scenario?
} | ||
// create the HTTPAlertsList struct | ||
httpAlertsList := HTTPAlertsList{ | ||
Kind: "RuntimeAlerts", |
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.
Is this runtimeAlerts? I dont think so.
I believe this should have a different kind so it can be treated as admission controller alerts.
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 is a RuntimeAlert the admission kind is passed in other place.
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 the same kind of alert as coming from the node-agent, in other words, we will not know "down the line" the source of the alert. And I think we will want to know...
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.
done
func (exporter *HTTPExporter) SendAdmissionAlert(admissionAttrs *admission.Attributes, ruleID string, RuleDescription string) { | ||
isLimitReached := exporter.checkAlertLimit() | ||
if isLimitReached { | ||
exporter.sendAlertLimitReached() |
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 sends an alert every time the limit is reached. Instead of sending multiple alerts for each instance that reaches the limit, we should send a single alert indicating that the limit has been reached. This can be managed by wrapping the alert logic in a boolean condition to ensure the 'limit reached' alert is sent only once.
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.
done
admission/webhook/validator.go
Outdated
func (av *AdmissionValidator) validatePods(attrs admission.Attributes) error { | ||
var errs error | ||
|
||
// Check if the request is for pod exec or attach. |
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 not "pod validation". You should have a different function for this
admission/webhook/validator.go
Outdated
errs = errors.Join(errs, admission.NewForbidden(attrs, fmt.Errorf("exec to pod is audited"))) | ||
} | ||
|
||
if attrs.GetSubresource() == "attach" { |
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, not pod validation
admission/webhook/validator.go
Outdated
} | ||
|
||
// Check if the request is for port-forwarding. | ||
if attrs.GetSubresource() == "portforward" { |
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, not pod validation
Summary:
|
Do you think we should use the rules packages from the node-agent?
Which kind of interaction do you expect? rule bindings? |
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Not really, because here this is a different set of rules, but I will expect to see a similar code structure, there are different restrictions so I don't think there is a need for a Factory design pattern, but I think there should be a package with rules etc.
Possibly. What were the requirements and design for the admission controller? Also, as I wrote, I'm unfamiliar with the big picture, but I believe we will add rules and possibly block user actions. I don't see how all this can "fit" in the current code structure without the need of refactoring it all in the future, so I will recommend writing the admission controller infrastructure in a way that future modifications and requirements could be met without refactoring. This being said, if the scope here is a POC and not actual product development, I don't see a need to merge it into the main branch. |
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
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.
- fix the conflicts with go.mod
- remove github.com/zeebo/assert and use testify instead (as everywhere)
- improve some of the test coverage (for example the cache)
- I wonder if we should have a component test or something testing the full functionality of the webhook (outside of the system tests that you will add)
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestNewCache(t *testing.T) { |
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.
lol, maybe we could add useful tests?
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.
done
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func TestResourcesToWatch(t *testing.T) { |
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, maybe use real data?
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.
done
import ( | ||
"testing" | ||
|
||
"github.com/zeebo/assert" |
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.
why we're not using testify?
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.
done
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
|
GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
---|---|---|---|---|---|
13049693 | Triggered | Generic Private Key | 7c7c360 | admission/webhook/testdata/key.pem | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Signed-off-by: Amit Schendel <amitschendel@gmail.com>
Summary:
|
Overview
This PR fixes #
Signed Commits