mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
group version registration and names correction for gvk
This commit is contained in:
commit
5be203d2ce
15 changed files with 99 additions and 55 deletions
|
@ -48,7 +48,7 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// certClient := kc.client.CertificatesV1beta1().CertificateSigningRequests()
|
// certClient := kc.client.CertificatesV1beta1().CertificateSigningRequests()
|
||||||
csrList, err := c.ListResource("certificatesigningrequest", "")
|
csrList, err := c.ListResource("certificatesigningrequests", "")
|
||||||
// csrList, err := certClient.List(metav1.ListOptions{})
|
// csrList, err := certClient.List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New(fmt.Sprintf("Unable to list existing certificate requests: %v", err))
|
return nil, errors.New(fmt.Sprintf("Unable to list existing certificate requests: %v", err))
|
||||||
|
@ -58,7 +58,7 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
||||||
csr.GetName()
|
csr.GetName()
|
||||||
if csr.GetName() == req.ObjectMeta.Name {
|
if csr.GetName() == req.ObjectMeta.Name {
|
||||||
// Delete
|
// Delete
|
||||||
err := c.DeleteResouce("certificatesigningrequest", "", csr.GetName())
|
err := c.DeleteResouce("certificatesigningrequests", "", csr.GetName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New(fmt.Sprintf("Unable to delete existing certificate request: %v", err))
|
return nil, errors.New(fmt.Sprintf("Unable to delete existing certificate request: %v", err))
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create
|
// Create
|
||||||
unstrRes, err := c.CreateResource("certificatesigningrequest", "", req)
|
unstrRes, err := c.CreateResource("certificatesigningrequests", "", req)
|
||||||
// res, err := certClient.Create(req)
|
// res, err := certClient.Create(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -99,9 +99,9 @@ const certificateFetchWaitInterval time.Duration = 200 * time.Millisecond
|
||||||
func (c *Client) fetchCertificateFromRequest(req *certificates.CertificateSigningRequest, maxWaitSeconds uint8) ([]byte, error) {
|
func (c *Client) fetchCertificateFromRequest(req *certificates.CertificateSigningRequest, maxWaitSeconds uint8) ([]byte, error) {
|
||||||
// TODO: react of SIGINT and SIGTERM
|
// TODO: react of SIGINT and SIGTERM
|
||||||
timeStart := time.Now()
|
timeStart := time.Now()
|
||||||
c.GetResource("certificatesigningrequest", "", req.ObjectMeta.Name)
|
c.GetResource("certificatesigningrequests", "", req.ObjectMeta.Name)
|
||||||
for time.Now().Sub(timeStart) < time.Duration(maxWaitSeconds)*time.Second {
|
for time.Now().Sub(timeStart) < time.Duration(maxWaitSeconds)*time.Second {
|
||||||
unstrR, err := c.GetResource("certificatesigningrequest", "", req.ObjectMeta.Name)
|
unstrR, err := c.GetResource("certificatesigningrequests", "", req.ObjectMeta.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@ package client
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nirmata/kube-policy/config"
|
|
||||||
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
|
"github.com/nirmata/kube-policy/pkg/config"
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
certificates "k8s.io/api/certificates/v1beta1"
|
certificates "k8s.io/api/certificates/v1beta1"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
@ -32,6 +33,11 @@ func NewDynamicClient(config *rest.Config, logger *log.Logger) (*Client, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if logger == nil {
|
||||||
|
logger = log.New(os.Stdout, "Client : ", log.LstdFlags)
|
||||||
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
client: client,
|
client: client,
|
||||||
|
@ -39,6 +45,10 @@ func NewDynamicClient(config *rest.Config, logger *log.Logger) (*Client, error)
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) GetKubePolicyDeployment() (*apps.Deployment, error) {
|
func (c *Client) GetKubePolicyDeployment() (*apps.Deployment, error) {
|
||||||
kubePolicyDeployment, err := c.GetResource("deployments", config.KubePolicyNamespace, config.KubePolicyDeploymentName)
|
kubePolicyDeployment, err := c.GetResource("deployments", config.KubePolicyNamespace, config.KubePolicyDeploymentName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -172,7 +182,7 @@ func (c *Client) GenerateSecret(generator types.Generation, namespace string) er
|
||||||
// if generator.CopyFrom != nil {
|
// if generator.CopyFrom != nil {
|
||||||
c.logger.Printf("Copying data from secret %s/%s", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
c.logger.Printf("Copying data from secret %s/%s", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
||||||
// Get configMap resource
|
// Get configMap resource
|
||||||
unstrSecret, err := c.GetResource("secret", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
unstrSecret, err := c.GetResource("secrets", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -212,7 +222,7 @@ func (c *Client) GenerateConfigMap(generator types.Generation, namespace string)
|
||||||
// if generator.CopyFrom != nil {
|
// if generator.CopyFrom != nil {
|
||||||
c.logger.Printf("Copying data from configmap %s/%s", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
c.logger.Printf("Copying data from configmap %s/%s", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
||||||
// Get configMap resource
|
// Get configMap resource
|
||||||
unstrConfigMap, err := c.GetResource("configmap", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
unstrConfigMap, err := c.GetResource("configmaps", generator.CopyFrom.Namespace, generator.CopyFrom.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -269,7 +279,7 @@ func convertToCSR(obj *unstructured.Unstructured) (*certificates.CertificateSign
|
||||||
func (c *Client) createConfigMapAfterNamespaceIsCreated(configMap v1.ConfigMap, namespace string) {
|
func (c *Client) createConfigMapAfterNamespaceIsCreated(configMap v1.ConfigMap, namespace string) {
|
||||||
err := c.waitUntilNamespaceIsCreated(namespace)
|
err := c.waitUntilNamespaceIsCreated(namespace)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = c.CreateResource("configmap", namespace, configMap)
|
_, err = c.CreateResource("configmaps", namespace, configMap)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Printf("Can't create a configmap: %s", err)
|
c.logger.Printf("Can't create a configmap: %s", err)
|
||||||
|
@ -292,7 +302,7 @@ func (c *Client) waitUntilNamespaceIsCreated(name string) error {
|
||||||
|
|
||||||
var lastError error = nil
|
var lastError error = nil
|
||||||
for time.Now().Sub(timeStart) < namespaceCreationMaxWaitTime {
|
for time.Now().Sub(timeStart) < namespaceCreationMaxWaitTime {
|
||||||
_, lastError = c.GetResource("namespace", "", name)
|
_, lastError = c.GetResource("namespaces", "", name)
|
||||||
if lastError == nil {
|
if lastError == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ func getGrpVersionMapper(kind string, clientConfig *rest.Config, refresh bool) s
|
||||||
}
|
}
|
||||||
|
|
||||||
func getValue(kind string) (*schema.GroupVersionResource, bool) {
|
func getValue(kind string) (*schema.GroupVersionResource, bool) {
|
||||||
|
|
||||||
if val, ok := groupVersionMapper[kind]; ok {
|
if val, ok := groupVersionMapper[kind]; ok {
|
||||||
return &val, true
|
return &val, true
|
||||||
}
|
}
|
||||||
|
@ -48,12 +49,12 @@ func refreshRegisteredResources(mapper map[string]schema.GroupVersionResource, c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get registered server groups and resources
|
// get registered server groups and resources
|
||||||
_, resourceList, err := client.Discovery().ServerGroupsAndResources()
|
_, resourceList, err := client.Discovery().ServerGroupsAndResources()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, apiResource := range resourceList {
|
for _, apiResource := range resourceList {
|
||||||
for _, resource := range apiResource.APIResources {
|
for _, resource := range apiResource.APIResources {
|
||||||
grpVersion := strings.Split(apiResource.GroupVersion, "/")
|
grpVersion := strings.Split(apiResource.GroupVersion, "/")
|
||||||
|
@ -63,6 +64,12 @@ func refreshRegisteredResources(mapper map[string]schema.GroupVersionResource, c
|
||||||
Version: grpVersion[1],
|
Version: grpVersion[1],
|
||||||
Resource: resource.Name,
|
Resource: resource.Name,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// resources with only versions
|
||||||
|
mapper[resource.Name] = schema.GroupVersionResource{
|
||||||
|
Version: apiResource.GroupVersion,
|
||||||
|
Resource: resource.Name,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
init.go
2
init.go
|
@ -6,7 +6,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
client "github.com/nirmata/kube-policy/client"
|
client "github.com/nirmata/kube-policy/client"
|
||||||
"github.com/nirmata/kube-policy/config"
|
"github.com/nirmata/kube-policy/pkg/config"
|
||||||
tls "github.com/nirmata/kube-policy/pkg/tls"
|
tls "github.com/nirmata/kube-policy/pkg/tls"
|
||||||
|
|
||||||
rest "k8s.io/client-go/rest"
|
rest "k8s.io/client-go/rest"
|
||||||
|
|
7
main.go
7
main.go
|
@ -4,14 +4,13 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"k8s.io/sample-controller/pkg/signals"
|
|
||||||
|
|
||||||
client "github.com/nirmata/kube-policy/client"
|
client "github.com/nirmata/kube-policy/client"
|
||||||
controller "github.com/nirmata/kube-policy/pkg/controller"
|
controller "github.com/nirmata/kube-policy/pkg/controller"
|
||||||
event "github.com/nirmata/kube-policy/pkg/event"
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
"github.com/nirmata/kube-policy/pkg/sharedinformer"
|
"github.com/nirmata/kube-policy/pkg/sharedinformer"
|
||||||
"github.com/nirmata/kube-policy/pkg/violation"
|
"github.com/nirmata/kube-policy/pkg/violation"
|
||||||
"github.com/nirmata/kube-policy/pkg/webhooks"
|
"github.com/nirmata/kube-policy/pkg/webhooks"
|
||||||
|
"k8s.io/sample-controller/pkg/signals"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -23,6 +22,7 @@ var (
|
||||||
func main() {
|
func main() {
|
||||||
clientConfig, err := createClientConfig(kubeconfig)
|
clientConfig, err := createClientConfig(kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
log.Fatalf("Error building kubeconfig: %v\n", err)
|
log.Fatalf("Error building kubeconfig: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error creating client: %v\n", err)
|
log.Fatalf("Error creating client: %v\n", err)
|
||||||
}
|
}
|
||||||
|
// client.Test()
|
||||||
|
|
||||||
policyInformerFactory, err := sharedinformer.NewSharedInformerFactory(clientConfig)
|
policyInformerFactory, err := sharedinformer.NewSharedInformerFactory(clientConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,7 +51,7 @@ func main() {
|
||||||
log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
|
log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := webhooks.NewWebhookServer(tlsPair, policyInformerFactory, nil)
|
server, err := webhooks.NewWebhookServer(client, tlsPair, policyInformerFactory, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to create webhook server: %v\n", err)
|
log.Fatalf("Unable to create webhook server: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
|
// +genclient:nonNamespaced
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
// Policy contains rules to be applied to created resources
|
// Policy contains rules to be applied to created resources
|
||||||
|
@ -60,9 +61,9 @@ type Validation struct {
|
||||||
|
|
||||||
// Generation describes which resources will be created when other resource is created
|
// Generation describes which resources will be created when other resource is created
|
||||||
type Generation struct {
|
type Generation struct {
|
||||||
Kind string `json:"kind"`
|
Kind string `json:"kind"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CopyFrom `json:"copyFrom"`
|
CopyFrom *CopyFrom `json:"copyFrom"`
|
||||||
Data map[string]string `json:"data"`
|
Data map[string]string `json:"data"`
|
||||||
Labels map[string]string `json:"labels"`
|
Labels map[string]string `json:"labels"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,21 +64,12 @@ func (pp *Patch) Validate() error {
|
||||||
return fmt.Errorf("Unsupported JSONPatch operation '%s'", pp.Operation)
|
return fmt.Errorf("Unsupported JSONPatch operation '%s'", pp.Operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns error if Name or namespace is not cpecified
|
|
||||||
func (pcf *CopyFrom) Validate() error {
|
|
||||||
if pcf.Name == "" || pcf.Namespace == "" {
|
|
||||||
return errors.New("Name or/and Namespace is not specified")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate returns error if generator is configured incompletely
|
// Validate returns error if generator is configured incompletely
|
||||||
func (pcg *Generation) Validate() error {
|
func (pcg *Generation) Validate() error {
|
||||||
if pcg.Name == "" || pcg.Kind == "" {
|
if len(pcg.Data) == 0 && pcg.CopyFrom == nil {
|
||||||
return errors.New("Name or/and Kind of generator is not specified")
|
return fmt.Errorf("Neither Data nor CopyFrom (source) of %s/%s is specified", pcg.Kind, pcg.Name)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
return pcg.CopyFrom.Validate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is declared because k8s:deepcopy-gen is
|
// DeepCopyInto is declared because k8s:deepcopy-gen is
|
||||||
|
|
|
@ -161,14 +161,15 @@ func (pc *PolicyController) syncHandler(obj interface{}) error {
|
||||||
return fmt.Errorf("expected string in workqueue but got %#v", obj)
|
return fmt.Errorf("expected string in workqueue but got %#v", obj)
|
||||||
}
|
}
|
||||||
// convert the namespace/name string into distinct namespace and name
|
// convert the namespace/name string into distinct namespace and name
|
||||||
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
//TODO: currently policies are clustered, but the above code is to support namespaced as well
|
||||||
|
_, name, err := cache.SplitMetaNamespaceKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("invalid policy key: %s", key))
|
utilruntime.HandleError(fmt.Errorf("invalid policy key: %s", key))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Policy resource with namespace/name
|
// Get Policy resource with namespace/name
|
||||||
policy, err := pc.policyLister.Policies(namespace).Get(name)
|
policy, err := pc.policyLister.Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
utilruntime.HandleError(fmt.Errorf("policy '%s' in work queue no longer exists", key))
|
utilruntime.HandleError(fmt.Errorf("policy '%s' in work queue no longer exists", key))
|
||||||
|
@ -180,6 +181,6 @@ func (pc *PolicyController) syncHandler(obj interface{}) error {
|
||||||
// get the violations and pass to violation Builder
|
// get the violations and pass to violation Builder
|
||||||
// get the events and pass to event Builder
|
// get the events and pass to event Builder
|
||||||
//TODO: processPolicy
|
//TODO: processPolicy
|
||||||
fmt.Println(policy)
|
pc.logger.Printf("process policy %s on existing resources", policy.GetName())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -56,18 +55,23 @@ func applyRuleGenerator(client *client.Client, rawResource []byte, generator *ku
|
||||||
|
|
||||||
err := generator.Validate()
|
err := generator.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Generator for '%s' is invalid: %s", generator.Kind, err)
|
return fmt.Errorf("Generator for '%s/%s' is invalid: %s", generator.Kind, generator.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceName := ParseNameFromObject(rawResource)
|
namespace := ParseNameFromObject(rawResource)
|
||||||
// Generate the resource
|
switch generator.Kind {
|
||||||
switch gvk.Kind {
|
case "ConfigMap":
|
||||||
case "configmap":
|
err = client.GenerateConfigMap(*generator, namespace)
|
||||||
err = client.GenerateConfigMap(*generator, namespaceName)
|
case "Secret":
|
||||||
case "secret":
|
err = client.GenerateSecret(*generator, namespace)
|
||||||
err = client.GenerateSecret(*generator, namespaceName)
|
default:
|
||||||
case "default":
|
err = fmt.Errorf("Unsupported config Kind '%s'", generator.Kind)
|
||||||
err = errors.New("resource not supported")
|
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to apply generator for %s '%s/%s' : %v", generator.Kind, namespace, generator.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Successfully applied generator %s/%s", generator.Kind, generator.Name)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,3 +116,24 @@ func TestProcessPatches_RemovePathDoesntExist_NotEmptyResult(t *testing.T) {
|
||||||
assert.Assert(t, len(patchesBytes) == 1)
|
assert.Assert(t, len(patchesBytes) == 1)
|
||||||
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, patchesBytes[0])
|
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, patchesBytes[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEqStringAndData(t *testing.T, str string, data []byte) {
|
||||||
|
assertEqDataImpl(t, []byte(str), data, "%s")
|
||||||
|
}
|
||||||
|
|
|
@ -132,21 +132,21 @@ func (c *controller) processNextWorkItem() bool {
|
||||||
func (c *controller) SyncHandler(key Info) error {
|
func (c *controller) SyncHandler(key Info) error {
|
||||||
var resource runtime.Object
|
var resource runtime.Object
|
||||||
var err error
|
var err error
|
||||||
namespace, name, err := cache.SplitMetaNamespaceKey(key.Resource)
|
|
||||||
if err != nil {
|
|
||||||
utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key.Resource))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch key.Kind {
|
switch key.Kind {
|
||||||
case "Policy":
|
case "Policy":
|
||||||
//TODO: policy is clustered resource so wont need namespace
|
//TODO: policy is clustered resource so wont need namespace
|
||||||
resource, err = c.policyLister.Policies(namespace).Get(name)
|
resource, err = c.policyLister.Get(key.Resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("unable to create event for policy %s, will retry ", key.Resource))
|
utilruntime.HandleError(fmt.Errorf("unable to create event for policy %s, will retry ", key.Resource))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
namespace, name, err := cache.SplitMetaNamespaceKey(key.Resource)
|
||||||
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key.Resource))
|
||||||
|
return err
|
||||||
|
}
|
||||||
resource, err = c.client.GetResource(key.Kind, namespace, name)
|
resource, err = c.client.GetResource(key.Kind, namespace, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -63,7 +63,7 @@ func (b *builder) processViolation(info Info) error {
|
||||||
utilruntime.HandleError(fmt.Errorf("unable to extract namespace and name for %s", info.Policy))
|
utilruntime.HandleError(fmt.Errorf("unable to extract namespace and name for %s", info.Policy))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
policy, err := b.policyLister.Policies(namespace).Get(name)
|
policy, err := b.policyLister.Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
return err
|
return err
|
||||||
|
@ -90,7 +90,7 @@ func (b *builder) processViolation(info Info) error {
|
||||||
|
|
||||||
modifiedPolicy.Status.Violations = modifiedViolations
|
modifiedPolicy.Status.Violations = modifiedViolations
|
||||||
// Violations are part of the status sub resource, so we can use the Update Status api instead of updating the policy object
|
// Violations are part of the status sub resource, so we can use the Update Status api instead of updating the policy object
|
||||||
_, err = b.client.UpdateStatusResource("policy", namespace, modifiedPolicy)
|
_, err = b.client.UpdateStatusResource("policies", namespace, modifiedPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/nirmata/kube-policy/client"
|
"github.com/nirmata/kube-policy/client"
|
||||||
"github.com/nirmata/kube-policy/config"
|
"github.com/nirmata/kube-policy/pkg/config"
|
||||||
|
|
||||||
admregapi "k8s.io/api/admissionregistration/v1beta1"
|
admregapi "k8s.io/api/admissionregistration/v1beta1"
|
||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
|
@ -12,8 +12,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nirmata/kube-policy/config"
|
"github.com/nirmata/kube-policy/client"
|
||||||
"github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
"github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
||||||
|
"github.com/nirmata/kube-policy/pkg/config"
|
||||||
engine "github.com/nirmata/kube-policy/pkg/engine"
|
engine "github.com/nirmata/kube-policy/pkg/engine"
|
||||||
"github.com/nirmata/kube-policy/pkg/engine/mutation"
|
"github.com/nirmata/kube-policy/pkg/engine/mutation"
|
||||||
"github.com/nirmata/kube-policy/pkg/sharedinformer"
|
"github.com/nirmata/kube-policy/pkg/sharedinformer"
|
||||||
|
@ -27,6 +28,7 @@ import (
|
||||||
// MutationWebhook gets policies from policyController and takes control of the cluster with kubeclient.
|
// MutationWebhook gets policies from policyController and takes control of the cluster with kubeclient.
|
||||||
type WebhookServer struct {
|
type WebhookServer struct {
|
||||||
server http.Server
|
server http.Server
|
||||||
|
client *client.Client
|
||||||
policyLister v1alpha1.PolicyLister
|
policyLister v1alpha1.PolicyLister
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,7 @@ type WebhookServer struct {
|
||||||
// NewWebhookServer creates new instance of WebhookServer accordingly to given configuration
|
// NewWebhookServer creates new instance of WebhookServer accordingly to given configuration
|
||||||
// Policy Controller and Kubernetes Client should be initialized in configuration
|
// Policy Controller and Kubernetes Client should be initialized in configuration
|
||||||
func NewWebhookServer(
|
func NewWebhookServer(
|
||||||
|
client *client.Client,
|
||||||
tlsPair *tlsutils.TlsPemPair,
|
tlsPair *tlsutils.TlsPemPair,
|
||||||
shareInformer sharedinformer.PolicyInformer,
|
shareInformer sharedinformer.PolicyInformer,
|
||||||
logger *log.Logger) (*WebhookServer, error) {
|
logger *log.Logger) (*WebhookServer, error) {
|
||||||
|
@ -53,6 +56,7 @@ func NewWebhookServer(
|
||||||
tlsConfig.Certificates = []tls.Certificate{pair}
|
tlsConfig.Certificates = []tls.Certificate{pair}
|
||||||
|
|
||||||
ws := &WebhookServer{
|
ws := &WebhookServer{
|
||||||
|
client: client,
|
||||||
policyLister: shareInformer.GetLister(),
|
policyLister: shareInformer.GetLister(),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
|
@ -175,6 +179,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest) *v1
|
||||||
|
|
||||||
allowed := true
|
allowed := true
|
||||||
for _, policy := range policies {
|
for _, policy := range policies {
|
||||||
|
// validation
|
||||||
ws.logger.Printf("Validating resource with policy %s with %d rules", policy.ObjectMeta.Name, len(policy.Spec.Rules))
|
ws.logger.Printf("Validating resource with policy %s with %d rules", policy.ObjectMeta.Name, len(policy.Spec.Rules))
|
||||||
|
|
||||||
if ok := engine.Validate(*policy, request.Object.Raw, request.Kind); !ok {
|
if ok := engine.Validate(*policy, request.Object.Raw, request.Kind); !ok {
|
||||||
|
@ -184,6 +189,9 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest) *v1
|
||||||
} else {
|
} else {
|
||||||
ws.logger.Println("Validation is successful")
|
ws.logger.Println("Validation is successful")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generation
|
||||||
|
engine.Generate(ws.client, ws.logger, *policy, request.Object.Raw, request.Kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &v1beta1.AdmissionResponse{
|
return &v1beta1.AdmissionResponse{
|
||||||
|
|
Loading…
Add table
Reference in a new issue