diff --git a/controller/controller.go b/controller/controller.go index d07418c5a0..975f84abe0 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -85,15 +85,19 @@ func (c *PolicyController) GetPolicies() []types.Policy { return policies } +// Writes error message to the policy logs in status section func (c *PolicyController) LogPolicyError(name, text string) { c.addPolicyLog(name, "[ERROR] "+text) } +// Writes info message to the policy logs in status section func (c *PolicyController) LogPolicyInfo(name, text string) { c.addPolicyLog(name, "[ INFO] "+text) } -const policyLogMaxRecords int = 10 +// This is the maximum number of records that can be written to the log object of the policy. +// If this number is exceeded, the older entries will be deleted. +const policyLogMaxRecords int = 50 // Appends given log text to the status/logs array. func (c *PolicyController) addPolicyLog(name, text string) { @@ -125,7 +129,6 @@ func (c *PolicyController) addPolicyLog(name, text string) { func (c *PolicyController) createPolicyHandler(resource interface{}) { key := c.getResourceKey(resource) c.logger.Printf("Policy created: %s", key) - c.addPolicyLog(key, "Added") } func (c *PolicyController) updatePolicyHandler(oldResource, newResource interface{}) { @@ -133,7 +136,6 @@ func (c *PolicyController) updatePolicyHandler(oldResource, newResource interfac newKey := c.getResourceKey(newResource) c.logger.Printf("Policy %s updated to %s", oldKey, newKey) - c.addPolicyLog(newKey, "Updated") } func (c *PolicyController) deletePolicyHandler(resource interface{}) { diff --git a/crd/crd.yaml b/crd/crd.yaml index c1e0e303a4..04f6af1c97 100644 --- a/crd/crd.yaml +++ b/crd/crd.yaml @@ -13,3 +13,6 @@ spec: kind: Policy plural: policies singular: policy + subresources: + status: {} + diff --git a/kubeclient/kubeclient.go b/kubeclient/kubeclient.go index bf84a61193..23cd53ffdc 100644 --- a/kubeclient/kubeclient.go +++ b/kubeclient/kubeclient.go @@ -13,11 +13,13 @@ import ( "k8s.io/client-go/rest" ) +// KubeClient is the api-client for core Kubernetes objects type KubeClient struct { logger *log.Logger client *kubernetes.Clientset } +// Checks parameters and creates new instance of KubeClient func NewKubeClient(config *rest.Config, logger *log.Logger) (*KubeClient, error) { if logger == nil { logger = log.New(os.Stdout, "Policy Controller: ", log.LstdFlags|log.Lshortfile) @@ -34,6 +36,8 @@ func NewKubeClient(config *rest.Config, logger *log.Logger) (*KubeClient, error) }, nil } +// Generates new ConfigMap in given namespace. If the namespace does not exists yet, +// waits until it is created for maximum namespaceCreationMaxWaitTime (see below) func (kc *KubeClient) GenerateConfigMap(generator types.PolicyConfigGenerator, namespace string) error { kc.logger.Printf("Preparing to create configmap %s/%s", namespace, generator.Name) configMap := &v1.ConfigMap{} @@ -67,6 +71,8 @@ func (kc *KubeClient) GenerateConfigMap(generator types.PolicyConfigGenerator, n return nil } +// Generates new Secret in given namespace. If the namespace does not exists yet, +// waits until it is created for maximum namespaceCreationMaxWaitTime (see below) func (kc *KubeClient) GenerateSecret(generator types.PolicyConfigGenerator, namespace string) error { kc.logger.Printf("Preparing to create secret %s/%s", namespace, generator.Name) secret := &v1.Secret{} diff --git a/server/server.go b/server/server.go index 783b0dd516..8495b0844e 100644 --- a/server/server.go +++ b/server/server.go @@ -79,6 +79,7 @@ func NewWebhookServer(config WebhookServerConfig, logger *log.Logger) (*WebhookS return ws, nil } +// Main server endpoint for all requests func (ws *WebhookServer) serve(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/mutate" { admissionReview := ws.parseAdmissionReview(r, w) @@ -148,8 +149,7 @@ func (ws *WebhookServer) parseAdmissionReview(request *http.Request, writer http } } -// RunAsync runs TLS server in separate -// thread and returns control immediately +// Runs TLS server in separate thread and returns control immediately func (ws *WebhookServer) RunAsync() { go func(ws *WebhookServer) { err := ws.server.ListenAndServeTLS("", "") @@ -159,7 +159,7 @@ func (ws *WebhookServer) RunAsync() { }(ws) } -// Stop stops TLS server +// Stops TLS server and returns control after the server is shut down func (ws *WebhookServer) Stop() { err := ws.server.Shutdown(context.Background()) if err != nil { diff --git a/webhooks/mutation.go b/webhooks/mutation.go index 995b9d3239..63776215a0 100644 --- a/webhooks/mutation.go +++ b/webhooks/mutation.go @@ -66,7 +66,7 @@ func (mw *MutationWebhook) Mutate(request *v1beta1.AdmissionRequest) *v1beta1.Ad if stopOnError { mw.logger.Printf("/!\\ Denying the request according to FailurePolicy spec /!\\") } - return errorToResponse(err, !stopOnError) + return errorToAdmissionResponse(err, !stopOnError) } if rulePatches != nil { allPatches = append(allPatches, rulePatches...) @@ -78,7 +78,7 @@ func (mw *MutationWebhook) Mutate(request *v1beta1.AdmissionRequest) *v1beta1.Ad patchesBytes, err := SerializePatches(allPatches) if err != nil { mw.logger.Printf("Error occerred while serializing JSONPathch: %v", err) - return errorToResponse(err, true) + return errorToAdmissionResponse(err, true) } return &v1beta1.AdmissionResponse{ @@ -108,12 +108,14 @@ func (mw *MutationWebhook) applyRule(request *v1beta1.AdmissionRequest, rule typ return rulePatches, err } +// Gets patches from "patch" section in PolicyRule func (mw *MutationWebhook) applyRulePatches(request *v1beta1.AdmissionRequest, rule types.PolicyRule) ([]types.PolicyPatch, error) { var patches []types.PolicyPatch patches = append(patches, rule.Patches...) return patches, nil } +// Applies "configMapGenerator" and "secretGenerator" described in PolicyRule func (mw *MutationWebhook) applyRuleGenerators(request *v1beta1.AdmissionRequest, rule types.PolicyRule) error { // configMapGenerator and secretGenerator can be applied only to namespaces if request.Kind.Kind == "Namespace" { @@ -156,7 +158,7 @@ func (mw *MutationWebhook) applyConfigGenerator(generator *types.PolicyConfigGen return nil } -// SerializePatches converts JSON patches to byte array +// Converts JSON patches to byte array func SerializePatches(patches []types.PolicyPatch) ([]byte, error) { var result []byte if len(patches) == 0 { @@ -183,7 +185,7 @@ func SerializePatches(patches []types.PolicyPatch) ([]byte, error) { return result, nil } -func errorToResponse(err error, allowed bool) *v1beta1.AdmissionResponse { +func errorToAdmissionResponse(err error, allowed bool) *v1beta1.AdmissionResponse { return &v1beta1.AdmissionResponse{ Result: &metav1.Status{ Message: err.Error(), diff --git a/webhooks/utils_test.go b/webhooks/utils_test.go index 2ad348d3a2..4b03350431 100644 --- a/webhooks/utils_test.go +++ b/webhooks/utils_test.go @@ -1,38 +1,38 @@ package webhooks_test import ( - "testing" + "testing" ) func assertEq(t *testing.T, expected interface{}, actual interface{}) { - if expected != actual { - t.Errorf("%s != %s", expected, actual) - } + if expected != actual { + t.Errorf("%s != %s", expected, actual) + } } func assertNe(t *testing.T, expected interface{}, actual interface{}) { - if expected == actual { - t.Errorf("%s != %s", expected, actual) - } + if expected == actual { + t.Errorf("%s != %s", expected, actual) + } } func assertEqDataImpl(t *testing.T, expected, actual []byte, formatModifier string) { - if len(expected) != len(actual) { - t.Errorf("len(expected) != len(actual): %d != %d\n1:"+formatModifier+"\n2:"+formatModifier, len(expected), len(actual), expected, actual) - return - } + if len(expected) != len(actual) { + t.Errorf("len(expected) != len(actual): %d != %d\n1:"+formatModifier+"\n2:"+formatModifier, len(expected), len(actual), expected, actual) + return + } - for idx, val := range actual { - if val != expected[idx] { - t.Errorf("Slices not equal at index %d:\n1:"+formatModifier+"\n2:"+formatModifier, idx, expected, actual) - } - } + for idx, val := range actual { + if val != expected[idx] { + t.Errorf("Slices not equal at index %d:\n1:"+formatModifier+"\n2:"+formatModifier, idx, expected, actual) + } + } } func assertEqData(t *testing.T, expected, actual []byte) { - assertEqDataImpl(t, expected, actual, "%x") + assertEqDataImpl(t, expected, actual, "%x") } func assertEqStringAndData(t *testing.T, str string, data []byte) { - assertEqDataImpl(t, []byte(str), data, "%s") + assertEqDataImpl(t, []byte(str), data, "%s") }