mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-15 17:51:20 +00:00
Merge pull request #147 from nirmata/78_refactor
Go Report formatting and support
This commit is contained in:
commit
01d6af03bb
19 changed files with 92 additions and 65 deletions
|
@ -14,6 +14,9 @@ install: true
|
|||
script:
|
||||
- make build
|
||||
|
||||
after_script:
|
||||
- curl -d "repo=https://github.com/nirmata/kyverno" https://goreportcard.com/checks
|
||||
|
||||
after_success:
|
||||
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
|
||||
- make docker-publish
|
|
@ -1,6 +1,6 @@
|
|||
# Kyverno - Kubernetes Native Policy Management
|
||||
|
||||
[![Build Status](https://travis-ci.org/nirmata/kyverno.svg?branch=master)](https://travis-ci.org/nirmata/kyverno)
|
||||
[![Build Status](https://travis-ci.org/nirmata/kyverno.svg?branch=master)](https://travis-ci.org/nirmata/kyverno) [![Go Report Card](https://goreportcard.com/badge/github.com/nirmata/kyverno)](https://goreportcard.com/report/github.com/nirmata/kyverno)
|
||||
|
||||
![logo](documentation/images/Kyverno_Horizontal.png)
|
||||
|
||||
|
|
2
init.go
2
init.go
|
@ -28,7 +28,7 @@ func createClientConfig(kubeconfig string) (*rest.Config, error) {
|
|||
// Loads or creates PEM private key and TLS certificate for webhook server.
|
||||
// Created pair is stored in cluster's secret.
|
||||
// Returns struct with key/certificate pair.
|
||||
func initTlsPemPair(configuration *rest.Config, client *client.Client) (*tls.TlsPemPair, error) {
|
||||
func initTLSPemPair(configuration *rest.Config, client *client.Client) (*tls.TlsPemPair, error) {
|
||||
certProps, err := client.GetTLSCertProps(configuration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
2
main.go
2
main.go
|
@ -45,7 +45,7 @@ func main() {
|
|||
violationBuilder,
|
||||
eventController)
|
||||
|
||||
tlsPair, err := initTlsPemPair(clientConfig, client)
|
||||
tlsPair, err := initTLSPemPair(clientConfig, client)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err)
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ type Violation struct {
|
|||
Resource string `json:"resource,omitempty"`
|
||||
Rule string `json:"rule,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Message string `json:"message,omitempty`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
|
@ -102,6 +102,7 @@ func (pc *PolicyController) Run(stopCh <-chan struct{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//Stop to perform actions when controller is stopped
|
||||
func (pc *PolicyController) Stop() {
|
||||
glog.Info("shutting down policy controller workers")
|
||||
}
|
||||
|
@ -144,7 +145,7 @@ func (pc *PolicyController) handleErr(err error, key interface{}) {
|
|||
}
|
||||
pc.queue.Forget(key)
|
||||
utilruntime.HandleError(err)
|
||||
glog.Warning("Dropping the key %q out of the queue: %v", key, err)
|
||||
glog.Warningf("Dropping the key %q out of the queue: %v", key, err)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) syncHandler(obj interface{}) error {
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Issues TLS certificate for webhook server using given PEM private key
|
||||
//GenerateTlsPemPair Issues TLS certificate for webhook server using given PEM private key
|
||||
// Returns signed and approved TLS certificate in PEM format
|
||||
func (c *Client) GenerateTlsPemPair(props tls.TlsCertificateProps) (*tls.TlsPemPair, error) {
|
||||
privateKey, err := tls.TlsGeneratePrivateKey()
|
||||
|
@ -26,17 +26,17 @@ func (c *Client) GenerateTlsPemPair(props tls.TlsCertificateProps) (*tls.TlsPemP
|
|||
|
||||
certRequest, err := tls.TlsCertificateGenerateRequest(privateKey, props)
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Unable to create certificate request: %v", err))
|
||||
return nil, fmt.Errorf("Unable to create certificate request: %v", err)
|
||||
}
|
||||
|
||||
certRequest, err = c.submitAndApproveCertificateRequest(certRequest)
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Unable to submit and approve certificate request: %v", err))
|
||||
return nil, fmt.Errorf("Unable to submit and approve certificate request: %v", err)
|
||||
}
|
||||
|
||||
tlsCert, err := c.fetchCertificateFromRequest(certRequest, 10)
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Failed to configure a certificate for the Kyverno controller. A CA certificate is required to allow the Kubernetes API Server to communicate with Kyverno. You can either provide a certificate or configure your cluster to allow certificate signing. Please refer to https://github.com/nirmata/kyverno/installation.md.: %v", err))
|
||||
return nil, fmt.Errorf("Failed to configure a certificate for the Kyverno controller. A CA certificate is required to allow the Kubernetes API Server to communicate with Kyverno. You can either provide a certificate or configure your cluster to allow certificate signing. Please refer to https://github.com/nirmata/kyverno/installation.md.: %v", err)
|
||||
}
|
||||
|
||||
return &tls.TlsPemPair{
|
||||
|
@ -53,14 +53,14 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
|||
}
|
||||
csrList, err := c.ListResource(CSRs, "")
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Unable to list existing certificate requests: %v", err))
|
||||
return nil, fmt.Errorf("Unable to list existing certificate requests: %v", err)
|
||||
}
|
||||
|
||||
for _, csr := range csrList.Items {
|
||||
if csr.GetName() == req.ObjectMeta.Name {
|
||||
err := c.DeleteResouce(CSRs, "", csr.GetName())
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Unable to delete existing certificate request: %v", err))
|
||||
return nil, fmt.Errorf("Unable to delete existing certificate request: %v", err)
|
||||
}
|
||||
glog.Info("Old certificate request is deleted")
|
||||
break
|
||||
|
@ -84,7 +84,7 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
|||
})
|
||||
res, err = certClient.UpdateApproval(res)
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Unable to approve certificate request: %v", err))
|
||||
return nil, fmt.Errorf("Unable to approve certificate request: %v", err)
|
||||
}
|
||||
glog.Infof("Certificate request %s is approved", res.ObjectMeta.Name)
|
||||
|
||||
|
@ -115,9 +115,10 @@ func (c *Client) fetchCertificateFromRequest(req *certificates.CertificateSignin
|
|||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("Cerificate fetch timeout is reached: %d seconds", maxWaitSeconds))
|
||||
return nil, fmt.Errorf("Cerificate fetch timeout is reached: %d seconds", maxWaitSeconds)
|
||||
}
|
||||
|
||||
//ReadRootCASecret returns the RootCA from the pre-defined secret
|
||||
func (c *Client) ReadRootCASecret() (result []byte) {
|
||||
certProps, err := c.GetTLSCertProps(c.clientConfig)
|
||||
if err != nil {
|
||||
|
@ -147,7 +148,7 @@ func (c *Client) ReadRootCASecret() (result []byte) {
|
|||
const selfSignedAnnotation string = "self-signed-cert"
|
||||
const rootCAKey string = "rootCA.crt"
|
||||
|
||||
// Reads the pair of TLS certificate and key from the specified secret.
|
||||
//ReadTlsPair Reads the pair of TLS certificate and key from the specified secret.
|
||||
func (c *Client) ReadTlsPair(props tls.TlsCertificateProps) *tls.TlsPemPair {
|
||||
sname := generateTLSPairSecretName(props)
|
||||
unstrSecret, err := c.GetResource(Secrets, props.Namespace, sname)
|
||||
|
@ -186,7 +187,7 @@ func (c *Client) ReadTlsPair(props tls.TlsCertificateProps) *tls.TlsPemPair {
|
|||
return &pemPair
|
||||
}
|
||||
|
||||
// Writes the pair of TLS certificate and key to the specified secret.
|
||||
//WriteTlsPair Writes the pair of TLS certificate and key to the specified secret.
|
||||
// Updates existing secret or creates new one.
|
||||
func (c *Client) WriteTlsPair(props tls.TlsCertificateProps, pemPair *tls.TlsPemPair) error {
|
||||
name := generateTLSPairSecretName(props)
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
//Client enables interaction with k8 resource
|
||||
type Client struct {
|
||||
client dynamic.Interface
|
||||
cachedClient discovery.CachedDiscoveryInterface
|
||||
|
@ -32,6 +33,7 @@ type Client struct {
|
|||
kclient *kubernetes.Clientset
|
||||
}
|
||||
|
||||
//NewClient creates new instance of client
|
||||
func NewClient(config *rest.Config) (*Client, error) {
|
||||
client, err := dynamic.NewForConfig(config)
|
||||
if err != nil {
|
||||
|
@ -51,6 +53,7 @@ func NewClient(config *rest.Config) (*Client, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
//GetKubePolicyDeployment returns kube policy depoyment value
|
||||
func (c *Client) GetKubePolicyDeployment() (*apps.Deployment, error) {
|
||||
kubePolicyDeployment, err := c.GetResource("deployments", config.KubePolicyNamespace, config.KubePolicyDeploymentName)
|
||||
if err != nil {
|
||||
|
@ -63,13 +66,14 @@ func (c *Client) GetKubePolicyDeployment() (*apps.Deployment, error) {
|
|||
return &deploy, nil
|
||||
}
|
||||
|
||||
//GetEventsInterface provides typed interface for events
|
||||
//TODO: can we use dynamic client to fetch the typed interface
|
||||
// or generate a kube client value to access the interface
|
||||
//GetEventsInterface provides typed interface for events
|
||||
func (c *Client) GetEventsInterface() (event.EventInterface, error) {
|
||||
return c.kclient.CoreV1().Events(""), nil
|
||||
}
|
||||
|
||||
//GetCSRInterface provides type interface for CSR
|
||||
func (c *Client) GetCSRInterface() (csrtype.CertificateSigningRequestInterface, error) {
|
||||
return c.kclient.CertificatesV1beta1().CertificateSigningRequests(), nil
|
||||
}
|
||||
|
@ -110,6 +114,7 @@ func (c *Client) ListResource(resource string, namespace string) (*unstructured.
|
|||
return c.getResourceInterface(resource, namespace).List(meta.ListOptions{})
|
||||
}
|
||||
|
||||
// DeleteResouce deletes the specified resource
|
||||
func (c *Client) DeleteResouce(resource string, namespace string, name string) error {
|
||||
return c.getResourceInterface(resource, namespace).Delete(name, &meta.DeleteOptions{})
|
||||
|
||||
|
@ -228,7 +233,7 @@ func convertToCSR(obj *unstructured.Unstructured) (*certificates.CertificateSign
|
|||
func (c *Client) waitUntilNamespaceIsCreated(name string) error {
|
||||
timeStart := time.Now()
|
||||
|
||||
var lastError error = nil
|
||||
var lastError error
|
||||
for time.Now().Sub(timeStart) < namespaceCreationMaxWaitTime {
|
||||
_, lastError = c.GetResource(Namespaces, "", name)
|
||||
if lastError == nil {
|
||||
|
@ -253,7 +258,7 @@ func (c *Client) getGVR(resource string) schema.GroupVersionResource {
|
|||
}
|
||||
//TODO using cached client to support cache validation and invalidation
|
||||
// iterate over the key to compare the resource
|
||||
for gvr, _ := range resources {
|
||||
for gvr := range resources {
|
||||
if gvr.Resource == resource {
|
||||
return gvr
|
||||
}
|
||||
|
|
|
@ -5,9 +5,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
//CSRs certificatesigningrequests
|
||||
CSRs string = "certificatesigningrequests"
|
||||
// Secrets secrets
|
||||
Secrets string = "secrets"
|
||||
// ConfigMaps configmaps
|
||||
ConfigMaps string = "configmaps"
|
||||
// Namespaces namespaces
|
||||
Namespaces string = "namespaces"
|
||||
)
|
||||
const namespaceCreationMaxWaitTime time.Duration = 30 * time.Second
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
// ProcessOverlay handles validating admission request
|
||||
// Checks the target resourse for rules defined in the policy
|
||||
// Checks the target resources for rules defined in the policy
|
||||
func ProcessOverlay(rule kubepolicy.Rule, rawResource []byte, gvk metav1.GroupVersionKind) ([]PatchBytes, result.RuleApplicationResult) {
|
||||
overlayApplicationResult := result.NewRuleApplicationResult(rule.Name)
|
||||
if rule.Mutation == nil || rule.Mutation.Overlay == nil {
|
||||
|
@ -112,7 +112,7 @@ func applyOverlayToArray(resource, overlay []interface{}, path string, res *resu
|
|||
case map[string]interface{}:
|
||||
for _, overlayElement := range overlay {
|
||||
typedOverlay := overlayElement.(map[string]interface{})
|
||||
anchors := GetAnchorsFromMap(typedOverlay)
|
||||
anchors := getAnchorsFromMap(typedOverlay)
|
||||
if len(anchors) > 0 {
|
||||
for i, resourceElement := range resource {
|
||||
typedResource := resourceElement.(map[string]interface{})
|
||||
|
@ -170,7 +170,7 @@ func fillEmptyArray(overlay []interface{}, path string, res *result.RuleApplicat
|
|||
case map[string]interface{}:
|
||||
for _, overlayElement := range overlay {
|
||||
typedOverlay := overlayElement.(map[string]interface{})
|
||||
anchors := GetAnchorsFromMap(typedOverlay)
|
||||
anchors := getAnchorsFromMap(typedOverlay)
|
||||
|
||||
if len(anchors) == 0 {
|
||||
patch := insertSubtree(overlayElement, path, res)
|
||||
|
@ -287,7 +287,7 @@ func prepareJSONValue(overlay interface{}) string {
|
|||
func hasOnlyAnchors(overlay interface{}) bool {
|
||||
switch typed := overlay.(type) {
|
||||
case map[string]interface{}:
|
||||
if anchors := GetAnchorsFromMap(typed); len(anchors) == len(typed) {
|
||||
if anchors := getAnchorsFromMap(typed); len(anchors) == len(typed) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ func hasOnlyAnchors(overlay interface{}) bool {
|
|||
func hasNestedAnchors(overlay interface{}) bool {
|
||||
switch typed := overlay.(type) {
|
||||
case map[string]interface{}:
|
||||
if anchors := GetAnchorsFromMap(typed); len(anchors) > 0 {
|
||||
if anchors := getAnchorsFromMap(typed); len(anchors) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ func ResourceMeetsDescription(resourceRaw []byte, description kubepolicy.Resourc
|
|||
}
|
||||
|
||||
if resourceRaw != nil {
|
||||
meta := ParseMetadataFromObject(resourceRaw)
|
||||
meta := parseMetadataFromObject(resourceRaw)
|
||||
name := ParseNameFromObject(resourceRaw)
|
||||
|
||||
if description.Name != nil {
|
||||
|
@ -35,7 +35,7 @@ func ResourceMeetsDescription(resourceRaw []byte, description kubepolicy.Resourc
|
|||
return false
|
||||
}
|
||||
|
||||
labelMap := ParseLabelsFromMetadata(meta)
|
||||
labelMap := parseLabelsFromMetadata(meta)
|
||||
|
||||
if !selector.Matches(labelMap) {
|
||||
return false
|
||||
|
@ -46,21 +46,21 @@ func ResourceMeetsDescription(resourceRaw []byte, description kubepolicy.Resourc
|
|||
return true
|
||||
}
|
||||
|
||||
func ParseMetadataFromObject(bytes []byte) map[string]interface{} {
|
||||
func parseMetadataFromObject(bytes []byte) map[string]interface{} {
|
||||
var objectJSON map[string]interface{}
|
||||
json.Unmarshal(bytes, &objectJSON)
|
||||
|
||||
return objectJSON["metadata"].(map[string]interface{})
|
||||
}
|
||||
|
||||
func ParseKindFromObject(bytes []byte) string {
|
||||
func parseKindFromObject(bytes []byte) string {
|
||||
var objectJSON map[string]interface{}
|
||||
json.Unmarshal(bytes, &objectJSON)
|
||||
|
||||
return objectJSON["kind"].(string)
|
||||
}
|
||||
|
||||
func ParseLabelsFromMetadata(meta map[string]interface{}) labels.Set {
|
||||
func parseLabelsFromMetadata(meta map[string]interface{}) labels.Set {
|
||||
if interfaceMap, ok := meta["labels"].(map[string]interface{}); ok {
|
||||
labelMap := make(labels.Set, len(interfaceMap))
|
||||
|
||||
|
@ -72,6 +72,7 @@ func ParseLabelsFromMetadata(meta map[string]interface{}) labels.Set {
|
|||
return nil
|
||||
}
|
||||
|
||||
//ParseNameFromObject extracts resource name from JSON obj
|
||||
func ParseNameFromObject(bytes []byte) string {
|
||||
var objectJSON map[string]interface{}
|
||||
json.Unmarshal(bytes, &objectJSON)
|
||||
|
@ -84,6 +85,7 @@ func ParseNameFromObject(bytes []byte) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// ParseNamespaceFromObject extracts the namespace from the JSON obj
|
||||
func ParseNamespaceFromObject(bytes []byte) string {
|
||||
var objectJSON map[string]interface{}
|
||||
json.Unmarshal(bytes, &objectJSON)
|
||||
|
@ -105,7 +107,7 @@ func ParseRegexPolicyResourceName(policyResourceName string) (string, bool) {
|
|||
return strings.Trim(regex[1], " "), true
|
||||
}
|
||||
|
||||
func GetAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
|
||||
func getAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
|
||||
for key, value := range anchorsMap {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// Validate handles validating admission request
|
||||
// Checks the target resourse for rules defined in the policy
|
||||
// Checks the target resources for rules defined in the policy
|
||||
func Validate(policy kubepolicy.Policy, rawResource []byte, gvk metav1.GroupVersionKind) result.Result {
|
||||
var resource interface{}
|
||||
json.Unmarshal(rawResource, &resource)
|
||||
|
@ -116,7 +116,7 @@ func validateArray(resourceArray, patternArray []interface{}, path string) resul
|
|||
|
||||
switch pattern := patternArray[0].(type) {
|
||||
case map[string]interface{}:
|
||||
anchors := GetAnchorsFromMap(pattern)
|
||||
anchors := getAnchorsFromMap(pattern)
|
||||
for i, value := range resourceArray {
|
||||
currentPath := path + strconv.Itoa(i) + "/"
|
||||
resource, ok := value.(map[string]interface{})
|
||||
|
|
|
@ -206,7 +206,7 @@ func TestGetAnchorsFromMap_ThereAreAnchors(t *testing.T) {
|
|||
var unmarshalled map[string]interface{}
|
||||
json.Unmarshal(rawMap, &unmarshalled)
|
||||
|
||||
actualMap := GetAnchorsFromMap(unmarshalled)
|
||||
actualMap := getAnchorsFromMap(unmarshalled)
|
||||
assert.Equal(t, len(actualMap), 2)
|
||||
assert.Equal(t, actualMap["(name)"].(string), "nirmata-*")
|
||||
assert.Equal(t, actualMap["(namespace)"].(string), "kube-?olicy")
|
||||
|
@ -227,7 +227,7 @@ func TestGetAnchorsFromMap_ThereAreNoAnchors(t *testing.T) {
|
|||
var unmarshalled map[string]interface{}
|
||||
json.Unmarshal(rawMap, &unmarshalled)
|
||||
|
||||
actualMap := GetAnchorsFromMap(unmarshalled)
|
||||
actualMap := getAnchorsFromMap(unmarshalled)
|
||||
assert.Assert(t, len(actualMap) == 0)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ type Info struct {
|
|||
//MsgKey is an identified to determine the preset message formats
|
||||
type MsgKey int
|
||||
|
||||
//Message id for pre-defined messages
|
||||
const (
|
||||
FResourcePolcy MsgKey = iota
|
||||
FProcessRule
|
||||
|
|
|
@ -4,9 +4,9 @@ package result
|
|||
type Reason int
|
||||
|
||||
const (
|
||||
//PolicyViolation there is a violation of policy
|
||||
Success Reason = iota
|
||||
//Success policy applied
|
||||
Success Reason = iota
|
||||
//Violation there is a violation of policy
|
||||
Violation
|
||||
//Failed the request to create/update the resource was blocked(generated from admission-controller)
|
||||
Failed
|
||||
|
|
|
@ -37,6 +37,7 @@ type RuleApplicationResult struct {
|
|||
Messages []string
|
||||
}
|
||||
|
||||
//NewRuleApplicationResult creates a new rule application result
|
||||
func NewRuleApplicationResult(ruleName string) RuleApplicationResult {
|
||||
return RuleApplicationResult{
|
||||
PolicyRule: ruleName,
|
||||
|
@ -67,6 +68,7 @@ func (e *RuleApplicationResult) String() string {
|
|||
return e.StringWithIndent("")
|
||||
}
|
||||
|
||||
// ToError returns the error if reason is not success
|
||||
func (e *RuleApplicationResult) ToError() error {
|
||||
if e.Reason != Success {
|
||||
return fmt.Errorf(e.String())
|
||||
|
@ -74,22 +76,23 @@ func (e *RuleApplicationResult) ToError() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//GetReason returns reason
|
||||
func (e *RuleApplicationResult) GetReason() Reason {
|
||||
return e.Reason
|
||||
}
|
||||
|
||||
// Adds formatted message to this result
|
||||
func (rar *RuleApplicationResult) AddMessagef(message string, a ...interface{}) {
|
||||
rar.Messages = append(rar.Messages, fmt.Sprintf(message, a...))
|
||||
//AddMessagef Adds formatted message to this result
|
||||
func (e *RuleApplicationResult) AddMessagef(message string, a ...interface{}) {
|
||||
e.Messages = append(e.Messages, fmt.Sprintf(message, a...))
|
||||
}
|
||||
|
||||
// Sets the Reason Failed and adds formatted message to this result
|
||||
func (rar *RuleApplicationResult) FailWithMessagef(message string, a ...interface{}) {
|
||||
rar.Reason = Failed
|
||||
rar.AddMessagef(message, a...)
|
||||
//FailWithMessagef Sets the Reason Failed and adds formatted message to this result
|
||||
func (e *RuleApplicationResult) FailWithMessagef(message string, a ...interface{}) {
|
||||
e.Reason = Failed
|
||||
e.AddMessagef(message, a...)
|
||||
}
|
||||
|
||||
// Takes messages and higher reason from another RuleApplicationResult
|
||||
//MergeWith Takes messages and higher reason from another RuleApplicationResult
|
||||
func (e *RuleApplicationResult) MergeWith(other *RuleApplicationResult) {
|
||||
if other != nil {
|
||||
e.Messages = append(e.Messages, other.Messages...)
|
||||
|
@ -122,6 +125,7 @@ func (e *CompositeResult) String() string {
|
|||
return e.StringWithIndent("")
|
||||
}
|
||||
|
||||
//ToError returns error if reason is not success
|
||||
func (e *CompositeResult) ToError() error {
|
||||
if e.Reason != Success {
|
||||
return fmt.Errorf(e.String())
|
||||
|
@ -129,10 +133,12 @@ func (e *CompositeResult) ToError() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//GetReason returns reason
|
||||
func (e *CompositeResult) GetReason() Reason {
|
||||
return e.Reason
|
||||
}
|
||||
|
||||
//NewPolicyApplicationResult creates a new policy application result
|
||||
func NewPolicyApplicationResult(policyName string) Result {
|
||||
return &CompositeResult{
|
||||
Message: fmt.Sprintf("policy - %s:", policyName),
|
||||
|
@ -140,6 +146,7 @@ func NewPolicyApplicationResult(policyName string) Result {
|
|||
}
|
||||
}
|
||||
|
||||
//NewAdmissionResult creates a new admission result
|
||||
func NewAdmissionResult(requestUID string) Result {
|
||||
return &CompositeResult{
|
||||
Message: fmt.Sprintf("For resource with UID - %s:", requestUID),
|
||||
|
|
|
@ -11,11 +11,13 @@ import (
|
|||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
//PolicyInformer access policy informers
|
||||
type PolicyInformer interface {
|
||||
GetLister() v1alpha1.PolicyLister
|
||||
GetInfomer() cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// SharedInfomer access shared informers
|
||||
type SharedInfomer interface {
|
||||
PolicyInformer
|
||||
Run(stopCh <-chan struct{})
|
||||
|
@ -25,7 +27,7 @@ type sharedInfomer struct {
|
|||
policyInformerFactory informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
//NewSharedInformer returns shared informer
|
||||
//NewSharedInformerFactory returns shared informer
|
||||
func NewSharedInformerFactory(clientConfig *rest.Config) (SharedInfomer, error) {
|
||||
// create policy client
|
||||
policyClientset, err := policyclientset.NewForConfig(clientConfig)
|
||||
|
|
|
@ -14,25 +14,25 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Properties of TLS certificate which should be issued for webhook server
|
||||
//TlsCertificateProps Properties of TLS certificate which should be issued for webhook server
|
||||
type TlsCertificateProps struct {
|
||||
Service string
|
||||
Namespace string
|
||||
ApiServerHost string
|
||||
}
|
||||
|
||||
// The pair of TLS certificate corresponding private key, both in PEM format
|
||||
//TlsPemPair The pair of TLS certificate corresponding private key, both in PEM format
|
||||
type TlsPemPair struct {
|
||||
Certificate []byte
|
||||
PrivateKey []byte
|
||||
}
|
||||
|
||||
// Generates RSA private key
|
||||
//TlsGeneratePrivateKey Generates RSA private key
|
||||
func TlsGeneratePrivateKey() (*rsa.PrivateKey, error) {
|
||||
return rsa.GenerateKey(rand.Reader, 2048)
|
||||
}
|
||||
|
||||
// Creates PEM block from private key object
|
||||
//TlsPrivateKeyToPem Creates PEM block from private key object
|
||||
func TlsPrivateKeyToPem(rsaKey *rsa.PrivateKey) []byte {
|
||||
privateKey := &pem.Block{
|
||||
Type: "PRIVATE KEY",
|
||||
|
@ -42,7 +42,7 @@ func TlsPrivateKeyToPem(rsaKey *rsa.PrivateKey) []byte {
|
|||
return pem.EncodeToMemory(privateKey)
|
||||
}
|
||||
|
||||
// Creates PEM block from raw certificate request
|
||||
//TlsCertificateRequestToPem Creates PEM block from raw certificate request
|
||||
func TlsCertificateRequestToPem(csrRaw []byte) []byte {
|
||||
csrBlock := &pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
|
@ -52,7 +52,7 @@ func TlsCertificateRequestToPem(csrRaw []byte) []byte {
|
|||
return pem.EncodeToMemory(csrBlock)
|
||||
}
|
||||
|
||||
// Generates raw certificate signing request
|
||||
//TlsCertificateGenerateRequest Generates raw certificate signing request
|
||||
func TlsCertificateGenerateRequest(privateKey *rsa.PrivateKey, props TlsCertificateProps) (*certificates.CertificateSigningRequest, error) {
|
||||
dnsNames := make([]string, 3)
|
||||
dnsNames[0] = props.Service
|
||||
|
@ -104,12 +104,12 @@ func TlsCertificateGenerateRequest(privateKey *rsa.PrivateKey, props TlsCertific
|
|||
}, nil
|
||||
}
|
||||
|
||||
// The generated service name should be the common name for TLS certificate
|
||||
//GenerateInClusterServiceName The generated service name should be the common name for TLS certificate
|
||||
func GenerateInClusterServiceName(props TlsCertificateProps) string {
|
||||
return props.Service + "." + props.Namespace + ".svc"
|
||||
}
|
||||
|
||||
//Gets NotAfter property from raw certificate
|
||||
//TlsCertificateGetExpirationDate Gets NotAfter property from raw certificate
|
||||
func TlsCertificateGetExpirationDate(certData []byte) (*time.Time, error) {
|
||||
block, _ := pem.Decode(certData)
|
||||
if block == nil {
|
||||
|
@ -127,6 +127,7 @@ func TlsCertificateGetExpirationDate(certData []byte) (*time.Time, error) {
|
|||
// an expired certificate in a controller that has been running for a long time
|
||||
const timeReserveBeforeCertificateExpiration time.Duration = time.Hour * 24 * 30 * 6 // About half a year
|
||||
|
||||
//IsTlsPairShouldBeUpdated checks if TLS pair has expited and needs to be updated
|
||||
func IsTlsPairShouldBeUpdated(tlsPair *TlsPemPair) bool {
|
||||
if tlsPair == nil {
|
||||
return true
|
||||
|
|
|
@ -163,14 +163,14 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest) *v1be
|
|||
Patch: engine.JoinPatches(allPatches),
|
||||
PatchType: &patchType,
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Message: message,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleValidation handles validating webhook admission request
|
||||
|
@ -249,7 +249,7 @@ func (ws *WebhookServer) bodyToAdmissionReview(request *http.Request, writer htt
|
|||
glog.Errorf("Error: Can't decode body as AdmissionReview: %v", err)
|
||||
http.Error(writer, "Can't decode body as AdmissionReview", http.StatusExpectationFailed)
|
||||
return nil
|
||||
} else {
|
||||
return admissionReview
|
||||
}
|
||||
|
||||
return admissionReview
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue