1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/webhookconfig/common.go
shuting e9a972a362
feat: HA (#1931)
* Fix Dev setup

* webhook monitor - start webhook monitor in main process

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add leaderelection

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* - add isLeader; - update to use configmap lock

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* - add initialization method - add methods to get attributes

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* address comments

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* remove newContext in runLeaderElection

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add leader election to GenerateController

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* skip processing for non-leaders

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* skip processing for non-leaders

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add leader election to generate cleanup controller

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* Gracefully drain request

* HA - Webhook Register / Webhook Monitor / Certificate Renewer (#1920)

* enable leader election for webhook register

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* extract certManager to its own process

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* leader election for cert manager

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* certManager - init certs by the leader

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add leader election to webhook monitor

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* update log message

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add leader election to policy controller

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add leader election to policy report controller

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* rebuild leader election config

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* start informers in leaderelection

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* start policy informers in main

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* enable leader election in main

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* move eventHandler to the leader election start method

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* address reviewdog comments

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add clusterrole leaderelection

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* fixed generate flow (#1936)

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* - init separate kubeclient for leaderelection - fix webhook monitor

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* address reviewdog comments

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* cleanup Kyverno managed resources on stopLeading

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* tag v1.4.0-beta1

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* fix cleanup process on Kyverno stops

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* bump kind to 0.11.0, k8s v1.21 (#1980)

Co-authored-by: vyankatesh <vyankatesh@neualto.com>
Co-authored-by: vyankatesh <vyankateshkd@gmail.com>
Co-authored-by: Jim Bugwadia <jim@nirmata.com>
Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com>
2021-06-08 12:37:19 -07:00

223 lines
6.5 KiB
Go

package webhookconfig
import (
"io/ioutil"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/tls"
admregapi "k8s.io/api/admissionregistration/v1beta1"
apps "k8s.io/api/apps/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
rest "k8s.io/client-go/rest"
)
func (wrc *Register) readCaData() []byte {
logger := wrc.log.WithName("readCaData")
var caData []byte
var err error
// Check if ca is defined in the secret tls-ca
// assume the key and signed cert have been defined in secret tls.kyverno
if caData, err = tls.ReadRootCASecret(wrc.clientConfig, wrc.client); err == nil {
logger.V(4).Info("read CA from secret")
return caData
}
logger.V(4).Info("failed to read CA from secret, reading from kubeconfig", "reason", err.Error())
// load the CA from kubeconfig
if caData = extractCA(wrc.clientConfig); len(caData) != 0 {
logger.V(4).Info("read CA from kubeconfig")
return caData
}
logger.V(4).Info("failed to read CA from kubeconfig")
return nil
}
// ExtractCA used for extraction CA from config
func extractCA(config *rest.Config) (result []byte) {
fileName := config.TLSClientConfig.CAFile
if fileName != "" {
result, err := ioutil.ReadFile(fileName)
if err != nil {
return nil
}
return result
}
return config.TLSClientConfig.CAData
}
func (wrc *Register) constructOwner() v1.OwnerReference {
logger := wrc.log
kubePolicyDeployment, _, err := wrc.GetKubePolicyDeployment()
if err != nil {
logger.Error(err, "failed to construct OwnerReference")
return v1.OwnerReference{}
}
return v1.OwnerReference{
APIVersion: config.DeploymentAPIVersion,
Kind: config.DeploymentKind,
Name: kubePolicyDeployment.ObjectMeta.Name,
UID: kubePolicyDeployment.ObjectMeta.UID,
}
}
// GetKubePolicyDeployment gets Kyverno deployment using the resource cache
// it does not initialize any client call
func (wrc *Register) GetKubePolicyDeployment() (*apps.Deployment, *unstructured.Unstructured, error) {
lister, _ := wrc.resCache.GetGVRCache("Deployment")
kubePolicyDeployment, err := lister.NamespacedLister(config.KyvernoNamespace).Get(config.KyvernoDeploymentName)
if err != nil {
return nil, nil, err
}
deploy := apps.Deployment{}
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(kubePolicyDeployment.UnstructuredContent(), &deploy); err != nil {
return nil, kubePolicyDeployment, err
}
return &deploy, kubePolicyDeployment, nil
}
// debug mutating webhook
func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
sideEffect := admregapi.SideEffectClassNoneOnDryRun
failurePolicy := admregapi.Ignore
reinvocationPolicy := admregapi.NeverReinvocationPolicy
return admregapi.MutatingWebhook{
ReinvocationPolicy: &reinvocationPolicy,
Name: name,
ClientConfig: admregapi.WebhookClientConfig{
URL: &url,
CABundle: caData,
},
SideEffects: &sideEffect,
Rules: []admregapi.RuleWithOperations{
{
Operations: operationTypes,
Rule: admregapi.Rule{
APIGroups: []string{
apiGroups,
},
APIVersions: []string{
apiVersions,
},
Resources: resources,
},
},
},
AdmissionReviewVersions: []string{"v1beta1"},
TimeoutSeconds: &timeoutSeconds,
FailurePolicy: &failurePolicy,
}
}
func generateDebugValidatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
sideEffect := admregapi.SideEffectClassNoneOnDryRun
failurePolicy := admregapi.Ignore
return admregapi.ValidatingWebhook{
Name: name,
ClientConfig: admregapi.WebhookClientConfig{
URL: &url,
CABundle: caData,
},
SideEffects: &sideEffect,
Rules: []admregapi.RuleWithOperations{
{
Operations: operationTypes,
Rule: admregapi.Rule{
APIGroups: []string{
apiGroups,
},
APIVersions: []string{
apiVersions,
},
Resources: resources,
},
},
},
AdmissionReviewVersions: []string{"v1beta1"},
TimeoutSeconds: &timeoutSeconds,
FailurePolicy: &failurePolicy,
}
}
// mutating webhook
func generateMutatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
sideEffect := admregapi.SideEffectClassNoneOnDryRun
failurePolicy := admregapi.Ignore
reinvocationPolicy := admregapi.NeverReinvocationPolicy
return admregapi.MutatingWebhook{
ReinvocationPolicy: &reinvocationPolicy,
Name: name,
ClientConfig: admregapi.WebhookClientConfig{
Service: &admregapi.ServiceReference{
Namespace: config.KyvernoNamespace,
Name: config.KyvernoServiceName,
Path: &servicePath,
},
CABundle: caData,
},
SideEffects: &sideEffect,
Rules: []admregapi.RuleWithOperations{
{
Operations: operationTypes,
Rule: admregapi.Rule{
APIGroups: []string{
apiGroups,
},
APIVersions: []string{
apiVersions,
},
Resources: resources,
},
},
},
AdmissionReviewVersions: []string{"v1beta1"},
TimeoutSeconds: &timeoutSeconds,
FailurePolicy: &failurePolicy,
}
}
// validating webhook
func generateValidatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
sideEffect := admregapi.SideEffectClassNoneOnDryRun
failurePolicy := admregapi.Ignore
return admregapi.ValidatingWebhook{
Name: name,
ClientConfig: admregapi.WebhookClientConfig{
Service: &admregapi.ServiceReference{
Namespace: config.KyvernoNamespace,
Name: config.KyvernoServiceName,
Path: &servicePath,
},
CABundle: caData,
},
SideEffects: &sideEffect,
Rules: []admregapi.RuleWithOperations{
{
Operations: operationTypes,
Rule: admregapi.Rule{
APIGroups: []string{
apiGroups,
},
APIVersions: []string{
apiVersions,
},
Resources: resources,
},
},
},
AdmissionReviewVersions: []string{"v1beta1"},
TimeoutSeconds: &timeoutSeconds,
FailurePolicy: &failurePolicy,
}
}