1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/webhooks/registration.go

195 lines
5.4 KiB
Go
Raw Normal View History

package webhooks
import (
2019-03-25 10:11:50 +02:00
"errors"
"io/ioutil"
"github.com/nirmata/kyverno/pkg/dclient"
2019-05-21 11:00:09 -07:00
"github.com/nirmata/kyverno/pkg/config"
2019-03-25 10:11:50 +02:00
admregapi "k8s.io/api/admissionregistration/v1beta1"
2019-03-21 18:14:26 +02:00
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
2019-03-25 10:11:50 +02:00
admregclient "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1"
2019-03-21 18:14:26 +02:00
rest "k8s.io/client-go/rest"
)
// WebhookRegistrationClient is client for registration webhooks on cluster
type WebhookRegistrationClient struct {
2019-03-25 10:11:50 +02:00
registrationClient *admregclient.AdmissionregistrationV1beta1Client
2019-05-15 11:24:27 -07:00
client *client.Client
clientConfig *rest.Config
2019-03-25 10:11:50 +02:00
}
// NewWebhookRegistrationClient creates new WebhookRegistrationClient instance
2019-05-15 11:24:27 -07:00
func NewWebhookRegistrationClient(clientConfig *rest.Config, client *client.Client) (*WebhookRegistrationClient, error) {
2019-03-25 10:11:50 +02:00
registrationClient, err := admregclient.NewForConfig(clientConfig)
if err != nil {
2019-03-25 10:11:50 +02:00
return nil, err
}
return &WebhookRegistrationClient{
registrationClient: registrationClient,
2019-05-15 11:24:27 -07:00
client: client,
clientConfig: clientConfig,
}, nil
}
2019-03-25 10:11:50 +02:00
// Register creates admission webhooks configs on cluster
func (wrc *WebhookRegistrationClient) Register() error {
// For the case if cluster already has this configs
wrc.Deregister()
mutatingWebhookConfig, err := wrc.constructMutatingWebhookConfig(wrc.clientConfig)
if err != nil {
return err
}
_, err = wrc.registrationClient.MutatingWebhookConfigurations().Create(mutatingWebhookConfig)
if err != nil {
return err
}
validationWebhookConfig, err := wrc.constructValidatingWebhookConfig(wrc.clientConfig)
if err != nil {
return err
}
_, err = wrc.registrationClient.ValidatingWebhookConfigurations().Create(validationWebhookConfig)
if err != nil {
return err
}
return nil
2019-03-25 10:11:50 +02:00
}
// Deregister deletes webhook configs from cluster
// This function does not fail on error:
// Register will fail if the config exists, so there is no need to fail on error
func (wrc *WebhookRegistrationClient) Deregister() {
wrc.registrationClient.MutatingWebhookConfigurations().Delete(config.MutatingWebhookConfigurationName, &meta.DeleteOptions{})
wrc.registrationClient.ValidatingWebhookConfigurations().Delete(config.ValidatingWebhookConfigurationName, &meta.DeleteOptions{})
}
func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(configuration *rest.Config) (*admregapi.MutatingWebhookConfiguration, error) {
var caData []byte
// Check if ca is defined in the secret tls-ca
// assume the key and signed cert have been defined in secret tls.kyverno
caData = wrc.client.ReadRootCASecret()
if len(caData) == 0 {
// load the CA from kubeconfig
caData = extractCA(configuration)
}
2019-03-25 10:11:50 +02:00
if len(caData) == 0 {
return nil, errors.New("Unable to extract CA data from configuration")
}
return &admregapi.MutatingWebhookConfiguration{
ObjectMeta: meta.ObjectMeta{
Name: config.MutatingWebhookConfigurationName,
Labels: config.KubePolicyAppLabels,
OwnerReferences: []meta.OwnerReference{
wrc.constructOwner(),
},
},
Webhooks: []admregapi.Webhook{
constructWebhook(
config.MutatingWebhookName,
config.MutatingWebhookServicePath,
caData),
},
}, nil
}
func (wrc *WebhookRegistrationClient) constructValidatingWebhookConfig(configuration *rest.Config) (*admregapi.ValidatingWebhookConfiguration, error) {
// Check if ca is defined in the secret tls-ca
// assume the key and signed cert have been defined in secret tls.kyverno
caData := wrc.client.ReadRootCASecret()
if len(caData) == 0 {
// load the CA from kubeconfig
caData = extractCA(configuration)
}
if len(caData) == 0 {
return nil, errors.New("Unable to extract CA data from configuration")
}
return &admregapi.ValidatingWebhookConfiguration{
2019-03-21 18:14:26 +02:00
ObjectMeta: meta.ObjectMeta{
Name: config.ValidatingWebhookConfigurationName,
Labels: config.KubePolicyAppLabels,
OwnerReferences: []meta.OwnerReference{
wrc.constructOwner(),
},
},
2019-03-25 10:11:50 +02:00
Webhooks: []admregapi.Webhook{
constructWebhook(
config.ValidatingWebhookName,
config.ValidatingWebhookServicePath,
caData),
},
}, nil
}
func constructWebhook(name, servicePath string, caData []byte) admregapi.Webhook {
return admregapi.Webhook{
Name: name,
ClientConfig: admregapi.WebhookClientConfig{
Service: &admregapi.ServiceReference{
Namespace: config.KubePolicyNamespace,
Name: config.WebhookServiceName,
Path: &servicePath,
},
CABundle: caData,
},
Rules: []admregapi.RuleWithOperations{
admregapi.RuleWithOperations{
Operations: []admregapi.OperationType{
admregapi.Create,
},
Rule: admregapi.Rule{
APIGroups: []string{
"*",
},
APIVersions: []string{
"*",
},
Resources: []string{
"*/*",
},
},
},
},
}
}
func (wrc *WebhookRegistrationClient) constructOwner() meta.OwnerReference {
2019-05-15 11:24:27 -07:00
kubePolicyDeployment, err := wrc.client.GetKubePolicyDeployment()
if err != nil {
return meta.OwnerReference{}
}
return meta.OwnerReference{
APIVersion: config.DeploymentAPIVersion,
Kind: config.DeploymentKind,
Name: kubePolicyDeployment.ObjectMeta.Name,
UID: kubePolicyDeployment.ObjectMeta.UID,
}
}
// ExtractCA used for extraction CA from config
func extractCA(config *rest.Config) (result []byte) {
fileName := config.TLSClientConfig.CAFile
2019-03-21 16:56:03 +02:00
if fileName != "" {
result, err := ioutil.ReadFile(fileName)
2019-03-21 18:14:26 +02:00
if err != nil {
return nil
}
return result
}
return config.TLSClientConfig.CAData
2019-03-21 18:14:26 +02:00
}