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

327 lines
9.5 KiB
Go
Raw Normal View History

2020-10-15 17:29:07 -07:00
package common
import (
"errors"
"fmt"
2020-10-21 20:05:05 +05:30
"io/ioutil"
"net/http"
Update Kyverno test command (#1608) * fix link (#1566) Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update icon in chart.yaml Signed-off-by: Shuting Zhao <shutting06@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Adding default policies for restricted mode and adding notes to helm install (#1556) * Adding default policies for restricted mode, taking validationFailureAction from values.yaml and adding notes on helm install Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Adding emoji Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Update NOTES.txt * minor fix Signed-off-by: Raj Das <mail.rajdas@gmail.com> * adding to readme Signed-off-by: Raj Das <mail.rajdas@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update links and formatting in PR template (#1573) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * fix: restricting empty value to pass through the validation checks (#1574) Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Actually fix contributor link in PR template (#1575) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code improvement (#1567) * code improvement Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added if conditions Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * fixed unit test cases Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * feat(operators): support subset checking for in and notin (#1555) * feat(operators): support subset checking for in and notin Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> * feat(operators): fixed NotIn function Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * panic fix (#1601) Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update kyverno cli test cmd Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code indentation Signed-off-by: vyankatesh <vyankatesh@neualto.com> * change help text Signed-off-by: vyankatesh <vyankatesh@neualto.com> Co-authored-by: Dekel <dekelb@users.noreply.github.com> Co-authored-by: Shuting Zhao <shutting06@gmail.com> Co-authored-by: Raj Babu Das <mail.rajdas@gmail.com> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com> Co-authored-by: Arsh Sharma <56963264+RinkiyaKeDad@users.noreply.github.com> Co-authored-by: vyankatesh <vyankatesh@neualto.com>
2021-02-18 01:00:41 +05:30
"path/filepath"
"strings"
2020-10-15 17:29:07 -07:00
"github.com/go-git/go-billy/v5"
2020-10-15 17:29:07 -07:00
v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
client "github.com/kyverno/kyverno/pkg/dclient"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/utils"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
2020-11-04 15:56:33 -08:00
"k8s.io/client-go/kubernetes/scheme"
2020-11-19 15:56:14 +05:30
log "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/yaml"
2020-10-15 17:29:07 -07:00
)
// GetResources gets matched resources by the given policies
// the resources are fetched from
// - local paths to resources, if given
// - the k8s cluster, if given
func GetResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient *client.Client, cluster bool, namespace string, policyReport bool) ([]*unstructured.Unstructured, error) {
2020-10-21 20:05:05 +05:30
resources := make([]*unstructured.Unstructured, 0)
2020-10-15 17:29:07 -07:00
var err error
2020-10-21 20:05:05 +05:30
var resourceTypesMap = make(map[string]bool)
var resourceTypes []string
2020-10-21 20:05:05 +05:30
for _, policy := range policies {
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
resourceTypesMap[kind] = true
2020-10-15 17:29:07 -07:00
}
}
2020-10-21 20:05:05 +05:30
}
for kind := range resourceTypesMap {
resourceTypes = append(resourceTypes, kind)
}
2020-10-15 17:29:07 -07:00
2020-10-21 20:05:05 +05:30
if cluster && dClient != nil {
// resources, err = whenClusterIsTrue(resourceTypes, dClient, namespace, resourcePaths, policyReport)
// if err != nil {
// return resources, err
// }
resourceMap, err := getResourcesOfTypeFromCluster(resourceTypes, dClient, namespace)
2020-10-15 17:29:07 -07:00
if err != nil {
return nil, err
}
if len(resourcePaths) == 0 {
for _, rr := range resourceMap {
resources = append(resources, rr)
}
} else {
for _, resourcePath := range resourcePaths {
lenOfResource := len(resources)
for rn, rr := range resourceMap {
s := strings.Split(rn, "-")
if s[2] == resourcePath {
resources = append(resources, rr)
}
}
if lenOfResource >= len(resources) {
if policyReport {
log.Log.V(3).Info(fmt.Sprintf("%s not found in cluster", resourcePath))
} else {
fmt.Printf("\n----------------------------------------------------------------------\nresource %s not found in cluster\n----------------------------------------------------------------------\n", resourcePath)
}
return nil, errors.New(fmt.Sprintf("%s not found in cluster", resourcePath))
2020-10-21 20:05:05 +05:30
}
}
}
} else if len(resourcePaths) > 0 {
// resources, err = whenClusterIsFalse(resourcePaths, policyReport)
// if err != nil {
// return resources, err
// }
for _, resourcePath := range resourcePaths {
resourceBytes, err := getFileBytes(resourcePath)
if err != nil {
if policyReport {
log.Log.V(3).Info(fmt.Sprintf("failed to load resources: %s.", resourcePath), "error", err)
} else {
fmt.Printf("\n----------------------------------------------------------------------\nfailed to load resources: %s. \nerror: %s\n----------------------------------------------------------------------\n", resourcePath, err)
}
continue
}
2020-10-21 20:05:05 +05:30
getResources, err := GetResource(resourceBytes)
if err != nil {
return nil, err
}
for _, resource := range getResources {
resources = append(resources, resource)
}
2020-10-15 17:29:07 -07:00
}
}
return resources, err
2020-10-15 17:29:07 -07:00
}
// func whenClusterIsTrue(resourceTypes []string, dClient *client.Client, namespace string, resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
// resources := make([]*unstructured.Unstructured, 0)
// resourceMap, err := getResourcesOfTypeFromCluster(resourceTypes, dClient, namespace)
// if err != nil {
// return nil, err
// }
// if len(resourcePaths) == 0 {
// for _, rr := range resourceMap {
// resources = append(resources, rr)
// }
// } else {
// for _, resourcePath := range resourcePaths {
// lenOfResource := len(resources)
// for rn, rr := range resourceMap {
// s := strings.Split(rn, "-")
// if s[2] == resourcePath {
// resources = append(resources, rr)
// }
// }
// if lenOfResource >= len(resources) {
// if policyReport {
// log.Log.V(3).Info(fmt.Sprintf("%s not found in cluster", resourcePath))
// } else {
// fmt.Printf("\n----------------------------------------------------------------------\nresource %s not found in cluster\n----------------------------------------------------------------------\n", resourcePath)
// }
// return nil, errors.New(fmt.Sprintf("%s not found in cluster", resourcePath))
// }
// }
// }
// return resources, nil
// }
// func whenClusterIsFalse(resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
// resources := make([]*unstructured.Unstructured, 0)
// for _, resourcePath := range resourcePaths {
// resourceBytes, err := getFileBytes(resourcePath)
// if err != nil {
// if policyReport {
// log.Log.V(3).Info(fmt.Sprintf("failed to load resources: %s.", resourcePath), "error", err)
// } else {
// fmt.Printf("\n----------------------------------------------------------------------\nfailed to load resources: %s. \nerror: %s\n----------------------------------------------------------------------\n", resourcePath, err)
// }
// continue
// }
// getResources, err := GetResource(resourceBytes)
// if err != nil {
// return nil, err
// }
// for _, resource := range getResources {
// resources = append(resources, resource)
// }
// }
// return resources, nil
// }
// GetResourcesWithTest with gets matched resources by the given policies
Update Kyverno test command (#1608) * fix link (#1566) Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update icon in chart.yaml Signed-off-by: Shuting Zhao <shutting06@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Adding default policies for restricted mode and adding notes to helm install (#1556) * Adding default policies for restricted mode, taking validationFailureAction from values.yaml and adding notes on helm install Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Adding emoji Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Update NOTES.txt * minor fix Signed-off-by: Raj Das <mail.rajdas@gmail.com> * adding to readme Signed-off-by: Raj Das <mail.rajdas@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update links and formatting in PR template (#1573) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * fix: restricting empty value to pass through the validation checks (#1574) Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Actually fix contributor link in PR template (#1575) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code improvement (#1567) * code improvement Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added if conditions Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * fixed unit test cases Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * feat(operators): support subset checking for in and notin (#1555) * feat(operators): support subset checking for in and notin Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> * feat(operators): fixed NotIn function Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * panic fix (#1601) Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update kyverno cli test cmd Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code indentation Signed-off-by: vyankatesh <vyankatesh@neualto.com> * change help text Signed-off-by: vyankatesh <vyankatesh@neualto.com> Co-authored-by: Dekel <dekelb@users.noreply.github.com> Co-authored-by: Shuting Zhao <shutting06@gmail.com> Co-authored-by: Raj Babu Das <mail.rajdas@gmail.com> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com> Co-authored-by: Arsh Sharma <56963264+RinkiyaKeDad@users.noreply.github.com> Co-authored-by: vyankatesh <vyankatesh@neualto.com>
2021-02-18 01:00:41 +05:30
func GetResourcesWithTest(fs billy.Filesystem, policies []*v1.ClusterPolicy, resourcePaths []string, isGit bool, policyresoucePath string) ([]*unstructured.Unstructured, error) {
resources := make([]*unstructured.Unstructured, 0)
var resourceTypesMap = make(map[string]bool)
var resourceTypes []string
for _, policy := range policies {
for _, rule := range policy.Spec.Rules {
for _, kind := range rule.MatchResources.Kinds {
resourceTypesMap[kind] = true
}
}
}
for kind := range resourceTypesMap {
resourceTypes = append(resourceTypes, kind)
}
if len(resourcePaths) > 0 {
for _, resourcePath := range resourcePaths {
var resourceBytes []byte
var err error
if isGit {
Update Kyverno test command (#1608) * fix link (#1566) Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update icon in chart.yaml Signed-off-by: Shuting Zhao <shutting06@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Adding default policies for restricted mode and adding notes to helm install (#1556) * Adding default policies for restricted mode, taking validationFailureAction from values.yaml and adding notes on helm install Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Adding emoji Signed-off-by: Raj Das <mail.rajdas@gmail.com> * Update NOTES.txt * minor fix Signed-off-by: Raj Das <mail.rajdas@gmail.com> * adding to readme Signed-off-by: Raj Das <mail.rajdas@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update links and formatting in PR template (#1573) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * fix: restricting empty value to pass through the validation checks (#1574) Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * Actually fix contributor link in PR template (#1575) * update links and formatting in PR template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * update policy submission request template Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> * actually fix contrib guidelines Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code improvement (#1567) * code improvement Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added if conditions Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * fixed unit test cases Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * feat(operators): support subset checking for in and notin (#1555) * feat(operators): support subset checking for in and notin Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> * feat(operators): fixed NotIn function Signed-off-by: Arsh Sharma <arshsharma461@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * panic fix (#1601) Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> Signed-off-by: vyankatesh <vyankatesh@neualto.com> * update kyverno cli test cmd Signed-off-by: vyankatesh <vyankatesh@neualto.com> * code indentation Signed-off-by: vyankatesh <vyankatesh@neualto.com> * change help text Signed-off-by: vyankatesh <vyankatesh@neualto.com> Co-authored-by: Dekel <dekelb@users.noreply.github.com> Co-authored-by: Shuting Zhao <shutting06@gmail.com> Co-authored-by: Raj Babu Das <mail.rajdas@gmail.com> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com> Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com> Co-authored-by: Arsh Sharma <56963264+RinkiyaKeDad@users.noreply.github.com> Co-authored-by: vyankatesh <vyankatesh@neualto.com>
2021-02-18 01:00:41 +05:30
filep, err := fs.Open(filepath.Join(policyresoucePath, resourcePath))
if err != nil {
fmt.Printf("Unable to open resource file: %s. error: %s", resourcePath, err)
continue
}
resourceBytes, err = ioutil.ReadAll(filep)
} else {
resourceBytes, err = getFileBytes(resourcePath)
}
if err != nil {
fmt.Printf("\n----------------------------------------------------------------------\nfailed to load resources: %s. \nerror: %s\n----------------------------------------------------------------------\n", resourcePath, err)
continue
}
getResources, err := GetResource(resourceBytes)
if err != nil {
return nil, err
}
for _, resource := range getResources {
resources = append(resources, resource)
}
}
}
return resources, nil
}
2020-10-15 17:29:07 -07:00
// GetResource converts raw bytes to unstructured object
func GetResource(resourceBytes []byte) ([]*unstructured.Unstructured, error) {
resources := make([]*unstructured.Unstructured, 0)
var getErrString string
files, splitDocError := utils.SplitYAMLDocuments(resourceBytes)
if splitDocError != nil {
return nil, splitDocError
}
for _, resourceYaml := range files {
resource, err := convertResourceToUnstructured(resourceYaml)
if err != nil {
if strings.Contains(err.Error(), "Object 'Kind' is missing") {
log.Log.V(3).Info("skipping resource as kind not found")
continue
}
2020-10-15 17:29:07 -07:00
getErrString = getErrString + err.Error() + "\n"
}
resources = append(resources, resource)
}
if getErrString != "" {
return nil, errors.New(getErrString)
}
return resources, nil
}
func getResourcesOfTypeFromCluster(resourceTypes []string, dClient *client.Client, namespace string) (map[string]*unstructured.Unstructured, error) {
r := make(map[string]*unstructured.Unstructured)
2020-10-16 19:56:32 +05:30
2020-10-15 17:29:07 -07:00
for _, kind := range resourceTypes {
2020-10-21 20:05:05 +05:30
resourceList, err := dClient.ListResource("", kind, namespace, nil)
2020-10-15 17:29:07 -07:00
if err != nil {
2020-11-18 11:08:24 +05:30
continue
2020-10-15 17:29:07 -07:00
}
2020-11-18 11:08:24 +05:30
2020-10-15 17:29:07 -07:00
version := resourceList.GetAPIVersion()
for _, resource := range resourceList.Items {
key := kind + "-" + resource.GetNamespace() + "-" + resource.GetName()
r[key] = resource.DeepCopy()
2020-10-15 17:29:07 -07:00
resource.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: version,
Kind: kind,
})
}
}
2020-10-21 20:05:05 +05:30
return r, nil
2020-10-15 17:29:07 -07:00
}
func getFileBytes(path string) ([]byte, error) {
var (
file []byte
err error
)
if strings.Contains(path, "http") {
resp, err := http.Get(path)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, err
}
file, err = ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
} else {
file, err = ioutil.ReadFile(path)
if err != nil {
return nil, err
}
2020-10-15 17:29:07 -07:00
}
2020-10-15 17:29:07 -07:00
return file, err
}
func convertResourceToUnstructured(resourceYaml []byte) (*unstructured.Unstructured, error) {
decode := scheme.Codecs.UniversalDeserializer().Decode
_, metaData, decodeErr := decode(resourceYaml, nil, nil)
if decodeErr != nil {
if !strings.Contains(decodeErr.Error(), "no kind") {
return nil, decodeErr
}
2020-10-15 17:29:07 -07:00
}
resourceJSON, err := yaml.YAMLToJSON(resourceYaml)
2020-10-15 17:29:07 -07:00
if err != nil {
return nil, err
}
resource, err := engineutils.ConvertToUnstructured(resourceJSON)
if err != nil {
return nil, err
}
if decodeErr == nil {
resource.SetGroupVersionKind(*metaData)
}
2020-10-15 17:29:07 -07:00
if resource.GetNamespace() == "" {
resource.SetNamespace("default")
}
return resource, nil
}