From 49596c5ac1adff845048d1abf8903dcef71c0048 Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 26 Aug 2021 18:29:32 +0300 Subject: [PATCH 01/25] split to function --- policyhandler/filesloader.go | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index cdd223b6..e51684e9 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -20,25 +20,18 @@ var ( func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framework, scanInfo *opapolicy.ScanInfo) (*cautils.K8SResources, error) { - files, errs := listFiles(scanInfo.InputPatterns) - if len(errs) > 0 { - cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error - } - if len(files) == 0 { - return nil, fmt.Errorf("empty list of files - no files found") + workloads, err := loadResourcesFromFiles(scanInfo.InputPatterns) + if err != nil { + return nil, err } - workloads, errs := loadFiles(files) - if len(errs) > 0 { - cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error - } - if len(workloads) == 0 { - return nil, fmt.Errorf("empty list of workloads - no workloads valid workloads found") - } + // TODO - load resource from url + // map all resources: map["/group/version/kind"][] allResources := mapResources(workloads) // build resources map + // map resources based on framework requrid resources: map["/group/version/kind"][] k8sResources := setResourceMap(frameworks) // save only relevant resources @@ -52,6 +45,26 @@ func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framewo } +func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, error) { + files, errs := listFiles(inputPatterns) + if len(errs) > 0 { + cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error + } + if len(files) == 0 { + return nil, fmt.Errorf("empty list of files - no files found") + } + + workloads, errs := loadFiles(files) + if len(errs) > 0 { + cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error + } + if len(workloads) == 0 { + return workloads, fmt.Errorf("empty list of workloads - no workloads valid workloads found") + } + return workloads, nil +} + +// build resources map func mapResources(workloads []k8sinterface.IWorkload) map[string][]map[string]interface{} { allResources := map[string][]map[string]interface{}{} for i := range workloads { @@ -76,7 +89,6 @@ func mapResources(workloads []k8sinterface.IWorkload) map[string][]map[string]in } -// // build resources map func loadFiles(filePaths []string) ([]k8sinterface.IWorkload, []error) { workloads := []k8sinterface.IWorkload{} errs := []error{} From 409080f51b8a54c57efc0051f86fb40b84999a47 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 29 Aug 2021 08:17:09 +0300 Subject: [PATCH 02/25] update package name o kubescape --- cautils/datastructures.go | 2 +- cautils/k8sinterface/k8sconfig_test.go | 2 +- cautils/k8sinterface/k8sdynamic.go | 2 +- cautils/k8sinterface/k8sstatic.go | 2 +- cautils/k8sinterface/workload.go | 2 +- cautils/k8sinterface/workloadmethods.go | 4 ++-- cautils/opapolicy/datastructures.go | 2 +- cautils/opapolicy/datastructures_mock.go | 2 +- cautils/opapolicy/resources/resourcesutils.go | 2 +- cmd/framework.go | 14 +++++++------- go.mod | 2 +- inputhandler/clihandler/flaghandler.go | 2 +- main.go | 2 +- opaprocessor/processorhandler.go | 8 ++++---- opaprocessor/processorhandler_test.go | 14 +++++++------- opaprocessor/processorhandlerutils.go | 10 +++++----- policyhandler/filesloader.go | 6 +++--- policyhandler/filesloader_test.go | 2 +- policyhandler/handlenotification.go | 6 +++--- policyhandler/handlepullpolicies.go | 2 +- policyhandler/k8sresources.go | 8 ++++---- policyhandler/k8sresourcesutils.go | 6 +++--- policyhandler/k8sresourcesutils_test.go | 4 ++-- printer/junit.go | 2 +- printer/printresults.go | 6 +++--- printer/summeryhelpers.go | 4 ++-- 26 files changed, 59 insertions(+), 59 deletions(-) diff --git a/cautils/datastructures.go b/cautils/datastructures.go index d31e906f..53d7b2aa 100644 --- a/cautils/datastructures.go +++ b/cautils/datastructures.go @@ -1,7 +1,7 @@ package cautils import ( - "kube-escape/cautils/opapolicy" + "kubescape/cautils/opapolicy" ) // K8SResources map[//] diff --git a/cautils/k8sinterface/k8sconfig_test.go b/cautils/k8sinterface/k8sconfig_test.go index 88ce14f8..2b29a70f 100644 --- a/cautils/k8sinterface/k8sconfig_test.go +++ b/cautils/k8sinterface/k8sconfig_test.go @@ -3,7 +3,7 @@ package k8sinterface import ( "testing" - "kube-escape/cautils/cautils" + "kubescape/cautils/cautils" ) func TestGetGroupVersionResource(t *testing.T) { diff --git a/cautils/k8sinterface/k8sdynamic.go b/cautils/k8sinterface/k8sdynamic.go index 9d0091af..ae59f0f5 100644 --- a/cautils/k8sinterface/k8sdynamic.go +++ b/cautils/k8sinterface/k8sdynamic.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "kube-escape/cautils/cautils" + "kubescape/cautils/cautils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" diff --git a/cautils/k8sinterface/k8sstatic.go b/cautils/k8sinterface/k8sstatic.go index 308e8bd3..f7cedc2c 100644 --- a/cautils/k8sinterface/k8sstatic.go +++ b/cautils/k8sinterface/k8sstatic.go @@ -3,7 +3,7 @@ package k8sinterface import ( "context" - "kube-escape/cautils/cautils" + "kubescape/cautils/cautils" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/cautils/k8sinterface/workload.go b/cautils/k8sinterface/workload.go index 0f3b0205..bb347012 100644 --- a/cautils/k8sinterface/workload.go +++ b/cautils/k8sinterface/workload.go @@ -3,7 +3,7 @@ package k8sinterface import ( "encoding/json" - "kube-escape/cautils/apis" + "kubescape/cautils/apis" corev1 "k8s.io/api/core/v1" diff --git a/cautils/k8sinterface/workloadmethods.go b/cautils/k8sinterface/workloadmethods.go index 0a63070c..8ae380ea 100644 --- a/cautils/k8sinterface/workloadmethods.go +++ b/cautils/k8sinterface/workloadmethods.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "kube-escape/cautils/apis" - "kube-escape/cautils/cautils" + "kubescape/cautils/apis" + "kubescape/cautils/cautils" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index ac73aef6..2e791556 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -3,7 +3,7 @@ package opapolicy import ( "time" - armotypes "kube-escape/cautils/armotypes" + armotypes "kubescape/cautils/armotypes" ) type AlertScore float32 diff --git a/cautils/opapolicy/datastructures_mock.go b/cautils/opapolicy/datastructures_mock.go index 2c1937c7..4e2a4036 100644 --- a/cautils/opapolicy/datastructures_mock.go +++ b/cautils/opapolicy/datastructures_mock.go @@ -3,7 +3,7 @@ package opapolicy import ( "time" - armotypes "kube-escape/cautils/armotypes" + armotypes "kubescape/cautils/armotypes" ) // Mock A diff --git a/cautils/opapolicy/resources/resourcesutils.go b/cautils/opapolicy/resources/resourcesutils.go index 2ce18c29..ea89aa19 100644 --- a/cautils/opapolicy/resources/resourcesutils.go +++ b/cautils/opapolicy/resources/resourcesutils.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "kube-escape/cautils/k8sinterface" + "kubescape/cautils/k8sinterface" "github.com/golang/glog" "github.com/open-policy-agent/opa/storage" diff --git a/cmd/framework.go b/cmd/framework.go index eb48af53..8cd79ce9 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -5,13 +5,13 @@ import ( "flag" "fmt" "io/ioutil" - "kube-escape/cautils" - "kube-escape/cautils/armotypes" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" - "kube-escape/opaprocessor" - "kube-escape/policyhandler" - "kube-escape/printer" + "kubescape/cautils" + "kubescape/cautils/armotypes" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" + "kubescape/opaprocessor" + "kubescape/policyhandler" + "kubescape/printer" "os" "strings" diff --git a/go.mod b/go.mod index 0322258f..df427248 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module kube-escape +module kubescape go 1.16 diff --git a/inputhandler/clihandler/flaghandler.go b/inputhandler/clihandler/flaghandler.go index 9fa1d390..1a4be0dd 100644 --- a/inputhandler/clihandler/flaghandler.go +++ b/inputhandler/clihandler/flaghandler.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/opapolicy" ) type FlagHandler struct { diff --git a/main.go b/main.go index 4f4ce7ac..47f8524d 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "kube-escape/cmd" +import "kubescape/cmd" func main() { cmd.Execute() diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index a49118a8..52ac6f7c 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -3,13 +3,13 @@ package opaprocessor import ( "context" "fmt" - "kube-escape/cautils" + "kubescape/cautils" "time" - "kube-escape/cautils/k8sinterface" + "kubescape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" - "kube-escape/cautils/opapolicy/resources" + "kubescape/cautils/opapolicy" + "kubescape/cautils/opapolicy/resources" "github.com/golang/glog" "github.com/open-policy-agent/opa/ast" diff --git a/opaprocessor/processorhandler_test.go b/opaprocessor/processorhandler_test.go index 264f12f5..eae72844 100644 --- a/opaprocessor/processorhandler_test.go +++ b/opaprocessor/processorhandler_test.go @@ -3,18 +3,18 @@ package opaprocessor import ( "context" "encoding/json" - "kube-escape/cautils" + "kubescape/cautils" "os" "path" "strings" "testing" - "kube-escape/cautils/k8sinterface" + "kubescape/cautils/k8sinterface" // _ "k8s.io/client-go/plugin/pkg/client/auth" restclient "k8s.io/client-go/rest" - "kube-escape/cautils/opapolicy" - "kube-escape/cautils/opapolicy/resources" + "kubescape/cautils/opapolicy" + "kubescape/cautils/opapolicy/resources" "github.com/open-policy-agent/opa/ast" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -82,10 +82,10 @@ func TestCompromisedRegistries(t *testing.T) { // k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) k8sResources["/v1/pods"] = k8sinterface.V1AllClusterWithCompromisedRegistriesMock().Items wd, _ := os.Getwd() - baseDirName := "kube-escape" + baseDirName := "kubescape" idx := strings.Index(wd, baseDirName) wd = wd[0:idx] - resources.RegoDependenciesPath = path.Join(wd, "/kube-escape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies") + resources.RegoDependenciesPath = path.Join(wd, "/kubescape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies") k8sinterface.K8SConfig = &restclient.Config{} opaProcessor := NewOPAProcessorMock() @@ -108,7 +108,7 @@ func TestCompromisedRegistries(t *testing.T) { // k8sResources := make(cautils.K8SResources) // // k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) // k8sResources["/v1/pods"] = k8sinterface.V1KubeSystemNamespaceMock().Items -// resources.RegoDependenciesPath = "/home/david/go/src/kube-escape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies" +// resources.RegoDependenciesPath = "/home/david/go/src/kubescape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies" // opaProcessor := NewOPAProcessorMock() // // set opaSessionObj diff --git a/opaprocessor/processorhandlerutils.go b/opaprocessor/processorhandlerutils.go index 4982159f..8189f7ad 100644 --- a/opaprocessor/processorhandlerutils.go +++ b/opaprocessor/processorhandlerutils.go @@ -1,12 +1,12 @@ package opaprocessor import ( - "kube-escape/cautils" + "kubescape/cautils" - pkgcautils "kube-escape/cautils/cautils" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" - resources "kube-escape/cautils/opapolicy/resources" + pkgcautils "kubescape/cautils/cautils" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" + resources "kubescape/cautils/opapolicy/resources" "github.com/golang/glog" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index e51684e9..4adf6e2a 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -5,9 +5,9 @@ import ( "encoding/json" "fmt" "io/ioutil" - "kube-escape/cautils" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" "path/filepath" "gopkg.in/yaml.v2" diff --git a/policyhandler/filesloader_test.go b/policyhandler/filesloader_test.go index 903badf7..bec94f77 100644 --- a/policyhandler/filesloader_test.go +++ b/policyhandler/filesloader_test.go @@ -2,7 +2,7 @@ package policyhandler import ( "fmt" - "kube-escape/cautils" + "kubescape/cautils" "os" "path/filepath" "strings" diff --git a/policyhandler/handlenotification.go b/policyhandler/handlenotification.go index 05fecad1..754cbdbf 100644 --- a/policyhandler/handlenotification.go +++ b/policyhandler/handlenotification.go @@ -2,11 +2,11 @@ package policyhandler import ( "fmt" - "kube-escape/cautils" + "kubescape/cautils" - "kube-escape/cautils/k8sinterface" + "kubescape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/opapolicy" ) // PolicyHandler - diff --git a/policyhandler/handlepullpolicies.go b/policyhandler/handlepullpolicies.go index 926b0a51..822e4d30 100644 --- a/policyhandler/handlepullpolicies.go +++ b/policyhandler/handlepullpolicies.go @@ -8,7 +8,7 @@ import ( "net/url" "strings" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/opapolicy" ) // URLEncoder encode url diff --git a/policyhandler/k8sresources.go b/policyhandler/k8sresources.go index c87ca5b7..cd94a654 100644 --- a/policyhandler/k8sresources.go +++ b/policyhandler/k8sresources.go @@ -2,13 +2,13 @@ package policyhandler import ( "fmt" - "kube-escape/cautils" + "kubescape/cautils" "strings" - "kube-escape/cautils/k8sinterface" + "kubescape/cautils/k8sinterface" - "kube-escape/cautils/armotypes" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/armotypes" + "kubescape/cautils/opapolicy" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/policyhandler/k8sresourcesutils.go b/policyhandler/k8sresourcesutils.go index 4da5b2a5..8e6cc23f 100644 --- a/policyhandler/k8sresourcesutils.go +++ b/policyhandler/k8sresourcesutils.go @@ -1,10 +1,10 @@ package policyhandler import ( - "kube-escape/cautils" + "kubescape/cautils" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" ) func setResourceMap(frameworks []opapolicy.Framework) *cautils.K8SResources { diff --git a/policyhandler/k8sresourcesutils_test.go b/policyhandler/k8sresourcesutils_test.go index 73414884..7518aa74 100644 --- a/policyhandler/k8sresourcesutils_test.go +++ b/policyhandler/k8sresourcesutils_test.go @@ -1,8 +1,8 @@ package policyhandler import ( - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" "testing" ) diff --git a/printer/junit.go b/printer/junit.go index dd51e43d..7d2b2866 100644 --- a/printer/junit.go +++ b/printer/junit.go @@ -3,7 +3,7 @@ package printer import ( "encoding/xml" "fmt" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/opapolicy" ) type JUnitTestSuites struct { diff --git a/printer/printresults.go b/printer/printresults.go index 6f273024..bf712138 100644 --- a/printer/printresults.go +++ b/printer/printresults.go @@ -4,12 +4,12 @@ import ( "encoding/json" "encoding/xml" "fmt" - "kube-escape/cautils" + "kubescape/cautils" "os" "sort" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" "github.com/enescakir/emoji" "github.com/olekukonko/tablewriter" diff --git a/printer/summeryhelpers.go b/printer/summeryhelpers.go index 7a02bd3a..b61ddb67 100644 --- a/printer/summeryhelpers.go +++ b/printer/summeryhelpers.go @@ -3,8 +3,8 @@ package printer import ( "fmt" - "kube-escape/cautils/k8sinterface" - "kube-escape/cautils/opapolicy" + "kubescape/cautils/k8sinterface" + "kubescape/cautils/opapolicy" ) // Group workloads by namespace - return {"namespace": <[]WorkloadSummary>} From 29f4ae368db4ba6f6f4cef522664752693991032 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 29 Aug 2021 10:08:49 +0300 Subject: [PATCH 03/25] support url input, update readme --- .gitignore | 3 +- .gitmodules | 4 - README.md | 46 ++++++++-- cmd/framework.go | 24 ++---- cmd/scan.go | 2 +- examples/{example.sh => example.md} | 0 examples/online-boutique/README.md | 8 -- examples/online-boutique/bi-monitor.yaml | 59 ------------- inputhandler/clihandler/clihandler_test.go | 1 - inputhandler/clihandler/flaghandler.go | 97 ---------------------- policyhandler/filesloader.go | 92 ++++++++++++++------ policyhandler/filesloader_test.go | 7 +- policyhandler/urlloader.go | 73 ++++++++++++++++ 13 files changed, 188 insertions(+), 228 deletions(-) delete mode 100644 .gitmodules rename examples/{example.sh => example.md} (100%) delete mode 100644 examples/online-boutique/README.md delete mode 100644 examples/online-boutique/bi-monitor.yaml delete mode 100644 inputhandler/clihandler/clihandler_test.go delete mode 100644 inputhandler/clihandler/flaghandler.go create mode 100644 policyhandler/urlloader.go diff --git a/.gitignore b/.gitignore index 3c88c8d0..bd035f19 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.vs* *go.sum* -*kubescape* \ No newline at end of file +*kubescape* +*debug* \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 75b512e8..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "vendor/github.com/armosec/capacketsgo"] - path = vendor/github.com/armosec/capacketsgo - url = git@github.com:armosec/capacketsgo.git - branch = master diff --git a/README.md b/README.md index 2b8edc80..553747fb 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,14 @@ Tests are configured with YAML files, making this tool easy to update as test sp # TL;DR -## Installation -To install the tool locally, run this: +## Install & Run +1. Install: ``` curl -s https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | /bin/bash ``` - - -## Run -To get a fast check of the security posture of your Kubernetes cluster, run this: - +2. Run: ``` kubescape scan framework nsa --exclude-namespaces kube-system,kube-public ``` @@ -30,9 +26,43 @@ If you wish to scan all namespaces in your cluster, remove the `--exclude-namesp +## Usage & Examples + +* Scan a running Kubernetes cluster with [`nsa`](https://www.nsa.gov/News-Features/Feature-Stories/Article-View/Article/2716980/nsa-cisa-release-kubernetes-hardening-guidance/) framework +``` +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public +``` + +* Scan a running Kubernetes cluster with [`mitre`](https://www.microsoft.com/security/blog/2020/04/02/attack-matrix-kubernetes/) framework +``` +kubescape scan framework mitre --exclude-namespaces kube-system,kube-public +``` + + +* Scan local `yaml`/`json` files +``` +kubescape scan framework nsa examples/online-boutique/* +``` + + +* Scan `yaml`/`json` files from url +``` +kubescape scan framework nsa https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml +``` + +* Output in `json` format +``` +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o json +``` + +* Output in `junit` (`xml`) format +``` +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o junit +``` + # How to build -Note: development (and the release process) is done with Go 1.16 +Note: development (and the release process) is done with Go `1.16` 1. Clone Project ``` diff --git a/cmd/framework.go b/cmd/framework.go index 8cd79ce9..d21a19c0 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -4,7 +4,6 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "kubescape/cautils" "kubescape/cautils/armotypes" "kubescape/cautils/k8sinterface" @@ -13,14 +12,12 @@ import ( "kubescape/policyhandler" "kubescape/printer" "os" - "strings" "github.com/spf13/cobra" ) var scanInfo opapolicy.ScanInfo var supportedFrameworks = []string{"nsa", "mitre"} -var isSilent bool type CLIHandler struct { policyHandler *policyhandler.PolicyHandler @@ -31,7 +28,7 @@ var frameworkCmd = &cobra.Command{ Use: "framework ", Short: "The framework you wish to use. Supported frameworks: nsa, mitre", Long: ``, - ValidArgs: []string{"nsa", "mitre"}, + ValidArgs: supportedFrameworks, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { return errors.New("requires at least one argument") @@ -59,23 +56,13 @@ func init() { scanCmd.AddCommand(frameworkCmd) scanInfo = opapolicy.ScanInfo{} frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "namespaces to exclude from check") - frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "pretty-printer", "output format") - frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "silent output") -} - -func processYamlInput(yamls string) { - listOfYamls := strings.Split(yamls, ",") - for _, yaml := range listOfYamls { - dat, err := ioutil.ReadFile(yaml) - if err != nil { - fmt.Printf("Could not open file: %s.", yaml) - } - fmt.Print(string(dat)) - } - + frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "pretty-printer", "output format. supported formats: 'pretty-printer'/'json'/'junit'") + frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "silent progress output") } func CliSetup() error { + flag.Parse() + k8s := k8sinterface.NewKubernetesApi() processNotification := make(chan *cautils.OPASessionObj) @@ -117,7 +104,6 @@ func (clihandler *CLIHandler) Scan() error { }, Designators: armotypes.PortalDesignator{}, } - flag.Parse() switch policyNotification.NotificationType { case opapolicy.TypeExecPostureScan: go func() { diff --git a/cmd/scan.go b/cmd/scan.go index 98d6bdab..50af4324 100644 --- a/cmd/scan.go +++ b/cmd/scan.go @@ -7,7 +7,7 @@ import ( // scanCmd represents the scan command var scanCmd = &cobra.Command{ Use: "scan", - Short: "Scan command", + Short: "Scan the current running cluster or specified yaml files", Long: `The action you want to perform`, Run: func(cmd *cobra.Command, args []string) { }, diff --git a/examples/example.sh b/examples/example.md similarity index 100% rename from examples/example.sh rename to examples/example.md diff --git a/examples/online-boutique/README.md b/examples/online-boutique/README.md deleted file mode 100644 index ed852b72..00000000 --- a/examples/online-boutique/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# ./kubernetes-manifests - -:warning: Kubernetes manifests provided in this directory are not directly -deployable to a cluster. They are meant to be used with `skaffold` command to -insert the correct `image:` tags. - -Use the manifests in [/release](/release) directory which are configured with -pre-built public images. diff --git a/examples/online-boutique/bi-monitor.yaml b/examples/online-boutique/bi-monitor.yaml deleted file mode 100644 index d29fd043..00000000 --- a/examples/online-boutique/bi-monitor.yaml +++ /dev/null @@ -1,59 +0,0 @@ -apiVersion: v1 -data: - customer: Q3liZXJBcm1vclRlc3Rz - password: bml1ZGhmMjgzcnUyM3JrZQ== - username: ZHdlcnRlbnRAY3liZXJhcm1vci5pbw== -kind: Secret -metadata: - name: bi-monitor-secret -type: Opaque - ---- -apiVersion: v1 -kind: Service -metadata: - name: bi-monitor -spec: - type: ClusterIP - selector: - app: bi-monitor - ports: - - name: http - port: 80 - targetPort: 80 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: bi-monitor - labels: - app: bi-monitor -spec: - replicas: 1 - selector: - matchLabels: - app: bi-monitor - template: - metadata: - labels: - app: bi-monitor - spec: - containers: - - name: monitor - image: quay.io/armosec/demoservice:v1-debian - env: - - name: THREAD_TIMEOUT - value: "10" - - name: SLEEP_DURATION - value: "1" - - name: DEMO_TARGETS - value: "http://frontend:80 https://cisco.com" - - name: CAA_SIGNATURE_DEBUG_DEEP - volumeMounts: - - name: bi-monitor-secret - mountPath: /etc/secrets - volumes: - - name: bi-monitor-secret - secret: - secretName: bi-monitor-secret diff --git a/inputhandler/clihandler/clihandler_test.go b/inputhandler/clihandler/clihandler_test.go deleted file mode 100644 index 4ee666a0..00000000 --- a/inputhandler/clihandler/clihandler_test.go +++ /dev/null @@ -1 +0,0 @@ -package clihandler diff --git a/inputhandler/clihandler/flaghandler.go b/inputhandler/clihandler/flaghandler.go deleted file mode 100644 index 1a4be0dd..00000000 --- a/inputhandler/clihandler/flaghandler.go +++ /dev/null @@ -1,97 +0,0 @@ -package clihandler - -import ( - "flag" - "fmt" - "strings" - - "kubescape/cautils/opapolicy" -) - -type FlagHandler struct { - policyIdentifier *opapolicy.PolicyIdentifier -} - -func NewFlagHandler() *FlagHandler { - flag.Parse() - return &FlagHandler{} -} - -func (flagHandler *FlagHandler) ExecuteScan() bool { - return flagHandler.policyIdentifier != nil -} - -// SetupHTTPListener set up listening http servers -func (flagHandler *FlagHandler) ParseFlag() { - f := "help" - if len(flag.Args()) >= 1 { - f = strings.ToLower(flag.Arg(0)) - } - switch f { - case "scan": - flagHandler.Scan() - case "version": - flagHandler.Version() - case "help": - flagHandler.Help() - default: - fmt.Println("unknown input argument") - flagHandler.Help() - } -} - -func (flagHandler *FlagHandler) Help() { - fmt.Println("Run: kubescape scan framework nsa --exclude-namespaces kube-system,kube-public") -} - -func (flagHandler *FlagHandler) Version() { - fmt.Println("betav1") -} - -func (flagHandler *FlagHandler) Scan() { - f := "help" - if len(flag.Args()) >= 2 { - f = strings.ToLower(flag.Arg(1)) - } - switch f { - case "framework": - flagHandler.ScanFramework() - case "control": - flagHandler.ScanControl() - case "help": - flagHandler.ScanHelp() - default: - fmt.Println("unknown input argument") - flagHandler.ScanHelp() - } -} -func (flagHandler *FlagHandler) ScanFramework() { - frameworkName := strings.ToUpper(flag.Arg(2)) - // if cautils.StringInSlice(SupportedFrameworks(), frameworkName) == cautils.ValueNotFound { - // fmt.Printf("framework %s not supported, supported frameworks: %v", frameworkName, SupportedFrameworks()) - // return - // } - flagHandler.policyIdentifier = &opapolicy.PolicyIdentifier{ - Kind: opapolicy.KindFramework, - Name: frameworkName, - } -} -func (flagHandler *FlagHandler) ScanControl() { - flagHandler.policyIdentifier = &opapolicy.PolicyIdentifier{ - Kind: opapolicy.KindControl, - Name: strings.ToUpper(flag.Arg(3)), - } -} -func (flagHandler *FlagHandler) ScanHelp() { - fmt.Println("") -} -func (flagHandler *FlagHandler) ScanFrameworkHelp() { - fmt.Println("Run framework nsa or mitre") -} -func (flagHandler *FlagHandler) ScanControlHelp() { - fmt.Println("not supported") -} - -func SupportedFrameworks() []string { - return []string{"nsa", "mitre"} // TODO - get from BE -} diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index 4adf6e2a..e65a608e 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -9,6 +9,7 @@ import ( "kubescape/cautils/k8sinterface" "kubescape/cautils/opapolicy" "path/filepath" + "strings" "gopkg.in/yaml.v2" ) @@ -18,14 +19,33 @@ var ( JSON_PREFIX = []string{".json"} ) -func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framework, scanInfo *opapolicy.ScanInfo) (*cautils.K8SResources, error) { +type FileFormat string - workloads, err := loadResourcesFromFiles(scanInfo.InputPatterns) +const ( + YAML_FILE_FORMAT FileFormat = "yaml" + JSON_FILE_FORMAT FileFormat = "json" +) + +func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framework, scanInfo *opapolicy.ScanInfo) (*cautils.K8SResources, error) { + workloads := []k8sinterface.IWorkload{} + + // load resource from local file system + w, err := loadResourcesFromFiles(scanInfo.InputPatterns) if err != nil { return nil, err } + if w != nil { + workloads = append(workloads, w...) + } - // TODO - load resource from url + // load resource from url + w, err = loadResourcesFromUrl(scanInfo.InputPatterns) + if err != nil { + return nil, err + } + if w != nil { + workloads = append(workloads, w...) + } // map all resources: map["/group/version/kind"][] allResources := mapResources(workloads) @@ -51,7 +71,7 @@ func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, e cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error } if len(files) == 0 { - return nil, fmt.Errorf("empty list of files - no files found") + return nil, nil } workloads, errs := loadFiles(files) @@ -59,7 +79,7 @@ func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, e cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error } if len(workloads) == 0 { - return workloads, fmt.Errorf("empty list of workloads - no workloads valid workloads found") + return workloads, fmt.Errorf("empty list of workloads - no workloads found") } return workloads, nil } @@ -93,25 +113,42 @@ func loadFiles(filePaths []string) ([]k8sinterface.IWorkload, []error) { workloads := []k8sinterface.IWorkload{} errs := []error{} for i := range filePaths { - w, e := loadFile(filePaths[i]) + f, err := loadFile(filePaths[i]) + if err != nil { + errs = append(errs, err) + continue + } + w, e := readFile(f, getFileFormat(filePaths[i])) errs = append(errs, e...) - workloads = append(workloads, w...) + if w != nil { + workloads = append(workloads, w...) + } } return workloads, errs } -func loadFile(filePath string) ([]k8sinterface.IWorkload, []error) { - if isYaml(filePath) { - return loadYamlFile(filePath) - } else if isJson(filePath) { - return loadJsonFile(filePath) +func loadFile(filePath string) ([]byte, error) { + return ioutil.ReadFile(filePath) +} +func readFile(fileContent []byte, fileFromat FileFormat) ([]k8sinterface.IWorkload, []error) { + + switch fileFromat { + case YAML_FILE_FORMAT: + return readYamlFile(fileContent) + case JSON_FILE_FORMAT: + return readJsonFile(fileContent) + default: + return nil, []error{fmt.Errorf("file extension %s not supported", fileFromat)} } - return nil, []error{fmt.Errorf("file extension %s not supported, file name: %s", filepath.Ext(filePath), filePath)} + } func listFiles(patterns []string) ([]string, []error) { files := []string{} errs := []error{} for i := range patterns { + if strings.HasPrefix(patterns[i], "http") { + continue + } f, err := filepath.Glob(patterns[i]) if err != nil { errs = append(errs, err) @@ -122,12 +159,8 @@ func listFiles(patterns []string) ([]string, []error) { return files, errs } -func loadYamlFile(filePath string) ([]k8sinterface.IWorkload, []error) { +func readYamlFile(yamlFile []byte) ([]k8sinterface.IWorkload, []error) { errs := []error{} - yamlFile, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, []error{err} - } r := bytes.NewReader(yamlFile) dec := yaml.NewDecoder(r) @@ -136,24 +169,23 @@ func loadYamlFile(filePath string) ([]k8sinterface.IWorkload, []error) { var t interface{} for dec.Decode(&t) == nil { j := convertYamlToJson(t) + if j == nil { + continue + } if obj, ok := j.(map[string]interface{}); ok { yamlObjs = append(yamlObjs, k8sinterface.NewWorkloadObj(obj)) } else { - errs = append(errs, fmt.Errorf("failed to convert yaml file %s file to map[string]interface", filePath)) + errs = append(errs, fmt.Errorf("failed to convert yaml file to map[string]interface, file content: %v", j)) } } return yamlObjs, errs } -func loadJsonFile(filePath string) ([]k8sinterface.IWorkload, []error) { +func readJsonFile(jsonFile []byte) ([]k8sinterface.IWorkload, []error) { workloads := []k8sinterface.IWorkload{} - jsonFile, err := ioutil.ReadFile(filePath) - if err != nil { - return workloads, []error{err} - } var jsonObj interface{} - if err = json.Unmarshal(jsonFile, &jsonObj); err != nil { + if err := json.Unmarshal(jsonFile, &jsonObj); err != nil { return workloads, []error{err} } @@ -195,3 +227,13 @@ func isYaml(filePath string) bool { func isJson(filePath string) bool { return cautils.StringInSlice(YAML_PREFIX, filepath.Ext(filePath)) != cautils.ValueNotFound } + +func getFileFormat(filePath string) FileFormat { + if isYaml(filePath) { + return YAML_FILE_FORMAT + } else if isJson(filePath) { + return JSON_FILE_FORMAT + } else { + return FileFormat(filePath) + } +} diff --git a/policyhandler/filesloader_test.go b/policyhandler/filesloader_test.go index bec94f77..c41b6993 100644 --- a/policyhandler/filesloader_test.go +++ b/policyhandler/filesloader_test.go @@ -44,13 +44,10 @@ func TestLoadFiles(t *testing.T) { func TestLoadFile(t *testing.T) { files, _ := listFiles([]string{strings.Replace(onlineBoutiquePath(), "*", "bi-monitor.yaml", 1)}) - bb, err := loadFile(files[0]) - if len(err) > 0 { + _, err := loadFile(files[0]) + if err != nil { t.Errorf("%v", err) } - for i := range bb { - t.Errorf("%s", bb[i].ToString()) - } } func TestLoadResources(t *testing.T) { diff --git a/policyhandler/urlloader.go b/policyhandler/urlloader.go new file mode 100644 index 00000000..d1de20db --- /dev/null +++ b/policyhandler/urlloader.go @@ -0,0 +1,73 @@ +package policyhandler + +import ( + "bytes" + "fmt" + "io" + "kubescape/cautils" + "kubescape/cautils/k8sinterface" + "net/http" + "strings" +) + +func loadResourcesFromUrl(inputPatterns []string) ([]k8sinterface.IWorkload, error) { + urls := listUrls(inputPatterns) + if len(urls) == 0 { + return nil, nil + } + + workloads, errs := downloadFiles(urls) + if len(errs) > 0 { + cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error + } + if len(workloads) == 0 { + return workloads, fmt.Errorf("empty list of workloads - no workloads valid workloads found") + } + return workloads, nil +} + +func listUrls(patterns []string) []string { + urls := []string{} + for i := range patterns { + if strings.HasPrefix(patterns[i], "http") { + urls = append(urls, patterns[i]) + } + } + return urls +} + +func downloadFiles(urls []string) ([]k8sinterface.IWorkload, []error) { + workloads := []k8sinterface.IWorkload{} + errs := []error{} + for i := range urls { + f, err := downloadFile(urls[i]) + if err != nil { + errs = append(errs, err) + continue + } + w, e := readFile(f, getFileFormat(urls[i])) + errs = append(errs, e...) + if w != nil { + workloads = append(workloads, w...) + } + } + return workloads, errs +} + +func downloadFile(url string) ([]byte, error) { + resp, err := http.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode < 200 || 301 < resp.StatusCode { + return nil, fmt.Errorf("failed to download file, url: '%s', status code: %s", url, resp.Status) + } + return streamToByte(resp.Body), nil +} + +func streamToByte(stream io.Reader) []byte { + buf := new(bytes.Buffer) + buf.ReadFrom(stream) + return buf.Bytes() +} From 99431190332b4ac3f1cc4be1b7e0d5f0b69f7be8 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 29 Aug 2021 13:15:34 +0300 Subject: [PATCH 04/25] recursive glob --- policyhandler/filesloader.go | 38 +++++++++++++++++++++++++++++------- policyhandler/urlloader.go | 3 --- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index e65a608e..186fbe04 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -8,6 +8,7 @@ import ( "kubescape/cautils" "kubescape/cautils/k8sinterface" "kubescape/cautils/opapolicy" + "os" "path/filepath" "strings" @@ -38,7 +39,7 @@ func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framewo workloads = append(workloads, w...) } - // load resource from url + // load resources from url w, err = loadResourcesFromUrl(scanInfo.InputPatterns) if err != nil { return nil, err @@ -47,11 +48,15 @@ func (policyHandler *PolicyHandler) loadResources(frameworks []opapolicy.Framewo workloads = append(workloads, w...) } + if len(workloads) == 0 { + return nil, fmt.Errorf("empty list of workloads - no workloads found") + } + // map all resources: map["/group/version/kind"][] allResources := mapResources(workloads) // build resources map - // map resources based on framework requrid resources: map["/group/version/kind"][] + // map resources based on framework required resources: map["/group/version/kind"][] k8sResources := setResourceMap(frameworks) // save only relevant resources @@ -78,9 +83,6 @@ func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, e if len(errs) > 0 { cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error } - if len(workloads) == 0 { - return workloads, fmt.Errorf("empty list of workloads - no workloads found") - } return workloads, nil } @@ -138,10 +140,11 @@ func readFile(fileContent []byte, fileFromat FileFormat) ([]k8sinterface.IWorklo case JSON_FILE_FORMAT: return readJsonFile(fileContent) default: - return nil, []error{fmt.Errorf("file extension %s not supported", fileFromat)} + return nil, nil // []error{fmt.Errorf("file extension %s not supported", fileFromat)} } } + func listFiles(patterns []string) ([]string, []error) { files := []string{} errs := []error{} @@ -149,7 +152,7 @@ func listFiles(patterns []string) ([]string, []error) { if strings.HasPrefix(patterns[i], "http") { continue } - f, err := filepath.Glob(patterns[i]) + f, err := glob(filepath.Split(patterns[i])) //filepath.Glob(patterns[i]) if err != nil { errs = append(errs, err) } else { @@ -220,6 +223,27 @@ func convertYamlToJson(i interface{}) interface{} { return i } +func glob(root, pattern string) ([]string, error) { + var matches []string + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil { + return err + } else if matched { + matches = append(matches, path) + } + return nil + }) + if err != nil { + return nil, err + } + return matches, nil +} func isYaml(filePath string) bool { return cautils.StringInSlice(YAML_PREFIX, filepath.Ext(filePath)) != cautils.ValueNotFound } diff --git a/policyhandler/urlloader.go b/policyhandler/urlloader.go index d1de20db..9d2e14bf 100644 --- a/policyhandler/urlloader.go +++ b/policyhandler/urlloader.go @@ -20,9 +20,6 @@ func loadResourcesFromUrl(inputPatterns []string) ([]k8sinterface.IWorkload, err if len(errs) > 0 { cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error } - if len(workloads) == 0 { - return workloads, fmt.Errorf("empty list of workloads - no workloads valid workloads found") - } return workloads, nil } From 37afc1352fa4e532c28080e7166a78686f117632 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 29 Aug 2021 13:34:40 +0300 Subject: [PATCH 05/25] adding helm support to readme --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index bae0a089..4a414e09 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,18 @@ kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --sile kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o junit > results.xml ``` +### Helm Support + +1. Render the helm template to an output yaml +``` +helm template [CHART] [flags] --generate-name --dry-run --output-dir helm-output +``` + +2. Run `kubescape` with rended yaml files +``` +kubescape scan framework nsa helm-output/* +``` + # How to build Note: development (and the release process) is done with Go `1.16` From 2c6b1a440f66ac00dcd43f72d6ef57e456c774f4 Mon Sep 17 00:00:00 2001 From: dwertent Date: Mon, 30 Aug 2021 08:53:34 +0300 Subject: [PATCH 06/25] update glob function --- policyhandler/filesloader.go | 8 +++++++- policyhandler/filesloader_test.go | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index 186fbe04..57969138 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -152,6 +152,10 @@ func listFiles(patterns []string) ([]string, []error) { if strings.HasPrefix(patterns[i], "http") { continue } + if !filepath.IsAbs(patterns[i]) { + o, _ := os.Getwd() + patterns[i] = filepath.Join(o, patterns[i]) + } f, err := glob(filepath.Split(patterns[i])) //filepath.Glob(patterns[i]) if err != nil { errs = append(errs, err) @@ -212,7 +216,9 @@ func convertYamlToJson(i interface{}) interface{} { case map[interface{}]interface{}: m2 := map[string]interface{}{} for k, v := range x { - m2[k.(string)] = convertYamlToJson(v) + if s, ok := k.(string); ok { + m2[s] = convertYamlToJson(v) + } } return m2 case []interface{}: diff --git a/policyhandler/filesloader_test.go b/policyhandler/filesloader_test.go index c41b6993..40107267 100644 --- a/policyhandler/filesloader_test.go +++ b/policyhandler/filesloader_test.go @@ -31,7 +31,7 @@ func TestListFiles(t *testing.T) { if len(errs) > 0 { t.Error(errs) } - expected := 14 + expected := 12 if len(files) != expected { t.Errorf("wrong number of files, expected: %d, found: %d", expected, len(files)) } From f75cee0d7811d84796cfbaddd6f3fa85faa02882 Mon Sep 17 00:00:00 2001 From: dwertent Date: Mon, 30 Aug 2021 14:54:01 +0300 Subject: [PATCH 07/25] support stdin input --- README.md | 14 ++++---------- cmd/framework.go | 30 ++++++++++++++++++++++++------ printer/printresults.go | 14 ++++++++++++-- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4a414e09..f9743d2b 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,6 @@ Kubescape can produce output fitting for later processing: kubescape scan framework nsa --exclude-namespaces kube-system,kube-public ``` -* Scan a running Kubernetes cluster with [`mitre`](https://www.microsoft.com/security/blog/2020/04/02/attack-matrix-kubernetes/) framework -``` -kubescape scan framework mitre --exclude-namespaces kube-system,kube-public -``` - - * Scan local `yaml`/`json` files ``` kubescape scan framework nsa examples/online-boutique/* @@ -79,14 +73,14 @@ kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --sile ### Helm Support -1. Render the helm template to an output yaml +Render the helm template and pass as stdout ``` -helm template [CHART] [flags] --generate-name --dry-run --output-dir helm-output +helm template [CHART] [flags] --generate-name --dry-run | kubescape scan framework nsa - ``` -2. Run `kubescape` with rended yaml files +for example: ``` -kubescape scan framework nsa helm-output/* +helm template bitnami/mysql --generate-name --dry-run | kubescape scan framework nsa - ``` # How to build diff --git a/cmd/framework.go b/cmd/framework.go index d21a19c0..168209d6 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -4,6 +4,8 @@ import ( "errors" "flag" "fmt" + "io" + "io/ioutil" "kubescape/cautils" "kubescape/cautils/armotypes" "kubescape/cautils/k8sinterface" @@ -25,26 +27,42 @@ type CLIHandler struct { } var frameworkCmd = &cobra.Command{ - Use: "framework ", - Short: "The framework you wish to use. Supported frameworks: nsa, mitre", - Long: ``, + Use: "framework [``/`-`] [flags]", + Short: "The framework you wish to use. Supported frameworks: nsa", + Long: "Execute a scan on a running Kubernetes cluster or yaml/json files (use glob) or `-` for stdin", ValidArgs: supportedFrameworks, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { return errors.New("requires at least one argument") } if !isValidFramework(args[0]) { - return errors.New("supported frameworks: nsa and mitre") + return errors.New("supported frameworks: nsa") } return nil }, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { scanInfo.PolicyIdentifier = opapolicy.PolicyIdentifier{} scanInfo.PolicyIdentifier.Kind = opapolicy.KindFramework scanInfo.PolicyIdentifier.Name = args[0] - scanInfo.InputPatterns = args[1:] + + if len(args[1:]) == 0 || args[1] != "-" { + scanInfo.InputPatterns = args[1:] + } else { // store stout to file + tempFile, err := ioutil.TempFile(".", "tmp-kubescape*.yaml") + if err != nil { + return err + } + defer os.Remove(tempFile.Name()) + + if _, err := io.Copy(tempFile, os.Stdin); err != nil { + return err + } + scanInfo.InputPatterns = []string{tempFile.Name()} + } cautils.SetSilentMode(scanInfo.Silent) CliSetup() + + return nil }, } diff --git a/printer/printresults.go b/printer/printresults.go index bf712138..864d9193 100644 --- a/printer/printresults.go +++ b/printer/printresults.go @@ -17,6 +17,8 @@ import ( var INDENT = " " +const EmptyPercentage = "NaN" + const ( PrettyPrinter string = "pretty-printer" JsonPrinter string = "json" @@ -158,7 +160,11 @@ func (printer *Printer) printResult(controlName string, controlSummary *ControlS func generateRow(control string, cs ControlSummary) []string { row := []string{control} row = append(row, cs.ToSlice()...) - row = append(row, fmt.Sprintf("%d%s", percentage(cs.TotalResources, cs.TotalFailed), "%")) + if cs.TotalResources != 0 { + row = append(row, fmt.Sprintf("%d%s", percentage(cs.TotalResources, cs.TotalFailed), "%")) + } else { + row = append(row, EmptyPercentage) + } return row } @@ -181,7 +187,11 @@ func generateFooter(numControlers, sumFailed, sumTotal int) []string { row = append(row, fmt.Sprintf("%d", numControlers)) row = append(row, fmt.Sprintf("%d", sumFailed)) row = append(row, fmt.Sprintf("%d", sumTotal)) - row = append(row, fmt.Sprintf("%d%s", percentage(sumTotal, sumFailed), "%")) + if sumTotal != 0 { + row = append(row, fmt.Sprintf("%d%s", percentage(sumTotal, sumFailed), "%")) + } else { + row = append(row, EmptyPercentage) + } return row } func (printer *Printer) PrintSummaryTable() { From 1ff3a6c92c8c95e6f7f844831e10f5e967dd5385 Mon Sep 17 00:00:00 2001 From: dwertent Date: Mon, 30 Aug 2021 18:44:42 +0300 Subject: [PATCH 08/25] support output to file --- README.md | 9 ++-- cautils/opapolicy/datastructures.go | 33 ++++++++++++++ cmd/framework.go | 6 ++- docs/new-feature.svg | 35 +++++++++++++++ docs/release.md | 67 +++++++++++++++++++++++++++++ printer/printresults.go | 52 ++++++++++++++-------- 6 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 docs/new-feature.svg create mode 100644 docs/release.md diff --git a/README.md b/README.md index f9743d2b..7cb6764d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ If you wish to scan all namespaces in your cluster, remove the `--exclude-namesp - ## Usage & Examples ### Pre-Deployment Testing @@ -40,8 +39,8 @@ kubescape scan framework nsa *.yaml ### Integration with other tools Kubescape can produce output fitting for later processing: -* JSON (`-o json`) -* JUnit XML (`-o junit`) +* JSON (`-f json`) +* JUnit XML (`-f junit`) ### Examples @@ -63,12 +62,12 @@ kubescape scan framework nsa https://raw.githubusercontent.com/GoogleCloudPlatfo * Output in `json` format ``` -kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o json > results.json +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --format json --output results.json ``` * Output in `junit xml` format ``` -kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --silence -o junit > results.xml +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --format junit --output results.xml ``` ### Helm Support diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index 2e791556..ef5183e7 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -1,6 +1,7 @@ package opapolicy import ( + "path/filepath" "time" armotypes "kubescape/cautils/armotypes" @@ -151,8 +152,40 @@ type PolicyIdentifier struct { type ScanInfo struct { PolicyIdentifier PolicyIdentifier + Format string Output string ExcludedNamespaces string InputPatterns []string Silent bool } + +func (scanInfo *ScanInfo) Init() { + scanInfo.setSilentMode() + scanInfo.setOutputFile() + +} + +func (scanInfo *ScanInfo) setSilentMode() { + if scanInfo.Format == "json" || scanInfo.Format == "junit" { + scanInfo.Silent = true + } + if scanInfo.Output != "" { + scanInfo.Silent = true + } +} + +func (scanInfo *ScanInfo) setOutputFile() { + if scanInfo.Output == "" { + return + } + if scanInfo.Format == "json" { + if filepath.Ext(scanInfo.Output) != "json" { + scanInfo.Output += ".json" + } + } + if scanInfo.Format == "junit" { + if filepath.Ext(scanInfo.Output) != "xml" { + scanInfo.Output += ".xml" + } + } +} diff --git a/cmd/framework.go b/cmd/framework.go index 168209d6..1787473d 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -59,6 +59,7 @@ var frameworkCmd = &cobra.Command{ } scanInfo.InputPatterns = []string{tempFile.Name()} } + scanInfo.Init() cautils.SetSilentMode(scanInfo.Silent) CliSetup() @@ -74,7 +75,8 @@ func init() { scanCmd.AddCommand(frameworkCmd) scanInfo = opapolicy.ScanInfo{} frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "namespaces to exclude from check") - frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "pretty-printer", "output format. supported formats: 'pretty-printer'/'json'/'junit'") + frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", "output format. supported formats: 'pretty-printer'/'json'/'junit'") + frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "output file. print output to file and not stdout") frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "silent progress output") } @@ -100,7 +102,7 @@ func CliSetup() error { reporterObj := opaprocessor.NewOPAProcessor(&processNotification, &reportResults) reporterObj.ProcessRulesListenner() }() - p := printer.NewPrinter(&reportResults, scanInfo.Output) + p := printer.NewPrinter(&reportResults, scanInfo.Format, scanInfo.Output) p.ActionPrint() return nil diff --git a/docs/new-feature.svg b/docs/new-feature.svg new file mode 100644 index 00000000..3121dad3 --- /dev/null +++ b/docs/new-feature.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + new + + + new + + + + + + feature + + + feature + + + + + + diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 00000000..4690dda4 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,67 @@ +# Kubescape Release + + +## Input + +### Scan a running Kubernetes cluster + +* Scan your Kubernetes cluster. Ignore `kube-system` and `kube-public` namespaces +``` +kubescape scan framework nsa --exclude-namespaces kube-system,kube-public +``` + +* Scan your Kubernetes cluster +``` +kubescape scan framework nsa +``` + +### Scan a local Kubernetes manifest + +* Scan single Kubernetes manifest file +``` +kubescape scan framework nsa +``` + +* Scan many Kubernetes manifest files +``` +kubescape scan framework nsa +``` + +* Scan all Kubernetes manifest files in directory +``` +kubescape scan framework nsa *.yaml +``` + +* Scan Kubernetes manifest from stdout +``` +cat | kubescape scan framework nsa - +``` + + +* Scan Kubernetes manifest url +``` +kubescape scan framework nsa https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml +``` + +### Scan HELM chart + +* Render the helm chart using [`helm template`](https://helm.sh/docs/helm/helm_template/) and pass to stdout +``` +helm template [CHART] [flags] --generate-name --dry-run | kubescape scan framework nsa - +``` + +## Output formats + +By default, the output is user friendly. + +For the sake of automation, it is possible to receive the result in a `json` or `junit xml` format. + +* Output in `json` format +``` +kubescape scan framework nsa --format json --output results.json +``` + +* Output in `junit xml` format +``` +kubescape scan framework nsa --format junit --output results.xml +``` \ No newline at end of file diff --git a/printer/printresults.go b/printer/printresults.go index 864d9193..a4b4b74e 100644 --- a/printer/printresults.go +++ b/printer/printresults.go @@ -27,16 +27,18 @@ const ( type Printer struct { opaSessionObj *chan *cautils.OPASessionObj + writer *os.File summary Summary sortedControlNames []string printerType string } -func NewPrinter(opaSessionObj *chan *cautils.OPASessionObj, printerType string) *Printer { +func NewPrinter(opaSessionObj *chan *cautils.OPASessionObj, printerType, outputFile string) *Printer { return &Printer{ opaSessionObj: opaSessionObj, summary: NewSummary(), printerType: printerType, + writer: getWriter(outputFile), } } @@ -54,7 +56,7 @@ func (printer *Printer) ActionPrint() { fmt.Println("Failed to convert posture report object!") os.Exit(1) } - os.Stdout.Write(postureReportStr) + printer.writer.Write(postureReportStr) } else if printer.printerType == JunitResultPrinter { junitResult, err := convertPostureReportToJunitResult(opaSessionObj.PostureReport) if err != nil { @@ -66,7 +68,7 @@ func (printer *Printer) ActionPrint() { fmt.Println("Failed to convert posture report object!") os.Exit(1) } - os.Stdout.Write(postureReportStr) + printer.writer.Write(postureReportStr) } else if !cautils.IsSilent() { fmt.Println("unknown output printer") os.Exit(1) @@ -113,29 +115,29 @@ func (printer *Printer) PrintResults() { } } -func (print *Printer) printSummary(controlName string, controlSummary *ControlSummary) { - cautils.SimpleDisplay(os.Stdout, "Summary - ") - cautils.SuccessDisplay(os.Stdout, "Passed:%v ", controlSummary.TotalResources-controlSummary.TotalFailed) - cautils.FailureDisplay(os.Stdout, "Failed:%v ", controlSummary.TotalFailed) - cautils.InfoDisplay(os.Stdout, "Total:%v\n", controlSummary.TotalResources) +func (printer *Printer) printSummary(controlName string, controlSummary *ControlSummary) { + cautils.SimpleDisplay(printer.writer, "Summary - ") + cautils.SuccessDisplay(printer.writer, "Passed:%v ", controlSummary.TotalResources-controlSummary.TotalFailed) + cautils.FailureDisplay(printer.writer, "Failed:%v ", controlSummary.TotalFailed) + cautils.InfoDisplay(printer.writer, "Total:%v\n", controlSummary.TotalResources) if controlSummary.TotalFailed > 0 { - cautils.DescriptionDisplay(os.Stdout, "Remediation: %v\n", controlSummary.Remediation) + cautils.DescriptionDisplay(printer.writer, "Remediation: %v\n", controlSummary.Remediation) } - cautils.DescriptionDisplay(os.Stdout, "\n") + cautils.DescriptionDisplay(printer.writer, "\n") } func (printer *Printer) printTitle(controlName string, controlSummary *ControlSummary) { - cautils.InfoDisplay(os.Stdout, "[control: %s] ", controlName) + cautils.InfoDisplay(printer.writer, "[control: %s] ", controlName) if controlSummary.TotalResources == 0 { - cautils.InfoDisplay(os.Stdout, "resources not found %v\n", emoji.ConfusedFace) + cautils.InfoDisplay(printer.writer, "resources not found %v\n", emoji.ConfusedFace) } else if controlSummary.TotalFailed == 0 { - cautils.SuccessDisplay(os.Stdout, "passed %v\n", emoji.ThumbsUp) + cautils.SuccessDisplay(printer.writer, "passed %v\n", emoji.ThumbsUp) } else { - cautils.FailureDisplay(os.Stdout, "failed %v\n", emoji.SadButRelievedFace) + cautils.FailureDisplay(printer.writer, "failed %v\n", emoji.SadButRelievedFace) } - cautils.DescriptionDisplay(os.Stdout, "Description: %s\n", controlSummary.Description) + cautils.DescriptionDisplay(printer.writer, "Description: %s\n", controlSummary.Description) } func (printer *Printer) printResult(controlName string, controlSummary *ControlSummary) { @@ -144,12 +146,12 @@ func (printer *Printer) printResult(controlName string, controlSummary *ControlS for ns, rsc := range controlSummary.WorkloadSummary { preIndent := indent if ns != "" { - cautils.SimpleDisplay(os.Stdout, "%sNamespace %s\n", indent, ns) + cautils.SimpleDisplay(printer.writer, "%sNamespace %s\n", indent, ns) } preIndent2 := indent for r := range rsc { indent += indent - cautils.SimpleDisplay(os.Stdout, fmt.Sprintf("%s%s - %s\n", indent, rsc[r].Kind, rsc[r].Name)) + cautils.SimpleDisplay(printer.writer, fmt.Sprintf("%s%s - %s\n", indent, rsc[r].Kind, rsc[r].Name)) indent = preIndent2 } indent = preIndent @@ -195,7 +197,7 @@ func generateFooter(numControlers, sumFailed, sumTotal int) []string { return row } func (printer *Printer) PrintSummaryTable() { - summaryTable := tablewriter.NewWriter(os.Stdout) + summaryTable := tablewriter.NewWriter(printer.writer) summaryTable.SetAutoWrapText(false) summaryTable.SetHeader(generateHeader()) summaryTable.SetHeaderLine(true) @@ -221,3 +223,17 @@ func (printer *Printer) getSortedControlsNames() []string { sort.Strings(controlNames) return controlNames } + +func getWriter(outputFile string) *os.File { + + if outputFile != "" { + f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + fmt.Println("Error opening file") + return os.Stdout + } + return f + } + return os.Stdout + +} From 59c935e72347c304fd49d312b40d6f52828fedb2 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 09:00:52 +0300 Subject: [PATCH 09/25] update output f --- cautils/opapolicy/datastructures.go | 2 +- cmd/framework.go | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index ef5183e7..1c897716 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -160,7 +160,7 @@ type ScanInfo struct { } func (scanInfo *ScanInfo) Init() { - scanInfo.setSilentMode() + // scanInfo.setSilentMode() scanInfo.setOutputFile() } diff --git a/cmd/framework.go b/cmd/framework.go index 94f61c7f..878c40ad 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -1,7 +1,6 @@ package cmd import ( - "errors" "flag" "fmt" "io" @@ -20,7 +19,7 @@ import ( ) var scanInfo opapolicy.ScanInfo -var supportedFrameworks = []string{"nsa", "mitre"} +var supportedFrameworks = []string{"nsa"} type CLIHandler struct { policyHandler *policyhandler.PolicyHandler @@ -34,10 +33,10 @@ var frameworkCmd = &cobra.Command{ ValidArgs: supportedFrameworks, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return errors.New("requires at least one argument") + return fmt.Errorf("requires at least one argument") } if !isValidFramework(args[0]) { - return errors.New(fmt.Sprintf("supported frameworks: %s", strings.Join(supportedFrameworks, ", "))) + return fmt.Errorf(fmt.Sprintf("supported frameworks: %s", strings.Join(supportedFrameworks, ", "))) } return nil }, @@ -76,7 +75,7 @@ func init() { scanCmd.AddCommand(frameworkCmd) scanInfo = opapolicy.ScanInfo{} frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "namespaces to exclude from check") - frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", "output format. supported formats: 'pretty-printer'/'json'/'junit'") + frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", "output format. supported formats: `pretty-printer`/`json`/`junit`") frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "output file. print output to file and not stdout") frameworkCmd.Flags().BoolVarP(&scanInfo.Silent, "silent", "s", false, "silent progress output") } From f46ee93539fe520d7391e6390b3fd24512805fe4 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 11:39:27 +0300 Subject: [PATCH 10/25] update modul name --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index df427248..d29ac31a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module kubescape +module github.com/armosec/kubescape go 1.16 From 2779cb4e2582a2346c0a623fba583ad1f983fcb0 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 11:47:44 +0300 Subject: [PATCH 11/25] update module --- cautils/datastructures.go | 2 +- cautils/k8sinterface/k8sconfig_test.go | 2 +- cautils/k8sinterface/k8sdynamic.go | 2 +- cautils/k8sinterface/k8sstatic.go | 2 +- cautils/k8sinterface/workload.go | 2 +- cautils/k8sinterface/workloadmethods.go | 4 ++-- cautils/opapolicy/datastructures.go | 2 +- cautils/opapolicy/datastructures_mock.go | 2 +- cautils/opapolicy/resources/resourcesutils.go | 2 +- cmd/framework.go | 15 ++++++++------- main.go | 2 +- opaprocessor/processorhandler.go | 9 +++++---- opaprocessor/processorhandler_test.go | 9 +++++---- opaprocessor/processorhandlerutils.go | 10 +++++----- policyhandler/filesloader.go | 7 ++++--- policyhandler/filesloader_test.go | 5 +++-- policyhandler/handlenotification.go | 7 ++++--- policyhandler/handlepullpolicies.go | 2 +- policyhandler/k8sresources.go | 9 +++++---- policyhandler/k8sresourcesutils.go | 6 +++--- policyhandler/k8sresourcesutils_test.go | 4 ++-- policyhandler/urlloader.go | 5 +++-- printer/junit.go | 3 ++- printer/printresults.go | 7 ++++--- printer/summeryhelpers.go | 4 ++-- 25 files changed, 67 insertions(+), 57 deletions(-) diff --git a/cautils/datastructures.go b/cautils/datastructures.go index 53d7b2aa..8356e711 100644 --- a/cautils/datastructures.go +++ b/cautils/datastructures.go @@ -1,7 +1,7 @@ package cautils import ( - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/opapolicy" ) // K8SResources map[//] diff --git a/cautils/k8sinterface/k8sconfig_test.go b/cautils/k8sinterface/k8sconfig_test.go index be057d4f..ab4be81e 100644 --- a/cautils/k8sinterface/k8sconfig_test.go +++ b/cautils/k8sinterface/k8sconfig_test.go @@ -3,7 +3,7 @@ package k8sinterface import ( "testing" - "kubescape/cautils/cautils" + "github.com/armosec/kubescape/cautils/cautils" ) func TestGetGroupVersionResource(t *testing.T) { diff --git a/cautils/k8sinterface/k8sdynamic.go b/cautils/k8sinterface/k8sdynamic.go index ae59f0f5..f1cd93f5 100644 --- a/cautils/k8sinterface/k8sdynamic.go +++ b/cautils/k8sinterface/k8sdynamic.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "kubescape/cautils/cautils" + "github.com/armosec/kubescape/cautils/cautils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" diff --git a/cautils/k8sinterface/k8sstatic.go b/cautils/k8sinterface/k8sstatic.go index f7cedc2c..5317e66c 100644 --- a/cautils/k8sinterface/k8sstatic.go +++ b/cautils/k8sinterface/k8sstatic.go @@ -3,7 +3,7 @@ package k8sinterface import ( "context" - "kubescape/cautils/cautils" + "github.com/armosec/kubescape/cautils/cautils" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/cautils/k8sinterface/workload.go b/cautils/k8sinterface/workload.go index bb347012..c0264984 100644 --- a/cautils/k8sinterface/workload.go +++ b/cautils/k8sinterface/workload.go @@ -3,7 +3,7 @@ package k8sinterface import ( "encoding/json" - "kubescape/cautils/apis" + "github.com/armosec/kubescape/cautils/apis" corev1 "k8s.io/api/core/v1" diff --git a/cautils/k8sinterface/workloadmethods.go b/cautils/k8sinterface/workloadmethods.go index 8ae380ea..a3f2b403 100644 --- a/cautils/k8sinterface/workloadmethods.go +++ b/cautils/k8sinterface/workloadmethods.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "kubescape/cautils/apis" - "kubescape/cautils/cautils" + "github.com/armosec/kubescape/cautils/apis" + "github.com/armosec/kubescape/cautils/cautils" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index e3115cb8..fcc405ff 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -4,7 +4,7 @@ import ( "path/filepath" "time" - armotypes "kubescape/cautils/armotypes" + armotypes "github.com/armosec/kubescape/cautils/armotypes" ) type AlertScore float32 diff --git a/cautils/opapolicy/datastructures_mock.go b/cautils/opapolicy/datastructures_mock.go index 4e2a4036..afe9ae63 100644 --- a/cautils/opapolicy/datastructures_mock.go +++ b/cautils/opapolicy/datastructures_mock.go @@ -3,7 +3,7 @@ package opapolicy import ( "time" - armotypes "kubescape/cautils/armotypes" + armotypes "github.com/armosec/kubescape/cautils/armotypes" ) // Mock A diff --git a/cautils/opapolicy/resources/resourcesutils.go b/cautils/opapolicy/resources/resourcesutils.go index ea89aa19..bcd9f572 100644 --- a/cautils/opapolicy/resources/resourcesutils.go +++ b/cautils/opapolicy/resources/resourcesutils.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/golang/glog" "github.com/open-policy-agent/opa/storage" diff --git a/cmd/framework.go b/cmd/framework.go index 51272b29..7b31a0dd 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -5,16 +5,17 @@ import ( "fmt" "io" "io/ioutil" - "kubescape/cautils" - "kubescape/cautils/armotypes" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" - "kubescape/opaprocessor" - "kubescape/policyhandler" - "kubescape/printer" "os" "strings" + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/opaprocessor" + "github.com/armosec/kubescape/policyhandler" + "github.com/armosec/kubescape/printer" + "github.com/spf13/cobra" ) diff --git a/main.go b/main.go index 47f8524d..978bbec4 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "kubescape/cmd" +import "github.com/armosec/kubescape/cmd" func main() { cmd.Execute() diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 53084369..0aff7cc3 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -3,13 +3,14 @@ package opaprocessor import ( "context" "fmt" - "kubescape/cautils" "time" - "kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils" - "kubescape/cautils/opapolicy" - "kubescape/cautils/opapolicy/resources" + "github.com/armosec/kubescape/cautils/k8sinterface" + + "github.com/armosec/kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/opapolicy/resources" "github.com/golang/glog" "github.com/open-policy-agent/opa/ast" diff --git a/opaprocessor/processorhandler_test.go b/opaprocessor/processorhandler_test.go index eae72844..d3532980 100644 --- a/opaprocessor/processorhandler_test.go +++ b/opaprocessor/processorhandler_test.go @@ -3,18 +3,19 @@ package opaprocessor import ( "context" "encoding/json" - "kubescape/cautils" "os" "path" "strings" "testing" - "kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils" + + "github.com/armosec/kubescape/cautils/k8sinterface" // _ "k8s.io/client-go/plugin/pkg/client/auth" restclient "k8s.io/client-go/rest" - "kubescape/cautils/opapolicy" - "kubescape/cautils/opapolicy/resources" + "github.com/armosec/kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/opapolicy/resources" "github.com/open-policy-agent/opa/ast" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/opaprocessor/processorhandlerutils.go b/opaprocessor/processorhandlerutils.go index 8ed58d6c..0991e84e 100644 --- a/opaprocessor/processorhandlerutils.go +++ b/opaprocessor/processorhandlerutils.go @@ -1,12 +1,12 @@ package opaprocessor import ( - "kubescape/cautils" + "github.com/armosec/kubescape/cautils" - pkgcautils "kubescape/cautils/cautils" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" - resources "kubescape/cautils/opapolicy/resources" + pkgcautils "github.com/armosec/kubescape/cautils/cautils" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" + resources "github.com/armosec/kubescape/cautils/opapolicy/resources" "github.com/golang/glog" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/policyhandler/filesloader.go b/policyhandler/filesloader.go index 57969138..88753bc5 100644 --- a/policyhandler/filesloader.go +++ b/policyhandler/filesloader.go @@ -5,13 +5,14 @@ import ( "encoding/json" "fmt" "io/ioutil" - "kubescape/cautils" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" "os" "path/filepath" "strings" + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" + "gopkg.in/yaml.v2" ) diff --git a/policyhandler/filesloader_test.go b/policyhandler/filesloader_test.go index 40107267..e0a943c5 100644 --- a/policyhandler/filesloader_test.go +++ b/policyhandler/filesloader_test.go @@ -2,11 +2,12 @@ package policyhandler import ( "fmt" - "kubescape/cautils" "os" "path/filepath" "strings" "testing" + + "github.com/armosec/kubescape/cautils" ) func combine(base, rel string) string { @@ -24,7 +25,7 @@ func combine(base, rel string) string { } func onlineBoutiquePath() string { o, _ := os.Getwd() - return combine(o, "kubescape/examples/online-boutique/*") + return combine(o, "github.com/armosec/kubescape/examples/online-boutique/*") } func TestListFiles(t *testing.T) { files, errs := listFiles([]string{onlineBoutiquePath()}) diff --git a/policyhandler/handlenotification.go b/policyhandler/handlenotification.go index 754cbdbf..ae148662 100644 --- a/policyhandler/handlenotification.go +++ b/policyhandler/handlenotification.go @@ -2,11 +2,12 @@ package policyhandler import ( "fmt" - "kubescape/cautils" - "kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/k8sinterface" + + "github.com/armosec/kubescape/cautils/opapolicy" ) // PolicyHandler - diff --git a/policyhandler/handlepullpolicies.go b/policyhandler/handlepullpolicies.go index 822e4d30..d219f42d 100644 --- a/policyhandler/handlepullpolicies.go +++ b/policyhandler/handlepullpolicies.go @@ -8,7 +8,7 @@ import ( "net/url" "strings" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/opapolicy" ) // URLEncoder encode url diff --git a/policyhandler/k8sresources.go b/policyhandler/k8sresources.go index cd94a654..082790de 100644 --- a/policyhandler/k8sresources.go +++ b/policyhandler/k8sresources.go @@ -2,13 +2,14 @@ package policyhandler import ( "fmt" - "kubescape/cautils" "strings" - "kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils" - "kubescape/cautils/armotypes" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/k8sinterface" + + "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/opapolicy" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/policyhandler/k8sresourcesutils.go b/policyhandler/k8sresourcesutils.go index 8e6cc23f..32e15bb0 100644 --- a/policyhandler/k8sresourcesutils.go +++ b/policyhandler/k8sresourcesutils.go @@ -1,10 +1,10 @@ package policyhandler import ( - "kubescape/cautils" + "github.com/armosec/kubescape/cautils" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" ) func setResourceMap(frameworks []opapolicy.Framework) *cautils.K8SResources { diff --git a/policyhandler/k8sresourcesutils_test.go b/policyhandler/k8sresourcesutils_test.go index 7518aa74..2441e519 100644 --- a/policyhandler/k8sresourcesutils_test.go +++ b/policyhandler/k8sresourcesutils_test.go @@ -1,8 +1,8 @@ package policyhandler import ( - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" "testing" ) diff --git a/policyhandler/urlloader.go b/policyhandler/urlloader.go index 9d2e14bf..c87c1252 100644 --- a/policyhandler/urlloader.go +++ b/policyhandler/urlloader.go @@ -4,10 +4,11 @@ import ( "bytes" "fmt" "io" - "kubescape/cautils" - "kubescape/cautils/k8sinterface" "net/http" "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/k8sinterface" ) func loadResourcesFromUrl(inputPatterns []string) ([]k8sinterface.IWorkload, error) { diff --git a/printer/junit.go b/printer/junit.go index 7d2b2866..7917abd5 100644 --- a/printer/junit.go +++ b/printer/junit.go @@ -3,7 +3,8 @@ package printer import ( "encoding/xml" "fmt" - "kubescape/cautils/opapolicy" + + "github.com/armosec/kubescape/cautils/opapolicy" ) type JUnitTestSuites struct { diff --git a/printer/printresults.go b/printer/printresults.go index b2667ded..31996223 100644 --- a/printer/printresults.go +++ b/printer/printresults.go @@ -4,12 +4,13 @@ import ( "encoding/json" "encoding/xml" "fmt" - "kubescape/cautils" "os" "sort" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils" + + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" "github.com/enescakir/emoji" "github.com/olekukonko/tablewriter" diff --git a/printer/summeryhelpers.go b/printer/summeryhelpers.go index b61ddb67..4575b629 100644 --- a/printer/summeryhelpers.go +++ b/printer/summeryhelpers.go @@ -3,8 +3,8 @@ package printer import ( "fmt" - "kubescape/cautils/k8sinterface" - "kubescape/cautils/opapolicy" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/armosec/kubescape/cautils/opapolicy" ) // Group workloads by namespace - return {"namespace": <[]WorkloadSummary>} From c6241fab38121e1785f0ae4ada50aba6b57b7c1e Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 16:42:12 +0300 Subject: [PATCH 12/25] remove sudo --- install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index dfc0c4c0..be06326e 100755 --- a/install.sh +++ b/install.sh @@ -29,9 +29,9 @@ OUTPUT=$BASE_DIR/$KUBESCAPE_EXEC curl --progress-bar -L $DOWNLOAD_URL -o $OUTPUT echo -e "\033[32m[V] Downloaded Kubescape" -sudo chmod +x $OUTPUT -sudo rm -f /usr/local/bin/$KUBESCAPE_EXEC -sudo cp $OUTPUT /usr/local/bin +chmod +x $OUTPUT | sudo chmod +x $OUTPUT +rm -f /usr/local/bin/$KUBESCAPE_EXEC | sudo rm -f /usr/local/bin/$KUBESCAPE_EXEC +cp $OUTPUT /usr/local/bin | sudo cp $OUTPUT /usr/local/bin rm -rf $BASE_DIR echo -e "[V] Finished Installation" From 4a9b36807a93b64e2811b1b482325c4dba3f1bc8 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 16:43:37 +0300 Subject: [PATCH 13/25] remove sudo --- install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index be06326e..974050c2 100755 --- a/install.sh +++ b/install.sh @@ -29,9 +29,9 @@ OUTPUT=$BASE_DIR/$KUBESCAPE_EXEC curl --progress-bar -L $DOWNLOAD_URL -o $OUTPUT echo -e "\033[32m[V] Downloaded Kubescape" -chmod +x $OUTPUT | sudo chmod +x $OUTPUT -rm -f /usr/local/bin/$KUBESCAPE_EXEC | sudo rm -f /usr/local/bin/$KUBESCAPE_EXEC -cp $OUTPUT /usr/local/bin | sudo cp $OUTPUT /usr/local/bin +chmod +x $OUTPUT || sudo chmod +x $OUTPUT +rm -f /usr/local/bin/$KUBESCAPE_EXEC || sudo rm -f /usr/local/bin/$KUBESCAPE_EXEC +cp $OUTPUT /usr/local/bin || sudo cp $OUTPUT /usr/local/bin rm -rf $BASE_DIR echo -e "[V] Finished Installation" From 67c2de74f1199bfe3479caa5208802c21531640f Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 17:05:16 +0300 Subject: [PATCH 14/25] adding download script --- download.sh | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100755 download.sh diff --git a/download.sh b/download.sh new file mode 100755 index 00000000..bdf35656 --- /dev/null +++ b/download.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +echo "Downloading Kubescape..." +echo + +BASE_DIR=~/.kubescape +KUBESCAPE_EXEC=kubescape + +osName=$(uname -s) +if [[ $osName == *"MINGW"* ]]; then + osName=windows-latest +elif [[ $osName == *"Darwin"* ]]; then + osName=macos-latest +else + osName=ubuntu-latest +fi + +GITHUB_OWNER=armosec + +DOWNLOAD_URL=$(curl --silent "https://api.github.com/repos/$GITHUB_OWNER/kubescape/releases/latest" | grep -o "browser_download_url.*${osName}.*") +DOWNLOAD_URL=${DOWNLOAD_URL//\"} +DOWNLOAD_URL=${DOWNLOAD_URL/browser_download_url: /} + +mkdir -p $BASE_DIR + +OUTPUT=$BASE_DIR/$KUBESCAPE_EXEC + +curl --progress-bar -L $DOWNLOAD_URL -o $OUTPUT +echo -e "\033[32m[V] Downloaded Kubescape" + +chmod +x $OUTPUT || sudo chmod +x $OUTPUT From 222b1545059c4d67da776f46c76c88e98bdab0f0 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 31 Aug 2021 17:08:02 +0300 Subject: [PATCH 15/25] store file localy --- download.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/download.sh b/download.sh index bdf35656..b03168b8 100755 --- a/download.sh +++ b/download.sh @@ -3,9 +3,6 @@ set -e echo "Downloading Kubescape..." echo - -BASE_DIR=~/.kubescape -KUBESCAPE_EXEC=kubescape osName=$(uname -s) if [[ $osName == *"MINGW"* ]]; then @@ -22,11 +19,9 @@ DOWNLOAD_URL=$(curl --silent "https://api.github.com/repos/$GITHUB_OWNER/kubesca DOWNLOAD_URL=${DOWNLOAD_URL//\"} DOWNLOAD_URL=${DOWNLOAD_URL/browser_download_url: /} -mkdir -p $BASE_DIR +KUBESCAPE_EXEC=kubescape -OUTPUT=$BASE_DIR/$KUBESCAPE_EXEC - -curl --progress-bar -L $DOWNLOAD_URL -o $OUTPUT +curl --progress-bar -L $DOWNLOAD_URL -o $KUBESCAPE_EXEC echo -e "\033[32m[V] Downloaded Kubescape" -chmod +x $OUTPUT || sudo chmod +x $OUTPUT +chmod +x $KUBESCAPE_EXEC || sudo chmod +x $KUBESCAPE_EXEC From 2ae2c81e0bf5c050a9e4a32d795a47e202cf2ed7 Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 2 Sep 2021 13:18:23 +0300 Subject: [PATCH 16/25] rm download --- download.sh | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100755 download.sh diff --git a/download.sh b/download.sh deleted file mode 100755 index b03168b8..00000000 --- a/download.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -e - -echo "Downloading Kubescape..." -echo - -osName=$(uname -s) -if [[ $osName == *"MINGW"* ]]; then - osName=windows-latest -elif [[ $osName == *"Darwin"* ]]; then - osName=macos-latest -else - osName=ubuntu-latest -fi - -GITHUB_OWNER=armosec - -DOWNLOAD_URL=$(curl --silent "https://api.github.com/repos/$GITHUB_OWNER/kubescape/releases/latest" | grep -o "browser_download_url.*${osName}.*") -DOWNLOAD_URL=${DOWNLOAD_URL//\"} -DOWNLOAD_URL=${DOWNLOAD_URL/browser_download_url: /} - -KUBESCAPE_EXEC=kubescape - -curl --progress-bar -L $DOWNLOAD_URL -o $KUBESCAPE_EXEC -echo -e "\033[32m[V] Downloaded Kubescape" - -chmod +x $KUBESCAPE_EXEC || sudo chmod +x $KUBESCAPE_EXEC From 2e313719bbfae6ac38a8d6fcc0ce7dc1d18e5d31 Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 2 Sep 2021 14:54:04 +0300 Subject: [PATCH 17/25] adding scaore and excpetion to code --- cautils/armotypes/portaltypes.go | 3 + cautils/armotypes/portaltypesutils.go | 87 +++++++++++++++++-- .../armotypes/postureexceptionpolicytypes.go | 42 +++++++++ .../postureexceptionpolicytypesutils.go | 1 + cautils/opapolicy/datastructures.go | 38 ++++---- cautils/opapolicy/datastructuresmethods.go | 53 +++++++++-- 6 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 cautils/armotypes/postureexceptionpolicytypes.go create mode 100644 cautils/armotypes/postureexceptionpolicytypesutils.go diff --git a/cautils/armotypes/portaltypes.go b/cautils/armotypes/portaltypes.go index ab611b6a..a258fd3d 100644 --- a/cautils/armotypes/portaltypes.go +++ b/cautils/armotypes/portaltypes.go @@ -22,6 +22,7 @@ type DesignatorType string // Supported designators const ( DesignatorAttributes DesignatorType = "Attributes" + DesignatorAttribute DesignatorType = "Attribute" // Deprecated /* WorkloadID format. k8s format: wlid://cluster-/namespace-/- @@ -45,6 +46,8 @@ const ( const ( AttributeCluster = "cluster" AttributeNamespace = "namespace" + AttributeKind = "kind" + AttributeName = "name" ) // PortalDesignator represented single designation options diff --git a/cautils/armotypes/portaltypesutils.go b/cautils/armotypes/portaltypesutils.go index 7e517beb..412c962c 100644 --- a/cautils/armotypes/portaltypesutils.go +++ b/cautils/armotypes/portaltypesutils.go @@ -1,24 +1,100 @@ package armotypes +import ( + "github.com/armosec/kubescape/cautils/cautils" + "github.com/golang/glog" +) + var IgnoreLabels = []string{AttributeCluster, AttributeNamespace} +func (designator *PortalDesignator) GetCluster() string { + cluster, _, _, _, _ := designator.DigestPortalDesignator() + return cluster +} + +func (designator *PortalDesignator) GetNamespace() string { + _, namespace, _, _, _ := designator.DigestPortalDesignator() + return namespace +} + +func (designator *PortalDesignator) GetKind() string { + _, _, kind, _, _ := designator.DigestPortalDesignator() + return kind +} + +func (designator *PortalDesignator) GetName() string { + _, _, _, name, _ := designator.DigestPortalDesignator() + return name +} +func (designator *PortalDesignator) GetLabels() map[string]string { + _, _, _, _, labels := designator.DigestPortalDesignator() + return labels +} + // DigestPortalDesignator - get cluster namespace and labels from designator +func (designator *PortalDesignator) DigestPortalDesignator() (string, string, string, string, map[string]string) { + switch designator.DesignatorType { + case DesignatorAttributes, DesignatorAttribute: + return designator.DigestAttributesDesignator() + case DesignatorWlid, DesignatorWildWlid: + return cautils.GetClusterFromWlid(designator.WLID), cautils.GetNamespaceFromWlid(designator.WLID), cautils.GetKindFromWlid(designator.WLID), cautils.GetNameFromWlid(designator.WLID), map[string]string{} + // case DesignatorSid: // TODO + default: + glog.Warningf("in 'digestPortalDesignator' designator type: '%v' not yet supported. please contact Armo team", designator.DesignatorType) + } + return "", "", "", "", nil +} + +func (designator *PortalDesignator) DigestAttributesDesignator() (string, string, string, string, map[string]string) { + cluster := "" + namespace := "" + kind := "" + name := "" + labels := map[string]string{} + attributes := designator.Attributes + if attributes == nil { + return cluster, namespace, kind, name, labels + } + for k, v := range attributes { + labels[k] = v + } + if v, ok := attributes[AttributeNamespace]; ok { + namespace = v + delete(labels, AttributeNamespace) + } + if v, ok := attributes[AttributeCluster]; ok { + cluster = v + delete(labels, AttributeCluster) + } + if v, ok := attributes[AttributeKind]; ok { + kind = v + delete(labels, AttributeKind) + } + if v, ok := attributes[AttributeName]; ok { + name = v + delete(labels, AttributeName) + } + return cluster, namespace, kind, name, labels +} + +// DigestPortalDesignator DEPRECATED. use designator.DigestPortalDesignator() - get cluster namespace and labels from designator func DigestPortalDesignator(designator *PortalDesignator) (string, string, map[string]string) { switch designator.DesignatorType { - case DesignatorAttributes: + case DesignatorAttributes, DesignatorAttribute: return DigestAttributesDesignator(designator.Attributes) - // case DesignatorWlid: TODO - // case DesignatorWildWlid: TODO + case DesignatorWlid, DesignatorWildWlid: + return cautils.GetClusterFromWlid(designator.WLID), cautils.GetNamespaceFromWlid(designator.WLID), map[string]string{} + // case DesignatorSid: // TODO default: + glog.Warningf("in 'digestPortalDesignator' designator type: '%v' not yet supported. please contact Armo team", designator.DesignatorType) } return "", "", nil } - func DigestAttributesDesignator(attributes map[string]string) (string, string, map[string]string) { cluster := "" namespace := "" labels := map[string]string{} - if attributes == nil || len(attributes) == 0 { + if attributes == nil { return cluster, namespace, labels } for k, v := range attributes { @@ -32,5 +108,6 @@ func DigestAttributesDesignator(attributes map[string]string) (string, string, m cluster = v delete(labels, AttributeCluster) } + return cluster, namespace, labels } diff --git a/cautils/armotypes/postureexceptionpolicytypes.go b/cautils/armotypes/postureexceptionpolicytypes.go new file mode 100644 index 00000000..81603b97 --- /dev/null +++ b/cautils/armotypes/postureexceptionpolicytypes.go @@ -0,0 +1,42 @@ +package armotypes + +type PostureExceptionPolicyActions string + +const AlertOnly PostureExceptionPolicyActions = "alertOnly" +const Disable PostureExceptionPolicyActions = "disable" + +type PostureExceptionPolicy struct { + PortalBase `json:",inline"` + PolicyType string `json:"policyType"` + CreationTime string `json:"creationTime"` + Actions []PostureExceptionPolicyActions `json:"actions"` + Resources []PortalDesignator `json:"resources"` + PosturePolicies []PosturePolicy `json:"posturePolicies"` +} + +type PosturePolicy struct { + FrameworkName string `json:"frameworkName"` + ControlName string `json:"controlName"` + RuleName string `json:"ruleName"` +} + +func (exceptionPolicy *PostureExceptionPolicy) IsAlertOnly() bool { + if exceptionPolicy.IsDisable() { + return false + } + + for i := range exceptionPolicy.Actions { + if exceptionPolicy.Actions[i] == AlertOnly { + return true + } + } + return false +} +func (exceptionPolicy *PostureExceptionPolicy) IsDisable() bool { + for i := range exceptionPolicy.Actions { + if exceptionPolicy.Actions[i] == Disable { + return true + } + } + return false +} diff --git a/cautils/armotypes/postureexceptionpolicytypesutils.go b/cautils/armotypes/postureexceptionpolicytypesutils.go new file mode 100644 index 00000000..c373357e --- /dev/null +++ b/cautils/armotypes/postureexceptionpolicytypesutils.go @@ -0,0 +1 @@ +package armotypes diff --git a/cautils/opapolicy/datastructures.go b/cautils/opapolicy/datastructures.go index 6a512499..a74163c5 100644 --- a/cautils/opapolicy/datastructures.go +++ b/cautils/opapolicy/datastructures.go @@ -16,14 +16,15 @@ const ( // RegoResponse the expected response of single run of rego policy type RuleResponse struct { - AlertMessage string `json:"alertMessage"` - PackageName string `json:"packagename"` - AlertScore AlertScore `json:"alertScore"` - // AlertObject AlertObject `json:"alertObject"` - AlertObject AlertObject `json:"alertObject"` // TODO - replace interface to AlertObject - Context []string `json:"context"` // TODO - Remove - Rulename string `json:"rulename"` // TODO - Remove - ExceptionName string `json:"exceptionName"` + AlertMessage string `json:"alertMessage"` + RuleStatus string `json:"ruleStatus"` + PackageName string `json:"packagename"` + AlertScore AlertScore `json:"alertScore"` + AlertObject AlertObject `json:"alertObject"` + Context []string `json:"context,omitempty"` // TODO - Remove + Rulename string `json:"rulename,omitempty"` // TODO - Remove + ExceptionName string `json:"exceptionName,omitempty"` // Not in use + Exception *armotypes.PostureExceptionPolicy `json:"exception,omitempty"` } type AlertObject struct { @@ -32,19 +33,26 @@ type AlertObject struct { } type FrameworkReport struct { - Name string `json:"name"` - ControlReports []ControlReport `json:"controlReports"` + Name string `json:"name"` + ControlReports []ControlReport `json:"controlReports"` + Score float32 `json:"score,omitempty"` + ARMOImprovement float32 `json:"ARMOImprovement,omitempty"` + WCSScore float32 `json:"wcsScore,omitempty"` } type ControlReport struct { - Name string `json:"name"` - RuleReports []RuleReport `json:"ruleReports"` - Remediation string `json:"remediation"` - Description string `json:"description"` + armotypes.PortalBase `json:",inline"` + Name string `json:"name"` + RuleReports []RuleReport `json:"ruleReports"` + Remediation string `json:"remediation"` + Description string `json:"description"` + Score float32 `json:"score,omitempty"` + BaseScore float32 `json:"baseScore,omitempty"` + ARMOImprovement float32 `json:"ARMOImprovement,omitempty"` } type RuleReport struct { Name string `json:"name"` Remediation string `json:"remediation"` - RuleStatus RuleStatus `json:"ruleStatus"` + RuleStatus RuleStatus `json:"ruleStatus"` // did we run the rule or not (if there where compile errors, the value will be failed) RuleResponses []RuleResponse `json:"ruleResponses"` ListInputResources []map[string]interface{} `json:"-"` ListInputKinds []string `json:"-"` diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index e2bce425..602f77c7 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -17,6 +17,19 @@ func (pn *PolicyNotification) ToJSONBytesBuffer() (*bytes.Buffer, error) { return bytes.NewBuffer(res), err } +func (RuleResponse *RuleResponse) GetSingleResultStatus() string { + if RuleResponse.Exception != nil { + if RuleResponse.Exception.IsAlertOnly() { + return "warning" + } + if RuleResponse.Exception.IsDisable() { + return "ignore" + } + } + return "failed" + +} + func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleResponse) { if len(ruleReport.RuleResponses) == 0 { return "success", nil, nil @@ -26,9 +39,11 @@ func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleRes for _, rule := range ruleReport.RuleResponses { if rule.ExceptionName != "" { - failed = append(failed, rule) - } else { exceptions = append(exceptions, rule) + } else if rule.Exception != nil { + exceptions = append(exceptions, rule) + } else { + failed = append(failed, rule) } } @@ -70,10 +85,9 @@ func ParseRegoResult(regoResult *rego.ResultSet) ([]RuleResponse, error) { func (controlReport *ControlReport) GetNumberOfResources() int { sum := 0 for i := range controlReport.RuleReports { - if controlReport.RuleReports[i].ListInputResources == nil { - continue + if controlReport.RuleReports[i].ListInputResources != nil { + sum += len(controlReport.RuleReports[i].ListInputResources) } - sum += len(controlReport.RuleReports[i].ListInputResources) } return sum } @@ -85,15 +99,36 @@ func (controlReport *ControlReport) ListControlsInputKinds() []string { } return listControlsInputKinds } + func (controlReport *ControlReport) Passed() bool { for i := range controlReport.RuleReports { - if len(controlReport.RuleReports[i].RuleResponses) > 0 { - return false + if len(controlReport.RuleReports[i].RuleResponses) == 0 { + return true } } - return true + return false +} + +func (controlReport *ControlReport) Warning() bool { + if controlReport.Passed() || controlReport.Failed() { + return false + } + for i := range controlReport.RuleReports { + if status, _, _ := controlReport.RuleReports[i].GetRuleStatus(); status == "warning" { + return true + } + } + return false } func (controlReport *ControlReport) Failed() bool { - return !controlReport.Passed() + if controlReport.Passed() { + return false + } + for i := range controlReport.RuleReports { + if status, _, _ := controlReport.RuleReports[i].GetRuleStatus(); status == "failed" { + return true + } + } + return false } From b87b687e2f7166f0cffde6a1d931776a68ede8bf Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 2 Sep 2021 17:41:03 +0300 Subject: [PATCH 18/25] support exceptions --- cautils/armotypes/executionpolicytypes.go | 4 +- cautils/datastructures.go | 2 + cautils/getter/armoapi.go | 55 ++++++ cautils/getter/downloadreleasedpolicy.go | 87 +++++++++ cautils/getter/getpolicies.go | 154 +-------------- cautils/getter/loadpolicy.go | 46 +++++ cautils/opapolicy/datastructuresmethods.go | 32 ---- cautils/scaninfo.go | 19 +- cmd/framework.go | 7 +- opaprocessor/processorhandler.go | 208 ++++++++++++++------- opaprocessor/processorhandler_test.go | 183 ++---------------- opaprocessor/processorhandlerutils.go | 74 +++++++- policyhandler/handlenotification.go | 17 +- policyhandler/handlepullpolicies.go | 31 ++- 14 files changed, 485 insertions(+), 434 deletions(-) create mode 100644 cautils/getter/armoapi.go create mode 100644 cautils/getter/downloadreleasedpolicy.go create mode 100644 cautils/getter/loadpolicy.go diff --git a/cautils/armotypes/executionpolicytypes.go b/cautils/armotypes/executionpolicytypes.go index 3307de44..a4b08658 100644 --- a/cautils/armotypes/executionpolicytypes.go +++ b/cautils/armotypes/executionpolicytypes.go @@ -1,6 +1,6 @@ package armotypes -type EnforcmentsRule struct { +type EnforcementsRule struct { MonitoredObject []string `json:"monitoredObject"` MonitoredObjectExistence []string `json:"objectExistence"` MonitoredObjectEvent []string `json:"event"` @@ -12,5 +12,5 @@ type ExecutionPolicy struct { Designators []PortalDesignator `json:"designators"` PolicyType string `json:"policyType"` CreationTime string `json:"creation_time"` - ExecutionEnforcmentsRules []EnforcmentsRule `json:"enforcementRules"` + ExecutionEnforcementsRule []EnforcementsRule `json:"enforcementRules"` } diff --git a/cautils/datastructures.go b/cautils/datastructures.go index 8356e711..6aa70e1f 100644 --- a/cautils/datastructures.go +++ b/cautils/datastructures.go @@ -1,6 +1,7 @@ package cautils import ( + "github.com/armosec/kubescape/cautils/armotypes" "github.com/armosec/kubescape/cautils/opapolicy" ) @@ -10,6 +11,7 @@ type K8SResources map[string]interface{} type OPASessionObj struct { Frameworks []opapolicy.Framework K8SResources *K8SResources + Exceptions []armotypes.PostureExceptionPolicy PostureReport *opapolicy.PostureReport } diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go new file mode 100644 index 00000000..00132484 --- /dev/null +++ b/cautils/getter/armoapi.go @@ -0,0 +1,55 @@ +package getter + +import ( + "fmt" + "net/http" + "strings" + + "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/opapolicy" +) + +// ======================================================================================================================= +// =============================================== ArmoAPI =============================================================== +// ======================================================================================================================= + +// Armo API for downloading policies +type ArmoAPI struct { + httpClient *http.Client + hostURL string +} + +func NewArmoAPI() *ArmoAPI { + return &ArmoAPI{ + httpClient: &http.Client{}, + hostURL: "https://dashbe.eustage2.cyberarmorsoft.com", + } +} +func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) { + armoAPI.setURL(name) + respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.hostURL) + if err != nil { + return nil, err + } + + framework := &opapolicy.Framework{} + if err = JSONDecoder(respStr).Decode(framework); err != nil { + return nil, err + } + SaveFrameworkInFile(framework, GetDefaultPath(name)) + + return framework, err +} + +func (armoAPI *ArmoAPI) setURL(frameworkName string) { + requestURI := "v1/armoFrameworks" + requestURI += fmt.Sprintf("?customerGUID=%s", "11111111-1111-1111-1111-111111111111") + requestURI += fmt.Sprintf("&frameworkName=%s", strings.ToUpper(frameworkName)) + requestURI += "&getRules=true" + + armoAPI.hostURL = urlEncoder(fmt.Sprintf("%s/%s", armoAPI.hostURL, requestURI)) +} + +func (armoAPI *ArmoAPI) GetExceptions(scope, customerName, namespace string) ([]armotypes.PostureExceptionPolicy, error) { + return []armotypes.PostureExceptionPolicy{}, nil +} diff --git a/cautils/getter/downloadreleasedpolicy.go b/cautils/getter/downloadreleasedpolicy.go new file mode 100644 index 00000000..e4bb4cd2 --- /dev/null +++ b/cautils/getter/downloadreleasedpolicy.go @@ -0,0 +1,87 @@ +package getter + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/opapolicy" +) + +// ======================================================================================================================= +// ======================================== DownloadReleasedPolicy ======================================================= +// ======================================================================================================================= + +// Download released version +type DownloadReleasedPolicy struct { + hostURL string + httpClient *http.Client +} + +func NewDownloadReleasedPolicy() *DownloadReleasedPolicy { + return &DownloadReleasedPolicy{ + hostURL: "", + httpClient: &http.Client{}, + } +} + +func (drp *DownloadReleasedPolicy) GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { + return []armotypes.PostureExceptionPolicy{}, nil +} + +func (drp *DownloadReleasedPolicy) GetFramework(name string) (*opapolicy.Framework, error) { + drp.setURL(name) + respStr, err := HttpGetter(drp.httpClient, drp.hostURL) + if err != nil { + return nil, err + } + + framework := &opapolicy.Framework{} + if err = JSONDecoder(respStr).Decode(framework); err != nil { + return framework, err + } + + SaveFrameworkInFile(framework, GetDefaultPath(name)) + return framework, err +} + +func (drp *DownloadReleasedPolicy) setURL(frameworkName string) error { + + latestReleases := "https://api.github.com/repos/armosec/regolibrary/releases/latest" + resp, err := http.Get(latestReleases) + if err != nil { + return fmt.Errorf("failed to get latest releases from '%s', reason: %s", latestReleases, err.Error()) + } + defer resp.Body.Close() + if resp.StatusCode < 200 || 301 < resp.StatusCode { + return fmt.Errorf("failed to download file, status code: %s", resp.Status) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to read response body from '%s', reason: %s", latestReleases, err.Error()) + } + var data map[string]interface{} + err = json.Unmarshal(body, &data) + if err != nil { + return fmt.Errorf("failed to unmarshal response body from '%s', reason: %s", latestReleases, err.Error()) + } + + if assets, ok := data["assets"].([]interface{}); ok { + for i := range assets { + if asset, ok := assets[i].(map[string]interface{}); ok { + if name, ok := asset["name"].(string); ok { + if name == frameworkName { + if url, ok := asset["browser_download_url"].(string); ok { + drp.hostURL = url + } + } + } + } + } + } + return nil + +} diff --git a/cautils/getter/getpolicies.go b/cautils/getter/getpolicies.go index bbd03c95..b1617763 100644 --- a/cautils/getter/getpolicies.go +++ b/cautils/getter/getpolicies.go @@ -1,160 +1,12 @@ package getter import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" - + "github.com/armosec/kubescape/cautils/armotypes" "github.com/armosec/kubescape/cautils/opapolicy" ) -const DefaultLocalStore = ".kubescape" - type IPolicyGetter interface { GetFramework(name string) (*opapolicy.Framework, error) -} - -// ======================================================================================================================= -// ======================================== DownloadReleasedPolicy ======================================================= -// ======================================================================================================================= - -// Download released version -type DownloadReleasedPolicy struct { - hostURL string - httpClient *http.Client -} - -func NewDownloadReleasedPolicy() *DownloadReleasedPolicy { - return &DownloadReleasedPolicy{ - hostURL: "", - httpClient: &http.Client{}, - } -} - -func (drp *DownloadReleasedPolicy) GetFramework(name string) (*opapolicy.Framework, error) { - drp.setURL(name) - respStr, err := HttpGetter(drp.httpClient, drp.hostURL) - if err != nil { - return nil, err - } - - framework := &opapolicy.Framework{} - if err = JSONDecoder(respStr).Decode(framework); err != nil { - return framework, err - } - - SaveFrameworkInFile(framework, GetDefaultPath(name)) - return framework, err -} - -func (drp *DownloadReleasedPolicy) setURL(frameworkName string) error { - - latestReleases := "https://api.github.com/repos/armosec/regolibrary/releases/latest" - resp, err := http.Get(latestReleases) - if err != nil { - return fmt.Errorf("failed to get latest releases from '%s', reason: %s", latestReleases, err.Error()) - } - defer resp.Body.Close() - if resp.StatusCode < 200 || 301 < resp.StatusCode { - return fmt.Errorf("failed to download file, status code: %s", resp.Status) - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("failed to read response body from '%s', reason: %s", latestReleases, err.Error()) - } - var data map[string]interface{} - err = json.Unmarshal(body, &data) - if err != nil { - return fmt.Errorf("failed to unmarshal response body from '%s', reason: %s", latestReleases, err.Error()) - } - - if assets, ok := data["assets"].([]interface{}); ok { - for i := range assets { - if asset, ok := assets[i].(map[string]interface{}); ok { - if name, ok := asset["name"].(string); ok { - if name == frameworkName { - if url, ok := asset["browser_download_url"].(string); ok { - drp.hostURL = url - } - } - } - } - } - } - return nil - -} - -// ======================================================================================================================= -// ============================================== LoadPolicy ============================================================= -// ======================================================================================================================= - -// Load policies from a local repository -type LoadPolicy struct { - filePath string -} - -func NewLoadPolicy(filePath string) *LoadPolicy { - return &LoadPolicy{ - filePath: filePath, - } -} - -func (lp *LoadPolicy) GetFramework(frameworkName string) (*opapolicy.Framework, error) { - - framework := &opapolicy.Framework{} - f, err := ioutil.ReadFile(lp.filePath) - if err != nil { - return nil, err - } - - err = json.Unmarshal(f, framework) - if frameworkName != "" && !strings.EqualFold(frameworkName, framework.Name) { - return nil, fmt.Errorf("framework from file not matching") - } - return framework, err -} - -// ======================================================================================================================= -// =============================================== ArmoAPI =============================================================== -// ======================================================================================================================= - -// Armo API for downloading policies -type ArmoAPI struct { - httpClient *http.Client - hostURL string -} - -func NewArmoAPI() *ArmoAPI { - return &ArmoAPI{ - httpClient: &http.Client{}, - hostURL: "https://dashbe.eustage2.cyberarmorsoft.com", - } -} -func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) { - armoAPI.setURL(name) - respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.hostURL) - if err != nil { - return nil, err - } - - framework := &opapolicy.Framework{} - if err = JSONDecoder(respStr).Decode(framework); err != nil { - return nil, err - } - SaveFrameworkInFile(framework, GetDefaultPath(name)) - - return framework, err -} - -func (armoAPI *ArmoAPI) setURL(frameworkName string) { - requestURI := "v1/armoFrameworks" - requestURI += fmt.Sprintf("?customerGUID=%s", "11111111-1111-1111-1111-111111111111") - requestURI += fmt.Sprintf("&frameworkName=%s", strings.ToUpper(frameworkName)) - requestURI += "&getRules=true" - - armoAPI.hostURL = urlEncoder(fmt.Sprintf("%s/%s", armoAPI.hostURL, requestURI)) + GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) + // GetScores(scope, customerName, namespace string) ([]armotypes.PostureExceptionPolicy, error) } diff --git a/cautils/getter/loadpolicy.go b/cautils/getter/loadpolicy.go new file mode 100644 index 00000000..8f2a8fe3 --- /dev/null +++ b/cautils/getter/loadpolicy.go @@ -0,0 +1,46 @@ +package getter + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "strings" + + "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/opapolicy" +) + +// ======================================================================================================================= +// ============================================== LoadPolicy ============================================================= +// ======================================================================================================================= +const DefaultLocalStore = ".kubescape" + +// Load policies from a local repository +type LoadPolicy struct { + filePath string +} + +func NewLoadPolicy(filePath string) *LoadPolicy { + return &LoadPolicy{ + filePath: filePath, + } +} + +func (lp *LoadPolicy) GetFramework(frameworkName string) (*opapolicy.Framework, error) { + + framework := &opapolicy.Framework{} + f, err := ioutil.ReadFile(lp.filePath) + if err != nil { + return nil, err + } + + err = json.Unmarshal(f, framework) + if frameworkName != "" && !strings.EqualFold(frameworkName, framework.Name) { + return nil, fmt.Errorf("framework from file not matching") + } + return framework, err +} + +func (lp *LoadPolicy) GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { + return []armotypes.PostureExceptionPolicy{}, nil +} diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index 602f77c7..b0b89711 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -3,10 +3,6 @@ package opapolicy import ( "bytes" "encoding/json" - "fmt" - - "github.com/golang/glog" - "github.com/open-policy-agent/opa/rego" ) func (pn *PolicyNotification) ToJSONBytesBuffer() (*bytes.Buffer, error) { @@ -53,34 +49,6 @@ func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleRes } return status, failed, exceptions } -func ParseRegoResult(regoResult *rego.ResultSet) ([]RuleResponse, error) { - var errs error - ruleResponses := []RuleResponse{} - for _, result := range *regoResult { - for desicionIdx := range result.Expressions { - if resMap, ok := result.Expressions[desicionIdx].Value.(map[string]interface{}); ok { - for objName := range resMap { - jsonBytes, err := json.Marshal(resMap[objName]) - if err != nil { - err = fmt.Errorf("in parseRegoResult, json.Marshal failed. name: %s, obj: %v, reason: %s", objName, resMap[objName], err) - glog.Error(err) - errs = fmt.Errorf("%s\n%s", errs, err) - continue - } - desObj := make([]RuleResponse, 0) - if err := json.Unmarshal(jsonBytes, &desObj); err != nil { - err = fmt.Errorf("in parseRegoResult, json.Unmarshal failed. name: %s, obj: %v, reason: %s", objName, resMap[objName], err) - glog.Error(err) - errs = fmt.Errorf("%s\n%s", errs, err) - continue - } - ruleResponses = append(ruleResponses, desObj...) - } - } - } - } - return ruleResponses, errs -} func (controlReport *ControlReport) GetNumberOfResources() int { sum := 0 diff --git a/cautils/scaninfo.go b/cautils/scaninfo.go index 20546b26..57251e54 100644 --- a/cautils/scaninfo.go +++ b/cautils/scaninfo.go @@ -8,8 +8,9 @@ import ( ) type ScanInfo struct { - PolicyGetter getter.IPolicyGetter + Getters PolicyIdentifier opapolicy.PolicyIdentifier + UseExceptions string UseFrom string UseDefault bool Format string @@ -20,12 +21,28 @@ type ScanInfo struct { FailThreshold uint16 } +type Getters struct { + ExceptionsGetter getter.IPolicyGetter + PolicyGetter getter.IPolicyGetter +} + func (scanInfo *ScanInfo) Init() { // scanInfo.setSilentMode() scanInfo.setUseFrom() + scanInfo.setUseExceptions() scanInfo.setOutputFile() scanInfo.setGetter() +} + +func (scanInfo *ScanInfo) setUseExceptions() { + if scanInfo.UseExceptions != "" { + // load exceptions from file + scanInfo.ExceptionsGetter = getter.NewLoadPolicy(scanInfo.UseExceptions) + } else { + scanInfo.ExceptionsGetter = getter.NewArmoAPI() + } + } func (scanInfo *ScanInfo) setUseFrom() { if scanInfo.UseFrom != "" { diff --git a/cmd/framework.go b/cmd/framework.go index 6144c12c..6281ed08 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -83,8 +83,9 @@ func isValidFramework(framework string) bool { func init() { scanCmd.AddCommand(frameworkCmd) scanInfo = cautils.ScanInfo{} - frameworkCmd.Flags().StringVarP(&scanInfo.UseFrom, "use-from", "", "", "Path to load framework from") - frameworkCmd.Flags().BoolVarP(&scanInfo.UseDefault, "use-default", "", false, "Load framework from default path") + frameworkCmd.Flags().StringVar(&scanInfo.UseFrom, "use-from", "", "Path to load framework from") + frameworkCmd.Flags().BoolVar(&scanInfo.UseDefault, "use-default", false, "Load framework from default path") + frameworkCmd.Flags().StringVar(&scanInfo.UseExceptions, "exceptions", "", "Path to file containing list of exceptions") frameworkCmd.Flags().StringVarP(&scanInfo.ExcludedNamespaces, "exclude-namespaces", "e", "", "Namespaces to exclude from check") frameworkCmd.Flags().StringVarP(&scanInfo.Format, "format", "f", "pretty-printer", `Output format. supported formats: "pretty-printer"/"json"/"junit"`) frameworkCmd.Flags().StringVarP(&scanInfo.Output, "output", "o", "", "Output file. print output to file and not stdout") @@ -120,7 +121,7 @@ func CliSetup() error { // processor setup - rego run go func() { - reporterObj := opaprocessor.NewOPAProcessor(&processNotification, &reportResults) + reporterObj := opaprocessor.NewOPAProcessorHandler(&processNotification, &reportResults) reporterObj.ProcessRulesListenner() }() p := printer.NewPrinter(&reportResults, scanInfo.Format, scanInfo.Output) diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 8ee4a475..8c8ee884 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -6,6 +6,8 @@ import ( "time" "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/scapepkg/exceptions" + "github.com/armosec/kubescape/scapepkg/score" "github.com/armosec/kubescape/cautils/k8sinterface" @@ -18,93 +20,149 @@ import ( "github.com/open-policy-agent/opa/storage" ) -type OPAProcessor struct { - processedPolicy *chan *cautils.OPASessionObj - reportResults *chan *cautils.OPASessionObj - regoK8sCredentials storage.Store +const ScoreConfigPath = "/resources/config" + +var RegoK8sCredentials storage.Store + +type OPAProcessorHandler struct { + processedPolicy *chan *cautils.OPASessionObj + reportResults *chan *cautils.OPASessionObj + // componentConfig cautils.ComponentConfig } -func NewOPAProcessor(processedPolicy, reportResults *chan *cautils.OPASessionObj) *OPAProcessor { +type OPAProcessor struct { + *cautils.OPASessionObj +} + +func NewOPAProcessor(sessionObj *cautils.OPASessionObj) *OPAProcessor { + return &OPAProcessor{ + OPASessionObj: sessionObj, + } +} + +func NewOPAProcessorHandler(processedPolicy, reportResults *chan *cautils.OPASessionObj) *OPAProcessorHandler { regoDependenciesData := resources.NewRegoDependenciesData(k8sinterface.K8SConfig) store, err := regoDependenciesData.TOStorage() if err != nil { panic(err) } - return &OPAProcessor{ - processedPolicy: processedPolicy, - reportResults: reportResults, - regoK8sCredentials: store, + RegoK8sCredentials = store + + return &OPAProcessorHandler{ + processedPolicy: processedPolicy, + reportResults: reportResults, } } -func (opap *OPAProcessor) ProcessRulesListenner() { +func (opaHandler *OPAProcessorHandler) ProcessRulesListenner() { + // recover + defer func() { + if err := recover(); err != nil { + glog.Errorf("RECOVER in ProcessRulesListenner, reason: %v", err) + } + }() + for { - // recover - defer func() { - if err := recover(); err != nil { - glog.Errorf("RECOVER in ProcessRulesListenner, reason: %v", err) - } - }() - opaSessionObj := <-*opap.processedPolicy - go func() { - if err := opap.ProcessRulesHandler(opaSessionObj); err != nil { - // opaSessionObj.Reporter.SendError(nil, true, true) - } - *opap.reportResults <- opaSessionObj - }() + opaSessionObj := <-*opaHandler.processedPolicy + opap := NewOPAProcessor(opaSessionObj) + + // process + if err := opap.Process(); err != nil { + fmt.Println(err) + } + + // edit results + opap.updateResults() + + // update score + opap.updateScore() + + // report + *opaHandler.reportResults <- opaSessionObj } } -func (opap *OPAProcessor) ProcessRulesHandler(opaSessionObj *cautils.OPASessionObj) error { +func (opap *OPAProcessor) Process() error { + // glog.Infof(fmt.Sprintf("Starting 'Process'. reportID: %s", opap.PostureReport.ReportID)) cautils.ProgressTextDisplay(fmt.Sprintf("Scanning cluster %s", cautils.ClusterName)) cautils.StartSpinner() frameworkReports := []opapolicy.FrameworkReport{} var errs error - for _, framework := range opaSessionObj.Frameworks { - frameworkReport := opapolicy.FrameworkReport{} - frameworkReport.Name = framework.Name - controlReports := []opapolicy.ControlReport{} - for _, control := range framework.Controls { - // cautils.SimpleDisplay(os.Stdout, fmt.Sprintf("\033[2K\r%s", control.Name)) - controlReport := opapolicy.ControlReport{} - controlReport.Name = control.Name - controlReport.Description = control.Description - controlReport.Remediation = control.Remediation - ruleReports := []opapolicy.RuleReport{} - for _, rule := range control.Rules { - if ruleWithArmoOpaDependency(rule.Attributes) { - continue - } - k8sObjects := getKubernetesObjects(opaSessionObj.K8SResources, rule.Match) - ruleReport, err := opap.runOPAOnSingleRule(&rule, k8sObjects) - if err != nil { - ruleReport.RuleStatus.Status = "failure" - ruleReport.RuleStatus.Message = err.Error() - glog.Error(err) - - errs = fmt.Errorf("%v\n%s", errs, err.Error()) - } else { - ruleReport.RuleStatus.Status = "success" - } - ruleReport.ListInputResources = k8sObjects - ruleReport.ListInputKinds = listMatchKinds(rule.Match) - ruleReports = append(ruleReports, ruleReport) - } - controlReport.RuleReports = ruleReports - controlReports = append(controlReports, controlReport) + for i := range opap.Frameworks { + frameworkReport, err := opap.processFramework(&opap.Frameworks[i]) + if err != nil { + errs = fmt.Errorf("%v\n%s", errs, err.Error()) } - frameworkReport.ControlReports = controlReports - frameworkReports = append(frameworkReports, frameworkReport) + frameworkReports = append(frameworkReports, *frameworkReport) } - opaSessionObj.PostureReport.FrameworkReports = frameworkReports - opaSessionObj.PostureReport.ReportGenerationTime = time.Now().UTC() + opap.PostureReport.FrameworkReports = frameworkReports + opap.PostureReport.ReportGenerationTime = time.Now().UTC() + // glog.Infof(fmt.Sprintf("Done 'Process'. reportID: %s", opap.PostureReport.ReportID)) cautils.StopSpinner() cautils.SuccessTextDisplay(fmt.Sprintf("Done scanning cluster %s", cautils.ClusterName)) return errs } +func (opap *OPAProcessor) processFramework(framework *opapolicy.Framework) (*opapolicy.FrameworkReport, error) { + var errs error + + frameworkReport := opapolicy.FrameworkReport{} + frameworkReport.Name = framework.Name + controlReports := []opapolicy.ControlReport{} + for i := range framework.Controls { + controlReport, err := opap.processControl(&framework.Controls[i]) + if err != nil { + errs = fmt.Errorf("%v\n%s", errs, err.Error()) + } + controlReports = append(controlReports, *controlReport) + } + frameworkReport.ControlReports = controlReports + return &frameworkReport, errs +} + +func (opap *OPAProcessor) processControl(control *opapolicy.Control) (*opapolicy.ControlReport, error) { + var errs error + + controlReport := opapolicy.ControlReport{} + controlReport.PortalBase = control.PortalBase + + controlReport.Name = control.Name + controlReport.Description = control.Description + controlReport.Remediation = control.Remediation + + ruleReports := []opapolicy.RuleReport{} + for i := range control.Rules { + ruleReport, err := opap.processRule(&control.Rules[i]) + if err != nil { + errs = fmt.Errorf("%v\n%s", errs, err.Error()) + } + if ruleReport != nil { + ruleReports = append(ruleReports, *ruleReport) + } + } + controlReport.RuleReports = ruleReports + return &controlReport, errs +} + +func (opap *OPAProcessor) processRule(rule *opapolicy.PolicyRule) (*opapolicy.RuleReport, error) { + if ruleWithArmoOpaDependency(rule.Attributes) { + return nil, nil + } + k8sObjects := getKubernetesObjects(opap.K8SResources, rule.Match) + ruleReport, err := opap.runOPAOnSingleRule(rule, k8sObjects) + if err != nil { + ruleReport.RuleStatus.Status = "failure" + ruleReport.RuleStatus.Message = err.Error() + glog.Error(err) + } else { + ruleReport.RuleStatus.Status = "success" + } + ruleReport.ListInputResources = k8sObjects + return &ruleReport, err +} + func (opap *OPAProcessor) runOPAOnSingleRule(rule *opapolicy.PolicyRule, k8sObjects []map[string]interface{}) (opapolicy.RuleReport, error) { switch rule.RuleLanguage { case opapolicy.RegoLanguage, opapolicy.RegoLanguage2: @@ -147,18 +205,42 @@ func (opap *OPAProcessor) regoEval(inputObj []map[string]interface{}, compiledRe rego.Query("data.armo_builtins"), // get package name from rule rego.Compiler(compiledRego), rego.Input(inputObj), - rego.Store(opap.regoK8sCredentials), + rego.Store(RegoK8sCredentials), ) // Run evaluation resultSet, err := rego.Eval(context.Background()) if err != nil { - return nil, fmt.Errorf("In 'regoEval', failed to evaluate rule, reason: %s", err.Error()) + return nil, fmt.Errorf("in 'regoEval', failed to evaluate rule, reason: %s", err.Error()) } - results, err := opapolicy.ParseRegoResult(&resultSet) + results, err := parseRegoResult(&resultSet) + + // results, err := ParseRegoResult(&resultSet) if err != nil { return results, err } return results, nil } + +func (opap *OPAProcessor) updateScore() { + + // calculate score + s := score.NewScore(k8sinterface.NewKubernetesApi(), ScoreConfigPath) + s.Calculate(opap.PostureReport.FrameworkReports) +} + +func (opap *OPAProcessor) updateResults() { + for f, frameworkReport := range opap.PostureReport.FrameworkReports { + for c, controlReport := range opap.PostureReport.FrameworkReports[f].ControlReports { + for r, ruleReport := range opap.PostureReport.FrameworkReports[f].ControlReports[c].RuleReports { + // editing the responses -> removing duplications, clearing secret data, etc. + opap.PostureReport.FrameworkReports[f].ControlReports[c].RuleReports[r].RuleResponses = editRuleResponses(ruleReport.RuleResponses) + + // adding exceptions to the rules + ruleExceptions := exceptions.ListRuleExceptions(opap.Exceptions, frameworkReport.Name, controlReport.Name, ruleReport.Name) + exceptions.AddExceptionsToRuleResponses(opap.PostureReport.FrameworkReports[f].ControlReports[c].RuleReports[r].RuleResponses, ruleExceptions) + } + } + } +} diff --git a/opaprocessor/processorhandler_test.go b/opaprocessor/processorhandler_test.go index d3532980..e6bf66f9 100644 --- a/opaprocessor/processorhandler_test.go +++ b/opaprocessor/processorhandler_test.go @@ -1,44 +1,21 @@ package opaprocessor import ( - "context" - "encoding/json" - "os" - "path" - "strings" "testing" "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/k8sinterface" // _ "k8s.io/client-go/plugin/pkg/client/auth" - restclient "k8s.io/client-go/rest" "github.com/armosec/kubescape/cautils/opapolicy" - "github.com/armosec/kubescape/cautils/opapolicy/resources" - - "github.com/open-policy-agent/opa/ast" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" ) func NewOPAProcessorMock() *OPAProcessor { - c := make(chan *cautils.OPASessionObj) - - deps := resources.NewRegoDependenciesDataMock() - storage, err := deps.TOStorage() - if err != nil { - panic(err) - } - return &OPAProcessor{ - processedPolicy: &c, - reportResults: &c, - regoK8sCredentials: storage, - } + return &OPAProcessor{} } -func TestProcessRulesHandler(t *testing.T) { +func TestProcess(t *testing.T) { + // set k8s k8sResources := make(cautils.K8SResources) k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) @@ -47,149 +24,21 @@ func TestProcessRulesHandler(t *testing.T) { opaSessionObj := cautils.NewOPASessionObjMock() opaSessionObj.Frameworks = []opapolicy.Framework{*opapolicy.MockFrameworkA()} opaSessionObj.K8SResources = &k8sResources - k8sinterface.K8SConfig = &restclient.Config{} - // run test - processor := NewOPAProcessorMock() - if err := processor.ProcessRulesHandler(opaSessionObj); err != nil { - t.Errorf("%v", err) - } - // bla, _ := json.Marshal(opaSessionObj.PostureReport) - // t.Errorf("%v", string(bla)) -} - -func TestRunRegoOnK8s(t *testing.T) { - // set k8s - k8sResources := make(cautils.K8SResources) - // k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) - k8sResources["/v1/pods"] = k8sinterface.V1KubeSystemNamespaceMock().Items - - k8sinterface.K8SConfig = &restclient.Config{} - - // run test - processor := NewOPAProcessorMock() - report, err := processor.runRegoOnK8s(opapolicy.MockRuleA(), []map[string]interface{}{k8sResources}) - if err != nil { - t.Errorf("%v", err) - } - if len(report.RuleResponses) == 0 { - t.Errorf("len(report.RuleResponses) == 0") - } -} - -func TestCompromisedRegistries(t *testing.T) { - // set k8s - k8sResources := make(cautils.K8SResources) - // k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) - k8sResources["/v1/pods"] = k8sinterface.V1AllClusterWithCompromisedRegistriesMock().Items - wd, _ := os.Getwd() - baseDirName := "kubescape" - idx := strings.Index(wd, baseDirName) - wd = wd[0:idx] - resources.RegoDependenciesPath = path.Join(wd, "/kubescape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies") - k8sinterface.K8SConfig = &restclient.Config{} - - opaProcessor := NewOPAProcessorMock() - - // run test - reportB, errB := opaProcessor.runRegoOnK8s(opapolicy.MockRuleUntrustedRegistries(), []map[string]interface{}{k8sResources}) - if errB != nil { - t.Errorf("%v", errB) - } - if len(reportB.RuleResponses) == 0 { - t.Errorf("len(report.RuleResponses) == 0") - return - } - // bla, _ := json.Marshal(reportB.RuleResponses[0]) - // t.Errorf("%s", bla) -} - -// func TestForLior(t *testing.T) { -// // set k8s -// k8sResources := make(cautils.K8SResources) -// // k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items) -// k8sResources["/v1/pods"] = k8sinterface.V1KubeSystemNamespaceMock().Items -// resources.RegoDependenciesPath = "/home/david/go/src/kubescape/vendor/asterix.cyberarmor.io/cyberarmor/capacketsgo/opapolicy/resources/rego/dependencies" -// opaProcessor := NewOPAProcessorMock() - -// // set opaSessionObj -// opaSessionObj := cautils.NewOPASessionObjMock() -// opaSessionObj.K8SResources = &k8sResources - -// opaSessionObj.Frameworks = []opapolicy.Framework{*opapolicy.MockFrameworkA()} -// opaSessionObj.Frameworks[0].Controls[0].Rules[0] = *opapolicy.MockRuleB() - -// // run test -// reportB, errB := opaProcessor.runRegoOnK8s(opapolicy.MockRuleB(), opaSessionObj) -// if errB != nil { -// t.Errorf("%v", errB) -// return -// } -// if len(reportB.RuleResponses) == 0 { -// t.Errorf("len(report.RuleResponses) == 0") -// return -// } -// bla, _ := json.Marshal(reportB.RuleResponses[0]) -// t.Errorf("%s", bla) -// } - -func TestNewRego(t *testing.T) { - // TODO - remove before testing - return - - // k8sConfig := k8sinterface.GetK8sConfig() - - // t.Errorf(fmt.Sprintf("%v", k8sConfig.String())) - // t.Errorf(fmt.Sprintf("%v", k8sConfig.AuthProvider.Config)) - // return - - ruleName := "some rule" - rule := opapolicy.MockTemp() - allResources := []schema.GroupVersionResource{ - {Group: "api-versions", Version: "", Resource: ""}, - } - namespace := "" - k8sinterface.K8SConfig = nil - - // compile modules - modules, err := getRuleDependencies() - if err != nil { - t.Errorf("err: %v", err) - return - } - modules[ruleName] = rule - compiled, err := ast.CompileModules(modules) - if err != nil { - t.Errorf("err: %v", err) - return - } - opaProcessor := NewOPAProcessorMock() - k8s := k8sinterface.NewKubernetesApi() - - // set dynamic object - var clientResource dynamic.ResourceInterface - recourceList := []unstructured.Unstructured{} - for i := range allResources { - if namespace != "" { - clientResource = k8s.DynamicClient.Resource(allResources[i]).Namespace(namespace) - } else { - clientResource = k8s.DynamicClient.Resource(allResources[i]) + opap := NewOPAProcessor(opaSessionObj) + opap.Process() + opap.updateResults() + for _, f := range opap.PostureReport.FrameworkReports { + for _, c := range f.ControlReports { + for _, r := range c.RuleReports { + for _, rr := range r.RuleResponses { + // t.Errorf("AlertMessage: %v", rr.AlertMessage) + if rr.Exception != nil { + t.Errorf("Exception: %v", rr.Exception) + } + } + } } - l, err := clientResource.List(context.Background(), metav1.ListOptions{}) - if err != nil { - t.Errorf("err: %v", err) - return - } - recourceList = append(recourceList, l.Items...) } - inputObj := k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.FilterOutOwneredResources(recourceList)) - // inputObj := k8sinterface.ConvertUnstructuredSliceToMap(l.Items) - result, err := opaProcessor.regoEval(inputObj, compiled) - if err != nil { - t.Errorf("%v", err) - return - } - resb, _ := json.Marshal(result) - t.Errorf("result: %s", resb) } diff --git a/opaprocessor/processorhandlerutils.go b/opaprocessor/processorhandlerutils.go index 0991e84e..33c06c28 100644 --- a/opaprocessor/processorhandlerutils.go +++ b/opaprocessor/processorhandlerutils.go @@ -1,12 +1,17 @@ package opaprocessor import ( - "github.com/armosec/kubescape/cautils" + "encoding/json" + "fmt" pkgcautils "github.com/armosec/kubescape/cautils/cautils" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/armosec/kubescape/cautils/opapolicy" resources "github.com/armosec/kubescape/cautils/opapolicy/resources" + "github.com/open-policy-agent/opa/rego" "github.com/golang/glog" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -49,6 +54,73 @@ func getRuleDependencies() (map[string]string, error) { } return modules, nil } +func parseRegoResult(regoResult *rego.ResultSet) ([]opapolicy.RuleResponse, error) { + var errs error + ruleResponses := []opapolicy.RuleResponse{} + for _, result := range *regoResult { + for desicionIdx := range result.Expressions { + if resMap, ok := result.Expressions[desicionIdx].Value.(map[string]interface{}); ok { + for objName := range resMap { + jsonBytes, err := json.Marshal(resMap[objName]) + if err != nil { + err = fmt.Errorf("in parseRegoResult, json.Marshal failed. name: %s, obj: %v, reason: %s", objName, resMap[objName], err) + glog.Error(err) + errs = fmt.Errorf("%s\n%s", errs, err) + continue + } + desObj := make([]opapolicy.RuleResponse, 0) + if err := json.Unmarshal(jsonBytes, &desObj); err != nil { + err = fmt.Errorf("in parseRegoResult, json.Unmarshal failed. name: %s, obj: %v, reason: %s", objName, resMap[objName], err) + glog.Error(err) + errs = fmt.Errorf("%s\n%s", errs, err) + continue + } + ruleResponses = append(ruleResponses, desObj...) + } + } + } + } + return ruleResponses, errs +} + +//editRuleResponses editing the responses -> removing duplications, clearing secret data, etc. +func editRuleResponses(ruleResponses []opapolicy.RuleResponse) []opapolicy.RuleResponse { + uniqueRuleResponses := map[string]bool{} + lenRuleResponses := len(ruleResponses) + for i := 0; i < lenRuleResponses; i++ { + for j := range ruleResponses[i].AlertObject.K8SApiObjects { + w := k8sinterface.NewWorkloadObj(ruleResponses[i].AlertObject.K8SApiObjects[j]) + if w == nil { + continue + } + resourceID := fmt.Sprintf("%s/%s/%s/%s", w.GetApiVersion(), w.GetNamespace(), w.GetKind(), w.GetName()) + if found := uniqueRuleResponses[resourceID]; found { + // resource found -> remove from slice + ruleResponses = removeFromSlice(ruleResponses, i) + lenRuleResponses -= 1 + break + } else { + cleanRuleResponses(w) + ruleResponses[i].AlertObject.K8SApiObjects[j] = w.GetWorkload() + uniqueRuleResponses[resourceID] = true + } + } + } + return ruleResponses +} +func cleanRuleResponses(workload k8sinterface.IWorkload) { + if workload.GetKind() == "Secret" { + workload.RemoveSecretData() + } +} + +func removeFromSlice(ruleResponses []opapolicy.RuleResponse, i int) []opapolicy.RuleResponse { + if i != len(ruleResponses)-1 { + ruleResponses[i] = ruleResponses[len(ruleResponses)-1] + } + + return ruleResponses[:len(ruleResponses)-1] +} func ruleWithArmoOpaDependency(annotations map[string]interface{}) bool { if annotations == nil { diff --git a/policyhandler/handlenotification.go b/policyhandler/handlenotification.go index ca53698c..7083911a 100644 --- a/policyhandler/handlenotification.go +++ b/policyhandler/handlenotification.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/armosec/kubescape/cautils" - "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/cautils/armotypes" "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/armosec/kubescape/cautils/opapolicy" @@ -16,6 +16,7 @@ type PolicyHandler struct { k8s *k8sinterface.KubernetesApi // we are listening on this chan in opaprocessor/processorhandler.go/ProcessRulesListenner func processPolicy *chan *cautils.OPASessionObj + getters *cautils.Getters } // CreatePolicyHandler Create ws-handler obj @@ -30,9 +31,10 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opap opaSessionObj := cautils.NewOPASessionObj(nil, nil) // validate notification // TODO + policyHandler.getters = &scanInfo.Getters // get policies - frameworks, err := policyHandler.getPolicies(notification, scanInfo.PolicyGetter) + frameworks, exceptions, err := policyHandler.getPolicies(notification) if err != nil { return err } @@ -40,6 +42,7 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opap return fmt.Errorf("empty list of frameworks") } opaSessionObj.Frameworks = frameworks + opaSessionObj.Exceptions = exceptions k8sResources, err := policyHandler.getResources(notification, opaSessionObj, scanInfo) if err != nil { @@ -55,22 +58,22 @@ func (policyHandler *PolicyHandler) HandleNotificationRequest(notification *opap return nil } -func (policyHandler *PolicyHandler) getPolicies(notification *opapolicy.PolicyNotification, policyGetter getter.IPolicyGetter) ([]opapolicy.Framework, error) { +func (policyHandler *PolicyHandler) getPolicies(notification *opapolicy.PolicyNotification) ([]opapolicy.Framework, []armotypes.PostureExceptionPolicy, error) { cautils.ProgressTextDisplay("Downloading/Loading framework definitions") - frameworks, err := policyHandler.GetPoliciesFromBackend(notification, policyGetter) + frameworks, exceptions, err := policyHandler.GetPoliciesFromBackend(notification) if err != nil { - return frameworks, err + return frameworks, exceptions, err } if len(frameworks) == 0 { err := fmt.Errorf("could not download any policies, please check previous logs") - return frameworks, err + return frameworks, exceptions, err } cautils.SuccessTextDisplay("Downloaded/Loaded framework") - return frameworks, nil + return frameworks, exceptions, nil } func (policyHandler *PolicyHandler) getResources(notification *opapolicy.PolicyNotification, opaSessionObj *cautils.OPASessionObj, scanInfo *cautils.ScanInfo) (*cautils.K8SResources, error) { diff --git a/policyhandler/handlepullpolicies.go b/policyhandler/handlepullpolicies.go index 59010b64..083029b3 100644 --- a/policyhandler/handlepullpolicies.go +++ b/policyhandler/handlepullpolicies.go @@ -3,25 +3,28 @@ package policyhandler import ( "fmt" - "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/cautils/armotypes" "github.com/armosec/kubescape/cautils/opapolicy" ) -func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *opapolicy.PolicyNotification, getPolicies getter.IPolicyGetter) ([]opapolicy.Framework, error) { +func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *opapolicy.PolicyNotification) ([]opapolicy.Framework, []armotypes.PostureExceptionPolicy, error) { var errs error - // d := getter.NewArmoAPI() frameworks := []opapolicy.Framework{} + exceptionPolicies := []armotypes.PostureExceptionPolicy{} + // Get - cacli opa get for _, rule := range notification.Rules { switch rule.Kind { case opapolicy.KindFramework: - // backend - receivedFramework, err := getPolicies.GetFramework(rule.Name) + receivedFramework, recExceptionPolicies, err := policyHandler.getFrameworkPolicies(rule.Name) if err != nil { - errs = err + errs = fmt.Errorf("%v\nKind: %v, Name: %s, error: %s", errs, rule.Kind, rule.Name, err.Error()) } if receivedFramework != nil { frameworks = append(frameworks, *receivedFramework) + if recExceptionPolicies != nil { + exceptionPolicies = append(exceptionPolicies, recExceptionPolicies...) + } } default: @@ -29,5 +32,19 @@ func (policyHandler *PolicyHandler) GetPoliciesFromBackend(notification *opapoli errs = fmt.Errorf("%s", err.Error()) } } - return frameworks, errs + return frameworks, exceptionPolicies, errs +} + +func (policyHandler *PolicyHandler) getFrameworkPolicies(policyName string) (*opapolicy.Framework, []armotypes.PostureExceptionPolicy, error) { + receivedFramework, err := policyHandler.getters.PolicyGetter.GetFramework(policyName) + if err != nil { + return nil, nil, err + } + + receivedException, err := policyHandler.getters.ExceptionsGetter.GetExceptions("", "", "") + if err != nil { + return receivedFramework, nil, err + } + + return receivedFramework, receivedException, nil } From 942f356d19f70f25abafe59a20339c4cbfed0098 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 5 Sep 2021 14:21:51 +0300 Subject: [PATCH 19/25] support exceptions --- cautils/display.go | 1 + cautils/getter/armoapi.go | 37 +++++-- cautils/getter/downloadreleasedpolicy.go | 2 +- cautils/getter/getpolicies.go | 2 +- cautils/getter/loadpolicy.go | 12 ++- cautils/jsonutils.go | 23 +++++ cautils/opapolicy/datastructuresmethods.go | 43 ++++++++- cautils/scaninfo.go | 12 +-- cmd/framework.go | 13 ++- examples/exceptions.json | 34 +++++++ policyhandler/handlepullpolicies.go | 2 +- {printer => resultshandling/printer}/junit.go | 0 .../printer}/printresults.go | 96 +++++++++---------- .../printer}/summary.go | 5 + .../printer}/summeryhelpers.go | 2 + .../reporter/reporteventreceiver.go | 56 +++++++++++ .../reporter/reporteventreceiverutils.go | 57 +++++++++++ .../reporter/reporteventreceiverutils_test.go | 20 ++++ resultshandling/results.go | 32 +++++++ 19 files changed, 367 insertions(+), 82 deletions(-) create mode 100644 cautils/jsonutils.go create mode 100644 examples/exceptions.json rename {printer => resultshandling/printer}/junit.go (100%) rename {printer => resultshandling/printer}/printresults.go (76%) rename {printer => resultshandling/printer}/summary.go (83%) rename {printer => resultshandling/printer}/summeryhelpers.go (97%) create mode 100644 resultshandling/reporter/reporteventreceiver.go create mode 100644 resultshandling/reporter/reporteventreceiverutils.go create mode 100644 resultshandling/reporter/reporteventreceiverutils_test.go create mode 100644 resultshandling/results.go diff --git a/cautils/display.go b/cautils/display.go index 5efd8ecf..597d0503 100644 --- a/cautils/display.go +++ b/cautils/display.go @@ -21,6 +21,7 @@ func IsSilent() bool { } var FailureDisplay = color.New(color.Bold, color.FgHiRed).FprintfFunc() +var WarningDisplay = color.New(color.Bold, color.FgCyan).FprintfFunc() var FailureTextDisplay = color.New(color.Faint, color.FgHiRed).FprintfFunc() var InfoDisplay = color.New(color.Bold, color.FgHiYellow).FprintfFunc() var InfoTextDisplay = color.New(color.Faint, color.FgHiYellow).FprintfFunc() diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index 00132484..d80cfa19 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -16,18 +16,17 @@ import ( // Armo API for downloading policies type ArmoAPI struct { httpClient *http.Client - hostURL string + baseURL string } func NewArmoAPI() *ArmoAPI { return &ArmoAPI{ httpClient: &http.Client{}, - hostURL: "https://dashbe.eustage2.cyberarmorsoft.com", + baseURL: "https://dashbe.auprod1.cyberarmorsoft.com", } } func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) { - armoAPI.setURL(name) - respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.hostURL) + respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getFrameworkURL(name)) if err != nil { return nil, err } @@ -41,15 +40,37 @@ func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) return framework, err } -func (armoAPI *ArmoAPI) setURL(frameworkName string) { +func (armoAPI *ArmoAPI) getFrameworkURL(frameworkName string) string { requestURI := "v1/armoFrameworks" requestURI += fmt.Sprintf("?customerGUID=%s", "11111111-1111-1111-1111-111111111111") requestURI += fmt.Sprintf("&frameworkName=%s", strings.ToUpper(frameworkName)) requestURI += "&getRules=true" - armoAPI.hostURL = urlEncoder(fmt.Sprintf("%s/%s", armoAPI.hostURL, requestURI)) + return urlEncoder(fmt.Sprintf("%s/%s", armoAPI.baseURL, requestURI)) } -func (armoAPI *ArmoAPI) GetExceptions(scope, customerName, namespace string) ([]armotypes.PostureExceptionPolicy, error) { - return []armotypes.PostureExceptionPolicy{}, nil +func (armoAPI *ArmoAPI) GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { + exceptions := []armotypes.PostureExceptionPolicy{} + if customerGUID == "" { + return exceptions, nil + } + respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getExceptionsURL(customerGUID, clusterName)) + if err != nil { + return nil, err + } + + if err = JSONDecoder(respStr).Decode(&exceptions); err != nil { + return nil, err + } + + return exceptions, nil +} + +func (armoAPI *ArmoAPI) getExceptionsURL(customerGUID, clusterName string) string { + requestURI := "api/v1/armoPostureExceptions" + requestURI += fmt.Sprintf("?customerGUID=%s", customerGUID) + if clusterName != "" { + requestURI += fmt.Sprintf("&clusterName=%s", clusterName) + } + return urlEncoder(fmt.Sprintf("%s/%s", armoAPI.baseURL, requestURI)) } diff --git a/cautils/getter/downloadreleasedpolicy.go b/cautils/getter/downloadreleasedpolicy.go index e4bb4cd2..837150c0 100644 --- a/cautils/getter/downloadreleasedpolicy.go +++ b/cautils/getter/downloadreleasedpolicy.go @@ -27,7 +27,7 @@ func NewDownloadReleasedPolicy() *DownloadReleasedPolicy { } } -func (drp *DownloadReleasedPolicy) GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { +func (drp *DownloadReleasedPolicy) GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { return []armotypes.PostureExceptionPolicy{}, nil } diff --git a/cautils/getter/getpolicies.go b/cautils/getter/getpolicies.go index b1617763..d88eaaad 100644 --- a/cautils/getter/getpolicies.go +++ b/cautils/getter/getpolicies.go @@ -7,6 +7,6 @@ import ( type IPolicyGetter interface { GetFramework(name string) (*opapolicy.Framework, error) - GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) + GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) // GetScores(scope, customerName, namespace string) ([]armotypes.PostureExceptionPolicy, error) } diff --git a/cautils/getter/loadpolicy.go b/cautils/getter/loadpolicy.go index 8f2a8fe3..9fb72027 100644 --- a/cautils/getter/loadpolicy.go +++ b/cautils/getter/loadpolicy.go @@ -41,6 +41,14 @@ func (lp *LoadPolicy) GetFramework(frameworkName string) (*opapolicy.Framework, return framework, err } -func (lp *LoadPolicy) GetExceptions(policyType, customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { - return []armotypes.PostureExceptionPolicy{}, nil +func (lp *LoadPolicy) GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { + + exception := []armotypes.PostureExceptionPolicy{} + f, err := ioutil.ReadFile(lp.filePath) + if err != nil { + return nil, err + } + + err = json.Unmarshal(f, &exception) + return exception, err } diff --git a/cautils/jsonutils.go b/cautils/jsonutils.go new file mode 100644 index 00000000..497e797f --- /dev/null +++ b/cautils/jsonutils.go @@ -0,0 +1,23 @@ +package cautils + +import ( + "bytes" + "encoding/json" +) + +const ( + empty = "" + tab = " " +) + +func PrettyJson(data interface{}) ([]byte, error) { + buffer := new(bytes.Buffer) + encoder := json.NewEncoder(buffer) + encoder.SetIndent(empty, tab) + + err := encoder.Encode(data) + if err != nil { + return nil, err + } + return buffer.Bytes(), nil +} diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index b0b89711..5c81ddc2 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -53,13 +53,26 @@ func (ruleReport *RuleReport) GetRuleStatus() (string, []RuleResponse, []RuleRes func (controlReport *ControlReport) GetNumberOfResources() int { sum := 0 for i := range controlReport.RuleReports { - if controlReport.RuleReports[i].ListInputResources != nil { - sum += len(controlReport.RuleReports[i].ListInputResources) - } + sum += controlReport.RuleReports[i].GetNumberOfResources() } return sum } +func (controlReport *ControlReport) GetNumberOfFailedResources() int { + sum := 0 + for i := range controlReport.RuleReports { + sum += controlReport.RuleReports[i].GetNumberOfFailedResources() + } + return sum +} + +func (controlReport *ControlReport) GetNumberOfWarningResources() int { + sum := 0 + for i := range controlReport.RuleReports { + sum += controlReport.RuleReports[i].GetNumberOfWarningResources() + } + return sum +} func (controlReport *ControlReport) ListControlsInputKinds() []string { listControlsInputKinds := []string{} for i := range controlReport.RuleReports { @@ -100,3 +113,27 @@ func (controlReport *ControlReport) Failed() bool { } return false } + +func (ruleReport *RuleReport) GetNumberOfResources() int { + return len(ruleReport.ListInputResources) +} + +func (ruleReport *RuleReport) GetNumberOfFailedResources() int { + sum := 0 + for i := range ruleReport.RuleResponses { + if ruleReport.RuleResponses[i].GetSingleResultStatus() == "failed" { + sum += 1 + } + } + return sum +} + +func (ruleReport *RuleReport) GetNumberOfWarningResources() int { + sum := 0 + for i := range ruleReport.RuleResponses { + if ruleReport.RuleResponses[i].GetSingleResultStatus() == "warning" { + sum += 1 + } + } + return sum +} diff --git a/cautils/scaninfo.go b/cautils/scaninfo.go index 57251e54..16ddfdac 100644 --- a/cautils/scaninfo.go +++ b/cautils/scaninfo.go @@ -27,7 +27,6 @@ type Getters struct { } func (scanInfo *ScanInfo) Init() { - // scanInfo.setSilentMode() scanInfo.setUseFrom() scanInfo.setUseExceptions() scanInfo.setOutputFile() @@ -58,16 +57,7 @@ func (scanInfo *ScanInfo) setGetter() { // load from file scanInfo.PolicyGetter = getter.NewLoadPolicy(scanInfo.UseFrom) } else { - scanInfo.PolicyGetter = getter.NewArmoAPI() - } -} - -func (scanInfo *ScanInfo) setSilentMode() { - if scanInfo.Format == "json" || scanInfo.Format == "junit" { - scanInfo.Silent = true - } - if scanInfo.Output != "" { - scanInfo.Silent = true + scanInfo.PolicyGetter = getter.NewDownloadReleasedPolicy() } } diff --git a/cmd/framework.go b/cmd/framework.go index 6281ed08..d5622148 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -14,7 +14,9 @@ import ( "github.com/armosec/kubescape/cautils/opapolicy" "github.com/armosec/kubescape/opaprocessor" "github.com/armosec/kubescape/policyhandler" - "github.com/armosec/kubescape/printer" + "github.com/armosec/kubescape/resultshandling" + "github.com/armosec/kubescape/resultshandling/printer" + "github.com/armosec/kubescape/resultshandling/reporter" "github.com/spf13/cobra" ) @@ -121,11 +123,12 @@ func CliSetup() error { // processor setup - rego run go func() { - reporterObj := opaprocessor.NewOPAProcessorHandler(&processNotification, &reportResults) - reporterObj.ProcessRulesListenner() + opaprocessorObj := opaprocessor.NewOPAProcessorHandler(&processNotification, &reportResults) + opaprocessorObj.ProcessRulesListenner() }() - p := printer.NewPrinter(&reportResults, scanInfo.Format, scanInfo.Output) - score := p.ActionPrint() + + resultsHandling := resultshandling.NewResultsHandler(&reportResults, reporter.NewReportEventReceiver(), printer.NewPrinter(scanInfo.Format, scanInfo.Output)) + score := resultsHandling.HandleResults() adjustedFailThreshold := float32(scanInfo.FailThreshold) / 100 if score < adjustedFailThreshold { diff --git a/examples/exceptions.json b/examples/exceptions.json new file mode 100644 index 00000000..7f67a52b --- /dev/null +++ b/examples/exceptions.json @@ -0,0 +1,34 @@ +[ + { + "name": "ignore-kube-namespaces", + "policyType": "postureExceptionPolicy", + "actions": [ + "alertOnly" + ], + "resources": [ + { + "designatorType": "Attributes", + "attributes": { + "namespace": "kube-system" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "namespace": "kube-public" + } + }, + { + "designatorType": "Attributes", + "attributes": { + "namespace": "kube-node-lease" + } + } + ], + "posturePolicies": [ + { + "frameworkName": "NSA" + } + ] + } +] \ No newline at end of file diff --git a/policyhandler/handlepullpolicies.go b/policyhandler/handlepullpolicies.go index 083029b3..56afabb6 100644 --- a/policyhandler/handlepullpolicies.go +++ b/policyhandler/handlepullpolicies.go @@ -41,7 +41,7 @@ func (policyHandler *PolicyHandler) getFrameworkPolicies(policyName string) (*op return nil, nil, err } - receivedException, err := policyHandler.getters.ExceptionsGetter.GetExceptions("", "", "") + receivedException, err := policyHandler.getters.ExceptionsGetter.GetExceptions("", "") if err != nil { return receivedFramework, nil, err } diff --git a/printer/junit.go b/resultshandling/printer/junit.go similarity index 100% rename from printer/junit.go rename to resultshandling/printer/junit.go diff --git a/printer/printresults.go b/resultshandling/printer/printresults.go similarity index 76% rename from printer/printresults.go rename to resultshandling/printer/printresults.go index 6e6f2411..78f52c3c 100644 --- a/printer/printresults.go +++ b/resultshandling/printer/printresults.go @@ -9,7 +9,6 @@ import ( "github.com/armosec/kubescape/cautils" - "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/armosec/kubescape/cautils/opapolicy" "github.com/enescakir/emoji" @@ -27,19 +26,17 @@ const ( ) type Printer struct { - opaSessionObj *chan *cautils.OPASessionObj writer *os.File summary Summary sortedControlNames []string printerType string } -func NewPrinter(opaSessionObj *chan *cautils.OPASessionObj, printerType, outputFile string) *Printer { +func NewPrinter(printerType, outputFile string) *Printer { return &Printer{ - opaSessionObj: opaSessionObj, - summary: NewSummary(), - printerType: printerType, - writer: getWriter(outputFile), + summary: NewSummary(), + writer: getWriter(outputFile), + printerType: printerType, } } @@ -63,45 +60,39 @@ func calculatePostureScore(postureReport *opapolicy.PostureReport) float32 { return (float32(totalResources) - float32(totalFailed)) / float32(totalResources) } -func (printer *Printer) ActionPrint() float32 { +func (printer *Printer) ActionPrint(opaSessionObj *cautils.OPASessionObj) float32 { var score float32 - for { - opaSessionObj := <-*printer.opaSessionObj - if printer.printerType == PrettyPrinter { - printer.SummarySetup(opaSessionObj.PostureReport) - printer.PrintResults() - printer.PrintSummaryTable() - } else if printer.printerType == JsonPrinter { - postureReportStr, err := json.Marshal(opaSessionObj.PostureReport.FrameworkReports[0]) - if err != nil { - fmt.Println("Failed to convert posture report object!") - os.Exit(1) - } - printer.writer.Write(postureReportStr) - } else if printer.printerType == JunitResultPrinter { - junitResult, err := convertPostureReportToJunitResult(opaSessionObj.PostureReport) - if err != nil { - fmt.Println("Failed to convert posture report object!") - os.Exit(1) - } - postureReportStr, err := xml.Marshal(junitResult) - if err != nil { - fmt.Println("Failed to convert posture report object!") - os.Exit(1) - } - printer.writer.Write(postureReportStr) - } else if !cautils.IsSilent() { - fmt.Println("unknown output printer") + + if printer.printerType == PrettyPrinter { + printer.SummarySetup(opaSessionObj.PostureReport) + printer.PrintResults() + printer.PrintSummaryTable() + } else if printer.printerType == JsonPrinter { + postureReportStr, err := json.Marshal(opaSessionObj.PostureReport.FrameworkReports[0]) + if err != nil { + fmt.Println("Failed to convert posture report object!") os.Exit(1) } - - score = calculatePostureScore(opaSessionObj.PostureReport) - - if !k8sinterface.RunningIncluster { - break + printer.writer.Write(postureReportStr) + } else if printer.printerType == JunitResultPrinter { + junitResult, err := convertPostureReportToJunitResult(opaSessionObj.PostureReport) + if err != nil { + fmt.Println("Failed to convert posture report object!") + os.Exit(1) } - + postureReportStr, err := xml.Marshal(junitResult) + if err != nil { + fmt.Println("Failed to convert posture report object!") + os.Exit(1) + } + printer.writer.Write(postureReportStr) + } else if !cautils.IsSilent() { + fmt.Println("unknown output printer") + os.Exit(1) } + + score = calculatePostureScore(opaSessionObj.PostureReport) + return score } @@ -116,7 +107,8 @@ func (printer *Printer) SummarySetup(postureReport *opapolicy.PostureReport) { printer.summary[cr.Name] = ControlSummary{ TotalResources: cr.GetNumberOfResources(), - TotalFailed: len(workloadsSummary), + TotalFailed: cr.GetNumberOfFailedResources(), + TotalWarnign: cr.GetNumberOfWarningResources(), WorkloadSummary: mapResources, Description: cr.Description, Remediation: cr.Remediation, @@ -125,9 +117,7 @@ func (printer *Printer) SummarySetup(postureReport *opapolicy.PostureReport) { } } printer.sortedControlNames = printer.getSortedControlsNames() - } - func (printer *Printer) PrintResults() { for i := 0; i < len(printer.sortedControlNames); i++ { controlSummary := printer.summary[printer.sortedControlNames[i]] @@ -144,6 +134,7 @@ func (printer *Printer) PrintResults() { func (printer *Printer) printSummary(controlName string, controlSummary *ControlSummary) { cautils.SimpleDisplay(printer.writer, "Summary - ") cautils.SuccessDisplay(printer.writer, "Passed:%v ", controlSummary.TotalResources-controlSummary.TotalFailed) + cautils.WarningDisplay(printer.writer, "Warning:%v ", controlSummary.TotalWarnign) cautils.FailureDisplay(printer.writer, "Failed:%v ", controlSummary.TotalFailed) cautils.InfoDisplay(printer.writer, "Total:%v\n", controlSummary.TotalResources) if controlSummary.TotalFailed > 0 { @@ -157,10 +148,12 @@ func (printer *Printer) printTitle(controlName string, controlSummary *ControlSu cautils.InfoDisplay(printer.writer, "[control: %s] ", controlName) if controlSummary.TotalResources == 0 && len(controlSummary.ListInputKinds) > 0 { cautils.InfoDisplay(printer.writer, "resources not found %v\n", emoji.ConfusedFace) - } else if controlSummary.TotalFailed == 0 { - cautils.SuccessDisplay(printer.writer, "passed %v\n", emoji.ThumbsUp) - } else { + } else if controlSummary.TotalFailed != 0 { cautils.FailureDisplay(printer.writer, "failed %v\n", emoji.SadButRelievedFace) + } else if controlSummary.TotalWarnign != 0 { + cautils.WarningDisplay(printer.writer, "warning %v\n", emoji.NeutralFace) + } else { + cautils.SuccessDisplay(printer.writer, "passed %v\n", emoji.ThumbsUp) } cautils.DescriptionDisplay(printer.writer, "Description: %s\n", controlSummary.Description) @@ -197,7 +190,7 @@ func generateRow(control string, cs ControlSummary) []string { } func generateHeader() []string { - return []string{"Control Name", "Failed Resources", "All Resources", "% success"} + return []string{"Control Name", "Failed Resources", "Warning Resources", "All Resources", "% success"} } func percentage(big, small int) int { @@ -209,11 +202,12 @@ func percentage(big, small int) int { } return int(float64(float64(big-small)/float64(big)) * 100) } -func generateFooter(numControlers, sumFailed, sumTotal int) []string { +func generateFooter(numControlers, sumFailed, sumWarning, sumTotal int) []string { // Control name | # failed resources | all resources | % success row := []string{} row = append(row, fmt.Sprintf("%d", numControlers)) row = append(row, fmt.Sprintf("%d", sumFailed)) + row = append(row, fmt.Sprintf("%d", sumWarning)) row = append(row, fmt.Sprintf("%d", sumTotal)) if sumTotal != 0 { row = append(row, fmt.Sprintf("%d%s", percentage(sumTotal, sumFailed), "%")) @@ -230,14 +224,16 @@ func (printer *Printer) PrintSummaryTable() { summaryTable.SetAlignment(tablewriter.ALIGN_LEFT) sumTotal := 0 sumFailed := 0 + sumWarning := 0 for i := 0; i < len(printer.sortedControlNames); i++ { controlSummary := printer.summary[printer.sortedControlNames[i]] summaryTable.Append(generateRow(printer.sortedControlNames[i], controlSummary)) sumFailed += controlSummary.TotalFailed + sumWarning += controlSummary.TotalWarnign sumTotal += controlSummary.TotalResources } - summaryTable.SetFooter(generateFooter(len(printer.summary), sumFailed, sumTotal)) + summaryTable.SetFooter(generateFooter(len(printer.summary), sumFailed, sumWarning, sumTotal)) summaryTable.Render() } diff --git a/printer/summary.go b/resultshandling/printer/summary.go similarity index 83% rename from printer/summary.go rename to resultshandling/printer/summary.go index 482c4887..9fd5f26d 100644 --- a/printer/summary.go +++ b/resultshandling/printer/summary.go @@ -2,6 +2,8 @@ package printer import ( "fmt" + + "github.com/armosec/kubescape/cautils/armotypes" ) type Summary map[string]ControlSummary @@ -13,6 +15,7 @@ func NewSummary() Summary { type ControlSummary struct { TotalResources int TotalFailed int + TotalWarnign int Description string Remediation string ListInputKinds []string @@ -24,11 +27,13 @@ type WorkloadSummary struct { Name string Namespace string Group string + Exception *armotypes.PostureExceptionPolicy } func (controlSummary *ControlSummary) ToSlice() []string { s := []string{} s = append(s, fmt.Sprintf("%d", controlSummary.TotalFailed)) + s = append(s, fmt.Sprintf("%d", controlSummary.TotalWarnign)) s = append(s, fmt.Sprintf("%d", controlSummary.TotalResources)) return s } diff --git a/printer/summeryhelpers.go b/resultshandling/printer/summeryhelpers.go similarity index 97% rename from printer/summeryhelpers.go rename to resultshandling/printer/summeryhelpers.go index 4575b629..6795bea1 100644 --- a/printer/summeryhelpers.go +++ b/resultshandling/printer/summeryhelpers.go @@ -34,6 +34,7 @@ func listResultSummary(ruleReports []opapolicy.RuleReport) []WorkloadSummary { // add resource only once for i := range resource { + resource[i].Exception = ruleReport.Exception if ok := track[resource[i].ToString()]; !ok { track[resource[i].ToString()] = true workloadsSummary = append(workloadsSummary, resource[i]) @@ -51,6 +52,7 @@ func ruleResultSummary(obj opapolicy.AlertObject) ([]WorkloadSummary, error) { if err != nil { return resource, err } + resource = append(resource, *r) } diff --git a/resultshandling/reporter/reporteventreceiver.go b/resultshandling/reporter/reporteventreceiver.go new file mode 100644 index 00000000..9fff9879 --- /dev/null +++ b/resultshandling/reporter/reporteventreceiver.go @@ -0,0 +1,56 @@ +package reporter + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/opapolicy" +) + +type ReportEventReceiver struct { + httpClient http.Client + host url.URL +} + +func NewReportEventReceiver() *ReportEventReceiver { + hostURL := initEventReceiverURL() + return &ReportEventReceiver{ + httpClient: http.Client{}, + host: *hostURL, + } +} + +func (report *ReportEventReceiver) ActionSendReportListenner(opaSessionObj *cautils.OPASessionObj) { + if cautils.CustomerGUID == "" { + return + } + if err := report.Send(opaSessionObj.PostureReport); err != nil { + fmt.Println(err) + } +} +func (report *ReportEventReceiver) Send(postureReport *opapolicy.PostureReport) error { + + reqBody, err := json.Marshal(*postureReport) + if err != nil { + return fmt.Errorf("in 'Send' failed to json.Marshal, reason: %v", err) + } + host := hostToString(&report.host, postureReport.ReportID) + + req, err := http.NewRequest("POST", host, bytes.NewReader(reqBody)) + if err != nil { + return fmt.Errorf("in 'Send', http.NewRequest failed, host: %s, reason: %v", host, err) + } + res, err := report.httpClient.Do(req) + if err != nil { + return fmt.Errorf("httpClient.Do failed: %v", err) + } + msg, err := httpRespToString(res) + if err != nil { + return fmt.Errorf("%s, %v:%s", host, err, msg) + } + return err +} diff --git a/resultshandling/reporter/reporteventreceiverutils.go b/resultshandling/reporter/reporteventreceiverutils.go new file mode 100644 index 00000000..d0ce0c43 --- /dev/null +++ b/resultshandling/reporter/reporteventreceiverutils.go @@ -0,0 +1,57 @@ +package reporter + +import ( + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/gofrs/uuid" +) + +// HTTPRespToString parses the body as string and checks the HTTP status code, it closes the body reader at the end +func httpRespToString(resp *http.Response) (string, error) { + if resp == nil || resp.Body == nil { + return "", nil + } + strBuilder := strings.Builder{} + defer resp.Body.Close() + if resp.ContentLength > 0 { + strBuilder.Grow(int(resp.ContentLength)) + } + _, err := io.Copy(&strBuilder, resp.Body) + if err != nil { + return strBuilder.String(), err + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + err = fmt.Errorf("response status: %d. Content: %s", resp.StatusCode, strBuilder.String()) + } + + return strBuilder.String(), err +} + +func initEventReceiverURL() *url.URL { + urlObj := url.URL{} + + urlObj.Scheme = "https" + urlObj.Host = "report.euprod1.cyberarmorsoft.com" + urlObj.Path = "/k8s/postureReport" + + q := urlObj.Query() + q.Add("customerGUID", uuid.FromStringOrNil(cautils.CustomerGUID).String()) + q.Add("clusterName", cautils.ClusterName) + urlObj.RawQuery = q.Encode() + + return &urlObj +} + +func hostToString(host *url.URL, reportID string) string { + q := host.Query() + if reportID != "" { + q.Add("reportID", reportID) // TODO - do we add the reportID? + } + host.RawQuery = q.Encode() + return host.String() +} diff --git a/resultshandling/reporter/reporteventreceiverutils_test.go b/resultshandling/reporter/reporteventreceiverutils_test.go new file mode 100644 index 00000000..dbe48ccc --- /dev/null +++ b/resultshandling/reporter/reporteventreceiverutils_test.go @@ -0,0 +1,20 @@ +package reporter + +import ( + "net/url" + "testing" +) + +func TestHostToString(t *testing.T) { + host := url.URL{ + Scheme: "https", + Host: "report.eudev3.cyberarmorsoft.com", + Path: "k8srestapi/v1/postureReport", + RawQuery: "cluster=openrasty_seal-7fvz&customerGUID=5d817063-096f-4d91-b39b-8665240080af", + } + expectedHost := "https://report.eudev3.cyberarmorsoft.com/k8srestapi/v1/postureReport?cluster=openrasty_seal-7fvz&customerGUID=5d817063-096f-4d91-b39b-8665240080af&reportID=ffdd2a00-4dc8-4bf3-b97a-a6d4fd198a41" + receivedHost := hostToString(&host, "ffdd2a00-4dc8-4bf3-b97a-a6d4fd198a41") + if receivedHost != expectedHost { + t.Errorf("%s != %s", receivedHost, expectedHost) + } +} diff --git a/resultshandling/results.go b/resultshandling/results.go new file mode 100644 index 00000000..31b95f82 --- /dev/null +++ b/resultshandling/results.go @@ -0,0 +1,32 @@ +package resultshandling + +import ( + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/resultshandling/printer" + "github.com/armosec/kubescape/resultshandling/reporter" +) + +type ResultsHandler struct { + opaSessionObj *chan *cautils.OPASessionObj + reporterObj *reporter.ReportEventReceiver + printerObj *printer.Printer +} + +func NewResultsHandler(opaSessionObj *chan *cautils.OPASessionObj, reporterObj *reporter.ReportEventReceiver, printerObj *printer.Printer) *ResultsHandler { + return &ResultsHandler{ + opaSessionObj: opaSessionObj, + reporterObj: reporterObj, + printerObj: printerObj, + } +} + +func (resultsHandler *ResultsHandler) HandleResults() float32 { + + opaSessionObj := <-*resultsHandler.opaSessionObj + + resultsHandler.reporterObj.ActionSendReportListenner(opaSessionObj) + + score := resultsHandler.printerObj.ActionPrint(opaSessionObj) + + return score +} From 13d27697e15157f221ceb863c4595d4d61d82907 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 5 Sep 2021 14:33:32 +0300 Subject: [PATCH 20/25] update readme --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4c79f458..a9f75926 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ If you wish to scan all namespaces in your cluster, remove the `--exclude-namesp | `-t`/`--fail-threshold` | `0` (do not fail) | fail command (return exit code 1) if result bellow threshold| `0` -> `100` | | `-f`/`--format` | `pretty-printer` | Output format | `pretty-printer`/`json`/`junit` | | `-o`/`--output` | print to stdout | Save scan result in file | +| `--use-from` | | Load local framework object from specified path. If not used will download latest | +| `--use-default` | `false` | Load local framework object from default path. If not used will download latest | `true`/`false` | +| `--exceptions` | | Path to an [exceptions obj](examples/exceptions.json) | ## Usage & Examples @@ -53,24 +56,29 @@ kubescape scan framework nsa *.yaml ``` -* Scan `yaml`/`json` files from url +* Scan `yaml`/`json` files from url ``` kubescape scan framework nsa https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml ``` -* Output in `json` format +* Output in `json` format ``` kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --format json --output results.json ``` -* Output in `junit xml` format +* Output in `junit xml` format ``` kubescape scan framework nsa --exclude-namespaces kube-system,kube-public --format junit --output results.xml ``` +* Scan with exceptions, objects with exceptions will be presented as `warning` and not `fail` +``` +kubescape scan framework nsa --exceptions examples/exceptions.json +``` + ### Helm Support -* Render the helm chart using [`helm template`](https://helm.sh/docs/helm/helm_template/) and pass to stdout +* Render the helm chart using [`helm template`](https://helm.sh/docs/helm/helm_template/) and pass to stdout ``` helm template [NAME] [CHART] [flags] --dry-run | kubescape scan framework nsa - ``` From 38103ac90bef7578a48be8f29e6db7324fe279b8 Mon Sep 17 00:00:00 2001 From: dwertent Date: Sun, 5 Sep 2021 14:39:13 +0300 Subject: [PATCH 21/25] update screenshot --- docs/summary.PNG | Bin 0 -> 45312 bytes docs/summary.png | Bin 210823 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/summary.PNG delete mode 100755 docs/summary.png diff --git a/docs/summary.PNG b/docs/summary.PNG new file mode 100644 index 0000000000000000000000000000000000000000..0274a8d687215a84f2903bd365ebe3d3a021fba1 GIT binary patch literal 45312 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

i|u&1CTKdKJkh9=W&QcdeV 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 tp literal 0 HcmV?d00001 diff --git a/docs/summary.png b/docs/summary.png deleted file mode 100755 index d3e7d5ce60f9f06435179e0367f9d1464996fd39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210823 zcmd432UJsC*Dfj+K&tdk=pelagf1Nc0YT{<1?hw$ohT4G1VoBd0g)z6q?gcxO7GH1 z5JK-gkQ3kXo%jF#JI*)mIrolx*B%*UXE4@Yd+%q?HRm%+w4RPSF#$cnjT<+JA8DxQ z-?)K$aO1`;8hl*rFQ}GIE$km0FMV~T8x@0$>)4aq4vLQzZ``Pc5~6MHV9)P*Xqb52 zxIxYN`-AgHpJVUF4NT!96~(81mRs|uRt9FX+}Gz~pKs%b(`Otde2CH{bFo%btxgNG z7^fKiPs9b#7FDo|Wd(pqvtdw;7X6ROWaV}t?(rdBmBqgQx zw9VMr%Kn$a%CBFn92~c~xVTjQIi7PE_p!76V~8s8uaNz7(6Le=M*Yx zQ4raG%)rLR-mS#^&nc3~Y+0fIoT3lEI#Kp z``Oi{X=L{2+!y{HavCZe0;|v1L@8GRY*!<@R}*iPatO_XD5{Q}xbz7L_M{GZNx08! z8)7T!{+#{ja48@$O2f3jOyxOGzkY@HH5I0!GHPqd$);>`%{mJB`$qd% z8kjlQ-cld(lF<Y;j$;zvmLgufU6r`qa$pJ2*vwAqkK8wsK<67RKP>~)L>VNXo$ z7<+B9CTWXQ87uJU)UE$GYm*{5kE4716p-Lq%aBcYcCMHs&Ww$ zq_B=N_M3wDe_D12p}$0k2hsa*sWJ&`43CPk6z&{_U+_ zw8H+Dr+kTj!>i5TGC&l%smR9WC{jtDlqZb2w@&)EJUzc>PD)PpDAqqEiU@KZsR90b zF1E0LgR$M7QVy{Tqw+mD2P$f}xhUeYRcrkycC?FkE$1KNlAnwBZ{WUKuwvr*ucAG2 z+WUWBQ2({2KgII@D}C`Fmyt(8dGOi##aisOT@kyD>CI2jZBi?leX(rU=%`{>`%v

)8v;Rg3HJ>dG%GaC5FD-z^~BL3Mfh73T2eHP(`$pQX4-;- z#_0!>0{ircGDQGht3wYvhwmL3WjwT*{8HZb$gAza?8|D;$n0I=xNLbmSP9&J(7T^@ zHTIq_-~6`OiNmtFjjS5!L0J7+Yfsv%47&!sxV)xq_jIvf{)qFLj(N@bUZuT=#SbI2 zLY9GU$j0kZ#{v<~83s+~Bw2xMOLgDuEdwT35k0}{oF5OYcAceXbJcbP)3>ef;E5gY+qyZpLEZ@F zljcaz5X8#LiOklLaz!7?>$&0L?awr=7LUG^S{yF7J5(-NV=%0$I(Y4iv7wa+$nXpH zQJ{x9W;i5J!!~z`N%>-5?UFgJ9tx}(l}lX^D@~t4(#3uAP_ry#V=CQGF*@HtljFjq z=(^*C{T!inI{8Yc^`oYT<;&*2!Sfu?81D;Xejljh_mJ9#lYFuYW(pDN!wKa6?1O$f zns}Q930F(43vL?!Vdhrlt6^tt+JFJZ&>X^W)eVeV{#ySV#99dAlmz8EaUe|zpOMNx zH6B^5_c+QJp=k}KV#~2-Aiics$=Tos3{a^B=GQj}X>aVtrjC0(AcJ=ix2o!FrO>h> zBu^eazA~i<8_}BQRv(EpgiEe#G9Cx|y#Drq<%ryMqK$DXXFWeS4mhX=Hx51oI=|&j zkVlI-Y!VtdKU>_oClbswnH?1OHB0*4GYMuZljx=_ z#^*V6kS;N{k;NZ4hN-LcaOai7n?9FHBiED(XnD;w=SCu{*Wq0zeQ5LO(DC4gFAwgu z4W^nZU`9^|c?J|MzH5Gd95=B8t*BFa@q*6NbJW9gO1eKPE<7!aiGN@snQZ%da&z>o z*hGnouzT;$r3bK#JeRK~vB@1L75Dp+OUcijz{J%c$GVZ{tIV16G3a#3I$nE2M);k9Yu(6FQbXDTvMZvZ++2DDeM?h6hJiQ?s{}_ygxHL=S(PxvI`qoxbkpYF-F6y+4n!?N={Dq4a1)v z9=Cm}xpI8qa_=D2;$FVqP#FI(e1^)oOMPj8hshO!kqvktuTI*bfWth!`aISq)pJCb zj$itj_f~Q0A@RJlgu*+gwmiX>jE>Ilq|CwGcD+r>K!0|FmbNB9Jp93cn0wS>d1k^l zMAqdvw9+0-|41U&T?*z@ZiO)YtX-n4N8tBk4lxT}EGT%mNZbj9@yA@$UP%~s11si@XLQgRv;?TcaAJh912 zXO01d7*>gjy(zI=rEw*jdY8hkeG!pAb+L{Dd5Jfz?WolAE?aG2+?4C*d{7}?^Z^y5 z%9RggjwUbEtt5o^HzOB}j0)73b5Ykjl1EvnsDV zrWR>3x_zE=c@~7x1n9=74z2W{u7{|-`P{aWP4~IH1HasplOR&5ylR#w zGO~>!cfmunF*a=^romVFTF3(XZo+TwvQ`7&H%U}}XUPWEJvnW{DKyJ?1ku&wdwQrE@^(<=Ste&h(kDlVq z+O135ao)*CyrT-IotTZ55G6@?_L#v=@Jom#yBRy72t9fXzUB>GBI|$#(o#kI` z?=_snhg>**23cZAM`grGcMk&K8bfK8v{=2ofo^*ExYQ?^tP=L1QjEA?ppdje&faFV)Zk3!*DXu=#_(i5ZtJ&2=|bx-Lh@qY1FbaEwP_P9 z(^3o6dvU#m=3?AZWJby>s)e7{E2F{tHA?%7*3u zeI4%n;k8n|=m>P9SH9$#yL$a7Y*^0uPQX^oLm`k{=2t(p@nfJq)xk$vhx;i&3xL@tKc<-^CSTuzHsQdyt?(>X~t}yK~B)vvX zSzo6R1@TZ*z@YE@+I;EKNVd8ZLFk-TJddpdIoUyUl#_q!3MvAl8jSZB$@lirf@U0$(H3;gCjb8=7MxD&gJ zWn}hYB)h}|?E(d=VxADFkx>GoWi@?^($3R3?pv(ObL!~39{cLg&40cYM|PRItnu`m z71LpqzSOK~)jYm+3{%t3-|enFyRv8fqE*UZYn1k(VvlREA~OnDNK{u|_hn>D_l}d3 zrk=ij*io#Rhf5Q=B}qKy`?t=!qPdXt`Ze59)y$xgPx<++N|uGjJik~Dm&MJg*Bp1# zyehlCn;6Tp(h8oq((pt_X*fk#kvd`Vb{O??g@~l%XGjN-axQ`efc~`}B~0iwT^qwq zv4YyAeqBpe@PVFbQLicnKpYp-UVcL|F8POb(Vs7FUG-N6l)T(0%CWh5kvrZ{qB0>TJo#HyaJIgE@?-R@jf#=p#%)2%d<2_ zj(h&lyZ>@XvI(n-?b~cVd4!7|N%qeMGmsKG>v64W1H=HxgpCEXj{wE300%MZTFt2Jz0L=1M2`gT8SG#{8YhHidQKo$DKV8m|m_R*XaiQH)vhAS2W_F@hAD4=*cCW4ZxfT}UdQ68YL zMgn)99|f@@sN9t5vtFP={6zy8DX*TKKH6U5IBEgn$yrt^L)p8IDAj8c>xt(vwIuTZ zt~_|fK5E3fMX(Gv&mojBU{*3@^yynrs&Ink`swv=qCg|}`6pqKn$Gt1%smHF0r}Kt z`G_ux7U@H7YN&^5VzQbUH}|wEw7t*Op~`83A1$SiYc%@_c#>$M)BQC*Ey<9ND?Eks z%!8fI;jNl&crsI#3Im~;`dPeoXDPCNPuE|Z*U2f#-=CdC`zs{{$FVYBe2}GH*vyR6 zQ$xc7=__(eKzfuO>E%WF$Bc`ypSphU(~rW`hc&nSQ^Jm#yjNOg!cr8OQAIW78TQ~A zQ~W3q5L5KD!VvOojPadOTK=aKWJm5z7qY@LihcXR)Sp9Y^wo?eu*(p;Zo;}O81ZF(##FyWJxxTD`0k>6)GZvb`cu7 zmVTf5D`~Ml?QP*fNlGJI__9JgQ!Iu80L9$DzQpwQAY8$K&-L5diUZV^bs-we)UlzU zE$3*DS{~v)R2olAs4&O4+#AW_5kYP$gDDPHOC;U*jPw>x~@O6y`8p& zNdy<;vqg(u1U=E9IBYRl{p6A8O~`+DE%I%@q;{UiT@_4k>qz55lB)Te$hmD}ao9c5XgB=Wv*V;VkLWQ_#AAPYH!ajyOqF^fHE~?u8UH~y@GK$@XRoC2|Yt{28M}%Guu=Vit zz!jBxCDWA46mQACJv?i|o?0WWZHpcWy!1XY6}aH2a7Y#!BIS%Jc-A)?w}UZ#&Ah2J zqQwMTKdU5n<)m{cL7+1K+6Imu33B!4Bnt;0QpxfQs+$am&CS9XwZek$efau1Wi=JY zQ>uR}MepJSQse;e}Ip2(Bv-(3;8c#@oMs{q#HGX8?@uvhn$_zrAU`JUdR) z0VMFZ)#f)}S`wollg#c(k)?_$8wEL>n)jc+>!@}_bI<{N`0Xq-H2vCENDvuW(LZP1 z5s*^GU$sMf%UyV6&4w)z1VTffJ0(Q?y)H%lo%4g+zJC|pTk633xF{E!#%<3wI7>#7 zpIuv~kT3BGaaQ=0QVtmDRT;bYb>jR5R=QE}yd(@bLMf+&Q51qleOsNy0gIedkVrAD z6gj}QcNrE>7u)jY8o0y}rXGpJpdqr2CGXR9P1xFdna8e_LA+ed7|7pyoJPsHVof|QoavZt@iC_{U8`OUt%LLtedLDZJ*InBBBZ9!;bHtKlq ziJy}a-URtmbMWLj{ii_<36k(n?D|)#6JO*_DOU4C(;ED?B$(wjlqWBL0OfsH5V9HE ziM>zy3@$GaI&b$&Fs=K79Go&%lff*6G_f@+MLeJRANmZ6%(Vqj$v}TC87RKUH1nz!rw+ei*!#O~ahrhNwBb(rXl zP2BD!tP+A?#6&5Fa7lZYhm(pK#HoFrur_SE-cg9{#dEVdKBPH#&?w_?7eQM_E@Fsr zoqqTcPsT2)lW|gdCWK*qHFC6H^1-FSn|xAI50K>z#FclgYp(q2;YDy_#mO-!)#;C| z5%%E1v2V>~u|-fX*=hcH%cc<4FToz`4GHGswuFzl8)l_DK&V}Tx;gJR>SL*K@t+x) zmRGikxd~%?*Ch0Z`P*GpPq%tdQj2u0GQn*e{3}0aI-Wn34ahNjvr`(6Ith>sxL%E4 z5U>qOc?#Ot?WmwWI1(AOh%Rvdiw7KK*K)ABE!3QFi4u75?B2G6e0%fek3`hk&H7Y|-7Gk;#f5t? zw>38Hd^a&k_D-zbybYIa-)$t%%KOgoaq85`Fft7MNmjpMUKK)MXXkzFd5EY;lJiUU zp0kEY%t92+Tk`BmAu}t>K^50W61 ze-m|hq>|fy-`Jo1R+?az>dfGa=}VwG{4WW%!Lmc|AhHHtcPJ~as=W5_(Xf%~Gpl8J zApO19kJ`w1qL|__GPc48myNcGoh?0!9d&3^h%7~>JpTS&I3D($I*i|Yr*dW!QOh~! zQ+vgwKR`P1G2I>5@l%pHR_F!7GK7_2ak2f|dIv4i@%jbHr^|-aqX)TDn_))@@ih-N znZ)g+tuE}(T1rp0H*boUOg>g?xwidtSJ2Uuy-97=el?Yw7`%(`_LxcP*TrtE~g&<1Zc% zv=F{y;x*!>1~@u#nai*4!or|23Yp5C2k&}}GOVJXCylu#cAk+drT7@b{)kn#6qL%F z(Dt_}19h3dDeO6GkmYXz`2wxnw^pY81o1hsnnU{GBIk5u4$4wGGGrgwCYF}0FZ zK7^jmj+DRTY|152A9|925*SR|vGY!H;1%iLaxjsq`%o15*K5TSO643iM+@i3jpipSI)8F+853px`jN|W~V59Yp zrnB5kr^P)Am}D#rCZ;wIiYMLex$QWw(#`v#O8jyG(jxjUI0S+hDQP`a3Ndb|`o_y| z=5qs2sHG=%N{Z))w(?8@M?U~T>OfYoY!#s?CLdNl4ij62e573a@q{0tX15F>n!6eg zdYnK=2yr-~-vYmlC7R$~aWHRh6OoSsjmsMPf+s6~CY1Zu>~Z;%OqQF!+2dSGI=SH0 zxjx5RRp+us5?idPdgXm2CoCjtX?R76*CS^|m&SGcq=XFqM@4O&Z8<-<`bxH1q>E`s8Hq z6;b=QbYn_rd>2fOsPhqxbKE$ZBuRo!i`AX~I(W`wB_a~>6-qj}$(V`jm9;Hm-XG|) zVO5rlRV~hb(|$HsGjAm-WQqvzx|PI`_Tbm$(duz{$PL;YlkY90s{*F3VXJW^yM;T2-g?ZfM#AU7R5)O?%lpE z*c#{XvobN@h#_2LLv5+8H>MUIv!tc`e+f60yeiKVoS^%O0%l3yKUmC<`3#|Cm1v@wnN_r3B(FeJP6myLPb#;=7!Z`Y8 z0;qHewVpgR3EMCosry3Y^AnNNP>r{Coe}+v;-)bF^j#fIGh?&#NpSv$Mj_Y!&5s#F z^<+hMq@!j~MX{2#BJPr+ zgJO`wNj3!Z=FQUi9q|zB4!LyYlZoJC+3#Q%qv)xW^T>j!y2W8EM4F7YAJ#WzqYP{B z%zIK7Tn^ktHTtszZ~+T^qr?OF1bRe7M;r!zlTOk!MXvfiPsaFHqOS?&r9Vt?6JuZe zT_h^yZwEw;9sJ7C_UBKa>sNPY#5My-W$}Q9&XCf~z&221jKY${6M28-SxSN6F5M23 zWkMlH9>2=<{0^KvUN`s>@F8(3j0dG=IKcylCuH7mTcRR#0)# zP&^nTAE$hgccw(18h<P=?#{aVB4Rb$`#EE7{4YE9WzHE)o>$hN zY~#xn44@SoD-Uh6ytQw?@)CVIBEkbD>SmL7Qk`+0 z-E05X4wAY{=t0hO>UAQk@@?2m`qXa`XV*yseAJRBb%%;%3k8qSN-E1aY>r|H6&gV- zq2kSh4FDhNMgq?|r9A0Vw`8F;X%%e8qpXbA&a7{_;vX7YSvB0>w&6T@J80Le*^kkt ztP`fA3|-*k%3rIAM_D#e%x}DU5QHf6U}^#zzu6I@DYz_mL{;eRgTpzbwHgxm|k^QKEb(I$x?V*M_y8U^{ z&=!RLyiX}%@Uk+v$MTZk)=aIsMsM_{P*Q54l8Gg*rTGQn>}ojM^vK4P;EK<3kO^^4 zbg_W$K364UX`Ghd7x2w|xh)&M5C^wioV2@_`)h?n@7}HDt*%qMyr&~6Jj=fL(Kx%M zJFRiX$=rMFOV@XwPkAuYTXt5O(u?hCmd*joK&1T1+WD9-)Dm8XXKx5dcpHn$P*a3H zw#Lj4-60#P)Mm#pD6;M@s;RL1df*Qp6L#2CCrnWD-?lEyyrpKE-d@);nK7wJN<(+uYe>I+ zO9LT$DbVbzuw35K54@M*i28bu^L7`s#2o1Y0vLONoK62j{j>j8|KK5izreWlp!Lk& z20EU~SFRQxPHJcl(!r*+4%d!Y8;-$5N@kr~lsUiS55)!pa zG9A>_uQRK{#G(aLgSei8MpU(PP-~9sd#0!bM4PaqkCpd}tmAv?LjN)`bUaSt;Rvnw z4QWrdH*6&pde_00 z?3c$lpBa{-ML>%+iBku`CQ*0802jUPJ#PtB{mk^@zlXy8z+S}m$G(wikX1vY(YPT! zhvVIl*GdbL*+R!@n2Zj&S0bMnhp-ekK~PgO-rCw_2mD)pUOa^2dB~xN?~p}HInQg} zOCX6rv@+O>j`EmPX%?lM+vY)P9k>=cyLK(Q3@2(eqzI(X9LT_@~t*T`A&GnDpCeZlx5H;}gI(wMzs z;3Ruup`}9XP+9zHP?DeDWqFMzHaz^ddeI$bJSAi+`d8l~0QT+Y!F-F+2VLd$1XD8`trnrl9uwe-^cmKmW~ddy*-OkFoW|H$kjpp~0M zy^^VB7#IuL2(YIJ-Rx7Tbk%VOtENv)WnbY?Y8VD4|{!~2xzWN z7?CeQ6gyHMNEBScs6W7)^p4(c$a*_v&9XjYe1we^|G~Pt|I_wHY!x-saonQ_#k$si zK&V>=f9H)>)wZLArD1Cqdn`!FL^2hk@U-UuJ_iuQu(S1oQ z%K5-&z5M|H3Snq>d1a0^&)m&Q*GJFKTPlEyCoHXENdAcc^?~%kv^F}?O3i9Py~_y#|KCBa#e{S90UU|J zq$txC3NUk1)VpK{klR2If3`4Xm{QR4rafsO6d$NA2uEb6fzStXbIrbHz%V5EI-(~j z$K%W77W z8ENzZez}dxIg|+y^ikZ^u^ReqNqDhV8X)ILN)Q@Kuv41f2}%Law>O|D1;A3b7uEN} zg{AdWo_vq)3SqU>>0BO%w@_IvxK}7!NK%flw4Z9YfTB^^uU3^Z239a9{@Fu*1 z{HpFA-ke(!a&|ztx{<#Baa;T9kld~HM|%wnZr%0i7?*!Vyc!a3Mj7GO7N3lv%xmIc zfJlPjGtt4~b+3}_gU}mbOc+0hOki8T3#&n|EuyKW!NfTJ?S@i|mRu|$Sg`v$CpM8M zZ-#tX7ac4?MXHi1I4oddl zaR}GBqHx|xW2yg&3#f=aU-jmcWg0&$-WATBB3qkf{wTRV4b-anQ;}@a-lr3;%y@*w z2>b#IlE>-bba2y#(SSmo9`HnY&)r!#aDvOlL>538aiUrrK=@efj`q7NGIAJ!*2!FF z_Pfl6;GNq#%(8LGr@4reW37f-yZiR4Qe8t&j9h~CY0_MW12=e%H0R@XUdRkz^%@^# zxj`04h+)Z}61f|s^G>Z|N02>+-j`p=7#J5V2z!RODV!A`m3@!ebGhq?G^~P>*JR7LVLADsF~aoObGv6RA3Q~3 zgWh*huQ7~FG3wW^P-P2)kJRUIVTP=_ZfgmOI8XYZOko%X8qUE;NiGvJ4L>;zNrea9 zL0vv8N*v73+>NFKz&NYB4+^V82H1Bm+Rt;2i{U z_{dmd(#XLqGRh=s_JmRB@cWbF9Rf>$wn};t`N1nfkqz+s{MSR%FV42LxxOqc!VBO~ z5W_xtoZ4G^uG#_`&PENOa33oZ}AV%uRYOE zbPIVIb*?rXo?`6z7_x7M-t>Vj3mR|}~ZTg4?%uMQx`ot)v(#c!b64Zz4XGdB+Zv`+$ zt5xENig3ldes;AXr;D_NgVj$r9-~ei=>wuRv8iSxwRXXfry!yyea>E4KK1UgPeIbU ze`)%Q=We$s)@b9bg2|0MpYl|EZ;w5cskSqJkl*66^s;bd@;d=Fv*jMMG)W#AD{9yE zrs|k7B}D9b$B!yh`>mDYm?tS9x;4qG2+&pQa$(i$l$Un)d9O#C71RXhcPTJ|b<_r3rGkT%wxN->ilIVaN2qDMjw|F>D)1oUy3iPBnh)BDXJd8hw znMsqAM|jyNC(1YxUAt-%eJ{9K)u%SnaHn2S0n9oyqfH{jC)0hr-`*RttidEtjZr;1 zw@X*Je)Tn6z1a-E8*1;r(ILwi@-en*nZ;lyhB3W46qx)k%4cIRkP$ev+LTZZ@vToa8M zZZvMXlwhVb{P6h#FgGKQSJTsq)C2Eo00;HUedD%+)>HBhN*`?A+`TY{d9XsyBhQPl z*)og0qd#fhXjNKUIpJt}S+c%(agY2mdeJ0iQ^Mmu^_G^Zp(6>efuXIdtwOd)84`3tylmT4RAL@gVhVfQ) zU(giu2bhOY3o;ZHUkKL@Ve-YL5)=F`R~}+5a5YbT#L&CUB!XE6w*Z@%rJb?*brsR{ zYG1Wdd~BHAm!audrP3)Oa@eayC?GI)(a~av?NbqIw#xb_0mU976f)^8hvigDm2#dU z`JesEQy%fXM~T5pHRtb~4Rv}-^_*?@+QubA{zjLQ`O?;w`HcccB`(s42Mn(U~Z08L0WJJl|z)#J5zpFB{wJXw>NJk zldYDAw_LwTqeK==da}NcSBD$gSiB>=2$0C)p3hoZc}Z$USkrs0p;&tOi+~2E!ry#N z;)snP^@T)iB7E<E!yV_Fu#pS-O-QF~udJLN#{;cLr zQ8_6|Z#TjK?eUa!Gtw2|KC~nRUVLohXitJiNZ5d1k(xleMH}VSh13&u13E>V!rer; zqiVjY0QN8CsXcjm76r6GE{76U<%IsbxMy~mVVoCyx9!@c;-$KHy%(*>T6Tj{FK*`u^JQkl)r^Fd1x3x{foqJsS2l5g6iqCHC&qiJ+h@ z34nifZ*vDZQ=l|HVff+Gfw;I1TGEC48p&U#sV9I7;Ssbzm)IBzC+G^*xY2Yld-yZUfjYv&}98E_&UXD z{wS;*_TbN~V2y&1*r(+J50piMUrY5<2_`zbG@85$zHi8Rdp&Odu`J`r<}SyPtO%8y zB$m(%XE`ES4_g?NIMz15Xy*VDwN47DK;fCgx&YAwctFnpNvPwWcf8blYw)3M@>gGO*B|Z?3_U5NYlwV zG{m-vAC|=l|Qxy zL5%!W8v;G4>S7c=xLIAlE`=Q#-z~}`6gg=ZdmbdH{_GJ>%tG`D>DZngV{XRD4PDDt zLyBpg9V1IQJ;&L*7E)`<<>ZGkHHq2$72%qs=8ucecuL89SE#@?kxqV=+VVdz-X`5xUg`aYT4WvyCV@0P6%qT;R5qG<-X_vqED(a%4 zj;Qyls%;uo{IJ2C37bqs0|f&l=`o-ck05f_F*Bwz8xIBZ&CLih0;#O81pfPHi+1XH zuZ)T0)v&&DRD$9{RZ=mNz=9q6B|2@IRpZcC?X5*uYJt7gLK@}AEP$riVwD%o;RiWg zj{^|%!Iy=lUkXF}di}GRP%^KxNZY~l3j8~q&x(05;Vll$)$)$`zr$ykgDR7Z^U{(z zYD2ez#D;4|tbwKoD)F=Wi3pB9cQU;Sde*G)D_3l9tKFENapQI&ux&Z$k<=h@Q`>?_ z-C?0_#P_n%&xE}frC{!frgc0su;Xug7i;lGtWuXeHhbxoa0xPmZqtC}%ES}NcpShD@}SZD-%3>0Uc{lte& zB`Q=1XciBlfA&WR`0s2sRC5(1e(VNOb~6PyrvW;iCUur>btk2?@l3x+KX1d1#8Y1g zITv&HOh5%!{TRS70IbOKV5ng<)1B+QG6EzS=tq`j^dg;|^o;aF^NpbUM{~?BmvSV^ zN*3Y?Q+;dO+UZn-ZTKdynD79UwNGeA-4?ZB5ZPlGi_cL`)Z(Bld>eX)=kg4nbP{ee za|6CAVL=ZNAAmg1Hr9|}zI?{C4t99t-NtCQBxVl~e7=G-7`fHbT+J9ABIq#@HKKo* zdY`xWKy2^TB5gkd{oJ?12}_JPji!%n-nggitX{i6KH11=QPL2&8|(byTnn-`h_R9Q z6hwaD=%f+*EU;Wr=E}~XvfB37Y*- zX>;xExP$?4My=%Uyvn>PUuBI>!_UAEIbGm;US~H&B8?oG3=9k)Z{ISufPDbI-LhV> zgZ}mff`$ zaQBih)2O0n^^nx#e9}Tzx|)g)-cZ|++SIo|(#oBnIusT=d^KU}jX`raJ#$m72XDI= zHWSZlPTZ+dMS((Y23(W9Uby9A)~)aUlV_nTQ4!S|OcEe#6}i*n+U+k&BX`Z5U6wUreP#P6V}*tp zi5&(EL@cXC-EL<;vVp^LbD|45Ei%KPoFzVsUssXXBjYZGj`&d(Mig#I%7s3bqh@AFZ7e5fqVcnf$F?d_eJ$DO`yqjgg2{$T$>aS!Dh_iQ%+DG9~5$t&q3@2v%yxha+iu9(<0I9M^pBy<%eH6={Epp{o8ZD*z7 zBf{wSZEAz*i5cSJa4gfUU%ZhQB?Ou^TCcx;IS2SuP@bsZLTgFH9OZ1OV{B{p=Hb5O zxEZ95QPNRE>W`uisYr$Ut9!m!zoR9!R|Fvcd}$x)1#GhDSL~4;d$J~5V=}c`_BhLC zO@h2SbI>+$!&%nwv_KVHS4kUbtU%{t=E_}|>+d%;DbpL+_R-sTnec0T*C^AGQ%1}VV&VzEMYU7pE_ zlQ&qDP|mj)cB=EW_8GY8nGwIZGdAJA;M7WNSgbrA$fqpbFi>E>Xdm4cja+<*#q!}7 zzij_&)Wj5SYtJ!%FryEvZcFYW#Yjy_uzJh;upRF1O@GN?gdSD_Uj(g({hfr*a10xL z(*Avr%1yolf1M_wBaEGl?&r%r>+s0i?9-3$8u3X{B4{lZZ`nK9lR!qPD%x1_Nn%y} zRFL~*WKl$fT{oYgFTXki_#)>V?JY^xn&CJd$-u|tgVYl=NMo>Gv7;+6ZNo?Mo!8K#l5?9 zaeaGlqKIBaMi#85sr$b8qx8=L062@W!xLx1D(Fq{nud4VXU04aQZ-b&hYAV4N->n2 zAohe?tO@?JEqSf1^;*(p8-XH=vL0F76GEO*g((ZO^ih$dveo?yy)Olf+Q%kw$TabY z>YlXgq6Hk!5*kQ^le@l;QiowH&72&<6m1h;yqKBnO2GXjY5EFdX@MwBNIN+1$NPQipHYXXc_S7dmS`l@@;%2x!eKeX*V@T8FS z7h13MT&)XTWka%P)W59U^CxP_$d>U53DrJSriaD&e`>_)@0yAMqs%@V`@HZlW1}+? z+Bjh!1=Az=)EJp2q~XNWm7DVy(7A4mv1|~lw@-r}4L$UK_QmJTMT=yd*VNQwY?{u^ zKNC0Lx>bbRg#W(j6VQ4AlV;Yn&;M7-nw<8C|v_8+TgvM0K zqqd##C<=Q|+txWM*a<-v7f~m-W}=Xe^Bu0t;+I?rn?ebI&t$suy2qzoCH0kGorIvi zoCyIfJwtL?nX|s#)?`8&acM6MWJ|D=5b)yT|EeY(TekamLH-kle=AG>D{}KkW&KS1 zf2~Yc|BKA|U8p>c``^oyua#f9F^7izj=}#P`KkYX?h8_1%e4-ne^vK8MgP~jWoXE5 zB_{D;!xM**axTHqdc|o@S()NzwXPGE3 zAqAv`3Eg*jn959t&vdI&&44V&Kt_zCh&=wQn$Z9pF^Is{WxUc+gNf-jES)j7n@4Ec z>__eYY3G29Ri&IC9%o#Py%YUIJjG?o7TnK52301PZ}Zdc^pDo zvQUE;*oN(S0Iy^hFQWxK!zODuEFT{u8~luG2AH?zT1YmFj^K$m%*ttm>p|f^h8s1^ zn@q~CXq-d3N~2jls*PSUO_Be7^?$Zb_`RsFQC-I@e>8fC8=H}Y+gQH%-Ms+L0!jzd zVtYZz^^A;N9b@f$StgiEyHE$#hQW>tanOHjqVYT7SS0bQ%*U84eKRsQp`+S|L~H_R-s_4vOBYVF^8YhX2)5gx&RZ8dV#`rjId z{4E@R+#eg;|8M&d{AU$Yd=Vq8KlPE+)pUhE= zaoK7YledvH&DN=x0y)qRr%17{`^g%ur(AJ|_UG-bo*9osV+I|v!zrnFXPA`jwfGAn z1l~DY_rh%gF(x=U868#E+A~NP!`!7Rt8~asa)7uz*vHoZ2xSN{cn#Jh5cmV_=L$i5Ljm zO=d-8i8#~0?G3kmT^TlrG)-~}nT7!EJ)QS0*+gDGXZsXow^|I%Op2njVSf~H z%~3EcM5f4Ru*X|O>2qiCvT3wq`eKYk=9Hy-*FTzY9g)-L4|$iOsIgVl>>BtnM!A#J z`|2L{Y563uPKCv557^jm63i+Zh&aHX%?(i>PJQpKwJJ;pzrcpAm|!-?)`4f!nH`}$ zvTUMGxcz0K2I+m}OH|CzXlLlsS;1N#5C3?;C&T*(PIY}{a8=7}-hX8#GwPxf_s z(1ZWud=vt1JXC66jc_X%WFRN)CAMbc-DL4;_0wW zX`Q(tHATl4%Ks{--zqvZ7QklHHh9E%@Fy zgHVx4IC(09_PsU|c=71ZY;~eANQ--~QqEu9dO}Pi%tKRzi?Qx?>Qe8IWc`L||x8 zk&qCOZt3ol5|Hj0x@+jc|HZA(^Ze>~H{UJU@__4GYn|(}&NU@DNX#cCX8Dki5)W-n z$DXB^k<4=FRM{&nE+VGu32SM=DDX#f92F?7jK?sRN|AWG>os`mU}YQOGCPUIba)EH z9%`;23hcCPI}6!)oA4kWlzUJU zXrV|4utox#w>H|X;~QMlaZ0>kOdNcm_Zl9GE1`xr}`NxZ8RSH?3r8=Df} zj~_N45cTvMb-EqUhHp#*O~2DNR-f}VbUp{og-*I0zi}JLQcy=6Z6152Hc~{u#SdK4 zU?;t?$MxtaqDjjOJko_m@1P=^nmCUu{^$k&sGj`@G5y|;z`;U-@cG>MeD>|FRw8J; zY>Dw7d$o=&(C(Gn^NL=eEs(A(k0(`4Nxf{0F1|zxE@Ghk05t&hG`R8Qr-^?x8kUVs zr}`Do<49pJoQ9znn;+CcUoUMKH*UGQd_Ce%wr9MlhFmn0Fj z-U%-3t4!LY5Ap`30%euqKNn@tAJp(NGGH!y{my%IuXYn#0{c4Stf=0?&y1y)5smc*E91AFdkafL zC65P=Z#(zwL3NT=bXbX}ldry!j%O6r<4>Ovz<0jiP*AR5+H9{Sy4DGOI_1VZcoSIB zg#7on`0jD~&e!F!Oc2_`9mGA)#XI^cQ?rLak?mL(3l7*`&D?GP#^A>8m>;J=i1+ES zO8Uq5-(E2B@r@FnQhki@!IvuAmj+&+A-R{MxGL(AvXwPlb0n5W7LEkNybXj33JR}UO$x!fnmjEqGAS7Y#yUOS8pd7sS(|3 z&PNOoLULfB5yt3TA4_Bv2%C`QKEntT-*XxfEvO$ffNCI-59=^1^bydefgkQsO(R5% zu-L~+4;FE1C>i{Kq(0jDWEC1kvad`doh#LiJCGtp1rwHpw$Zfx+DrRS!#-i7i~ zU#Pl#3(eqM>>9Fzg>9#u#|;hoB>5t7Rvld-*qW1(pZj@Y09DQP?(5szGlK*&XGvZ) zB{N32R~_vFGYHpIHF7f5b*`JnpgY~tSA}%hgFvk#W5m&9yVA4Y=)-{P)9hQU4Fmj~ z>9WS;{HhAuo3tu#ur_=WgPCbS534SzJ__*qv0QqCJLg4TD*ZXL`jY9$G_@_wi(XE= zhShJS`T39fKz&h9vK-jyncP+TCC^bY$@jQJ7YzIoy7v$1eOYH%4HJ`%+PkZG&{aiY zv^@f`sV1R6esuGU6_G%`%cme1hkiZV*mff5_duM7feOnn&)w(9d*TaXO83=++S_p@ z>JuWXwBUq$tEMfbbw%xKmE($sZf zN0Z(jiKz8-Vb8hW&@nkGvkvk^`c>8APvW)?9D)fYR`264a6El(;TFJO!rc+rSAF0q z7+ja{AsxBz^VuV1oHG?lSbKtfnoaig=vdr}Htl^jm~n|#;z1$7LPtkrdv~qnfV^5Q zhiki>G)C>@`g`LE(8o z%P*~$$-8@}1T~WI`zQ$(`Dyvct|t%28_MT8a+ij5`|w^loq9_dnJ@g6OAXL0SaJ4t z`n*X$;E-!e`y#JzDzs%CFStboJwo>o*6T%KakFXl&#rk4xr|n59qsozI2CZ+r*B6J z@nPb?o}KK-PQ|`_cSdivv=%LzxXu%l6^x}aIAGyq`+&p9_gvvQqZr@app;K8j)w!E z{k4I5qkkOG3T*!1Rj(DU83galEnM?uTFmu&LRr9P9!tMpjzwMe^5z@YsHxv2m=^_h zpBg1%u4a486I*C^R=Ke0{I$g+>4 zX>2-9p%+=#i&e+SLPIRdP%XtG$XmUgbenu#@z44E?B=?|R4vuEnE;gf{9+nEj+H+i zlC?34D6^%gJ-llgz$rW4Kj!t_{r-n3IE?cs*;?r?$86#Z_aP`hBt*B}dvqI4yIl$@9p_ASz5&`&nF^*41 zAL`w&_Oe!%W(QO{?Sd9+WmImeX8nC|hJ{27;{PFb%^u72Mx#bNnIcQqY??k8KAme3zY+71$ z(K$*iS=3Lh`k~-Y_7Tpzm_5wzxATb?Wyca-Ka? z*_n7S$XzLA9}N#ND=3xFb>7JK@>zU(bf|cOr94d1xYKaEI9q>2XLkbxDhdSa^IZ z9;!B6G)VckpyLS`fCd4`+%Bd-FwTywuK8wLsA6ehU_lAVusUZ?&TC3zN2(cp%a(dp5YRAv_=Bc0zL>c*04ba$QA-a6<#^0h98i9Yyhcxfu zAw7+8F_57D!w_+M=dMhhbJpLH_3NQ72Qh$8 z!5*eUoi~c?V-90;JWSeU&AO=elu)!QySKR&lknQ*knd243yp;rR4}y&q~cFKFIA%8sA-oB$*SJMkq4xCbGj6-3c+ zo2@=A)PC{RQ?hcpfXCAE{t$fE(&E;&B(&xA*AH+iLT>ViW5eQ^QWQAb&s)-&1X^fT z)jvW4p!ct@^hGMmAwdqEx*daMMzqCEn3S~Q&JU&hB{|q%UIY_t% zr_nbELwq^qb)uoqrbq|zNjZ0&S1ybyBp+u(Y1bmQ51e;Q1T!!E!oaI(Xv^hGg1~d~ z+_AiNsD!)w2UegNye1lqJ6WNPm{X~U)iW{*3lHa%5N{$BN1#R)$6s!1HMk;smQAjg zHZ8HTtIm_kO@?o43g{NK$ge{foU+g*K`VYT=JfWsV+EJ3;o!ubt^2nYz#E|!wT+iL zKQw9y%z{!q7nj{3qy^z_2b(k44k<)Oe|LxRZynkzm#gk4jlJhE86?E4`6%n2&T1X2 zUjPBmP;u*#*Sy(?jND=b;Tk;~w)Y~h^sj9REjIZ32#}Hb@=Bd@t?%JOd`Hvp3oQkP z%z!%*wDD!1MI;Hb(?kEeK7liNw%f7Xy?gM+AVCoO<7HB-X$FTiT20ygNHb3~y~WRu z)U(sfe_>|#`nu!mc|NvmY#?&tiXLffvk#a0dNS$);;)MXOjoQ5& z70Tea5eCe|%21gFpQ~pA*(^J`v>l(f4f43JBHvY_Kvizj3B^iP4iYdV`PgB(;y63R zw)GJfv)?)Ycq~U{C`3hAQ`Hm`*rd5 zNj1F$k*=k>HU22hXq=lnf$pWxS9+kDbkf0VZ0e|m&{IC4ZMvs?n!DV!&i{$DN#Ul$ zYA02MV&v}3?4a$MO?&~(=B9e=%|Y^B>1%H!UEMf<6)ScOroKodwIslxHH!iyxS)S8 z=O@3ke3!TFlJ^;8;e^uAyPu2ZBcTe>h@WX(Qka^kmq7jax14EgqNsG(*qLDZUnby|5IYE^xTF1R9{9 z=@>8pxK#?m&f`ntQd8e;_vnF< zpPn7KRRv~ycjSg8zdlts{upJ3JY_W9rHwHMoUM2SZr0ASbK67TpfsIPtf9f}9q z66@DM(PqOB5$q*FO0i2L7LF9+t}$BM}PVL zp|RSRror&!(-x{ASThDwzqFkR+lsq|KdUN@R#=RdqW~u<|qJ_3Y zn@xGYIG|=mI?V}weG$ji+-Jw=JXhyb1j6{8m1W&nO3J&Bv8ikBL{44a&o$F^ zXHz4t8^v?7uuRcS=?Sx+K0nDXflvpr|C;!mk(qfX-E9$$Y&r%tFrpu3C>0}wuCgjL zMn5--d-*!i!TnOc0=b0NzOs5S!R95HtE2-HH}!_xW8OCegR-s{Wz5}Or50Hl4Y3`y z^h-7^EL>OKCQwzt_Ac=I)ifPs@?zvaivo1}6<{wS#`-q(iPkg5bGZKIjFchE6G6$x zIy(O73p-)5qnHHxV&3gM68D0#(3u!J3DU5Yrz*vVA2aeZhx8YUu|bz;1kiAXrCW@^)q50UNRI7ol0>gWtbk>o z>mtWF7mmCdTJAm+09AM}+$0L#(?q-Xa4F;cC=-p^atnBQ!VTnlL*_JJ&z#a4hpZ@j z)Q+Y$F=u(ao^ktja;=D-x3c+=knnQGFWE)q_1BYK~ znPm{XrzbfWphM&FY*6w5>8Z=62o^ZEq@z2^x7_#4bVu9+H?-8a11VDHW%f`w78nn@zwVJ6mI~9Osa#$ETdZPLP9gPHxaT& zW%=G!EUCWF0mG<0&_zs&xDdpfR8MVRMvF3fE;!@4My4kHL*ByR%81ir)z8*6l$L!( z$N#y>gvE{#FHInPq5KzN4@HR$G_t~)K^>J}U(|u6&pRhysA?4XM7(H$ zrE8KH{H~(n@ana5s$((w@Y9tw7O#(b_~XaKUS(`lcT4;92Z82$U2qAK-XL&7R?5BDCj~$s5JI(^b)y88^n&pD=oG{zpeV7JN@={m%YmxQC;SxSfhm^e6 zq~!Gv*9%ipEkp$Ivph_?HUp$Glp-yPqxmXbjskzf`=@+=yP*`q_DgqT*fLTVON|AF zCKnP6Hb_p)d|Pgyn}r7qIst+;`b9dVS?nlmwbC!4pn!lW!`A^a%Ex~0mr(Zuzs;;z z8z8KZ>aODmmH;=T-Bu@YWe03=E9r{TW4Ib&E&Hok&znrHQB_mCPbzQdYlR%i7h6f3 zn8tyuCCc+b{JCEM4>!+gXp9zh0~=5kxz$_*1QHEJJM5OM2E<$+oY~uJWU|W-RUm3> zpWv4}dALk?8>0*JluKQ(gPmBBmfy2v<+zcW)^ri zi=mpuyqZrmdj&$a4d@Yb@iJ+D1Gf-{H9>Skf@H&nb}>69U7COp^>O(;c8Smx>25}u z0o&r1%8wDqRE%~T$Bxf7q`e%aT@4&xTv$h_(tZfju@nDY2zrpOdQZDn4TOt@{-TRM z&eu`0dN}5JfV2Y0FgakFRFQn}Iwd|mFyNQbsJwjuS1&oh-%t{Qd!@PFdd`y(HPF7jGJha2r@?fX;cn+Q0GlI=dPJsB)awsZ6$pi=# zE&2@VcY_@t%2ZIT1!f3I}m8o?qh z(sA{tLk=myBMfN=+WJo!W)k~~E%qq`mm|(BjO?V2euT$*djn;hlfY1DM>Blwly2jr z%bhRWHksO;`S~#dl;v%wWsY;B6>LMV32jr}n1A6swDSwd@rZJa&t|88iIur8NaYcd1@;mjnfCHx)@Qc1GdivxJiy6#5 zYl(LBBMW%kOT=p?!anOp>kD=w+nhN)|NV}H!eQS)(0)C(7?2?XzLSy5KA)XZzPM+{ z+PwLj*ug}jGA4r7PGgZTS}Ronqt5~v168p!meTe$MV|ZPrCPs^ZOr%r(t^6gof(D9 zD%q42ex%j?5x%2=kqziJt&KA$#+I#|DrTPeBCZv2H#d}N>9av5Zs?56U!!*Uj7EEh z&yJ1`mKTHp{e^}w?Gy;gixWsKn`j~fD}>=^IGerPFEh@U8Rm>f2%5RWC-}lP#Cff5 zY-Isu;lm&SQeya*A9FtPdSaCFduz6S84sxe9Hr~Oiy9@60|E>J-QI>6jxX!x1uwC9 z+7=c}MZ~G642)!)*vBqei}LF*=HBIkSEJ6n^!0<1;b(cZN8-AX`#3lXJm35dl*GF)g&5$s0qK`#KS|bM zFfA7NFTn0cP%5GtK9^;+WAyQ@x9mMW{dt0C`MB@(T1iw)pagn!WZ|H$JWZ31Bpoc+ z$G)wW$r6U>Vivq@O#GXO{bVINe_7B2VczweMPYtJ#1r*PCu2 z7!vGQ)kzwlv;O>%*Aek*uC!3j)k!SxiNIYJFbC@87@!5ZLR zXe?P?Iz(}j1q{SNqLCgIbluN-c(HE^?q!l^;{Q|PRbbyg^B}BQ`6}6;dI1&e=h5Q zS0MS>9z4x!_fx~!;gY=Y!g@khrUZS}@bB)Dx)GNeenPC=a-JO5MEyD@s~^t+l>$q& z3s97Y+SY3bVm)}WZzKh~`UoLgaw%dakmPQgajZGkA$gx}fkq$JXf1j(X|gkyv$PGP z5HB8NXcKp;(mA=6->r$*J&FQ(|5VoYN}6G zyg|$r0p#PqB7|o^giuYV?QCELlrl*ERmxyo`#@@$dK9CdJJ;fFW`ARx_M2?@cXY?x z>nBB>hdIS?LPAP3U~APiVMq|+FO@1Mu@)7|yPE{}rtZg~;CJ^H9rf3@T&+-ooUquo zzIrxYuzz$~L~Tp@vZKF6A&AX$KMZ+f)HuxZTwaIIPTHhnQwT6McpMZ}=g|V&@a0=+ zEQwRcm0)r1$k0llavhkzszowV@BbRcE!4^580c(BAo${@QMi5$sG>-5;O-ilt_)r? z14Ea#mmVxq_Ec5RrI1==38151|3v}BJ{3ssjuLXwf9o%{fKvu$P|aShHc5rrixcrJ zm|%%SO}-)c5*cg5QZwSN6 zWcGt&xX*fwA8REn!;&f}8%m_xkBuRYc{LgiROEcj1#=0CE&ep2(J8InDpoCb+(8#0sz{*7f86B5TLE(2p6@1&p)wY`&EcR8H) zT?xO?A5ZYMj!(2%W89zS`nF>hp_6s>Xh2l~7hog+RjQ!w`OWutIe6K=vl0p>E<#@~CW4yS=zs`L1hR&AvXn($3I5%qA+@@Vmum#ZDdL}!EB-sRZO zeblQJAeQ8!Pk4fOX~7_c8B81Jji;_Y*rV^v0xCpI)yt68Q1*YI4_jQv8iqJtrI5{P z3vc4oyv?5aaETowSJW7p>(%Vbxh5yR&H0rxO^mKwnP(YZNYGmpfC@Q}DJkw=ySQ<2 zuY65t_9b}ZOUuUWmPyRPb)8pJWA|As3tWO6;t>XdFh)CyLsG8VZ8z=>EV|>d(7l4! z)h{BUn^rVJIDBh25Li+TP6LmmLN^BT$~N+em9>=2k1CU?YID}iE3xfph7EtSr1Mw^ zVS-1G<@Gyn%!i22?A^uV7o%t|E}6Qgxpa-G$-AoJrX`qzEmioro!a*FMLKb*7c)R6 zqGr`4H?Y~1@D&B%0*nt=Rz~A(F7==;wwL0O?VO9+b*q%VEan($?CS<!Y?L|m20bg{HV9Z0bU6F zpQTpl>+du)Wu7<^gA4o5cb|{5$oczoAGwXWeG6H~N{aDVhJOZi)=xvCRIFT{^OkNG z9;%eemyF~$tvlSFY0=>~(IG}VP7Za6Bj+gPRqcIitLWPoOFgsd%Y#NmMk)7&L|(_?q?P6aElw_*ne$D{G4f3cuUn`Ve(F{O5VOq$w>9&LfJ) z$uX3Smf>z|K;7Kg1R`+>q6Yd+`an2Hqcxus+19rVhG*ZczeNALddj!rqalkB>zY<5 z!t3(myzH0I8famZ;cM-wi$c;8#+CB{#aCmd00Vo^)}@C$<)1|e?Y(Is+bvEVS$xt8 zu)pWFJ+>_n6Y2RrD_eB37YJAHAB)*X+4yj|Myc&e+5l)$-mrI$F_v=A)ALY#Ti~uf zFB19|G`zKmk-2!)-;3kjoh@rbMFdnq0JjUl|4sB;GL#bku3M| zO6ULguQb3}w6q~j!4MS6Am+*|BU!xUP~5=v&tEYT6Z7Ap9AV4p zkXKW+<{+8W&Of7#Zco_%f3wekiE310vNNw-#yw12flPovRE>6lT9CD^avu@EVGXDgu_< z{cG&{J@Uo-oK4ALziRS(8|z81n&CELvr2>b{00(4lcrCVOlXyY>pkMJ*=oy#2@m-x zcW$F;w&^+y2LEAYV@2|_*FzlNig0BtrRN=6@&&fQ7P>WB^Ot%_Z+{Mu%?tN2@5`)G_-|qM=+&Vgk#{xn5Q8+~% z%;1Srj@optHOYA3vnZ9L4>ZSw&f0*-pBi~hht+*fG}?@mm9ruN256`ba+$Ahg$91q zv)CK52l-1=Kgf>9^R5!aaA)Hv7cNg90t>w$4TUu)q_g~16qepmqS12G7rkQQJiJqF z;uq{mntg6;Z1~%c`|R{CjWTZg>(Ua*v#eWG>UK_0p0a-L_P|wqM9Ny=&vSYGWIs}y zQf6>ZrkBb=Y@2CGA!_mu)qeS^7irG)iq$wP0Z<4U6rt%c?crkDlfpy$c7>XHny}2X z-%A(SK~qBG#C!{Xh+BZn-cQU=tVeKjXE${z$LYD@aA@e5%*N`8A3icE0Lh&+T}xaj ze80tHy?R=GXPi51e>vv|i8{dcHjc={|b;$eTe6JL}@bB<5R&RGS z5p|kpM>ke9FPfvN30x1Q)F0@yiGO2Zv9v9s-sw8D{u6G?u8pH_39TGavwzFYW!m<} zrkkq^UlDgcSb;)v>AordS!jmeibB#mJ~W{lk0URyg!qr7nU0UlK)fSpX-WjOJtbYA z5cCHnj|fVKirT8<;O-7ByBz)-3V-k6`u}@i2p8ezY|KFzZ^AN8tP2PyDV?JM@TsH% zCd}OaWtXp7kzZBrCK+Hp=azzjr>j`=ik^@63wYJJlfdV9mKfavQ?+QGbJe~Z^E}eX zXMegIiU3tUCPS_8vs#H+0-S!za(cys7_;bL76Axig)YT70ro&Eq{H^|Sy5B$LjJuJ zZ3vJQTwoo={KI$VMSS4UVvp0BfnS*ZYl6m0H0jW9`^ta1$9_ElUIg@ie!G(_K7jEB zu-2Y80M<%7%>F~u^vZZ3l?)MchsDb%xud=F-kPf($UC~DD2m(#1ttwwb~{`;u;h%1 zZR;{rPyrwgfonHmY8z*-6Y6(m{(&3ovlw*#cgqsXYQ`Rb{<(gRh*#)=sFbJ^=)tMH zRgj-xd%N2EdWERB9=xAUl=8m!99a<>^M#{GGV>vw2q~794fu2?sr@nF-6K<*i&fO} z-MKhvj>sdeZG&3qUKX=z`$^IkVjM!HlA8RM52A^A>Js!a<0oZS8X%K<05^1m9bs;{ zG&u7i=?<1ia3iW%h8j@|kglD1FJS3X#9Bs37UPp1!xM!oeG>$t_?Huyu_h$U1|$>8 zVtzW1pD4+O9rvsRxhR`w-%ll=Y&7*CMs5W-kD~63%<|q0z2kSW?FsIO_E@OAgN^*E zdA|(9IeQ;k6@A7!ey*5}gSZZ^rCWi{ElsPRK;`Z+t0qS!34E~>Y%I;k(sYatD>)vY z99Fm{qzSI=8>7Ag)EEm)g6g2ESK{=GdzJxjNRO=XP^UMn#z9M@LRiGP1u?c;3PHl9 z!=)Qa45juc&8HUI!An3RNRHI-Kv#;WeHm)Ss}Z|dKe>gu!B!5#)Az+ad*Nqqn(naZ&@hgEq?f)uPM;W~eRnKXMAPQW zg4Z^Mri9xGovQI&V5Xy%{ew~mWg^az(@!(B+uO#7@sIXTRK7H$-Rh=t4C;kHW3Q;# z3T64ga}@VgrJ~W!uwymzZtnFfF;G+L-L&4w*`JFhw--ef>swj7PSu`2ayViyQfdyl znx1AY)}~)Pmrs**7uL>kO~H0re78Sb!p zT$&t-)eK#F#V}J7nZf+8_k_t`haZ1&xceBe465E4o=53R_7R{-RwCYP5bGqrs5%nZ z`VIhD@0Kx1`UYQCnEW&QfxGD)H2*=~^)iDRE2O~Y7ffkxT8LH?$8scgElhRk59Ii!*yvHi5lUq7mBj~=#1(# z(*w$J+cD2?IDbl=+W&i;UnN*cSc+)g?8B-o5Ipg}yk$x!N&YgWyBa`Ucb22<-%M%1 zfeDHx|Gy!n<&rkHQRSul_4$PYKomcQyz5~)IOFj8r1>`Hj9~e)fB_Rp{VvZSv`i|S z#K4;e;=AsgxX%;xF&N7#$C|fB%iEDj7tdY(HFdh3W=ORB$)ofud%9AiGa6Nj15XFkvW*%Q||cdxZu*%o+YfubHbAlx>K zVaCBj$O;#NRd$)GiH3T3p)2*ocm?p>`c_Y-!*zAM`DDS=EO?x_3bD}=n-Eph5dpCp z_9&9LqKR1~&CCO`bm!HJUT+UV1)EFDZ@{pu{B8wy6B-+0Vo@u8g7<31A**`n@IC60 zvujsv?Oz$y)ojl@t_s-6_s>kI($eR{R1f(KCu1fq*ncSesB5Z)qS(`HNHR5a=BLtg z4!vV`))QQuC$&|g4xRjYo=>OW`ey$0Wl+z&QvU9z2s|Xuf4FQv`%h6iqu@YNDm5kg z34~5;)(|%(B#@dOj_l#rZjy*%F;aNcI{4fMVC*{htJfWF!~Yi8-{bl?I!fRZ6wGIP zAxhJ5d8c$isx!5L;P4UhZd#6UYgarXj$|31fP=VKRrTu$zPx_>OU`+3vYz3zw)m{= zIFi-yR<%8e=iN%Tg>}7Nt#~pfNu*fXf>?yF$k5W%h%CtEn&yMEM0dxW>q`C)jg-{z zZDn*OhP+iWm#vtE83tAhywAowPdy+)+TI4eP%ku*4>9obKs3Wr#{nsgX6 zqKCnhxo|P$J43Yb!TaGUokZ_tp)@k+bEgTnMk17G#$JqAcSaV-Wewd)dbqtO^QHD` zE_~EXi?2-!{fftESExJ8;C<57%R|8yl2-*1pVp;15!8JkPvZvZNp3S)pBX2Iv@Dai zW4;WfwRa3AKOSx@xX+y{bhh}sY;az8LhJ;80X0t%Ahyi(3J&AK1rgV)S0igX?Kh!y z=j#i2615&QHbXS68M0A)REv{3hs~oA+8V35h_>i#eL4pMa`_I0mZ}n)c%Z&MSD`po>+9^eeL@CC2AY#woRwFFff!g4H*IWq6ToZ#M&$hj)FquUt+# zDd)U&U`3W4BuDiV^hQ%+c&)JD0Ly87WMV<-qCjo(Db;4SkjD5Y#(j4xIvAh26V>r^ z>b0o0760$LMwK2=zi;&|-+qJwd&g?-7N<$E(e?9*NDvPNt9?rys!m>%fBCNt+omXB zwmSN&+dCeJZT$(Q{cnJtJysnWw_qaZrD}JrH}%0}Alg)+KUp;xt(qq_aufB5Vrdt< zW{FiUDk*$gc@jQs5?Th{r@U^0Qdh%-A(>GP#nF@B=wokN3rb@3^a^E6kVe;T*0j}; zN182YtuMlzqn#2kVVR*Xmz;1w%A7ht!Y$tdLr$mmH)2b6pijLDyl0O6;qB>sKGZ$ zHyeqUF;xccd~5uC647s63Cmj&IndO-7^|}cxeH*x0xU8Gz(K^;MNxz1c20Mdsg0(l zW?CnH5Rv8N@PdI<-=CuUG({Ci`ZvfA5$m_XnNOy)E8}gwPL9gt)i!tp;!e2ni1BFF|I(&#KCz7_mY%atny;rZ%TUcByCofNy zmVQCp(2eov*En$4g}KZ2iSLw3eb$(PrN0o8dKvdRWqeV=#?taZb_CD$75-CL1Cs;| zr}?WVGlILpbLY)8omW&(7W6`ZiYfgx-OcLlT2_F_d7_toem|sG+Pr_ubh^K`bHd`t zy@Q)v^?;)^Ku+xio0Rcl$jT<&fvZLUV?V`JmQiTQaH%PH3JFD$~3Hu0L`;X$zcGzFu zm#8i8yFx{5UzQ4D5h4b+Ik?x zKb2VHRQlrfhP_2T@7A^BrESIN#3(+T?0107zqy9mrj;gV60kN2()agV)Obaqd&If% z`mHNBqO=3Qv-G%l&YPc~mD`OBOT!yGIi1SG z?KYKiI!@r9LQBaFj)@=u0RW)gsk90#;3pKL|MfK!P>ehB&XK_iHsXDk)ongdd7)o< z$+IKwLlk=E)N#5x#s`&qcyHdZDkdX6^3TOKxfbM9{4Fk`zM-(($u%HKT}#L<`U3AT zpru`UI$J|$;%jv^zPr0!a9$BG{fFKOVR)oeq=Fk%6M+X%GDa8$5ypSQvf!v5_n)&7 zUdS`A`@U1pCK%OL*Hs$DL3GEV?l<7NRJ!ybvLhu|4PV~}6DoH5V)o4A=NsWDE?~4A zF)`BJ9KSAG#2D2LJ}Lk!Hh*R)Nf3j~Z+JO7V_jjH)%!x>6TUcV6b6kXFeXPY37?y8422+ZO?&!-g2~cYvn|Kv@6Js8A4M z72Efx5h&f|JlZ6172{>B>lN9;{8W@APACI&Cmz3>vcBPT>r6LUb+sKlfP-_(v-?Be zn-=wda3Vmw46`21>s6TlA~_XLf=7^q>pJN1E_jr753L9M;|C7NTar3mYCNMr3AI#@ zT~(Exm&f|lUro$(K{8^jKa)>bJKw!A%IHprGxXgUPhm3s2TwUu?1i+{P)0X6dPowjvVSor78P5lSKO9{WO@v30K zf59ZtW!QmpH%=1m*9{q9HwM(NPuu#-Pg>EwO=>^Wxg<0greEq#5&-#Z#Gd+! zdQ#ia2gq4?lWt*G?u-A~n8z6XK*#>)+qbPv##8`0XJ*p(PuQ~aPuNnUO>UjBG~jS8 zHDhFB)U`wjo4da6eDov32SP+3()FmdYFRur3>FyyAX#7jYt91jZWgN~;Wx*^<_nj* zQ&oO!pQATI1Gl&Y2RXZZai0IoTTN_1pgU!MTN=uC1Eu@jTc?-mNZnqCfcx*M;CQ~P z`Hr+7jZyqZH&GQc$Q$jOru67|Zt-i+9&~&}T(GUAX_W8|$DWvw2R*K*P(08-zWmQ1$FVxv*S^Z;Tz|o zmUG>Gpo%e(XBi;bcF)3trG z-!w%R6oj(NxD~Ol^!*O*N_|@SdcDTKlSC5fKh(T2d0zkI`N7IqHnE z-&=Z+`!!hq`#!$uulP*ko*;XzY?dMx`u3c{eGQXO!R-}p0BSZ*`up^CcRts!Y}Xjq zlrV?!y2sbua@RxIse)P1QQkM;;{mP7Er3H_2YAn5N2w18=hgo_CPj7G7T*5MraP%` zyO<=GtzJEF)7ov%cU2^UpEkD5UWa?&*i>~*=hfCzaIoCBqb=o7>&s%QZDPmu=hj8G z{C|8u)nXG1S|kg=szv`{)gr(FkklnyM&f4cE`+@XKU2KaK0Djnm9IlS#8eFp-9J8yqvu7QFLRl>Q8hM;Nz6 zR$N~4Y1OusI6n^InvEzv!->^1oOfC-Qj1hi_3;yi9d2@TD~#|;S-WyfdA|owF}kPt z5$0khCH!u03xh6MI6Hkp*(y(B+u-dmuA83^C3s!s-+M)waImy=KN7QiQp}Tfyy_+~ z0_!Qg+~9O{Do^2Ie&!t>9>?|}th5b#=L~m8Pwm_*rfJj@O{rTm9VQzkg;>I>w{tTTG0S7k66nZ^q7+->f|b=In0s1R+EQkTBTE@LTUH zu0Kos?w@#K7=U|h5Qf9soT&^r#^HdqQQVUS=O@Q2>VK=XR_{ayxJb&rR|Q9z+mMGf z2MI5=eu?SL>u>E5!6>uPFq4~^Zkw2RUiPkChK4EH`I5pRlBk_R|#i!9&?FL=EURq9o^%d^He{=xe$)CSgABhc>sI{^Z=3e+_JIJSK0-c?> zB?SeV+C~xYA~|Y(&H0J0d|FFynx-a>k0Uxa4hzedr(|hn>mUBU&ZTyh z#~mhCN>SESNH4poM%@5VT~v(rH%go07zaJFuY0lpa~1KMe`ssFXWCf;y+ka83t+(X zOrn$y7iLlSQ_i7Pug`8VxDp}+Vv<*CD08s252I{X30>+Jz`&u%JkJI??gdb$aN;h~ z$8QX$lA-tr!LKZx*lrXJ11Qyn&b~fN^ji`tv4UNlA*knOc`+*(zx2#abYoBGx+Z@4 zVd!^aB6}crpQ|B^T=Yqv=6ci_qq7RRw=81LfP>TAmis8A=#WD4l*J2f$Jt;ImGZ%m zq#EM5T`K)@-t6TciOmTxRxyNKgh*Si?X@k4#Gij7I(Ff6_U2jR8tVe4r4E_dH)|ID zP(aQ$O$qRz-&i(VWC$=5#$^E0Vubl`2g&Jk%;cqKg(1`RD`vw0%eivvQVtZX-j}+} zR@X{=TPY0jaK!US;2$;pGS$XT%F}U1#?3B|a^Q_aU7e3**jqZ-dJ|kRR!$wMJ#qG`Qr`2b*B3FeM64^ui1x8RntG)R`%lqG&kzHU12 zz{=rOR@UF|+X>)PzBQ0sDcvA(&(VW(TQPpu@PmWSA7lih)QI*X$_DIPkpntT!Y3iVEci22Y`^YUhczV_eE^ksrp*Qk-hurJ44_b|L7#4Zzm}$hrqX_E4(^U1NIEy7QAgU<{b9nRLybguI;({$7(xPX{@V zhOX)VW9+M=qI%o4mF@v4VQ5s4MxF#c+0jZ%Gx>Iss z_y&LPd%knl_nx)BwOI29YtP=ZpS$n-x}Ikd@#2kUBNKO&AB#(5;_J}t@Z zQ~}&Ce$tSyUlsUNP&RebQ~&LK5zb}3AIpN|fPi{``nqRvE03;{8_!3Rj@6rd1j(Ti z@o+T{+CmL;)}dED5!D+@OF~WP3W7?K@kQeCJ3@^x*>+J2QKg%^y#+TTwbyglN1F+c zb+=vt-sR<@xrQ@^zN|PX^_nY3)nH|`svY61ObkpthT8>X*2d3&pVIk4X>c4KJ^G#= zvup_V1~qjG$E67K#ica#f6pPQnXf+%hyrH8>N~t#1*1Q;pUW}9k_QgQKKKq%+y#^0 zdCOxKLFoAH^qj6p3c=s>t3!t&X>Suv5+u6g88Y3>k>C+ifCkCJBqe_-wsp3f`Gi~Mk zg~fIFm5FTLS2rKs?Fw8o*wsY>W2{fuBSF%`0De*E+F=tBZMMgYPC_S(rVr7-W7FC= z1=LcoQmkLjwK@&%9$tG{tow!Npz7F`0G5D2U$ol`nSq_p~>IvQoh{$$yJ%3->od;k6r-ksq+p{SEa$Lui0Ric2*Aazf71vDJ) z9N#KH#6TyO)0en;LDPOWt|HwVQdD{TS z75hi<3KhbEwSwO6r$;PVg{sgEC2<+2{MJmrw#833@sQ5lK1ZR>hsa0d*2L1GBcpzf zlWw$Pq^GL7efzn;`o=2?^tA92h#1XMZ=_ctDyK55g^esw-49t3VJ#%Mq)gS1& zy;xEiGHkMD1-yH=w`kJb=8a*g1r5k;SfMnCHt8M^vgg;dZHpXK4nMAmUI6K5YI-Bi z>4F-P9DFT#G~MS4l>)jHH^mh5WAaYlJsB9*Z2HQKPb;&w(u9?;_x87mNKZmkFn(IvYeKzr z#FGYhb)pv#2@75+3r$Qw5da z7j+(#o5(kA{i9W)owJX2bB!8W2NXAN z7to8L;o4aVMrH7u$1_5e5}zp)4%!qPd4V#iWaBA`H#lQ$fiwVI#z5knfa(UiwOFWL z4y3$>F->%ma5y6sc2j+c`xzq3PB*87!ziMN-K$~0NDa2S6`*jrPZk*i-^LkP-N149 zK@)3YPQ|ybv+Rf-t6K23JA<+>2C7?45gg1Eic70TTt(da$rVqbjw@oMYiRz+>< zK?>9CqUU=<@rHwvkvakg4yOkGqcP+-20OR_7Jm8!{ucpoTT3CY>n{6WcpT)jxRV+vpe7={iBl?mimsW`v zRCt|K)%E{KF|F%fitP0$DO!e=0e7pauv(KoEqfAfDnM0+u0usPE-R1~@llM7;oEN& zeFL|Qq@zOuiKTJIq-OO2C;gk8u1>JonBffn;0+~4Ti-@!#v7f?^sByFQk3ETMj38o zT`#?ETa?^FMIP z6%a_w#6hiv%Q!2&3Sdmlok7a^iAh^L##-oYhlC=kD3I7L`#6Mnc+B=L zN0N?_j{x%obpf$-|DWtL2GqSGdNrg&Yez3-LN`zHU>ru}bV(CD+ zRW?RhJ*yi=StnE+V2x4eConzOik`GwT0TGscyogTivPL;AI|$5<1niIuMdy(gOLdw zM8KP#kV*Yp@zjkJ|M@`^|LJMHB>h!i8urlw4@ANOScq2EN>w<@`9p#RZ0_yl{#|cG zti)g8Fm~oRCJ^UvzC;q|2&2|)73ZIo_jUKvSVi{%rxJ{?H6m-H`pIOfPP!ZwC%y zU(nXf7dS5ejG)7})WPHe82tuf^))*TGaYT3NhnpksJ;g0v?8!5VaKK~hg%>ZNQ;%C z%&_c_H+G3p%j0ZA3LetkqUJ1OjlhptYnJuC)(^3#F|{92M4SNyl?(5b{&6&XB*hQBMm>r$UWv^vP|#p9Q`}H+T$=G`8BqVJUm6T`59cVcQHFilVx? zf<5AP7uJ!qMIAP%urwMNCG4k7Jk;do^Kz;Tulo^;n$Tl*L*@QID1D<=V1N?2I+>KS zAn*+}Tf39?#6wfMe1DwiX6r~k3GZ&qrRq=mH9FGYJ2A4xyt*YK8!lU}lCn|u7I2Lv z&+~#e=;u$|$S8sj1%miY3DbB`>6Nhl!KeKNsH4|Q$*#gOwKt2dXDdSOHrq{=DZU!M zNyt28*dBahwtw7CqgOG22&=WOqb+1sM?5hlk@{|l$Gm!lv-FvwF5)AD-C?HsUB=dF zj-!m8b5$ED%2>Xl7BJus0fF(S&2Y@!M-^w@wJS8aEkuvFvz_j~ zG_~nI{yEeF(5*x$W#f!)E065qQ@d;v<;OW`K)%b<3O#H`o=+0#B~j#?rk+?lwV4rDj?)h3j?Y_N zZzUD`05_M0;n%2*0NAH!i!unUjr^^`ED)5KC%#m{#ii*y;9;dbrD0iJ3$~Gc{Qy=L z5)MKQ18y;tCor%I*->Gz7t!wcZA_Je^!zeGX{5@sFRN^S_x+k1^TYye0k!ul%D}%5 zpDi;?ukVuFL7mK+ITVhkpY;g$$_j*++$@*df{>mnUnq@$jQjD~bw(0KTZci#YT@8E z-_E{B8zK6`$n{dT-wc5<&k-)Y8Xdis()};THZJ+9L&^b&!!{YI*R(sxeMuG|_jLnr z0EoVby|2&G&A~SSmB9|V2zcV}3xU&h}(2>LZw;j!Rqi`aem^|WpIG~(s=gIpin z9L|4yAfE;8JOD{DS8;glqHpnO-aQZjSjyd7qPI$@S?OytcfUK5pj)W-+nwg-LzIhm z()%)vRnseeGceKAqQjYq4NRL{usSI19sEuUTV?bw(Vjf(BxO@E`S1xHF=_yFKSJ}$ zoW`CX_6XWc*tbGuorE44KW<$MqAL=_Z&o0th$UMNVJ{klrf9oS&b97~*S&Nx7<;`9 zNj0q7A6A`!z^tsQ<0~#f3BdU}KDMBVR)M(f5TSZLqu|)4+-k7E)+aCv%EX@7m11LG zm5PQ3G#C^V6w3~8N;g0E4sQw~zf@Te8HqBv8e57$O8!Zqbe|iIj-L8hogm(Iil}qE z=rx#cMG!z2CvqDr@C|;Kv9^(iEU?pJA%)bz>YjnbFUZ?E>qTDujU;jrtB~xcvLmW6 zhZA1ISBTNYx#->`td@@a9r>4cdQra>+L#@O`?aieIPXY} zwce;sPDGX|E5SXBNz+Tx8E{2|3Ee&(Ys`N6TFop(`4Lxv@A@P8iv?6XKpwUzVV|fU z2gO-3aV1Sgr={ty5j(AH*QZwx^H{>LQ`)zKCn~<1nqweJRIr`@R$GN z{CdpD2{=uv+0iG7VT!^A;4+&1_VshrQ2J-ByjCIozj3j~v>e5%@G6m9e=gL&EqCzl z;bdV0Pdi$uD;fwlf)3lqs?p-z?jlBzOlEXO5Gw)tDzj7G0|@q`(ebl`Y-8Y3qjAms18jY+miuxrPiu(^+v>dLPnHsw(cUe zrd?ORgmBJxWAUV#W1urDz#3&&FG#8S?Y5-!^k@y2U_rMLFhpwDe|p`pTQLq1%|JbR zk26?gavfN6csKT z-&Ni2-Wh7WY+pE?CR(FP)oy?8!0De;`$0yZM)T^D!TmL{W=}cTe%AkTGJ<%;9No#3 zvflH^m#&7o2(5*Im!D4PhZ^5@vH7-k=j5B`OTo{Q*U50&zOmZQkU=`LTtqT~OxLp9X+YN`7K+%>-+fAJVJ8q`Y6s+BtnMr`1d7Bg4C! zZ+N8ts5pM)TL-c=@XQT+YAK5Ra9wiT8EV5P*vy)13kbCibtVL+z_u^?WG}-#OzInCnXra>7IM;9xlsEC;y)2eJuH; zvad5L-{HnZbVu}B<@V3Z_ky~eGvUz|Oo2Go8<3)pxTv~SR;F4Id2|sa3S?LP%!mQz zs8I3X1o8A`L0)S8HvW^6MrZyQy4p5?QcE9kmKK5T6j_2-0GJfCUxYx7&+|a4l47E z^8bz=>RJ_$n;HCD_2L&laxK4!s&Xgo)hr1bpcY03(C_l%dVfXfAFU?WtEwMOCS}qA zekZ=Am~LG6k#i+_sk3Ac71eLts%`*_)58MarxHrSNy3p3uAWn8^4@(4Y|(YI3OI@~)%Y=yld#FMDc z_3OQlPP+!uABWVGx;h92g_7A zm8;~4fS7#HlV?Y|Zt87>ycD-R9M?_PiyM1(JQmP~s`x_u-it##4MT3rpTD3vaIAAI zQ3)@kFuWC;iTEyLT0d;DFAKL~T(Aj|xwMnNs_8ooQ#IZRQD}E%t<6A(i0i!ad@kp9 zs-?aZDc89pDb&yhU#^jEF8vsrKNtm4hFy{l_R<&m9V=*f#xd0f^_v1*pR~yGdu4pO z+P#fzM2b#s=7n=b0t0R*g3iWeX_^yC{wiT+xQrvok=ti=E2s%jaA+>pk3Hz!mfc-6 zGRO4NrVH(HrRC50jfRRI)Pb73uk-qgcVx8GFblsY*K(t8I0y<3DGSSu<|N>hritJ$W_+hPJjn&<>5jojA(v# z9wHe?e4@q&*4KzYRYO}s`%$29gl!(H*j|)7h~KNTSu(TJdq|X;&Q|FHsfbT)sIQ>3 z^60XWvtxyG+L5CTo&TMAf7>OC>kw&&ycj-{xX%`lx}zUPR_f=cO#>vnn@KFs_j!;* zavvtN)EB>ape{bSM3=MIqWqqaU{!1vSRHrUWE7kUR#ZKO^KxZ?LyGkmp`u8+g^>JL zGh&q4rKztK1kpT#iNl^G(^pXXBYv4Wpb`qs~mMalh zfkS~|5E3Q^#asVqE$w@4E;cyQiFot;yFtqqJa7E?kWwAoFNwTzFE-j>gNAsj&BnMH zV1-;d31uFm$r))QMMYmPc`#(>=1K=gBT}0 zbkIhXd0*DXzOC68>+Fy7@=~x#{3ea8N#xFr_Lba+nO4NB!8?EMnm5o0c6xS81y005 z1i?Ir5`vTGsp)R`ZYdUg#dEOmMs5}%;vMUnn;W79in3QpccH=75^7h5tEo0l6NTVV z_oq4E9^t@<$k9D&3R+XXq$Q24NX~jS-!k>I(TblqHyr23Mu8x(%T)m$Bx^pub(<%H z^0!TXnDSwT@4)qGI|37wA%%Wxpc{5_A?R>kmw>mg10BWs!6jOL`<_waqBd9U8V#ac zst_-WfxoU?S5eXPe2wSpqPK#E0&QyH?-;U!DDtYP;Ib55-@v`Y&uYb%*^5c!C$gv_ zGOV-&I|cU>S( zRO~n`<``9?UAJxK5hf$(@z#EM`buiv(b40-a6lks))HQ#$V3iH94l!R-#j#mp{#5G|y60tM+d z;Mz>$YugIQw<$>w_o$>(J=e={z33iHF@A?A%A0qQ2!tB%qz86`w_Mvw5J0{KbL! zvh|djdTV1OANVLslo|BfVT}H6c?kbG^{m&}q;~Xd9pHHR;6uaZ*$sEm<}*#`9qVLO z=jlg#xvK~o?+-4g{taD|fWfYo<_mYdJM<_6TB{PDu=KzOvR+4!+3^-vq3%vT9Q@k! zj-U9`SO>J*`K$N@xN0C8_*}L$LzzbSPP(4E+9jEC#0)Gh?guRK1>O-WAHa=t!(<-= z-PrU6Pe{M-Q-49aZmM&U>H6uW3$kq}yXstTCZWxoU5)***zKa^68!+QCjeMslZUEL z$RR?>_lZE$D%La|=Q4>82Cne?iQ3P%@di*JAY>qeW=+cj1e9XYHwTne3PIUBmtI4SWdpwhzoewK6kc`v-$(Eh{mp?sJH&uK%hDsE~gKdwjwu&SvY$c)tL)Hs!>ue^xhuUFy=f1ln zHLKnIz7sv9_2u^BwU@faensds&50j=?YQ40I$(f}>ite%17e+#Vj~qcnpHOPx3Rp8 z{-gKy0MH{#&_GJwDiFkdQN-H9f?oE`ByJYcE6_P>o3JRX%5 zi36-XkHeO7eFC>|5ln4LX#JzME-q8=waLi3!K!2g?cBc$GFAwsMVVe1zcVWC)Y7uMlCOM)_Y&^xOQV0 z(;YTMbk~kvEJ6%^m8o{^G=NG-K@G`oasOc4N z+`P?Bm!mn_iv9F*Q8m6#-uC6CvXB_f@VYflT9%aB)*;$tl{6@$6HzI>h-##yKfEB!j+(&#B3e*U1ETy~05#qN|Lt;?yoh)3>)t0?7Dj8F^#38AZ})_w7m8V zoUA9@C5FUOvH+_AzmT%gF5s*=Zjz*#)ZXgXBQCq3zpzH8icOWC;FQf{g|SMRYX~UM@}r zr{-@u*yN&m0QJgNN2mNI?|~=J&WSlif_>^FzE$jtwrX5Ld}N4l`#Dl3-~@U>i=6D$%9Mu{$2Ss`wCob?-lpvW3xCupC!eo=?S+B z6LoFxK>tK!G9;k(R>7f7nnAgIv*!?ByqNptir%^0_ipaM{Dfca?m~Z3^}%%}w+m5c zZj@6?4c}599$wJ!K_7E0#6{%H3cR}W2|CF~9L?#A))U<<2DWH2XdX2BO^BQ$4zS`S zgo44EGo6l?agfdp%TcoHCdsoQdloehBh7vws*n7%v6jv(5N8duq0{0uP3=N`)LOOK zyhJOZBawhZ9;#_CyJ~@~FQhj&f%Dvwe9}7sU#Y7QCNc0i z+04w0`}Ll1xI}#JkqqymH!?DMWaN0buNcBK_!upiH05M2ouIOCC zFBO>L;iJBqMJcuns;~!9_OH_CbuJMc+LTCnZ4l9Diz@GT%aCqw$uro8@)AVRE_eIf z2npfw^6Hgak5kyrbUMAn4WUn5Z3>47oDSxx0CEjO44T#ef%>dc=B6wni%Zh*G07oX zW(R>3LJuEyOYKi@d$#i@QU2WjPY?OLaFbqz*eYw1%H`GeZh-<~cU7pyk#TQ^Pow2^ zY3l6xkCoYqos_#~&+khrU`zBzny<;mlaHS0BlcA?9M44QvUe0n_hXi@%*5?tCO20) zDzuBMDLdvRk7upV@G(vTy$rF6xnZX8UNs@)wb6vz%WSv|MW&HRV9Q)xC1O>lDcWpb zl&nKhj6C|Q$}f|L=>gHJ*CC$X`yVCMCS~+-ow`0B=)1|-gr?WRp%Iv@hr5zm2pcis z8WP81ac!bHY`;^!4=1+<1)dvqaX*{6**EW}2U&mfzvxZ2P4XgGmM0#59QT`*x@o$B(F^8%!?4m&dh)0iH?66Jg)OEjHn%&cPSoV?T?lQ6665xi&v$)M2&(sJI{1b=wJX;8 z#|-i;3xDlcFz^cKvoLI=;=^aL%nIrW>vQYJ1FUK{(-*%?kCtw|y7(v-Bk0bN=9kU4 zXTVI7lpL-%lTh$8HoGYe_-eAiJMuTX4ZH_SjzlrU2&ymc-9#6(-%(5_-$KXNfq7yk zu-34-QX_~xZCFz<(kAj|{e8l@+0p6g_%&5m;BOSqvyYrrbv!skf>tQ?d@g&Zx=+XO zUt$Ao96?CejB?4_BpH;qHqGl+l#5$*N3K6$H+o%mS`I%lorjjlnC23Qi_eRT7aP=7 zoi9Z8&VDA_%!eET!`FcB%>I&HN}7aNqe^+-AVNzdLe5g{=>S(*XIAzI z@mxcv=?oqRp>8-izS#0dreNXwIUlv)X`e<-;F}QQ9L7c-hcVsfUI~ zpDTK8Hzi>h&pyokM7&ZOly`M~7U#dloL0f9f@VW{X0$KcKk;{ndT0ssX=a#ZVsTwE zL-$yHrNFrK@nBMxLD|R_AHVDtmT^P9?jydnQ=l-sS%-4RBnR`2L1}{a(eC1x@y&Dfq6Uu}+{lu`{iiOUwE+m}jhmn+L^mN(Fyk#6a`fs|o z0~55ZY>4p5x0NXVyCC_#(-yu-<10Nm!O;MvT7`VU>|93NKi+=&f~VHMWyw?4 zPB@Iu@)MJAiUIge;$Uq9?(x)Sv%~=1uVEvnOQ>QIptMJqAobK#G<1W-?3GHsGa42zSx#mOFjkg$+!zn6dq}viv+r!@WEcF*bTJ zI=f{nN>JYFAgsmHrfeCu`X&lnrTzv$?>IFX-ddRd3e<`YKRDo_WdGzDakHWzF)Jp| zP}X$C{_(v@1>b}r+*f1!PZCJ_I1k4iho+x&uCc@Cg7is?6`fe{K`3BlbN6SntH{ym zIH&np9Ce5RJMA;??`bApY2M=a3g9^Q4E}>@os6*>XlBz?dr>o(AZ`Gve%-`#R$Q9#_K#1>y?c8>ao@weIrgRj_LujE9YoGfl@#yH`@KTZE+7r zu?i)M26;1?h7x#}v%y6^P4+YFA1J7eX_y_Dobm#%yx(#J_b>Q-pqGIgR&f4lzA)7~ zVV|g;%;vKPp|&+`pLQkkCdJzHvlA%?z4bLmb;!v2$E6wUvr$6}@pMSMn_ZVeldZuI zckh(!8uoN#Qgp=C88zVB5kzR$_Szr%nitkGfLV*;&W)&-J&Rkga;+tSmvDQj-W!=S#i2CH5i?xs*Uhwz2xPs+g_B)ZBpI1Use{9 zo^b2Nf!eYTL+SFBps!cjoBt%L7&MR7-0{`mSP}x5ko|58ep4CwN>wp!28b}7il_D{ zQaoI|fv~{NrmHO~s^Dj_jE$C{=T2t!%Hp9m`~}d0?U26f`w8C_l1u&GZvFxj7`IW4 zOE_e66~;Qn=kjH{l2pk3f|S}zZJ)d{}?VOg5*D@^BzJFHr z&R@@m3I6|IsllhvHVBQ;c?f+v2kcue2)|eJ+`-^c5U1eMinT_ckRXr{);Uh6cqatGf7)WT zXDk0}HBN|r9fMm@=5bN8CGlNB3fHz)e10zz?{8xvP?ZIhjM3f$d}t5OtQ%&2MC#b+ zqNoLf^3)l(**d`S?$V;z4649HHx$sCjmwdaMqC}Im>-sR%H3*_(Rn6x?wL6M>}>1C zks}f57lZ$_z;;hoVbZi&DOx%d^0YWo!wB>ROh7xR3`oiv=KwwA06hzLF|oD96vgJg ztanWjEbrQ*jXH)|hK z_}Mnb zDx1Sy6evZm2ae&IOiCCc9bNHWOYlW(gBip!#oo>4^YGNhQKbD-yiydK?urQ($?t|5 z_2VKido^7CiLJBr;Nm?49;iL<&4zIM;zzSP|2aSshWrQew6Z)Ot1rd*gq7F&VnP%V z3Fl17z(}PCNE_f=IpoRzod*Du8m;x2s8J}UdjR4={cBXl6wWBXAB1cAu@Q$39|G6a z5oa?`DBx}iHpLe&w_0|4M$j}Bv(R-wFY-*TAW9+|&4X@lvlmY3ux6Zcb6LqG)=+`D zOOf1ZT>E^ULXP1a#wk{2C+!5j3lsphm_j~)4e57g&8&WU`*+&x67Rxs>in*$%s2!B zV0u#|XnbJj3LT z&%$<}o$NXphaeND3%K8QS7>VmRXSXSMb3v!#J5!l8g4g4*fD%w3cEAlk~LQbHEK8L z8ZNbu2jDNSig+y}vprioc654obbjPyV&bd+{5I?=6tQlX*h)gs)7w?nM}iW z^!;l>T`PfHABD+jPV7=zYN$>o!8ho^W-k$ZN8!@-QW5h6!_$y$d}^oOxZ`(NcVmWS z4DuPd7LlCEZjP{a`$3wxLmQCBz_fy^f>_zGPI3x*0*j0I(^Y|EY5rm}NhW0hZz$|d z=jy<-mlZdJe~yu5tc{JdO%u_1se@3n>n4@6xA$nP6r#Nr{W;)>=k=(mjkGE0ryS2g6L&tpe}Uvr+u*ChJttmU`oT`MOnI$tjdxmgO*KQI!Oulcy}W@ZPzx;7!P~&$b1TAk#iT9np%R{!}6z3+nBeq zpaoWYvdRkR-zN``B|wxO=x1^K%d_yaOQUZ%Q_lh}2LAQc2YW=INA^0vFI5o&IO}F3fs$js!x=^0qUj;Pwlr;cqcLG#zpgG~7@J+?>bU2~t8dE# z&5bPXdGW1)$s}CA`DSDTzUQ-v?X`5(zUY=|3DR<>-?J_3-2CofYh+BQ=6WaFHl9i> z-Fwa+S%j7^gOleoZsiQLaHaFu0?2n+E6l1 zEb5z!3|u0@=Sfltx7$|D0@>#+n%eDFIn&o^8?F#vkMmylcmE4S+2 zF%bV^yLL>$Z(E;1*$l0sAMkKjX~o^}sl=39c1^_K-SV+j34hk{vCgw-7E7khVGKdw z(}xb>!qJKi^v4agafjcwXN^QI))|`>}^SE(I-v4l2Ayn!6_o0;}3~-;KK(jp+vj7xPWjks+2S$-5~*PivN{@k4bw9Wx~pP1EgP4!FJbYHYtaV{(nM;TVN zS=t=?2~HLH1yr^&yK3THs_r?ZzfdmnvE(MQvN-LPXfu{g{EkkXpO{^(Opw^A;bDI7 zN2v4!JR^*;n`GlDZU0 z#p57bDlIXwTnBB9_H=HRh*kqq7Sga|S@Ya$SF>0Cd(=dwP3<16+S|EkQ_}+9`xgXh zb;>LJkeBUe8q3iJTqny$1-e+}8N3M<-}5P_i^{@RaXz)DFy=mlOqme5Dg?zB?isBIru)}QCkJz5U9?y1D`Sa6l^3|R*ssD@Q~fGce1#S zb)+q#k1~1%R_Y_3f37DlML@;?HXmUnTWmN@q@mOVBuBvrRa19lFyCGE3FS6>yZOs&BIm4(hc{;$e4>nlr50Sjrv2PIm~b-@W0tcQ49dw3mqht@cu zM<-5x>-nMUmgT-EFV(l>OFg=lGuhg5kA&>KK^ zu7f&VKsH^bqne`X{d|XKz8`7!JqFI0RYcWAHwx-qbt`y>IZxQ=D7307S;Z+`{>JJJ zE3f$v`!fP&l&*%qWM)xKs|ti}@bAY8AdPo`L?wyPM&0nC0bgf+Ex65RvRcfjTtcfS zAk=gu{W&UAJv?-_rDhC_luO%{61HEQhg{HQPidcGTp^T(RBL<94t37DPAwB%bp%eL zdv9)FU{vt_YGkEP{`oJKnD#N)9r4J6-p1V&L$7UmGn>PUGP?Kjt#5|JlrI9~LIfw} z@$fk}Enw{zWHFVG{-Lokj(KM<*#O1|B#jqJQ3$$!l%MH`Ukz$gvnMjO50jl+RDH9w zLQ_k^Ji;UB9avu1KCr{ipOH^CZx^X9Vc8fm3NBCRz|lJ(keeM_}-aEv#2l86z&2>$1K2X#uZzLk>KEdQF=i~J!X)@9f zZxWjA3N|=|mICNrDI4}mYRXfpg%UQHeu_WIj;6B#{HRS9p9U@tCNaA|y?0WRi4ov3 z{3gLK3&28mdmi@H70GiB{bJs^NO941L{RS_gk=zF@-KJ9P~=3ZxoIKKc91k~YBv;L zQ_-;a2AWy~)KnO3))Akp^b~mf|EVc~@A@e?02bz|o?JUP_pWJp?7Y5Xwkoy;U%wf> z;)4!PViiJ@D33SVw=k8RX5%*6RBqCJX)G9w8u_@-dCQK_DgZ}c`TiJP5>_if;UAW^ zVK1d|s3K5M=+73-4fKcN(j^rexF;91hz8rJUyD`JA)8Q+{q=`9={9$#rgtbX<{RH^ zM~(jD6yg_z&L3{z`-&J`rn@I_UjLFMnVH8V%l-}L7I8-TkeVfljuxW-%C=D5Kpd*? zQ0?{sej;{XaOltucx+TRe75rx)}oK5yl%>VPZE&&PrL#Yivcz3+j>cI5BN5-#UzbG zZ5(oi6;1x@sKp={c@lEz%}7J{_1LG54t0wcj@5Ke0*Q^s>fhjuQBZ?%#%NIL`VZMc zWRRFC7Q>fBG$!V2fENV+c*T^E?fVPovjLT)3&6qcC;X%tEVhHE_dsjO|Am!-V*XTh z6NiZrS2E)Y7MWWeBuYKom4-q*UwXSoBNV2MySzzI#p=R6Qv%2De_?;1FejFdeqwGI zw}(uni7wxMst`$d9y6h91|dIRa3x!t_KJ@JKqe+)DpxpcQ@;D9|eUFPa>6 zXX1>!zGRcyD$3@h5Jq?N$DN)2B#oW)4?hW%3-Y~h%tWm=33UlJE~BjW%hE^E)j_@V z(k~UNZf$7%#PE~nxVi@x@?+iENb=pvx~27;vR{!(c|C!7Y#f&;is3L_=EFhP-R)9dYBhx{Ev`c%vrt`(iiZ4$-5NZ}L z1YRcdYj4{#hsp&&^vhBf}#<72~etmWibno`2+L<*k=obnfjAeQSOYbfx0z7UxvR3(mP^OQ+D^6EL~q7xj=M zLM&}TbpK*H*B!<)hBQrgG(onvY=7AktsTFY2B)OnSF8JUhlFSyLq%9PoHYLHy-EjH zDh~Ge#5mZx^0}i55?phd>cE}A?fa=y3Rm06B{S^Cfo;2YwEnD`fc|t`)!B!| zSFep!6sgpAcEje)))*2mUQLf&Lh(6KAes_VnI|Wb{n1b6ix1?T-1rTj?YGkbNNjrw zOX)kkxbztyK>g(4n}}C;S)}?Ugyf}JNXbRB!L!}me;H?raCIGBI)4O$?EyXv8yQ`o zCif39fx0?rGne6(?)Up~2kw30lcmYrA3yOkesi-bN6ASS?34i+0*M#C4LiCJ*Ks=@ z=}@w<6{+Z*pdA{D$;?Kuc^6t|jLJ8vY!gfW7%byKqUek1o+6rq$nL_yyaL;gz0<|x z^(31Fmh6^7L9|`HO)i(uN)%qt8mALhe95Kq>6t83uDV5`Gj&;H86b$FAm2Y{XSr=F zyl=|nJLY~p@@(FHj@n@Ke~1KoipoU6=hS&GJA~ zCYncMz`u!i8>5S!4vE?1vR|WMpUfO!p#<^lo?T^&e)?N*5-1d&h5ouWGE zS?E`FWCUktC%_92Q09Tf8C~?*;@oMukpUxu!rj!b30;4~qn&kQClKA?UwYJj$vknR z^2HgoHe}Yd;NfP;MJBK0R}_p4FNtCuffbIcSkLfc+2`ThDVT9t>4HV}R-M1kLY8t~ z$;#Pv2NUX34`C%Lkttfn(ku4)=kcBQ8JrRJpkJM8SEFU`wYnepa?v)_*S{*pGr&*| zL+6N!^0=UuvE9Iceyh>$Icc*VKOB-uZ^(e;Y#3Hw2;{!F6F8uq52S6gfB%Z_a}b~` zvU!s!AxA?uoW%|Q_FeJ+FBxQqbFAPtsqP$i9mrSXekYOxm^Bo+x*I4`p~h1#q$* z{#I5dC@-SKk%2B0lNu!LY9#8`cH^}p#L1c9ZV=<&o$SC7FGQ4{#!g+IrIpouSPKO7 zd;@@JpQr9Fu5NS;y5DSJ4y3i^u<;X#%FwQr36Dt9u_yHpQJA!8+ls^$s&jdWw<*c( zbZ8el*80UgZ1TNC{!COPU{SpAQ$AX_?Dg?4!zwG??>2-wdi$d~c(I#?d(G!~{FMUE z7wd3%tWaQ;Uy^8*cERQd$=rxvUna+smiU~sNvE@6?I(elk}m|Yu)pFRHCCF}>vJZg zu+~!tuxhaj?L>X&)nriaJ}I`h>Rx1UUDY-wY^`(4E~|TZW)5+%D*^iN$^Rz7@)B2I zffefqz)bgMES}$MN1ghQ9ERryJ3j# z{%P1Wi)pVg5oM3Qn~|tB9n&%$hdfCk&dIG7{0Cu)WVS&5bp|oc&8Ev0ch4of5tLEf zrOcblOzuq_(hP3uR!G3aORaCqzwgQi4KRSbb%F)h;^;Dusl(tahY&elRc)cUN9WEo zH{8;wRB!|1B(;_K?lLC3354N#45} zal3)+Wm@y|(K(B&5?h+0$MvL1SRZwmE&Ce!;8FD>Gy~Jpz^#f2JdNzIvhA5~AUgcs*$BE;doUE9hn`q#z!KaQ51 zAF(X{$!*Og?XeCMB4zT=rQ(JZCJRfGeZ~s2?%7Kb$Z5M2Ltgpd+RpqR#?Cq{>aT0} zN_TgMiVA`>QbP}lfC$pvNOv=INUMOfl%OCmAV>_|Ejcs{HFS3j=ZnARdEax+`<&}K z|L_mjMa*7%?X~aqS@+%}pvlP+1M?CcEIs4 zNh|={r6$Z)OLo79op-SVM&Ee-T_XOAE`(Z=@vhoV*tn}o{|f;j_R($3IY3!%8}5`G z>ayP|{m~B-Do^P8)SbCm zH8!llyLrE<_9G=@LNhD@scmEIE6PAJt8h-1PANhu`cvoO>9LNaq-FuDw&45+9k6V}puzUwDGYo7IA0 z$X3k5M)9_RFBXcE?hL-JPv2Z6jSnEKL$xD~I}bq~EJF#2%@3DYgubOL`77}^!YT4H z#$83VhGw@G8l%Tz{3xj4UvsJ$C1T~h{7fY#M4>K(3@1-s*RK7P2xL?heKR^8@n5xC z?X`1RP8#rrHJ4ESlADU)rLOIt19NPml1z?8SLPg&Zrh|>Q4Y#7{Ol#0moGlJj3%ZE zy)FIKFC!lCF`~X6Y4U8Zo^c%Wux42Red#yCd=Ttsose7HK=%%_r{=JUq@>~wqT}UJ z=eT8R`}vpFe`P4yRSy#|FSl~@U8n8IzT!WfE!GvgL*KP-9~fsBV%l}cf+>4uhAJ2* zy=rmx(x-=q$3vM<_Ov0&>Luh8JXx#avg2EQB9(#|OeIE<5l8G!qU!I57+5ds6M#w( z2u|yexDxDt&wf<_vtPIMisqEGk82rlRin~?n}b~O|HxiNZUiwujX@CfT+gi5+A$4% zj;gt&;7x1g6{x81u`ij7i zd?ej{odaK9;ONj|523#Rp8sf3GDLL|tVD6KjKsHIF2}1)E`(LjKmGiTnfbfbE*)=u zrvw@lA|bb%BKga`=gq~rNU6d`Ws5?4A3UKa$#yZX7v4nVw^Y$|2-M6aVbt_A@|AL2 z5)DCS9I@>&iT96nGF?E_GlOC9MurDXOOg+@!ph)zg5E%1tVzXsx+G$Z_AP=@IKo104o`7@48p$qg zExX96$l!c`%bb0&&H^-~UaWXDr=l<0_qp$G&vvbFB~o&;h%MmC&2L~T z?55bBax3&Cnq-2fv?2id=>*?1;GPQkU4p|OUl8PV_!~p7spqtbi6B;W+4Iebt5^z$ z?m>vfI;nV|zD}T(^#wRS0Ipa8jKAXlIvJAUQEE(h8#KBvWGfD+2G=z5D%C%rmh==~)L`KoD4UoHocmk*V3~fI_Awb|MmnwN zpf~=m$`M6!IoN-0o_fDdZgNd{!6e`*{1-y*HhZ}B<* z(v`Ci|3$x92~oR`?tPTpEV$0F`_8Y8^KVq7PRdev5%@YbfMsVq{U9C~NWdHW?a-{C z57rlp_xKUz5|Qs}E2ur4&-q5061GS*L=DZ{ghT$9OBt!a>9&FuKz<6D!Y zbixuj&GKJHF;(DC&T9^2Z_BQuv^nT&Dzb+>a63BnvJ=&xbu9avBnP4B3dc9Mg&fxkGf|(V%Ea` zR_^fyTXjLI-?KUls5xIN>ogGf7iM4A>Qy3{TC#j8eRuQXo-S1}+o;m}&}XwEM?CCs z-NGV%CYolJ2bc_8h7oU3bC(!>smR{wffPo$eVfP%+uTc|5&oy9j&>-)ju6(?tZB7$ z=0d$zkth4jEz&!Id1_}M1$3OdV{#h)nY}t><~{0S&RL6~%e2z1Ykm}1;L1k%X6mvhcD!eu^anrYl0AOte&Ct9hMjWkc>Pc};R6f9C^D2)*c<{hH zho!Wp(BprAX!hUG><_JZL0`mRP{(_T-AwqxS*=E8dTI;9k>SLu37!ZRkJ~*@yIGnD zLV7k5O3E0@XmKpjUz1Mj=hE&NL@QHbEdje&482$3$UWxelkqAX=Za7yO^`Th_;bUK zvNd;I%#4*s#i1R8#VDd!@ihw3rlVLf`+&O+fA3UP-vC<^4Te10^Ns_RSjqsi8E77z`9<^gvdl!;;9SZ5W# z@Qa*2>TLv`4d!MA54&?5x!)5&yG`Z&ABVuc_c!Rnb|S!l=oen`#7&faRAGYK)_sSE zM(wMzO^Dy`=J(xlYd6Y(>2=#qjKgp-ioNwCyJ)Jpkry^@;x5rNM4D`%E)_W)b+ z^{wxsJ}!~XLE>Vi^T6;Bf}bflDX;YSDbbaP$;qpeAn|}3f@HG{invCN!3FcaRdkLa z^crpbh(i>W0AxVn)wX_#eht~t(%Xci0@8t-0qg6JA)jl!wV$LCb7Z&G=w31=-ITx{ zra1i>#g*iGmXj?81`@Gm1PY1m{J^0E#ZL!H;IK7uH&jR0@f0o|rTPUKl17jcmt>a} z=Bfxv1I{WcV&p#hB&2~P zEDU%=xamWFC<(@eh*ZASJ#<;#n0C`hYyzeko3CB|_MbOhKBg)HV+e4(73VI;WP{c) zP>M7gSqpGQ|L=lTbhGbZP41r1Me)V?rU+G_!o;AHE=7bgm@hF|FQQX{*2kv?$e_n( zzjHpV=0U3|va=W3G8>dgcWu8rHL)Sky|LEf%JIeG%{KPls2N21HVw2*fX1;8&rkA5 zCeLZ-hf|XC4gpCowQX7ur)i;B%FuvV*LH!`Hw7CtS%H}YK`tL5yUveq$eAFhnCm84 z=)(Z=wVTs>VdKx%t$iaLFCw7cSrQpKx-uY7B2WT+^pG(2OxWz~JyH!GD-SGL+a|1% zyaE-VStzk?Ul#o9F)7Ey)stT)1J6x{9+UJf-L_6yIlj@*44LjEnh3Cfv3$aNHRLaI zB95h;4+tikMK(h+C!Qumv*zgSv>WCuh#LlMW2CBykDylKak8;Z?5p?9eA?eQRSo%!mtm(xVxh>m${t4zr3KKe36OczBpEN>ps8>;BB37zgAdoY>}x z$vomWzsBqb!E~^aNnW&@jBapI`2B3Jk1lrF-pktrIQ7eoivu1yNlAs_PkM^V%8WBf zZ6ftnlvLAcZKfKiM|#}jLtEzy5zrR}G!I{Z51#L_#;tw+Dq_J;bnDL$t=b^#-A3%@ zKhWAmzeTcQCz!yjEbbWq=!s+6Cj&IwIH{9`ofK%^72Iw&)-vN=XGK50OUpWn`J_cB zxbAw|?f(i)(sl)NZAROhAZm$m;f6USW!RaFC393wvZ&>*8c$?gYh~j}K2AJHXmNpA zBH<-vSJ1z<+M6AnA{6)RU;8E!J_A5zT^ZW)0m#bhMd58iPc`qK&dqCy?kz}PFW09y zyTD^iZjXQ_P454FM78Fd-6u~E1DvrbJThUSwh_dO#$TAxYS{%&I!f%AoQ!IzAsOBu zX0O>OEI}=wu!;9qZa65`^4XCqx8>Z;bc4xxMxXlS?k3Trq_Rx+SN}~i^D@3jG!lmq zQ+_@66}#+X&RH3u^NKm+d9kx?OiC6PSzPO-Jsm2kBW7OVXU<>{p_rUK+`=7)h31WJ zQ^)Rg^-lj*KVr=aoREwBuM6n@H%coc>ciYDI7vKG1yoZSDAvTfjBA|M~!2bdh6x^cqUT z=6M!$BN285%v2stM*uUGZ$>pE24UzmbVzj2%!~a`O%Cag&Yne40kF*t5@;^`tXl7% z4{Lu++~KwYz{?#!lq`zuHsxmODOQ*bBWpb#JuPGG=*GdCC@nvF*_^e)M$tDt{5?sE z34Wo>>uJwcEphoFjc4d!^TamaTr02E-HkLWiMTJ$>cj21iB-(%8hNG;(-jiMuS}3D_lv@HA(i8ci-l20 zZa0>)U3WYtM%@@=BdzoHUFq4Mrl;TjL}ewDX-I&g+gZTp@7K%t&cSayg#6_XszkPN zUBiBUe?o9fu^{#Lb658>B;5ASY@K=*L@r6ELB4?l&wBSo1EM8;=g9-q00J_;ThbEh z*k7K3qT1`T|4hyVGi{*f@5V~8q_d|I7+G~sFp^<7yogrc6C2()JFW`^4B4XpheRPX zv~v1JSsDBE3~P_p+^=nBx4sh%|QR=Xsht zo$wOFqMZ#3L}IsJ7gv96psV6tborlArc%vLbo!l3^d{l(951E^S=deqVx>;{^oLk> zQcleypuuICmppW0>1rRH(QZqUnny=SI-l+#fG%W_)I3Xc7(MAV9N({`Ou^kBy|*`Q zcxp=QX@YRyBvI}~METX4oaHQl zaB&malN^me7XBue7_cbXI}Z%*704iR?s$s~b0Sh{kBuKX_)(XYR2-31eBaS=w=)Nz zeQAlmvCq0PvjWS_w)~hI{DB2(+~kTEs=obF-}@9ZN%`$BVVL~z_o{P=<}7$;XxlB0 zci}O9?^{!+=OY0uJmHtKf}MY;E8(Zwp_INn%NlC@z@$8IDWu4TFAjgbfS;LK6>+SI zeK2_fVPYt~nVcEw$dzy0cT#(r0+fVr|Id;T*o%ive2ea24uDtQmpoxX5hXO685?#D ze7+>(-AzD}cBenA4(j%&t~Pig^Ue`e2ducH#3D8ihf-vR zsrK|hn2{Y>sg)*?pJQst9{z_?hc0f<3El{hwB`N8$7EX`S<;tV6#9}hK?~^m2rD}R zrQ~oZ6n{I@jKufrz0@*2mMuqF$R5AAI9Wtwwq5sCJ7Y@_OmeIW3VUbyj~u*%XdPKQ z?BeAU2n?F%x=;&&A#)!Ai_VSXn)@+PXDa5Are&(#A0R-aYS~D9z4ooUG(CQ5C^PBn zqm}b5vBVX?6gE>c*`91~F#YO9gY|l@)CIJy?Sc>UtuDPqu(_-{(4z$*j9bpqHPhe znWoU{uWvF4_LaG}-IKN!S-9YmY~F1y?3v0WSBz_-{Key9Jio0iS>ZFT&*pT_xeVfit`i225@NwT&FT z*H)a(!hRyeqPd#0Msqy+8@CY1{HU(X&hU5Ez?Ocj0VPt+U|{{~V@&Z(2%_{k2p}~K zasd})m3-pFM%I`ZEO@7BeeLr&<<^DS`R-;?SMb5vw?ITyrM4XgyR82@6#5Ra#dFsr z;ZqI>`fNT?K_b7iWm%3K}f)^P$OAz6! zM_dP-+S+OH$XcE5{(d>lLH?DdtMJWmqHfW27S6`-zL}84_oDa;KC)#T3kj;QklAFq z&&iD~U9I{nu4nwIfKPOff3#=8fVK68f~wxLw5**DsCHSj80C@kxR6_u0 z2j|@%SeQrH8xpx-k1)CkIy0gONLr>t>m$ze$1o3LN=%l?gEDR2J^n$@nb75b*iS^n zdB$?-!E2}_#`^A4#O$mL%t!shVHy>z@zeRJ)O>qi2d~KqjHLK1e=*<_!7~Z21$XbF znlrIr{hub1eK?wf_amEh!nYl_Jtgd(+tPi zqDfI!gmc!m#nLCEM~XN6B!d&n;!Exs3X(D?T4n!|22_!>?6@tgZ%9ss>dek1G3g5H zqCoKR_l#FvZz>qTjAEmxTOHm<(POL~1~q`2%_y<^ehse(^Ei!C>} zBcc^i<+?UEswhbp)p43!J|_1c{j%9+DIF>e7QZ>ISUwLhGA-pJ;fYR+}_q?i=nALNQ-YiHxtP^ zW8(Rd1{fKH5qUte#T7eM3m@>)zMMfLU9!pf9EXSA^%ND$IV71=qxr`(=-GXZ=$R=>1r*TCm#N+ZwJA(a<)qQMRuhek97vs zQgt2w*ycQ_ntQ&|WT>tePW z;Af_`s_bvNr{U+u)E;FAZ!cgNN>;shRdZ>JbI9N9unbhq44vuBmelaCK?6wNaO9DM z9n*N=wxsgXA$6sj-?A_OY)Bsz54ATCtztqzT&aC=WL0+DE8o1$% zcl@e?`f|R>aAWu@Gv`pOEL9!_*>^i^zj`X=bKt2_el=4g@F*>g3`*EH!=3!wtpL_T z2@+`^p@0h1ZtWOvQH2@MT6Eu{7~L&sYp7PkSqh}GWNx}gFR~!Cw0Amm9-E^ne&j4W z35*jL?!x&7-rn2R*LJqo;q@*dRH(eoSdl zd*%FC(_f5grIue7Y-Bii8&_S&r=cI+dK>(Rs{1HPBJ`%#;Cwp2aeEe8%#mL(AJZz0y-eW zVpX~+hz|(}GEz@|A z6nFZNFyRn#>iQQO^+lK2I8(eTaL~&G-q_4{-q;4BRPI;z{^Aagn*N-(-K}nq_csHQ z2MD+m$|loqA!#PPMCt&28vXhN*sB|EEJIRucw%L%+BIwp#lb1;PI0sh{Yj<##<6pQ z_^#BYQeN7RTSNR7cXCner9Rs}>K+aCLwFdNVeDL73<$()ZJK&v98SMkgoPCz^#0kw z^za$+b3hu7<<$45s)U8HMb0sI7Vr+ceO{-9!fGpE(2B<^$_^c^wOj)_T*|vX>@=y9 zZQ~%EXjxfOx)ow(Uvh2wCk1_F%-*6o(G7^b_ju&&l-{HK&0OkY+Vz*s9M5rbinYDH zym1H(f(oK_80)8-r)RB?Z=Sv`(Pxh-$u!v`5B>V5{BB9Bp3)$KT%W_GZ@LmNy?0}> z5^*`BK``nFHm=XB16@o&sxFRTT_bYk<#^7}QaqNDDMmHkK97x(-kz%P`(b}81E9l` z9z-y-5GdQ{yHzD3JPwZk$y;L2U@XKz(ifry&E`=^XyV*f)~44`iG~Nj0HnTmnmFY) zN1*n!@=L)+?}&hwL$M#7qSeUX9h~#89b5_QU=5aR_=_4IIhORHGPOz|2_5cQ|djcfDt{=W`tz}5PWV)=CRnjM&*xoqZquF<&HyQ7R{(joKT ztNL#r=SZR9|LkS`_pSky8HE3DEb>laDU$wwqMLW$CK3EkCe(i?IRAb-7wbQ8lXuQ? zf7=x#GGkx=gBkZ7xOg954^lGiN)$1~&{-={yy)0>=b!xdX98cEi2lQ04F^oA|NV3S z_1^&{2X2-kw6aNB&}^lSFzl-dRjLAz`v6r z`IKoN2dAaCT%^6-t~s30g_k!{k2aWu80@7@*OoDt$J3+*xLdl$Q{rgT^1Dc=_V?Z^ z*?%69`o))U75>m1jVsdxK^eSXBr@@+@OKkUnzqyubKI(}5DWKH23A8Vr)mxVpWGvE zC@Z;}*SRoV%==;|`rnI^%w6qPj{TvNFG zF-nu`_&B__9lbQ5kCdi@ir4ud#HK^uL^hHdmig@6Jb(tb4x?&%N$tePgxk4XaWni= z*v+5mrF8anSqn)z8ZRFKk2U+2ALv|vI?yp$;7ORHCXb-G&>o61aj)V_xEVAgP=fxr z!es>&axTZ?(nGEh^floF%QY9Xe`;DfbE<5imfkFA5)aC$>EkkgKZyagd20_IHt$9u zccXPezK}pLMAMq%I%)Y#096L?GM{R3P$4)qhqUzdrksClz~*(G1YE|8pRh&BJt_&g zFgBSCV0g{lzD2x~@X8{gXC?pbuO@COM2q#d-Xacmrl`|0PcWJN!t| z=n<=JJoeh;ha^MKZ=}+ys@db8SP5v+0b7DfQIhYlWb4p9QLjg9dA~|Ct9mwec&Nx! z1^&Exkf78#!u3GyA zP(D#}&|WQ4z1lPnzC#xjS%%1xPnAf$SGYgAD8130i%FiCPgLRFTW@$aV9o6xJv*8X z6_&!#`_yuEOApNZ32h`c3;WS~7(yavh|89btDWRt$(29XaF-ay!CO(L!#w<#k-r?$ z+F8Qdlu)f%(@ruo4qh-`WMdddyX zyS@nTO(PPDUtV*SUB;r12)LF4%M!kyUtK(z^0G7h@vTYK;@VjUFXbGPkf#2D_+sO6 zU1}gm=#eqJ$8EN|ti21c@~urj9q*C5YrscJWfdH~<(hXQg)a!^zMT$dCZs&q*vHY? z`0adEt?wf`l12SBFo|PtLi(=*E3a2mQ0+5@)>G5I#Nsx1A+kYsIECn!=gAFQkT|a# z8*%8iV(Y-BgMg>jvc(9|_5n#tvLv3k|1X+u{%V)zVCBLDr!}FEJXtbJbYKk8?~R(& zHli$o?3-3(J67L7o_E=DUG!Ng_Ok~h@`jx)dOUwLPH>sCKxVeh$BBZA_SIN^?Gu5N zz*PU1f>odJXNk!ebi|;O`5FDw0%ZN}Va0&j$Wvty*VPNeY3j`B?ln|(1nCd0Ni@~y;jUW)2;N8k^| zyqg&qRRrXq*|9EJUO68_oH=j8Cx2n!VXadVO6ofpI5aadcBtCUPX%ywC#BD>&rcZ7 zXY+=?3M*@+ZP??Gg&2|R7H2O_1v#}}#>8BBcu3+HRFl5M7Ge{!F7baY6X^q(bhTHL zc<*)$+VTK{;9yS(PcM^UOBjx)A{W-#N(YsYQ@mpH0&(I1ICtOlB|5{#4zSGd*^~r|-Om)>f zG)S|i0JDvaF*a^HT&>4pV&dMfHp^THJo9}BYMl z3XhK9Nj@J8OCPYS#u8Y%`%pW{Ca>B}wm_-fwwrQ#jO#>FaD@2^xb5|m<}UIp!i-{=Gv6LlE+`z%D|*eOO4~g@m+*2bwv_WEU31p8j~^%tZd*sN4;T*w+^?wN&)QZk9Dwr8#7)%-&%|{P`18t zA$&O#TrTw>82Vw0!;}w5(d4co+yq?}ktdM`^l`>K_#%2w4Xmt#b>i?54P0njaCtL- zbCzr5)OT^wz&tCUn8*{GMNeTD;RD{bnlQP!JZUpEWh0?uz##_vYJa%6Aiu+(<0)-P z=-LeGY3YTwyT0oUO|2BBCR(;uFQadKBvhc=jsk zpn2ol^X>i%bOTo zvZw$9S52hQFI|mv1Z7q&GpSU^bxtd(5z;hGCxOb~@d^yUA%Jo61gq_0DH4FISJ!bkWeIo8KGD7g(q$pK zw<*v7noW17t_~q_{CEpOJOnI3&siNwu-j zVqVSemwRRgc}0b1`~FYq@#@Z7n}>$f`HRNK@41}Z7BSJihvY?FZoD272e!%ikfdt2 z{o$aaS1o+J8gb=F_|&L?#R4MG`f$Q&%nE+AheTv$-hs|N*#-dRysf)R4E}As-J~0+ zl{A95R^;SQgb32v8k8(P_nU{lk^AH76zZ-hk{e$EvwD~NO(A@DH|LUuE9Dm-CZ?7d z$&MvDE@#S*uUm^pE*3*uPgSfc+$L{Aj9^^y^}p_geJ`0O+6~!DMEe}T%owR=4O(c* z+wUedFEFq0vAngsNNjwiFo?3)cbW|(#D!&RHJYAO#*fEm%G~VF?7uM}q8;LxrZ{RV zwbS)ey?5{S_@$h*252RO5K+8HmHD9<^Q{KaFU||sq1Vmh*0MF)&`SnMG+FJuL)S^_ ztAK^Tb@s5w#wSl0AJ4oI6OS#v@?TuDM)Q|Q>^*k-8Srg7Abcb>YIWKvFloyP^<|aq zZ=@~#6mt_wK)&#Uz2#2_6&vh5z8j5^<8*V<&s_BCUMTxiHJ$@m^cnY!o~0AI>=eF0 z%?O(BoiI#6%*u*?pW?;!oc+0MGGLyRb=87KDBzF=Q*|*z3FUU{q3j!&jaB|&PXsB0 z5eQ;z%e0AZDI(8WQOg`I^^cjrtqbh&~C?YrTH-gcTZ z^z6ymE8V$_$OhNr2rcQ@m43&T@CW=;Xj*L$G8l65COJtDw*`NJU)?q8c`}JsQUO2e z^M0{eo?Qj7|BLx7oc2ez&=C9Ojs*g^Cd<%>r(p7KV_3a+_M5k(fosg5KQnM)*ps1+ zT?ep|>x)+l50=N)NHEIXUSsVdC8z=86>cRHW=}dW69r3Cg~DB?f_yd54M|h=_Hwr+ z_9#0I3ta_YD6PEs5CqfJSeOl?r&clB%M|u{H$`A`rAU%n-@sJ0H|p&FiC#uup-|8} z-0o{qv#^iwskl!V%ryBd+~fM3Rn}rFb0$N@ zWJxDnj2@5$DZ06Ji=n#OHNr!qrp}vIzF)sQ<7m6LcDChQb!h3{Z|X=?LMnkybM(Q^ zoNNZ@iZ0&O3*?wmaoJ;e!mpJRfI+w}Fu{8JmTh+y79{5Q{!P!wN^oS`Py_0rq=aPf z4WMj_brv>!lVJrti|tmekDTR*Klm0iZf{j4E+Q~S#CdQshrW^(D?9s^I%#7=_vUrg z4M71vdEbeMFg5k);qau)-;22U8UhF_z67hzwd7iFZ(qc-lOnufh-Co~avL|ONOPggR8Tj))nRYr2k-nL= z>HU|@baqV{L9O9Jzu-vL8!raUnP_9~TfAq|oy@M-{ik{%%3!8thf^hr6bcrO!h4t( zJO__%akChryW&<$o%qu+*&B4q-44QxR*1Gm-06jP=Udvgzz0{R*fqA+@t^xOfLp96 zV1?G!3%rk<|Czn8j{c{hIlv6$1B;x-N$kjZdgsf=Fq6BQ8+WcMBq{v_`C&Q;#nz~(Z2xg zUQe&=o{<_c0MLHjs%xjq5Wdcyo3PZdDqM7zCUSZ8bf0aHv|hUNn*I31Fcq>4DU<-9&QGlNIuz6U`UCF?m z9j1kI4VZ1YYN=x#KL0q_jxL(H^Ybxhzvamh4$qXU>T;Htt?veA_I?fmJFRYJSoaET zs{WdE)uDv1;rrWeRV$9(-rhGi7e8g1Xnr6+P7ArY3FVb>VZOx8aT2z&SJ@cN5LE}E zRb?amHu_ze8HD|oZ#!8vOZU)M-!gQC_nvIqW6nd77a|)bi$jFzX$j{Y4bDpe;R0yzpRJxP zTIOF@Tpox&41uRj4#_tUqvba`GOJj@={!YzFxW%{=y+je0W^DBxqvN3?!bZ7evMMu zAN$EH{XmWaLa+4f5G&-F8Jsy?2V@jK0I_RB9eEzG+&+Bu3O^wQMm{6cu*gEzB9#^Q zW;s3xO36TFCu7%2o6+P?|D=DX*vjc-@zFIeM2MtKsX1^ulIqEbS_Q0cqi!6w|FQL(Q_$r4ADl z;v!2hvb;*8NKZ_RnTz-a9lMONEvv>@uG|d^-MjbP#-maosj=kFSsZ}9^`g(s;?-ET zWb^<~UE&&_nr)U9ngEabVzA5U-{8d*ZIrq*EtPt0B`O zm6cUI%hkHU-VVkN{>>t6=rg%2U+B@a(pdN9@Z3W5x7=c{j71{h^cLIp?b>>k?m_d@bF@&R_JJ_Q!4$y%zd4stSw3>wrjPW-G3{>?pFE5(!! z2a46RMmqp(kK5go0qONo7|cofQGDFIS~<5BzKhjwvH#@ZcV)7*><7nR9gXjy$2CeG z%WYek+2wQQ^Y2sAOHN+RJe6Zqly9+pl7AO=*RMWX%hkr-yyFQ?fUX0RmK6~Nt`8;* zd%BiCB$gR2ebR)s`7mGN zW5}!HtQ<7z*W~PoZ63ufW&eyu*jr%%O^FR@kJzmHmZ?)MymmYj52=@JT{)%~Dx=1S z@AX#+(X53e`Rkfy~>TRoY1QSHN z`)N(qi#$(e?P82Ah46i3v*$mi^o1wc5^`!$a;6-r5m)vzu;NLEv|n|c5BKz{`_X@o zO2l#E4~ZH!zFDV@G_gd+b~p6Y81&COiB8cE-6722Cgtt5)>|jZxARcpq&T1M`K;z1 zWmI{&OL)g+x=7NE@=*{>WkNIhQzA^*Zl$)e+G?d5$Dy8i>D933an-~Uc!HZD#^s-Y ziD*a!%)=R|YN40>d^GFSvL`UFEs#hWJaEt69w_{y#|X(p^auk8j2QnbY|3vW31IF@NcH+(HBXk14-SX1U z#)(6WqCQ3ldv>CJP|I{{0|ppSw}`ewMv==Jw7o4b#GatAzLCa=IlColH4f*EXyeFS_*~8O zR=M!tEL{_@zs^P7n602HiN$UwW6sa5+dF=CrU`PEb2T&W#;uXi6FHn03tvcONm4(b zP6!@-ap%)5=ZcWe&zkK#Bn9C=3cP5lcX6 z`{z>HKmxiJ0ZVNurYADsFMUIAHI)fup%M&p=p^M_8RNF%#YP=&olmKo0{$6W;vg!` zEIg(Q$!PU38*NbVv)!QO2LOiSdJWXDW7t;?kiRsFP35GD0d*n))I?s67m+h-O?nMcj zU%9XN$dDo}o*6-~!9k+WNe!|cGgd{9{erDeOTt9TSw}Q+-0x-MU~yBv>$YG=H?A)N=c662xETp7DY=~ zpqe;zd71Uc8_(!F``9`EYdc(M1NJPs3@P0eHcH%!?B#FfrNP)fMbS%al=cofPoeYR zvmQvsKgxz3QVw_w({~ObHLo8!SzPC_^ozcm-kcgnsMhnY$a-DQ$Ov?K6@fYo6pO3C z5ELBRe_+9U3ifStuI4@dEcvR$`Y=eGJ7J|(m>yp9HGRZLDkh3BupkAF5>Mz7Q+Rt( zm#wA(mruVgXot<3HUsX&RV2nhl1Oe=fmGxqLe|Xj3g7{!V217i6k3-|@b7T&1 zFEg)OpRVbB?Ifg6#z1t}2g^h&gpBber^SY) zl5&QQpy|tZeh=|j%`<+9pdz`x7BYvObb%YEzek>&VN5L8uiO~enV_FVVqBk;;~4n> zZ{QfkYW38Y581A8x`)z1ETiPOKv>TcxBwHXfbDw2(A-?MF=|7gR(*qUH7)yKB!wAn zgCi?DxCqU>^s$o^)!>#12L$g8Czhc*#zq@b$uPB02UK4~I`!fttEHRMQKMl}S%3*o z26dNNACyB8a>}Tz%y)e1@+rmP_@oNa75_+J?DL}fyus{r14Xg_Gs;~p0btt#lzi|I ztnJ2hoY_jVSdux37!{FJDpaoV>JxLu5;J>Glco6iMp1v;7ik7^O^*B8b-N-eNSKWD zOTzbb(>e{k+BZKGZ6n_TkJyZ=8O8nPK!f%eDeKX)8|ReX!~mc-0D??C)Ss+-y>mdi z{61Tp++k?ByG>*Nh(E_?B1tMM?eFG;WnH}MlmFY3%lUcom2Nf>tR!r_H7B#8p%f9% z4e{Y3qW9l6v9SAkDf#Z)mFb@YH!ij~12-<>+Wn#D(wnJ*q)EC>0<){yeIg?HKR;MP zvAoPmqjnM)S`KiJiuV>}xNsZ+ zs1RV+aeaAF!@fSIH+wZ38yD^Z6RW~WM~``DD5h3N(!ESWGZfwytQ>i>%*Cx=6EZd? zR&%t^$|TMsg-F2~t9H*zQO-@nCqM9n@i0tD{6K$vcb0F~BEg(=Ac>Y}yJX^BoDk>( z#ukuo+oB`T9xf0V$140>dPR%wswWb<)8PpIsDVUmJ7i4%x<^zA{*CVsea0nz%Er3! zu=mpE&(v__^he^yeuo$~XDeUQ&OS9v|aPs#NW*A&!RoTv%hn>U8o#T?; z0>fE_!P(ikzmc zegk(mS1df0cH=8HE0OZr51V`BS|Ol+_UH6^cTKNw%RxdD(+bL~{>6^)Hts*HyCs+C z3DGJc<2uTZ*ijX;WzOXJy)M;=TgnH$HUwYVCGWAyr2-EEkzdu~i0B56o$aV^?zP5% zsGdU&A~D5O&Cb4a)&vNUMraO!Sv*4@?ctm)s2~?@Q1}!Q0}7{Y5#6YLTKN~m2{&h& z?U#COIvZD4-H^WyrSFixa zraM1rODeGZ%5{o&MqIc|O}y6@_HdIkT_7Nb6lknNQ zndracyIT(<_>e!NEW(5#`b-^a#1ZVjuG0Q(Y;kKJl`b~Ba^-mKHa)geNqCoK(f-Vz z=an-HhM~BD6H4h{e%^)%Nx;ur{LBF7l+ z_kckzNalc%+DC@?hT=J6D@!bNi3?Ifm*l=`)71h#4Iz&>Jc0eK!m=tVP=yD=n1X)Y z`;6EbcOm4N&A|D@h*A&?cL|BKI_ZZP?(DryfV4Ba?qGpT%i^jx!9}Nen?8g8`>r@4 zw4&CoZ#T1jCBy_N2K(!wZypUU9%dzJZx0-r0_~8bvzvAd;Zk6lnWpY}>C@D|LZa=a zy|kk%-P^Np&K)>lLgXUXyv8qbv5UP4IY#K6KAF{b#IoYN;PrvIy{F?m(CLtzc@E@F zwtK+qgx5EZ-LE#=I@kAPVnLNP4JQ1RLH_3mxCOz_4A!ZH50x**6I_-@!i=}IP4DBM z)=?e8e>z@-``kYr>M6Usr2=YnB|$%{3y$pUf!m6pNAAx;g1x=W_JtOF#GW;pQb6D< zuJD`&b_Vod1VW5@H?ERJXywK*s$&F1;sbSiPVy!-Nb6-H&SCYN*XmJ0Rh$gf-w@YF zd+c2Xs5N}B>qO7Vg4cG}{ax*DARiG--dhbU&>LDdwfT$6X8@?Y+^a6$K0)^Anp~uQF{rTs>c6FU(N3!0{s)&7nt6H+4ABysz2mw3&Jx6qcLm z>Ji9}@yf&Ut~2wG^Zm*L0sLI<73#E>1!Cf?OnB`H(@iYk8GZg>_SOW{ByfN zxO=-5>;K4xoA>^6Ft*HBR#hXojD)=%F;l%3H%gX!Ub zXB&ZiT=DzYZsG#v!QCc|LYafD>2WG<$4LnP-unzjkAtq7CCPr5t)fMBDcFHhVp}`8 zfBg=SRvYoy)@KQh?OAs-6dKDDy?wxKZxk06w+4&@=<-BQ)r~MV(#Me9Z~6&(g} z&n#x${ZY{R!_dd0^XF~;QkE?_$eN34!iJp_Yi{wVO5iB1L~%3aHE}XU^^B0czg7!r zQY|ibeDuFrd2`g;%quDY-Z6KCWQOXt2}A#uys|CmvLNZ)(1{Y9J6ryzha^1QMMb3? zH(ti=)qSFjsi=lTwn^P06~{nT2619Zu(JXEr3KeO8P|aO2OGNeEomc1DmmFRC-U@2 zC6UV_{eW2uRwfQdxnJ?5z!TeuU(X5Dz;E|qrMM#~6fYVx6-g8u)B#DG-=xw~fQ~q~ z&ms4Vi7}SkpDy7d(@eg>^tyi4YZ$Q#ADA^mYNx zF0qe==|u>~KmBkaT;V`-1~ajh{bv4ov$^N)q8s^VA6+EvknTxI7Eh&5a#4|$0nW-3 zzp=XXaWmzoOxZ;A0fzb#=}N7LN)TqDq2?mJujL%yyP)u#OYcxvW56${ZGPFu#L5M1 zrtN|7Vro}J8L<)NRQ(n(Z`c?zN92>sSS=3)Mf$p_{oeDY)Ny*sa zVM(Vd+6?e_KA#5u&sj`zK6Vb~EKSJ+?_wtPS9yefe1mxp8sh#^`{kt!FOiq< z(xB0T&t2ZG^x*2!+4#|Tqnz-cPwKC(-k{cTxD|@#nQLBur@_Zy78$YZtCELJkC|{a9ktA-jP5Y+}0M2e1QE6g}rR8I}h-m_ccU&HcxF!6A{Q{6`J)hk1UYyi>Wq^%_pOo&s7h*Jqy z$!I#(P)I~zb*Jq>WDgK^{ufSZV%tmNOyNih%`zJ-AG7ENq6Uv(p}OylA<6m zfOJR>9n#(1AU(i)>GSO0-p{-D{|ldHhMDtP=h15&2N;W-Y4D&`3?@Vf-{JOS(;BEe_U7hBPZ@rSmeN`DRLx7&b3!rOCD{I% z9M--b1+@U~HhADGM9h3hYGvYp^(9D(+P+Af>Cclw_oZHmUMXx0{n3^47o@4c(940nSgQbv(gqS*2HnUY4-6HgzpfTR&5{aX`^R zH7lpFIJ0kGA*paqeu!2bMAjU**<8N4hjjEaYjd>JHZ7ifhqtDBuBjR+^-=@A>mX(P zj+&Y}q0816ZwMOG_b;MY6G_xV#b+z5rJ7Y2yRfnYtd!kY{wqb`j>{i`!r>DyrT60}6$NuYE$_ z2updw z1bY>Rv|6r=9k_u_z_#~19ff8&2y2912nt|`y2ea+Ja(GpihQPKy4|KxbE(;^*TDS_B;2 z53P3R*IZS4W{2oC;j(QcM*e=bNK55&M<+XBOdZRHto94Vw$p>OAFVH^ui6M#ZPe*B z&K2n#D5$D%ITEe*kT&um7kR^~alD}C9;LvFA73TJ^OIbO=|XoxKU?W8oaq(R0lE`A zm2%^jmaxtC0$lRlq6}it=zzy7Vyu}_&4tleRvk`u65rtt7yBZEy*WLGhl6`J%@PNh z(z448$jg5XBYbc}LCHT^;dQf8U$EY$p0Z;GIB&G0xU#NLavaW<5B1i< zS4(}J6QADmReLy&0&3F6IObGw)@!6S*D?sa!!Ew9PdZbj$97QqnJ@f@+JGfy#keLNJ8?6? z`1EHVH7{c#j0`?o?&OScWe^bFDadJUy(^)bU?7F~{<+(ky{Ztt-x2ImeNOKWzhH*; zrqY~IM=L)sn-#Md2B^>UhViozfAs8dey-Zvv*?q8y&2S88EyDP^3oAAY@*jrD90!| zFW%?3CeucAQ^N85?N0%B98Y8R?!sRvn$Vd;QXl`9TpX&!{ee)Ch8ht}f4`fZZUOuT z7K5M035x1kJ--e~Urc0dtz%9pAe1FrmA`#YcuQeK# z6jwc?x+E%9jPI;lwE=2ACYOhV0g0lOwzn6b%q+f+wnlC`vmjM&#=rLuSDoTK+zBh~ zTZ}7xT~|2YI2$~5M6O-m4{x$?sLcD(y6N0~q@b1^AJ&a%_tH<&#|G#9H_+OgglhL~ zth$cDtFYEISABA{&F_suH*U){w_jbhBaDqaz@$1)S+rWW3bUjU&f1X1axn^&KcEXM zH)gB~;D$qer~~p+4?b{AsDa+ufOrcG4)2m&Vs$E7o8^e3eiv^7<>x-k!q!XLz`SzT zyu$GL%aNZm?0q}$*^Vh>z+$p!birdm{sMF`sar9PMdLm1-swh8DPJ`zj-zi@tZ??X zdk3#3aTluG@pa!M=)Te7$jyH!?ePB?{>yyR$RNa-MTtBaJ(CX*>DHy@aFBvpUh^|1 z%r{fdUn}+g0OW~m@00(ed4&U{_fG^%Wh_rbe?Y6Nm&v*hJ^ z3?#(iQ%WRe+=JQKjot<{sky~gAN4FftIkeCjICL zo&l#uEzdg;!K=p@7Bjv-^-U4YqG+~nQO#7k*~-x`LjWnYgk$o|u0BibMR*!Ltq^AZ zAwNU75o8c!@Ld&+(!@yYmdWl$7YN{@Ve$$(c_Se)@TC-!ach)t1GJ`Z1cKTuF?zY> z+U3brRUbHv_fa9Q1*!xD$^F}N04l_w6s=!+IGw2$n&iXbn(6mPpE%P?dwaoj(aO~G z9VXa7wJlT-ei& zwH@?u{N=$eSaS=evW_OK4T;h7564Q8TAoR(4p{5G>p6w(gKxmv6(LY%sR!lahoMMU z=z&}>w^5^{z~3DJXqnKz8Uo2$BW{yw&CA?gq?vYK8=MHYZb<>%Xi3zoxll@+t$X=+ z>POw7>Bh2%tIzbh^Z7B*$u9LX03+kPrh5%gcLd!x`TvEHst+KJE6YoBdvP-!z&#>v zjB+rLlFt2%U+|^=;U!vo0t?u&M5QQ%{PxQ4rP1o0e}b$UiQZNM6satUzmpDcV87xy z|7nH#B~kb-a+-`Ff7v2n6qVuzwEx#?)>!Mlq~@0t6F4|It>3O81KYTG-f;dcF46uU z)CQ8jn$OC4PH5YQaEdvv`nAcnu+uAn(9Fzdn3$L!ERX&<+4UE?ydknR=W)Nj&WDfV zUCQ0#|0#-~{yzyI=I4Het56WtiCC+wg@V}mIZt9{W>75V)k?YjX6p+Hi&jF=o8n#e z#*od{vPqhwKPud~RMP)1LP%o2+w)+zAtFZ6mlAvFK)<|iY=$L7x%c;_#PoPjT@%;M z`9AmgQ+&sr%-e5(fMep5)yc?HR>Rd(P~an`3>_NM^Nuh^4z{vrG{=Uj{`lytZ{O#& zIX-I{>@OS5H2qVj^)>jpqd4+=8!d6?XBcQ5?9a%fZXdBKPcj*QGBOVE&`GR-L}*%d zEU~RDN5G?*7nUQqlJ2eZ}A^=_gFisu_|R3NpQshu)52KcwBvpmPZqokzvlr#KiDAQ$bPERT;B@co^mvNM_j} z)X`&31{gOqsNruBfT!JA0LZIDiK9WGy73nGGf!IlEt0Fg1YmsmA`HCt4WX-t1{|1I zw^@G5Lw3KzA8GeLK=BjV1t$X9>M|~=xTc(hfoM?5!K=zAJO9h)7u&5|f4te8K-EA5Ld>^mOchO7XwhGtjHRK#*_P=hrE~82x{J&c8mkJ5BA+3I69l zq2LRZ2FNj9G)OO%#5Mg0@zanyVYz?4HSFUo#<3WlZdzh+%5V2_1qE@_P#lDo?vna? ziTL%=RlEkwHT4(rR?ucZEg zaQv1o_~Lh%T%TgOqN0>fG*-6)d$smcwY$L&enMC;Ma2?Wd|wy`kDVatQ=O&sQF6uo zjpWRMRQUv#*pK_LSN0p=v2i_2oD=aO%s4)KUK<5@W3u4aZF$Vsz%O06;O^G4>ZNFN zOEYC!U{MLA;g2!prxWNTUQZw$F@4d3$bgGSlpsyaF#WqHn%_oV)gY=gQXI+0SNzaE zK=~!HuW2|R8XcZ`WUMMTs}&YIOHwMqZJsM-uAv^L!AGzX*h4-_ZXg;tGO@Ws$-Y69 zj>Zy@(E<*SP~&N;j}06@@FmsT=u_C#+@y8vF%U3NuT;tXsHC$|wJIp5;#>eU~aTUtNb3mV#7Zj^uS@ z7QB2G%}_4U$<4M78kqBD%`E*Wb>op$s0_=6R+Qqvjmp{aYrH(JN7{V6BF^F%z};=+ues zfyOzV5lx*gS84i4(Fa{jkq`!%OKZ(*Ktr75PX&idGz6ZK8JQ}a^|%z8VF8@;F+MmC zLy&&knVn0sR$SQ4N32sx4ZVHH2P9eEo;t}5)%~pWp(S>ZpaO~&e#$4 z6_TIo(eSO_Ed-LPl;d^8El4lJCfb3U?=s{GmZaB@F3K@Z(jTDKAhd`7Dx+4vFFJ5k z;9DlupFSW->7zhD0O5=nG@;nVr+ofgjuI&9z;DmX_gWc^%nLXi#V8TUUKYDvng?DT zczs`sZd5Z)_Sj^;v|tS0ew%Loaaf6dP<#ow2y1^A)E&f;Yoi&z;2udYVAl0$tfsCP z(^P_8%ch00Rod81$^IoZ_2TrnvLU09ux$Hm87;4oFklZvTUmr1m}=Pd0Ozn@N(mcc zm`T)`{up7=zS>!TR_H^`2%!gTh)YV}1ZO)z3LuPZifq(oLX~}x)9UnDop56yk53vL zxhmE(*;d!n--U60lY8U(1U6`LS12nzpQW-rn1h79j-C>CXNWakTNV#L{7zxMFpEcvNu10u0qi}s-<4dc7Dv@ zUD$m(*T%QUM_bwxzL!S|viqjS1QvLbz41gF3A`~B%L=+)Rk&Nv`BPdA)%a%C)*eg= zjX1}8ql3%BSlga(J%*pVw>U~Wbf8=*ucA8D1wIW5_&;3sq#oqOD3hB2W!|7X&*oDrUA7?rpDepn zJ__ca8=zE6$%@UHI{eyo(9N9*-FZ%=LQ9GpU>b+pp-w-_tZu+0AVH4xGzGq6>Yx~d z!}&bF+|p~>n(CX%0Em4jFwM0aa7H&BNS#yfiBla7Y%G$Q@AKe33tyl5cJN=93J)yt1Pz8Wc-A7KBeDRFc#2c)&4YtvS}>8x-9c(x?19 zJY8Dwidd-yHzy@3WQOfjaw#g1f2*M_kV=CR3=LD-WXkOp+=+31ItH6F_0qm&mU>lh zP!d4Fy}+E|aPiJWbduQ>b&-bm@a4OFJ)7T)u9Rwb~KL^5+v?D@9e{wnNeMtPR z*>~)Fg^ZFChOOPy?%tm4aO#o}IaBcBQg_?NKPt2tQUrG9l%J*ZQ~>vDj{q{sFPGhT zXq_c|8A7wvWseyr*qah}iP2>27kLRm6>SMwZD*w(Bn~qfr!>AnjSz3SV^IXAUV6U* zVA7yZNIdKJIfJPXe~fJ1YS8^I?PSG1uhb43|E{#g&Bmq|7x~eR&}#?}II1 z>=RlNpI+LQ5!Z@G-?#YN;&o%EgaA%WC$Y)guU9upt+Tw@q{oYocPm?cbuLy5Mdrpo zi{JCViFHKp@5x&o(p}nX33s^aCC=_R-z%xE)_-5l z;9mldwT)CzpBhy?SK63JN~?X&E+v91G(mEnn5vtU5)QcIqA!&u_;@t@I2Z_`t8CNA zxJoHz1J=yA-A2z&qvWL}pI3@RU60ZFl5yoG7awtXZqta-I|h0%%xj}sDz)<$jgb%uM1BqncTZ^ zo9}6z^$-d)8jha2%s12?MN`;)@(;B>uNjF2^uL8oKVeSB5VX5v6MG8-Q|(8lbfXD{ zHS83pFMqb66>hxm8hC3yBN}Yz<>a}P8!;W=XQ9#1&rtP2=K1;$SeX+@2~n9khFi{x zyG)f9fq@?S>EV&Dg1Tj6!mtv}v$g2ZC$1w-F7m2NC>j(Zx5^VLSNuUm5dojU50~~b zbXFz)Co(%O5rjw060X7P5H&sn^D+t@za59{uujV&>iPFDUv2HRA1lpySlw5SrzHi~ zrV#0p(M1>^mgF;?%c=vF<^-(kO7$MB30YxoJEaG^+MPN4Gr3oiJy`mYqw(cb-bnPc zBDS>JejaEm)LgJG0j87zlv+_Z5v+YFy7D*di)e4DGl!X3_-Je|CUIk6W|Uc*M9}Gn zjZ7_jk>ou5uuzMjQx_}lkR!WuIO&s-b{islAT~S5A1h`&>d*&8ey!ud@zK*KxEoCF zq+2J7(Gz|z15sx=N1||=oo%Rq#EIaX@1<)NNCV>|es`qnY)t29WRP-_z?+r2V;kS- zrey9}%Km#tDjKf*Y4-!PbI|q2mB}?Om#<2*He=!QqM0E-lpi*1;#<7^R6xzCT2&m*xqEH#bdFJ zP`?i5oBj%MOWwhfDHYBQ#--{1?2jcDyrL0NozvJiUrXKZJD@&YARTcfmC-a~Pw_2& zRr!kYM!|6Ib2rac22U0`(qr5F3CcO&w9Go#6sNaK2w?!*!?D~nI<>)pUuE+jr&Bqdit=6uK|QMh_# zp&eA&>VXMg&R<0}5Aa742HA`6@9zOKSXR!Aqq_~7<%i6kOBb^qswOl3`(yK?cQ?92 z$|JB$9%S;`KPa53uW>E;Ig=dd7;Ak1G|u{EJ(pEdYE~*Y_dA5emM#Y@X4vBmxiW97 zk?54~*CJctcsW|JHK|l;FY*dsIPvqCl86iNlFeBSs7;M=t66q=Os8oi9`2xLcD&x% z=hf1OT*{rtjwC#a=s*RU7>LR?-~BjBGzJK%2LZW;UUlt?`m(4g(L52u+jwA2~YL)Mz+I9~bommH9 zL~mXfi&$Y()Mt}XP_&SFVKa4+L);n~HX?5iuFO;$Q8)*@=64$2DctQejQv2H(~8at ze3QRAu!0va4i@U1hIHjs2adzHk=X+7P%=CG*=wD*xH(GtyE<|6J_RGci`$_?huS}p z3r2|uE+5nzOt)Q0^YJ{^P_JcItOjh@u{K(O2d+)uea7UCyW&S9tXxpjcBZU%BFz6* zL3JeBdWVk8KY_*MD<1H;`rMJqFoa*p>U|OAJ6YZ!+S$yVkJATQ2OM6*__tF49|e ztMjR-27>IqYSgV-csv_bvB&-HDO}Z6h7GssS0^oQ6AAfN8eIi^sWaZ$Q zx_3uva82yFH1}xhK*sj_o9>F!H%S{UrkAOp4m*p4Tj^!i0|w=LXwM^)^x`WAK9{NK zyBX`znlZp)BJ^NoM~w<(Rgo%EvN!otz%T~JuI9;s7`+#;Y_VJ3W|Lx9(s`dZuqeo9 z$X5Rc(tyz9Qu3>f++Z^5&Bi?c;)e=uWaRes!?_da!GScRthdy<<&8E5T{rn3t2g>$ zaq%(v9dx$(u*+%lt8K+<$2cqC)PSrhl4X%`EmD3lp$h~OH}u8v@v&3)@#7U3l+HNr zt~)#Jt*s)oU-UvuS7HOW{?Y5}8YyYo>j~ASgfuslWbBq*D@)H_#@m;RxlwPk_=i;D zY;AOMfj0JUTW?&WFeTFRcF7k1z^1Hyy=ks7DhqbcEeH)-m(rTH;KS&MahGxv2km#+09><#9AUq02@6p>T|l!+&~+@ij^9CT1l@VZ4z!fYAk#W z9VvqFw1Buv*r56_r(2Om)#p3hgcFi=?Qsi-#+-rzeb#pU=$*j4UL5^cmfhbg=_Vep zb(X@LKqng}U_6Y_!xqBbt9DIiqV$-P!tx3-uI1n2Q`!*&G<6K@eTYV;$3!;hjK9Jn zSHP6_qi*+vtLIy$DG!&JTuqZ|UzY)dZUH9_|=UDp#F=sk9bl;9iHukkV za}F1Ymjh!X97NShQ_6F7J_|7*e3j@u`lxR@fGF|xbswwt>J~+X*f7db)k%)?Oj#{l zj2iTWMN+N7SvwS_c4YOj1L=eUIV<`?O)CI{>4&Pip3hR%kbWxb%NJd#L*hl&m4$6$ zXTs37&%{%e!egBk7wRbt_4I&twJOl31NGN(efGRLT zm}JoMvJpX)h{^sR^mjZm$uGXrI+h0#?@O-S@jR=w^#nDfXo@;wNUjL&Cm6%k;Db2v9yu@&Wu=9OYePmn?h!XM^tOB;G}gsZ5M8p zP0yz64JLYe14b;T7wIEUk#4UkpcWl`(nIDu zOsoia>MwMkhP`I*R}69*oDspG+zy*M6`qCOncW28{x2id4|aZx=hFG7xyd2C9-P)= z?p4^jv5S0x(u3xw=c-cL+-3Tx6hawb&U8?IK9yRFFRF|T-LVBT-T2@;Uk+0NYxK8o zqC&zht^K|PD^7$CxRLc?@A-ylH@GU3O&KFlko^kHekSmbn{r3fgAA(`ta!4eOIQZ^ zu`xZ$Fvgyt*}{4(|rax$^W2F-xillCzRnZ;dN+w)f}9R z>tBl77-0^!xjvyUPfD&w9-x@) z%#Mujl^3TA3DG|wvXdm#o&7~0Zsc`eA1?YZ9m{UFT57V+o{V$x*KxkL)TIe=D;S4# z(Wh84F{ppDi|}7?ow0k}Y}7n=Ibb=%-cL^;Ciw&M427VDjVLRtVQZXCFY`;4@c2yC z(AW>%wxEZ56k}$QvWtJ~o zYkz~oG)lDl>bmzB7ppyxEO!SdUVj#v8EGbU*IJ%~$8sJ{wZn-gXirNWA92M&SaucD zA?w+`3Pjwog1tTd5r!0h?AidL65mnjJ?4)d;Z~x;8blU&7Dg*8RbN)0lcxS{WFeem!EQW6HrUXX^t3 zO2n|CSh>{_gcQ5x2*b4T10?G%}PZO7CgVL3udE=*=$w795pKXCCgzI*;XH`lt!1M~Kv^&VvVLi2TrE`QQa zFNy}9Z<0Th{HQf|*MX}imzQjoaxbBghs67oxvJX~#~VB>txH-4xyEd$33NMTm%AtF zInG$43I?w!;c@GK6Gidzs#956h>U;h?3`{Q>jwyhOjd6k-Tq|%H4V{q%iBjixx5wf zEJI%ciYz~7M3G}2me#flo??S>VeKqSs|!qgY$$Ic$6TUBlcJih4gn&&Ph1<3n? zPoJB;g*}T=$R=T@Ilrsje#Q5GdUpf%N7}BYpb6|uX*QaeyL>)r%tdxD$g(_&Os9Ll z<^aoH)hg54J$CHeu#-C@@J-a+J+Rd+i4ZKgACaQHzb2zTT=BlNIkK0r+q)KO^Vs_d z-oBcsm!g@*o~iM?3H~8vaVe8>5-0v~NToimnX;g?aMr(gJ7h+b=^o+bRP{4SoaVY- zf=>ujfDm$*6(Ye5aTLXyLe2M;(*}IOXPZB&7Qr*Bh_+gdrhZ!Z3-%GKv-quxt1*BAT(&98y22)Ju_yRN?s@LZ( zcR!iU1CoMM2wS<@e(s=RZ}hd2!{-V@-(R9EsR+7QII-blEi1Ex#&WXv(l{1l>mmHY zF_5xpCeLkM+O@V3AExnA_bZfdW^@{lGhKWrM6sCS_g2#{)91D%j1tkZ!^&F{i8e%E zmQvaTk97Y&<+EQ7q$UY?@$-9GW8cFGwYigCNJFs+T8aCaAMF?DPZZAbWQMv|6^( zB0V#Vd8o)Os<%egNXE@_a9aEQM8Y?}KkD~*idi&20XY7U(#J0^fuWu}-*TtwphJRk z3HMoJ-|y=|F=b3EDB<}}G-(dQu+Y#Sx~)E((-m8DVEj3q{nOD1qolf^DE^Rs*`WE+ zg_$_(=IUpeX93|Bm^PF4X-H2m4kpU%Lki$R=Quz?Hc-ks z0tI#%bZ|@piNeyEAG^6b`i$##kMym7bGYPk3-`_AoCuJ8TiRga zdp3u}&dd=`0K3_-DklJU#a$o*1@i49JyseCdcYOm-!z<5*+~IaUNpQh7_QFJ>;pTc zTRP*1;WTgQ;bg$~b>~PU)Ppf_+bnRfjqVW>7JSApw1cwPeVyHlQCpT^k7Uufolr~o zc%1J}ucMUgv44t)O;^lYq9#7X73aW(iSRnuwafQXB#_aIF7{)J;}hR_H)`G9r^&6s zo3KW|MznUK)WXd*j7ffhRmi-4!|yI;KRl|>4~);QhlN9Uy7426?Q^K`!b)qoptsFk zLicubFSnjTFIJp7rbEFQ2UY>cQHjs~6x!&MSa<^(wmG?r23xFbc~9clkTq4nLg{!R zxXaymPtS~-{nUUSfJ``j~~XV;^m0T{I$CxPL%+b|1w!qez@! z`LDdNb3DfLo0&m#UtXB9aP84OcC*0Wj@UE*_b&W={xqKHtrG#Go~#gg+ECq3oZU1p zMEnVo-1n(pirBy~evpgKZ+S1AwWnXJHL>IEQSfrJe4+H<41suwDL>b#)J3w&gLOn- z``<;2zKf<@W5o#(aYU`=()?Udjo?7E<3h(yte#)}Xd%#O0YY`YKMSOx^XFJ-w--r* zS?sq$oj15CD~_e@uGvM}azYr`7wJy!52)n4A{TXN`FD66+xC02M{F10)Zrbp%4B?d zigA2I4A8L?rKU6r#lo{h!IH`$B~t;M2XE5OOB~6`anuHl!n;$KR+4KHJv`kePa13z zor3Zbbd~Rl?p}7fueMd?No_d0CRXa`J*P3fvDqf>2<*DvfF$3RU)D-oY!be;*F$k4 zaQYf)HPkuOcX_jZZ)(sy6MW@)Z1!vMwHEYZsei2*-;1 zLn|1(aAH%R8^PHY5Y3mDMqNMbkcaeg?i@wiVo!Vd1TP?C^boeeE3SpNn=T4(5>n-t z+>m>sjav5pT@-yE!wI?O)al}Uog5~0d#yH7r(W$4Ydp0BT6H5}n2I1V>*^d=iH-ep z*K+&x`&Fbxrd23guN#)T)DMvpK6BWE^rPNf>i>5Ck>7YscbuNGI`7oJR(*A8*}9;` z3SJBs6b(tI=i`_WV4e>53kc28rRbC{ty$pf>k>3MN_$$L{5p8EMdIlg6YcyRF2-h5 zb+PhQl8YjgeZXt&!<|T9qkrrGDQEsX4ozUN&b_we@;+Vr_pZv(g*-uPUxVOp3oUh4 zBexGiP+n?`V*I1(R))4?W_+;ZBnO<$oQX%=BsJjQOR3*;LVFGw-)oq|KpKD8}9O4FzC$7=RUx>e-3Z?(z5cSlJz`q z@teSyGCRikM>~EO=bxd#PvQuIm1v<(pzw0DL$cF*(b?pxe_|S$_^1q5SMef0?m9vD zoY5UqwbmbV7aE3px9VxcdLQ(WS;bD7v?Ej_xB?YSB*pfmsq5`6~G9Nz_zn<5* ztdY8-`FV?TgP1H+-O-+a2YnXaQP%uLS@mC!CbN&gcUXWs)AFui8TKKHPK#xkKds<& ztX}>(c6j%$)Mu0(STD=8vZ_FQ#e=T9sR~<|l|B8ZkrgSER)iD2@|RgWghxtpJnS&< zU)HsuwjjU4%+;+KxjBu9^PJa*A~DL2_hMbIE3N^|@0(>_nXx}8?Kb2ym>V1k_Wr#u zJ3u!|it*6j3hBX}W21(MfLOAJ`{+cp_^EY!J>wC6NV9%RW|&hiz4-Yoy!ftJ;om+C zb*}q=9P{^vySD#6=Da~lDcoci>{}J`D}&zQi<-07PrUkFuUH>XpAtWc3P;cKG72sW z%qBn*cI|uHIjHk2&R)feR)+1to^sPDpORgMsvibR2*4xn9#&h$Xkdz2W8e4gPq!kz zW+|Ss28tF~y``vS%)J{{awli8VwkF4TI^q_w+Tu@zLHe@%gY3m2m0q- znLX@RXuIps^g`n>B3fJUuhaYel`t<^jXqy>`W(uiMhq=cy^Rm2;n{{j&iJ6rn)lG% zZt`Zl*S^Eyei8zno7$hX3#Ai~S^WO{jGGPgpVb>IC?_wpC3Lv>uQrXwj&_y=d-Am% zQ%&ZDeM_*IPq@7QgX4G^e6ZPK`w-bNn7ZbMR~m3KE_jgd8CAG!@s0fmxX^ma+o|%_ zdQq9Bue$b8djkxg}GyvpFE1*8+W8uU3zjGHz zzioQ79);XkFMv@?rRt8GuAOaUbzmMKw^IC_7nkO~=Yv(92#Qz@KPJj(NN<$L@m!Lq zl1{$sp3;% z#~X@qu4qcri@kB5VBU8nsJR2Sd}$|LCE{e3)zvpRH(7ZzW0Qs*mA*4(GM_13p*5bJ zo#S&v)aS1_?(Z0})9UlJZc+YrG%K8r4Aus?dsekp!X-5yQbJSRbQ4KCHpi=2_!f(B z!%if$1Ni5C<{GtAHkKQe{aWeK@?D`4RNbcNMZe}EBQs*ejk&z50^KH`V%xjb64qbu zpKCyQ)t@(_Vg$!83YaS6DXrm=23f4Q?#OkFjIN@0J^I+VtSF=~xDLAHlpo0GCm`^L zp`Mw25)5W)a&v5Wh`_prTO-~yiBNLdNRu=l+a7tSN|}E~6>}S3lD@0(nm-DTg$X)sa<*@fHQ4#YakZiv))DQ>}h`sw?St9WuDC%>_4TeCar#CZ>p8 zs1d)!t9UroYY)_8cHE8SsF>INzfzD+b4p%ON3b#F1oK`U;i|OF;LqxS?Cnc{z}Afs z5JPZwdka$g^_lY5Etvy-LNA3jU@DE*~{5=o%3`9IR*-arEn&j-x&D*2(9NO9>Z z%3oxM%T~@S=GR<;o~oGoL6@k378}a^6jq*CHUY7?rV7&uAbc+4p*)J9#+u^OPneA3 z4Lge98@6&GXTc6*jFNl~!%P$vB9)Pn$j}XRxT# zH!S+G+#{So49*mO#~c=o4WnlYo$60rFvb?tque&%S$Agg3iv%(jBSFz@;7?48C&ch z0V4|USk1n^p2)puYtlOeVClh(F-ZheoXXr*&c8p?&^Z$GpLw7Z+_ji7ya>ADZHnSQ z_F-ZW-C(WI-df*`7qZ7pW(WnQ8%Z}a*py@yJ;|aQ?D9<<_H!LOS)x)I;GsarC&EcH zN+jg2YPQ3Wi`OB%Y;>T3YBpIvtfi1lD3>Ex_33Wff2+#>egJ&pF$0urj`T9_bX`rS zvmORNxtN*%Da(@-f~+2P5&^qbXMRsc7PKBd++#%`n^iSt-1TTT5DR}CNiaJM%qFdG z5sY_%<+&?*9g;ihwYw7L>aVP*Ze5rq<|Ie_vh<8ye3TLb6-Hg~EmxWP5=U#@hoLjH z8KdzpS3&PbXb$BtR`TKO5=D=K&>vELi$DUr!6LNL#lv{4eNMt?GW2o#G zvx5!;N;n%f_r=zOOW{dlb-B!w!Q5P|S8+4c>$^#{J?k0Ffz6j%*<>_?qhv1+btS*e zndU9i8EmcO3?hh?HpchfH5ngl{_0=$61hXzTR2|KJBnNjV?K{~Rr)svuv^L=Ul~Fa z$BC?}K3~v%(CbQQ|6Cfb+=U*Omq$H0JzW4TAwNneQ`7Q8?9r(#IQ2n4))bW!U8rxC zd**S3oYNl}+zxEAuMJ${Gzg)R|zLomU+9A^^Vpci19Eea-x|4D$hLr zQgnZHwYzV%#+!ZmQ7sx|>>>GeUtIOxY*L$uVluzshMH|4P;MiH_r@e2K3o_8flD1Jnq^`P{=^5EjW1ePA%Et3A(7sRq z#U@Z{A2>1sjyle{o*FjYiMa3k+6?Lxr0%&cKC(VK4Ewf$Y$VzivLJ}@}gOR8X4X2taYzC`04oasCZ@V=X_%# z^da|d5HI=<(%qv({Qb3$e$FfXxTz^brLvsI)Pbz9+p5jX27NR3q);i}8^~ss<;$RB0ssb;;hTdBzsN{mtoCLwkO6+hmV&zOYJF( z4>6*==>Z9a6kQ+@kSrRM_5cPMo8&Mzc96EPKt8TXetlE*da$AD?p-%otcQ%2sg$_`z?wjk8Y`brcf1=5Q^s&8*DmMrYW9C48aee6fZhVt3GaP;Uzi zsg!Ews@1~dIZAG(c_#7e0o28xv0N>IC$3`zq^HoBsB?F{{8qsgEAHXZe2 zXB&yz8e{7oPGesteSyu#@*Vx-`RJpg40n!7bw*q^@;r)<{N;2CRwuXtAbf!)+nWv2aTVumYzt?z-P)aKpZ{fimM zY@@|ac?q02esificRxQDqTcgos-zN_DnYpm%THS5`YkKETs7{J`^@vWTy(8G(5|{7 z^Kz^0;#^G1K?j%sCE5U0G!381++4W{>E7Tby? z^Wd{ay3&qD7XsMno9}S^JuB+`+PBY;DXy`*v4|#}h<0s#Lz{%bHy%68MG9ZA29O(6 z%+9O`VnFHC!Gm^utpQzmsJB~~-HyKp{~N{Vad75CFgVc5|N#2>G8{f|}ZJ`M-R^wND8WEb+hO zzhEBGX8jy+firnG6yeOqODe`J=FFw}+A@j> z7nz0bZVY)-K%k&Cf<1=)oz)oo&&5!b`bjO5)(%gaqSBu=*?RI9*W`Xw_xp+9XP{Jp zf;*Lj#|C%8Xdlf*;jlw#<50!8t0M-iFsF6LoTh7>eIodZeu8J6)5`_HH}MpF`;{jE z51!%b++^mO5Zka)&a9AJRJ5f!6DkBU)wX=aeldnz_{MoA+OXyhI89toRst5J}wc0yj88L6Z{ zha@mJb$airde6(ZU9y(F#(XZ+a<^H1S6g%Ud#bonY>KG7Vh$RK&2QYccK|Fpy7FZm zR+0Ac+#Z|1VBH5+ByyWxK3e2Aa340z!?gbb^w*JkMH!Si@!>b#so0^eAAy@5$YJLCT?Gj0rr$Sm6s~*Y z*zjuefea7%P+H0bR#l;rG9Px0q~XXc!2k#20-SM{U!3iw39|;|6+fEI$`Gri!FE zoI6!PCReI)VHN!?I?BxP7^w@78tJZsIIgAd!w$iT#v|hJ#sE5kOndmy6Y)x7>&fj5 zo0+TW{htb+U=qt&xbFwX0v#rLeoH*x-PDeyRQ=B0?mD0NmynL7K<;fWRdL&Owjx;+ z`aXSxcjyf&gZ{K;TXNOs1RC#>va*J{=`6tjfoExLe_g254~TCElc*rgn7opmxWpt8 zq2?7F70S68G92<}#?L%m!$M+_>twi57W~yZUAteNMZkH}JDx!+u^&w`XviW`qx$bQ zeksUDcAWRAA@vyy<8*f8Hw+-)kvBf)Mu)FZgdo*9kuG?Jr;q-;^f&hRrZhB|yTp>| zTPN-ADW-p&sUyHkyaP*0-5VLeMCbj6==FV;KL*`w#;~`dd1Ce8cyk|H&zg_8r-^U#}4Ll_+}{Ynb#Gs+@mL@XP#jT!YWN2WsDgRbR(lS+qGF4;4yZsv1*JXAeNi17-Q0(uTSZKL}E+1Zz z`60j~rt{>~X*w1X@XD^aFnZ!lU{hjszuJ-BjHWq)3h6Z$U(KnK*>ziqoniVh<8*zR zMe^j3vagrC<|=uDSMi|E^K!-a*xxzRCs4(dal~FuAo+u~?g)hIV`dvKFN4dRW)nvf zXkGGpDa=;#!b}++I)BQakih-rc$cesTns_%qB!Sg5Ul%=!F$ZhCIZPwEk7iesidWt z#U;A4OSzwLc@E>uzCUAnlNgQOn_*{P5Ak-ubD-*|$NYvDaLGqxa_1#Sb95C&6#Y#+N#pK%7 z0kymKP9ea4L@06$8Ke*O3+{dT!-JV6jxGzuwadSeirfO``qb&2NdJ;x05u{OKJrI0 zRQ2-%9ibee@I+j>hNd^2<4F%*-w5em%n2E2Mlr{sunjj~bJ5A8-6F+3?MMJ@7*0YR zbh>HDvk2TlU_PrrdimAgQU@B{##?K)U@xPd5V_RSKtCL>V*?qJH7$eIfk)p5W*}ac z^;be|@_qBUqBRslSUb~LG7)=kahbLR+Lj}1X9IF%hcN^s?LDYRSZ|MP3!N#lb%^_UKxs{o<3Me9`HVC z-T!z%F9`hmjeprekyw8QO#grMA%RHz|3x>NrTx>f|4&AdX-IftAAuA+ zQxGAoqBFXINcRWdKg$qkAaCOlDQu}h)GYE( zfLl7PA6Vp*#xHj$Khv|abX2--Ia61V*`G&ChEazfXrQ;4k??xW#hwxtxAWVqnU5H> zzJXWINV)dRRlaBB2gXS?;r~LZRqSCrHfhhaKH;HRb5DSFNHjyElh5 zf?XAg?FrCt{8fWjK7l-m44SWzu=7ov`{u%jOYtuWPA6~Y9%H+k>eTT38p5yW&(zxkjSp@$CV& z0$j&E%6yeV&-j{xB7Rxi2uwhznEJAgEj$0kLY)6zKJzs%v*v3+iu42f87#dgZbB$$ z;b*VQqW4=+-8<;b_+)4}MPuLaTZx=W0-mH>aNl@04OH4Vf?gYSSQvhPOttL6C$8>8 z4ps<=q&~P+J;$p8Mn(gpTEg(EKsixSmGOI@td>w;<-eg$7P#wNHh`5#=N;us=ZWXg z0cBsKMN2=AZG2a*+>W4O7x`0SiFJEh-?n^~^9J-!@mD?~6+^I|R+k%kgHRjCk^#bj zzJ!>6UkJ(S^^4C7e36~)KLfE1dmmt<C$l-3j#Q=e@*JRFvaSazt z9bQDdeT#mb6S)9`f0GsQJ`q7snZ$6JAiWjFZ28{mA+YxJjgdHtCYNv1ScJ>v{~vE} z85Z^0wtX)_y1TnWkZw>w5J5s(8YGk)x`$3FkuDWMknW+oy9X)h8oFbc=Z|Zx`?{X@ zez)!Y_HLVBRhVTG@5i%^Dq%q`?QO5ch=#!&3+pD{bvrQI8USo`vFd@dpFFhY z7PVJ)P8F)B5Rr;_{=MgDyy~;X)H?rupi#%Y<0!ZXk0M5{FzVeX*}WlNja!~NURWYn zWgmLob+O9UbT*hI-|KvNXy+L5_zy%V1OV-vkDGUjMBsa*Fi(n^ol1)18fB060y!yX1IybchRrW!N1bzkR0BXiM z*u1;c-W_OHj2kb@x|+hq{7)c;qH;;&eIWAsQNC}(!^yi&FX4_NoA+i(_>JccYh{HA z2h}Y|*?}|7nRwsCS~Q;}1V6(Z?j`JiBzfyC!CAJodNYoox3%E@PUTWjR$vB=lw<%h zkB=k()>1(x->%;$s{1Ds$p5;{t;&MdsmM6v(CJ4eCMt#%9tE-2vdduA${u_wMkktn z)w$o;s1j|0ETx_0(}i0>?U|MO;GNI>c?rqs_| zb2kSZsACA9I|y#cq+bD4i8;kT0;tVL;~jb`_hMK?)8Ty2D;~LTEStV*f39-34Cbrg zMoFxFWh&zrwF8fVssNcqnpCEDr?ez`;+hvO z;lzhxr zL#U)E^@{Qzr3G7esKvFf*t^n^r-sRzkhRJ#H(;@@Ec&(UT;J&z{X3bz_CjT+V|SzH zpi~S&L*JHNSwrFzD%&AHO$I!t{zSYGy$C>ED4kFjt-M}w_2u65+v{K}mdlwX=}cA9 zc13BR>;wu0We4w0$DdX0E#{Grvz^5xvtqV{|412RA|)f) z_CCH()vBf17#k88GdeDoFydN^xGjLArCTRx5qxZ&>2{da?9P{p2*Mx)FYzJ!`dCr{3P zt3|yVp%-ZU==DJ7&Knd;altVgNZf`ob`Rrz-QX?$rdoC) z^txNNWliYa-Kl3J?H8->Yc_NBKijI$WgyG@k(jW)_nufTM1n`z@Xv~~c(oKj1C`#b zw!V`bM0XN`#}J|yiqoSFguj!>a`QWaz2un%_gcc&+|mWbseJh<~y0YNK{l!#hS8UPNW7eigw&o=oYXpLvRdBzfYXZ@B za3rZ>yxV^<*_>eA%J(SoUOYB(u~ScH$_PnAi;Eoj2u2CzdpMkMVT@jQ3LJrZaR_z{HCp0VdCL+mC4&JC2OE|ccBq3@4Ec}tpSu^& zo9T9c28Txu(Dkq;%+7qQOk7^s!rDqOnTxn_C;9w~IWc`Fta3w|mh?bY=R2{>FgMwb zm4_CkHJ#o|nbiz=U#1aQ2M=Fp+k#(JgmeMfE&X>}Fc zyB_Y<&yf_h`0`iIZ_tLC=vfYXNYyDUe=%p4u2(SOvPI-1Q(tT;HRV&_e(PfIet3+H z9iO<&&1vx)po4Z#%Xx}t=D6@CnmT3dVFrW_lr~mOqrq17RTVbGZ#+z%^HG6Y%+}N% zo-w;k)YWJ&A3IUcW1L9nSBoueJ+7r_V@hL;nwq#)!gFKqgy(9R2 z@E4gPn&-{%3!7Elt6fu`5x6e_%GSkdbT|LwaYIHvQ$V<>O6X-SI)vG^UL;oTbI!zi zpBSk$-)!0nCBx-APCdK&i?sz#OO#{Z^*wc`oUQ{oLz~FUPubAnRoC~E;8f_jiOM!K zI5MuTD^x9vr6j^#)^FbW4ykdVpri23yaL^4R0ylo+@;@ z@}*&2{1uInb^G)yGhyNz>+&4X;4|+w27eY$jXuJ^~UdcP2*Tdp=xC5iD=~M{f}Y=q(6-ayou3IO4=~ zSZF_wqLlow7bu(8m639(kx39c^(?n;hZ^8&XakO3_d0zkrYRXPE+8Hqzu6{zRa)hY ziRn~x#Ok0e-I-{mqZ)@~?^Z9GOt46Ig}en9>a^U`?vgQq5)hT@V-b*|t`nIJU*&=c=y{OmPr00mT5zWGx*>ktL?-rz zWpLk-o0yCQFPOCkEYiNzZ6`Ct-co(Wh&10F>n!4h}qnt%(|`2bk1* z^(?GG$}h2eYfQx%t-PO8lE)q;DZNB|V7s_WjZUoZ?vwE#wVo5^u%nUz?gjEgy1<;k z7TlT1u2OnSOH{u>VPe<*U1-vb_cTE689Pk*qV3=u!~Ue7M=`4ZYyQB~chmCO?Sv^e zb<-a&h4j)tCBYHcDPw|H&2mOMQ_)#fu;KC|@$bsz8{y_}swHkIQXmEB91`CowSsK%eIx{~)=_C87YRX0q|e1e+%X8nmD2TrKqdy&dl z88wc9p#J*&rfDeYu*txumDZaQvw6NAI>~(#=fp+sbm-xmie;fI5?K4-y{i`KS3xcc zr8k|k6?w%DT;_F*Y?ptze^<=#QjYE9)$AS+MC@Lg$^ne?oN#-8gtXR_iS_Gn5cSwB z0~}xV?rl^Ng;L+gM26Jq=L@=ML>oJcVR$*JKjj-}MnS&-3otVl^21BFSh z>u`)6RX-ZetA|Q$6TJ*M(g#Gbaq`(F=+wd&PrlX@5pfaniOC}QR1i@&`I&;bk=<*6 zf*b6^S3!@INSL3_6W;q10D6WY=R2ug%@mis68UV1z{Mr6ay+NN;AsECS8Udzz{7{o z#$-*RYm?s~P-#kvP}-XVsbwLBf2l7Yg<>~?V@*4X9G@QVnyX~PDX8U3o#JoW{dFl> zH}cvJTBD!NDIyL9kWIlLG>N$Ir^j^eBmBN*bX~iF(82@W_E>e>s9v zs;##K{*6YF%X_*uX=h+ayblnlIqEaooL;#vzZaa$H{ilop_+5hJ})%F zx%XN`el17vL5+>6E4;=a*xA(*BcYFK_@D4kP31`|m~V2kB=bR{<*EW3+`Jp|W-cf; zJoJi%ixA{e?--o{1)P)Yg8nCRSlz8`4sIOjSK_``1a}Yr0;^B94GS&x#C)^;MTS{Q zve>pi&|BbG&|dV5a6#h3Rf+iI#%_$@y%YH8kR%`gg{z#=ji?3cMQ+V&)Vq;0%5eEx z_llE`*adE5rxex!q@{+;CrcUJYrI=m7x=7AD&a;7^spBql@UIAxDbrG$<&gHTaI(fzLkn-Z{q3u5iO(Dk0v=S8$971q6s1sYm~wA z*_HLUmW^`p4o$G#r$k+m=`3YM?^CJe|QoCN-( zC7XYO@roY8%L$)IdASvArv!A&yHM92tP8H?^#tyZwivY4od>^?(eS4th#zc5GDGEF zERc^b{D>YRe}A_k-A zOgbP^*Ze8RD{P<378W`q`jew@cs7v9%K&LrTKO#l(!~;NYouobr~CusXokJZ$LXr% z{nHO3Fx=6u^-!w|zKlK#D-`pSX=-Tm4FM6Nzw7&c@j?s?isu^>S(CwcJgutobMa9l za$vbh;}@{kL?lokT={UbqIquABBvrvS1QM0Na$rjwSKZ3@B~d+U2g`U?s2?*>erJoKb%v! zdbG+8Mk`+J&AeE*;(iYEL44B#q90yk;LJ+9Bb$@mFr}Sg^V{2mIcX&&kY2s7G?Ha$ zJT~WSOcGHnOVQ=;-{;Gq!*Q%88;#1fvGTPQmV=Kq$*Vh#1_T1O;*vN6Yah)RM~D8s z3bxXC>1|KEs+nm_47ufwU0xt2Ep{6Bc)|IQp)5z<9kcd4uI86rwH7^YUv>J;r;FD@CXyr-%@qWQMF*wbqf~cFkRl>^`^3#c@@)ns8MA5 zJO9ejkmH;_3mF0Jk>~EPYYDz%Rce?&0x9v(H$3us1-864#H%*IyS1E~s&`Amy0nPi zxGYWYNW!|08Q45E?d#X0$*7hWkk5f(yfqHnv8-G8I zktudc#bb1X)4B)={C1mEU}tA7B6vVWH*CXui;Fg~71J(q@>%`EfO<7AO+O6E!dfRX zJl>5(`zWpN3dlTnjn7=GZf0db*8}faGT9y}OK#jFDSyIhou1&nz|JP{&y}py3 z)_NFG4eomxbxR97GZRxKMokcnH3jDopIuZT9 z7%!67%xegx?A0_p_(=^Ihnt$7c3o>DcfMZtdLrLdCu80lw{>*d-V9A4k7ZdPOmAXY z5TWLNuB1=Gd9c{MNG0NQ3BuuYFlrw@Y<;#H^!_Lzl{3S);o(Y3B=njHPfk&pZDKQg zwE|L5dS%gg8PN`*iNpt6m!kp9LzVU2jrcdj(+2{ zos8l=2=^YwgpVFRmdH7%P-=|PC@weFa(mBwo?TPc`kvUuIpAVQP?Z1~Py}RM(gZUA zRG(h9XK^e~%S2jLVOj1jJ#)0|r3|TZ)+)}dD$aabDAQ5-s`@mCu2|+;9?1LV+!-Br zwM2{6dcPa^yk>(9tt^QSZZ(6ff`DF)_@$Yw5;JSw$kXQi%I$YsR^T1K3Os3Z24MyGBHt0_d zm=kR#qmAfcY|TVeSa3wNt%nf!b|spOgvWB3p|FxscXc7)9)>I@Q;x>pZmm!sgqq2@ zTMx!me^h;F1G~}e%T$4X&7m2?4>}#_M_~E%c*}uVUL*yR?BfEsK>J06)Q32xU=U6% zL4-u_;SrvgdoX<^eRujt`38Jm$8Axg!SK7Mi;g%gqG06E(TwqLc5=3JV351DWb$Z= z+~%%|g{W+ws5usB8vWnEaJ02oj8LHM9M*4WwB53}MjS{^<1Ou-fQr8p&=hA2v022o z@9yjz;EX0ICb-n2mH;|hXG^BaRXFwqOOE*8gr->g!?>`Q-&EJf6LnBPL?}UkJe?%=Oyqi9`QIijkC=H(lYwX zFt{#9s+NBM%`AZtl0)<33(X(fwV=}gc1F}h-pVy?z~BX%2fxo+tcppcmY}()@?F6v z3Ra414O<*MG`n1HgZ(~=-!O>-I3Bre!| z5cqQwla@M07Jq&OqJoUnO?Qt)gL)dpx-^x0rGWi#p8!O|Z6rV)ngR=4+#?!$a?Rek ze$6Nv0Ubq4=rmImWRAlvNO}e@lPv`X5KB%WIsLbq4~V(* zfRK#_u5}~>L&^+yyV(9j`hwWdi}9~E%vBaCHgQIny6?H?H<56)h0k(2FWF996`cPw zMytt26Kgu&l^_wHBX9h={Zy4Lylr;!sO$#@!@Ik3D?=fk^{dLDm9iYbHRsF2+=Aa3C`*Jh`!XJd z{{||ECA7x6Ws6nd)({J1r3mu(h@TceQ)x*@Zq!xet9VbvYJV2goKt8|(a$Z~_1$!$ zDmb-|1=4V7x=LqY>fyo!!*pfcNAF&DTFS7^2X63z+&(SPkL4gp9GLSrLQMN<9vtgH z7op$h%WMQ-oO7)pj1DlKSw~_`YPHl~7qo!mnsc?|lj{y?9~xE;Rnu=bKuh)pm8guT zXI($1BByFuU=lBp_aJOh`9k2_3>b0-7`davUfjvkUh3k}Iz^aZ+;TOVUdkMlD7cU0 zIQDj}^13=o?#6W=Z0eRbwgzV{%az}<{9;e|!PP76N5Tr;hEVEVM+FzF*0xq#Ei0;a ziqK3pzs`qE`*W3@k3acr*cufSgk<=nDbgTm^eEG3qcJ>5GbK8Q|Jy^iG39tNOZtOcm29Z7yQU5Ad?@nHDZTZr#QAhDKvY|G zZKo7#Rlt8`Ykym{VsNk-oEFP&rZg#c7cFU(!U85~t|^^zh!0+k>C=sk1jB0niW??QBpf*ZtL&wXv)zs^daCi~~f40%_w^&CyKiZ8>XgM%6}6W|_0 z=_s^l=X?2hl+$s=>Z=2_!@zG4FL3b*_qwP3{grE_sEf37}`OLeo*0=*-W=EVMhqBx1%FWH=pis?9nXfhM z-GCOSJN6*j*XU~LB-;ntvWv!Hs}>pYwA+D&H`?Pj`hXg3OYAmzOcMVvJWbQuJoyi| zEK|O~cHIR~Omhy5aXIu<18>r(9eJU2gCR!yaj9e3$c>4CsnqXz3=aFn?|h+K4n5z) znp2@J*hEV-be_r|eKLyKN7ywi2iOPF$R6K1&bA+nIH=eGBLFG8TaOz!gdb7~EbV7aqTR7P!Q zX%q(nm#D$N94?=oz11YjJ?Bp#vs|j^m;1NJ6r~NMZtxH6^wqAo_jF>AUAmgGD22Q% z5!O?x`#AZ23qMv%vL`2o#zy<+*zkp}izRuICivFca6K72T_l7BFqRo~T;wxkFMHuv zq_KEL8FjHDXd5mK-&aosEZ!7gSrOXvYHQ{!xA1)_^`D-t26-Vr;bN3r%1(J-@Da^# z!fIz>`Qjn+OD|*p13yfh(sv@FZSJoQ5yzIBk3gG(8bQ zYjFnx;-@?mTsxe zEw3T&f>aVMca#!5I=|n(7y966+*VQJuV;RM!gvx{X@{s>1mv9WHXPuel13qpqr-vC zhiJxM&(m>l|L$-4<=S-|YNS@HT6r79>S1f3b6xhmRq?JTBU*M=*285k2}|y?P|%G1 z;a}L_M6I&El(tr#1jyjzLAoSn6TKu zJl1giSiTCfA_L)~d7Rva9er*9JEuu8d4sE(QuF0&@MWU}9ptGdU~@Hf6F)&SE=2D)ngX>&e5;r1m6|k^RBg!G4voRVR!gr&@c$ z`Q9s!^Q6|0B$-SX!oFBbF)o4bZM{!=Vq9~hNQ-kq{5gh#eul6H=3y&DPm+wq?;F+% zgu+Mw-1?Bi@o}c16nzd|Gz+LG;S+xJ#&gsSh&wl`+hnu>VaI^0spZ9fXO^RwuWYjE^)B)EV&hmA25CCO zo=I+Z!_rFnA(QL?2=mgRYLwi>$u)XPeTVWca@?1Vh}SR85G_bW$*66&0>?gy)}2!S zH55(CMxy}M#X?1$I68F7k0~ARE*XM*n*p3sxtL7%R>^a8lXZ2QelvSHlrtQkU%`(4 zUNmBbJ6V<%KlbRki{E<{$yJ^59F#r=5{ZmB5@2PoIWJ_OgAeTW$v<1uq>iOCr-~&9 z^C2t0SNI<`aPQj#21-EMtt}f-qkhNG8ZOC1>D||1Xzz0Lv3)jF6XPt^1dYJURaQzkd4J*09w7 z<+~p8k>wva=f4F+FO7Jh_LSorc^#yaA)c`&mv z3h@vQ%K832e3+jS0gDSFURT6Gb^#LEBTdG4i(5hO9W^0gq8msEMDm6SnPB}1UwsbW z1IGL@G>+>YU09m>g;=a=DNIk6ppqRGWS8^Kp*4h@Sw4(WWiyImwf#0eE(!3s!6)>3 z<9YpqVQ*7FOHk|g+%Wg|YoF&I9(c%@Fz{O*2Wi`I*%F0+bqzL!JNpzBvv!ZIm%8RK zQKo=jJ}RmTl1A}y&UiC1kQ(>_W>}6f6ebEOiD!zAH*+XIAK{i%Ji73vNvC4KMPmhg5vxa#!pdqd){bKzf!a+M>iJK|HC#C z=yntGK4!CAl~F8Zs;eg0cl34zoe#^XryTSw)%*u;JOXvowfBVQvMX{QoAo+lhGXuH z_g(C)Txd?^!k0MKS#KEMihI(XQ~>W9e zj-iQL!4s*5{z+~2TfuW=OBb2}_i*~fpMWjn^q*h7b`dv=fv}%XKtnX;f#6P z`te1R;bXi95B1cNZXDpN`VIzdJN@#G=X-RWnYBO0!IV&LiE=QY*n-HxNz+S(*>``c zpYP#`e%_4f_GcZS2N*LmIApg@6z4r!)Y0Bz_|=*cmT|S)^K+e&=%N8Dn*nzVlbdk1 zi9ex9M>_k833}xuxN-F)Y&o4t)T0>{?-iED@gUDTyT#B$fA+3XOSPlfEW^xs;f8B= z{_F>f+FT$7kj#)k(sU``w~{b!*_n1LSP~hlUhdk+)G9v0Z(r=!Cc!` zJOA~6Babue_pg>`Rsm8NpWnUsTC%_g^$c@4BIHo{Skad4^8l%Ym)-&58g8X^yz47E?lRC9QrDUVzwZaL1iLJ-VRIvxVhG>^HJy}K6s8# zAF*Zv$Dl{zf%AgV9j69iiCFFuws;RcA9qmPkJn2Zu9aIM@}mAXI+Smo(jQWkA7>p< zlz&AZ9sO<^v#izkqmNHJ`Qv98KQXB2aRKp|;N~i<*5+~5ZOwGc12%kU`M?}9`t{1#;9e0n=U*72rS-q{U1I zt4m+&3c99X>E2nH&tIBeqikf5LBI!8c6elFVHuJ9K+3yYEHlb_jPv~W#5?&XF>MoG z{^;0g$j7@m<&LR;(_-V*@raQW z7OFV&zgb(wCn60}Pm?grx-o8@ZoZJPxbO|>W?^Cw!yVij4SSF#t8jCDXnUYw?^C6~ zVykb65;7?xU$jfdSLBFMI7%R?mL9~1Dp+W!a1!diVB#O6xo;`HYkMhQ`br+j!>|wr zc{2xkV%@tj8aucFFC&ro&s)=vQ4xWaXmNp!VQ6T1gcs9wlKOb@+MLjwl!0FhHI0kR z4s8H`G!@57kJ_9FvRoq5>g{)amP~#R_=nTHA<|_K;>Ul!M3^}5jPW>Sbp6PLFnR+c ze~`}JPldwG$Ne3=#|Ski{;7PWdrDu8jD6NksV;fPo#l};pJZLn&HO3jO!nM;|1W;R z_|&#v&&auC+UNjfqkPpxe0n)`h4LK(V#v}d4KR&+8k9vx=I(#DLRSkdpw0>jA?J?6 zmJ1ldB0Tmf&1sPqxa)i>!;i~Fq|Z&RrOM9Lo0Mc>4mfo$do_^l0?7A|cSqEQzRj`5g#!5i1h z_c!%S%74EWr@kh~Fpx%(V_6=uIZl#&3c@$Y<6+uZh)#IXnzfSs0+bhC$u&z<{d@1_?@3UHu)( z=6M|C)2NP9lfJVPc+-s~S?`3;mKe0cw8N!|$nO`CS?P$Ttv+vRg9Em;R!8_tf&@O# zi8CV|{Tt%Qb`f6{jiPLQCKI}lK6g!BbTU6Y(*3=V3qZuvT>N~e6yLXzfhMx?73gpS zF*ZVzlK${#*3aEA4F-{RD(y0^BFOY2l38?ARGZgqg2ab8e(U_bkr6SZdFg~uYCQ1e z+gB@Hp|wShY{^F5*Q7khnc!(MZBM*iyg4nJ)g7(*8rGT;XM%Q)FqSoH!19?*Z~Xdl zWg{nSC_@d@y6AeHTN1~S>o97LVN0d-QpWR9UhyJ4&KCSj{M@JvOEf1fM31-A#kROr z%EV$nZGSoUNiGe-wlRDHEAr*&Jt;%6)KvM!7l+okA0h$?n}A0^RmAXB5JQ)9ZfeEB>J?Yz;$^M_H8ez3;^;^5XJn{D=@ zlAOz&FWDr!9PWAr@((D4q|=h&EO%jvx|QLm0q*A#GHRuM7AJZ@@)JK^v2^;yf!g?E z)q=CajrB7J^WLeG8GfQQ{I?wu_~sdQ@3LbYQ;Bx09&qR`*&gs6!3SSG3?-0 zU2@sUQFD*E*5KrY^%M>qoELg;2s0Y(3@8k6fY5=rfyAy!+>$SM;Lp!8l z?D`w7+QEI)0`mI^BUtan+Wm(%WGoTd_LUDpZ|8*Ni~;fzcYGih>bAkx01RYHB_h`h zlAi;`on6yD`pf?)VN6H(d zqRM1i+EFPs1A}eXba<=t3%3x&cbq8I1FFadm;7Bjg~^;0kUN~a_>77@7#wp`yPs=U zDmQn4|Gm{(c4>T(iWb(iU;hTVdwzD?zA@;o*fWIcE;KCL8ZeHg`(qsKF8HN>SJ1uW ztXpz4&|blSPE%nz8%`>h?*5kqxH($Fjd!f)*OWmi{QcgPN3-$o7j75>yzfj6V1|8j z6;yQ;!50fdzXaw@N}kAt)^X0D8ZY$Ld?LK_%)>4-=K8wxlt}II&p6Y^QZid}*M&Wu zWKR?}w*P4Er&q?|0-{%5pLc{=)3A0{?V)KVK^b@^zx55sj9az$Zpq3rlUt7qo)XRV z_nfcXr@sXJk>=wy)MG!j>Mza(bkYOgNagAN*vo#Sg;A-1OejnKUZ+5%JG;D}=Vf7R zi(gp&pG^cAFV``q)D%g#ylzj|J{SlLs2+56pKitbAW*Wa3&#rK#>Fi(!id<`vIBW5 zfM4ZE1D0gTKb`TRbxlDt+W>s;PV_>TW@FTe?PPWC0E?%nfBi5mEy8+rkA82zdT;}G z02ZOmST;jGkp7uYeMDR_OL zG^8T~{8OVzio7tI%-rhC%+Pl#iuFGRBY=gBi&i9FHbGLZ$*OaEPwrJqHBCuYv$~t$ zs`jwa0uN6|jqR+u>l*37{V_GplUJ@6>_oXqA`RoX#bsMm}QDt`9;gcT~a zRnoEQII^nZAL!mlRd=u&x0MCVCqS}G`bY^Lj59Rc@?Ji8pPOsgrCKO5EE!cqjAMD9 zqO8n2tlkfbY}+)1DqimqNV!l-dd+`qkY@c@EakHQ0yRf_PS0hB?;f`O%vKpW8v!D# zbJ+g1QuB=p;(m!IX=C%;$C}OCBx&^*!1b0}TyD#_8;QBh`p0DzONrRd3(PNdx$zb` zv?0&%H0a%uXZ8^RrjZ0cr43IOX#zPKEB@316u$n|mV7KMc@Pu*(1!dXKt%SUG6GRs z+#(%aXFiOVcXg`G_W397S@rCf(x1?B-g0NoL9n9cImI2Md#Km9F0-S)bzTFZOY(tJ z+3Av}QT4?Q|5>kgdu&l*71~eTngY@EKu7o@-YW4J2V9zmQy#WQmLceqA6vc(?D}&)%iJ2^izv!+R5$P@ z0(L(2(iPJz{r<(!IMc1|R$x|9DEEiV1-TfAzCj8H%K%%?WL2tw7~SqyzR!`J8P%O^ znax_a0gje$d^@=FE(9A?LkeUP2DMK|twI2;nlIx&F%(_JTiEjO)g?K_K0yn4|zFqVu7B;eF8L$G#O<<+_$^FxN9 z#K=qB!q5o%SxbSFj?12%Lho23WB!i+C9)1vMv=iE3n)3&AOKAJ0esWv=P(6ZCT*6# z?-YoKf1+{0XLkwC&1G81zcEwYrJ$}~3Sf=F{OJ)>Alg_0u+aBh50I+X?SK)id}vf_p6u^8we^JXuW(CStXsF++D$ zpHJ3|Lq1U#zM!Vg8Kw_Jx0f+35u0_763`hF9H>ULTI*j*X@>6=XUnN&Mm_~E`mcYs z9sB0{!!LU4bK%An)J0|5IRc9&R6!Y094>Dv?)%(6i&WecE`4noyMkVCl=~OhkIud}zU+kMFLeD1z1Xh+ zY_$P#}xoTSW6446^IK)5Ow|Y5yxj@~VCzHlK3@c!elQ|Fv z6vV+fvTC(?n^Hij&FDCFZU%n^zSGQy@VVeO!l~ztyK5a~r|b8j?E{~82C3W571zZ1 za`%5Ab$OLicS3%egK84Gb2{PsPMD1|C+kvBjhP@$ce-_R9}5S{=>0?e^rVMml@v%; zPY#0zlEpu74Vhhdhq&>McicT z{^~Xi6VHo0+0TyT0cL@^L$%Q!dI2wskx33 z>B_L`k==HGis(+G6K0t6p}d2(s+~u7G&F^?zlV*r)Bv!2;MA8Dx+*bLq7fKG@YmYg zIFdl;zU~G*5C3h*$H8^Blc^6R4Grn)nrFx(;FiCl;S2ODEQl^blc7|Ku-|D8N8W00 zdg;~im_VBVy8$>dS1%9k7LO>-Wjj57xp*eyVG$@ot+AZheNE>0MZM9amNF*vfEY zFo}9cxPHVKUDnYx9bmdI`k=9$g!}}y78H#>W8^I>OsT;^p>)jZ8O`DC0v5|RJ*Kkl zG{>-dY0V^R&J*O@jGfZFk+Wq?dPuwh@!%mcDMObnFtme`>50A3QGLwC7N4}%em`7M zMh!n{GH!9<1CL{JW5hG5bB2YZ&F3GM=)plsbD+G+HSdvFTXtow81B-y-=yzcN|o2O zvlqj-jf3nUVe@LC5vL2nVIb}H)ep2M?yR`ga_%MF_X+5~G`d#baXkPpdk?@1`em&U zkglp_ooA!HUIM4wn*Hi{XD1FqMQmhyxL0n`aQH0!*^IDI9_S@(@dxDR`@15Fjul`j z&O|BBl(Ih3yk}Y9?t5_%3BNknJAY|N5NKLYOjzOMa?+*q&|!*}&lWXDCZ+NJVh}!K zQ!l&!Zs*3Ax^X(>pj4-Tj=CoS2Ww@-U-&6VDi!e0M(r=e;|A^2+W}^mQsb;~pACad z9UmjTb8tE`44bR?aWt>#aB|6Kyd)E3zp{jWh8^N@B}`q9AdE|ju_+ntU3no;p)N^O z+4dT0uoUsZlIvIYeVArNRfS5MuE+Hwr>$8IgDMw%d)&$te*CuwYTG3!}Z`8%|u&Q@lhz6>^zb+v~c$YY$ zj@%2L*x^MIRHp==pxyf-kV6t=c|&p6o|`<76kY9;8j{GCTEX7RoSJ?~)y#zOhMUjv|@Gv8x9rceOKtLwx7_=sLWmM?~qA&oMtOPoiJ(AM_T|zf!%>(r=c# zfmy#XC|j8TDkXgV;Fw)6+BodVQQvOIl5qKzh35sg`cOZIqEWQ8dgcTgCIJ?=i?dTh z>5J9{8$RdBI|3R~97MGtv5fAQV8kK+;>q_PHG_%5U-AwFoj1#$G5_9cy!%UZb&dbm z2z|m2yTE)&wA#c}ok7*B+U<6l;vN4x#s$B_ag81bOdn^U`BV8R%$)^!#4(7i*UvwkJF zLXr_WbV>p-(TJ>#!s?r^z~nRYQ?}v1+wWKG1H7Ahh`dyb697BM6?R-{&)^xJMd#4o zZ;%a4fY3@?#Z6Eop13f44l*EHYVr#BluK29fb1x%|Hu2fV*uc3H!3iVO3n+U0iKpD zeXiH;%Td>vJ|FaEUh{M9&!f!^dp)GNa0Hn-gD+#7ga zicPZ5c>lIY6|+je$ztll3jm}fo%>gbD+}}Nm=?iscDi@{kmk|XJ*ErHwqlZu^7FAL#7Q->U&p@GrOYd$)ZE}SG`tKWrfZcbbak%O}zz;r&6UUCcT#)yGNpq$j-Phkw(d#FUw-G zz+FpUTNQxoM7xf;ck+FY1PLs>dlUgRh>f0pbyj{eW&Eu{n*vM&- zA1WU?^$~3t3TQ;s^@(Z*zIEgEZkRi?FKDOpI9yfGNLZ=(EZw%);O=^ndX@hbgXw*E za$%f3^NGR~?~*_{H83qgC>*Ijtf9b{4eRk94Mtt#bBNsGS|FUvZw+@i5(}d|Flf*? zgx3Nfk6zsQ>QDXu4w7aA$6eOOSOf{zCcc-;SXbv`{=PZHv3UUe8w+rhm%T6&imSV4 zd{Kk<&n(|_yo!$2c&iya@M#cI;mGu+Bfov#;^>fhEy40O#U60YuoMUusMxndp%kJl zNcA|JQop?THXHF4j(d3K_<@~sU$0O3uzJ2u za$&gSt_1tU{!FxWx(e^qbE(7}1rPSjEnsb?u#upHJG=yYyRB^jSry=a?TmU`w#PcO zEM(j^XFnH#GZ%_gGh8t1G?REO$uyY0B?^>)NJ502i@-o zjs>n2)&YtcH@fQT{HNyxQF*&ez`Esekf{%wqoYck+Vc;_6s00ggP!iPr=`T9w-X7> zgy*gH!o{a|w7*!y1sqrHP;6T{-D%PXK=7BsZ?;Cdt4F2RXwZu0gU(ayde7bzEq-8N0RqMV=za%^da#)9kp1P zCkd)K#Rk(+lmV5Roj9;%^$&deXCnwD&eVSo*29hP9f=yCs>L3!oZ4MoYc2gms1Bo z!tP$k{KIz}{kP=Rop^>Gtyd~`kcF_GSw}P$^M@?9r&!vYFEj7akuij5c|-e~Dqskn zkNpBTw;|5{nhgm-n%?}K;`Np*x zBlF+*Ghpc5{1;d3LhnZJ00XzZZj^z?-ceH(+AB*T%E3Pi5B*sO-2=8N0d3W}ya?zm z7$@lmQMsf%QkCL{i)KWiO&nct1Kr6g_Z+g(E>~QWpy|*-_ z=)n8jo{QASRJ@Ti&}pq1R^Cn@0a>-d^ip=``b2Of`^jo z$qj8wrHzdR2uMk>!G{!0%a#z=XUiw$bH@VoF8@H(u{_33mw25M*rhqORsQ1Dc|wX4 zxKA|ctY_4kE9?d_GQB6Fg-I`IO(X&=F!&!UW#W`Bs^iq$zl~s9I>B zkCZTNW9aSyt!t6(@m44el!#L=w zxLZPSCj_T(cXxMpf>RLOdPClGPT#(_pRb?q2lWGXQMK2ad#)*Cj^V7Z)2-BOLHZ-I zSkgM{&yUcEzGOvLFA|Qqv&i_?5dnWpYExyG9v3k_fdAvW5LoIS+@b|W5efSy06wm)H6-uj0Eq%;;dENWJce^qTIs&yH*GfE zrSrW7Ri@OSEq0Ar&j-*e(g%2k@8Tyhjk%`Zy|#zvw>o&n=aRmkTW=H*^sSfVy+Eaw zr#PbA%FK!a-g!W+v)M@%NrC>Qvd_BUGb~p<{RzgssChvZ+{YJmNAD!8RtCXn$Q3r+ zDC2Tch!6REV>_w6#3$`eG1yZVPUv5{LspN0Eo$+dd!vBp&IB1aW=^pHHNdCd-#{ei z%b3fTPiV z@u<_6C7i-n+dnHy6Rt(b3dR zE228+(zfMrpaHrfx)VW+ex0WsDdu4aw@= zJ-+8e8t&W6SCBy6JNY8EJh5|ta?ydOqPe?d#_`GIYVrVzgaL|mh&>#W_j15Q-<|l6 zl9W+LgtFwS9b-#(uN(4 zE41#c{h|pFf>J}#NW@qeEmF*kU+To$YOuA@W^9~$816pTxZ$3rV3TxA#+K#@{{6+U z<cGu0u~COUJcI00Iq1%-fW!U}{v0LqCjYH%+COLCrx8EWBUUF2DHL1*ZLiz3k$nM zq2x)M5qj&nGt~vd$&bq%kBu}APayGsuq|<9CZ{_MH~#{B6J^u!)`+_$vG|4a0)q$D z$-UoMx{7||)Sgz#HE4Y{yapY9NaU1zqNx@qnZc45H$3|g(q~CVYHU!i`-W%dM@B{_ zlHAggV*b?4&v1FMv1Te-#CJN8Pm;Vz*PLEW3tt22>FOJ}6${UAZH-FHW986XlvKZJ zN>1wyjVHq2+T+|Vp4tNK#E!K+t4gOr1W(;QKs7$VeZUsNM#m*&IV#8>01SAxY0|FK zA^PjTUc0MDGlFBVx$SnmQ_6kot^ht_B}Q|$nzeN--EeD-+)v2gAbwpSPVQ}&>?{N_ zWkd=~L_%Er`1KTMeA?aqDL*S@d@kvnK9zI~C}gHhxDH*nKlDzMipYx)SxuFC;#sWd zba<*T(LKzJ`FGDt-F48t6l_pMS`^LAs&F1-{-~zJHU&1!`! z0=mUU^FQqmiiiRSqLDvRv;n=C`Ym-DUefNe{!fCYdv6OrbO{Kff?IeO@9~69UUe0? z8e6TWol$Bgg{0^no9$2Z?wtv%QfNOC=P5|;(@ZYU`W$}{L%VILfTcdB?eunsZ@E(n z3cMg^RDroQn{6(*ATYhz;6e6k0NFILOrf)CP&gglO+S8ZT+yi0O5W^Iw?D_KO^@Um zR(>L<3_dS&Pp)F{aM?&74^(BGy|1i!^qL{m&WtJogX+qM?2iY(0=$>#=?59{=PdKSKVv~yzXYE!tBaAV{xFB;$j+m-1%;l%Y z8=vNM^O*ZOFm}DTobFA50v|9(V7>gw|A0x1H9o?+HnN`cWx__so3Htn=csX}`xe~| z<=V3~(~D&xl-TZoSoz0J@;)&yWgJ{4t1q0Ml12cCoJ4}38cQp8xHDyvlkeLMppRw+ zth@P-tTEMLuJCX30d@)q@|SfMRObEPaXcaXzC5BJBijrq1n8RMf`2MeAU zh9ry?e*T*rtvS%VeZzAhN$RtKd!z)Q9Bv*&J(EB0xlumXyk()Av(`*ThIZA!gt6n) zO~WHQT#~3nbYpk3z-ewhzXe-$>-;vKQOwl~dHQ&;dy&+sVmnU9f>HDk=qZ(YS!zX6 z0$CF9)22iY?|LVH&|BC(6o|fjtuOn>x#BRmVY=}q#qj((c}jAo1%6Li#R*AvA5kGaCtNw@HRl$IoaL;A(zT2yERN>aa)Ts|2)cv@WLqQ+ z4Bku^jUD&=XzLG+O6a*b*Soa?-=Z(40|lY43gXn*AEr?sw2M3tR3B1uAYuXx*?MN} zt`o?@y>pIQZ6$_4SIcH6kW39%pyaKSmcdz1*P8AG_e&(H@Dq_%#TMZnVW;KutBhDi zS{4-lsD>+{@2hDxXNYaSD({1LE{OW;s!Tl-#wvH3Jz?gWndh3n1m6Do*-1ms1idEm z!KI93FysClum^!|@#+=g!-tnrG8#TVubtI^30~oA0@g28%WuDYdc2Q~K*3g{HcJD~ZQVTa z=gz*>+8U|*>mnKfX4HRNL?jRz$wYE?>DYXi)N2dHz4svCRfr3|$`MO}q1^}uN*QS0 zG*RKaVs7^S9*u&=s}&k;>Xoe+Z52YRM@KIt@6m?G`rwYr=MdkIv~BB}k4=toni8o$ zBV2i_TF{|{GxO*fg-=V7ub7vC1MMq z)2g#Wihou1_~3-r)$$lo?>#>@1uzsc!1dm~5^4CEnVg>kdgj3mj`+V|@L|P58Wk1? zO$TL#gBriNadEx;OBMFWSM&)@&Y3s1SkBZ<(YN1lced2w*De6qd`7VUcTD{AK)~~V zOOZmK`BM0rmm5R!G<|(b2JIu0C(yC=-QJQBY)Xu3B+CzuSMXa@`dm-?cLBxzZwtuR z;M(fm#w1Sv)6nshsR$MF6`Z?k+1Dc#{&M((iwn@T3P6&QmhPFa+Lcl;nJ$rV`+$ud z$J*IWX$`ROVkWcrJwxti@&AWK{W~E5wC`ijaM061;pukYO4aHApC$wdV-O>if9ZwB z(TG#yEc}D&N4&loeInmR4EqmDH2#6^quTW<6||qP+yh`E&x`l(7Xz}#%Nbp7Dn`cM zO^oMV`uCrJE2kmeV4bG+Mpp{;Pv8H~w{raYpT-IR-scgxS5_Q@I=B(Nc~atRNoa{A zx4hpMkV7ur)##{RvZKFeKf`)s4!<}zLKac&oCv}xzh)1Pl<6$!Rb)vzMCT=t^s@x0 z1fsqd3jDNJqo!s;f|N0r(YBJ=VN5JwKi@zmFgH9JoQ*@em~(<2+4_x;=auZ|k>K}> z_6CCP@>;&Vde(zZCL;ln^cT;xqa?OdPtVTy+zFCK@U@HqCP8{$SRtfL>J#?Yw{<~% z_ukV7$Cf z1&FOaQ%|j+eE55-x=mdRC8~{{PUI%dA)?Vzuw`Qx<9Xm1w+ABPPYow~mz=c_OHAVt zOcD!#&)FNG|CD+IK~&pcUU!_JSzLN5smWRcP$Iz6{f&W%Ng4wragq1x?yF2kAj6IJ zR~O+|aqjXSLuok2>z6R*5X)#p&dz_|tqMz`PsUGc$n~0NO3N*3F}MMk5OBmlS%y(jw9gJ#D*)S`+^- zYL~oGrRPEAlS_cK{b~m`MknYC72>>sqn7bX{4f)0k$vK zTxl}H=O5-6ax*v0=S`>PG6!1!QrmCquSgDhS-TJCy+@~W+BCV{-vL2>i1nPk0m-~M zv(ojM5~~8*} z`2F_uFVU)p;Ijdk_CvH`SEhn&s(-UTu&|15f%&g4_DK&Otg*aa7K)u8qFn8gB=tNv zJauc+#mQ$}6XM)^Y>g^VIdcVwEEGZ-qkjB%{JttM!|`XP8oGSx?0{zp0fjfcvt&Y| zHr5>*Vcg@%vswQ2lcP`7nl;dm)kq=~9!jrAp^sG#qWKmQGhxDzRVQ{Uyd_acu`tA> z7`pfw-k*8lfn8n9bb#66>;G`$GJAK?*dUK9yb~J3Jzm4zWPaRX~JKk=J+=I z!|D>s5nH;Pccc%H*!cm89XfAJ^Ts=b0xO-)A&TbKVK$uAGb0eXmiL znB-=DsQ`Ho)Yga@LK@KVe2+qLzVVHo*h0^0Y%SH2J2@`99 zJ?nJIcwozY)sUnr#p*dNa#l&1`~uR&f+@tTs^2&A$z4}D!A0~g8?m*c;v6> zFJ>yd1S(ryoosz3{t!jO5BA&zyz9vUj}+ux8!zZk#P4!aB~$qQ=Ch*cSXpvz1dfYa zJC<>U^O+@qgsF7xbeE$ykVs~xZ)9f{)33A!DF`HMz4qGYM=S=@T1N9gH=b38Ho%A% zr@DXx`)vHvdH31HWyHu(aBbuFtDxIZnpw|l_IY>RY&E5?VRK08jM!~JA>IV2Agk9x z2+`G?v#T^Cy1&u%Y96DvL06i8uh!5lSpWirtS#hEv6iqtK4cnHyaiQ(ESO zC~N7C{$J{DwrV3(%*IFgomu?UqSh3Xsi`J@>;U5_@+ zCAhHaz?lowzH}^F%EN;ULfWximuEK9wKXbx;-D$it*{d>BJJQ{kq|WG@ojF3C;DjZG;#R=~`on|4y^Iqt=$Dj@hGU>+kskN!X zPj_BBupBrZuNBM;yoL6GNIeB8FhI1({eEii*p!U^uKjcFs^UIuv9M1QaYLNHqd{T4 zb-{kO|Xb%=Odyk6s(@8~}}yGqBk)3IU>5}oko(6Zz7*R-1`)!J=z zO-PURzfL<&m!aJV`8$Tgtx9c;Mdp^!T^f>vyl56B1O4iG z&t=6WntjP&A}8k{f4s>l!LT)&Z}!_4hN@oFA%e^+HY|&&zLN)b9(R)=C9nA5;c?%i z80)<_EqUeObrXEL=%;FqR597fw+e7t^~8&6PzITCCSLdjDo@MQsL7E)Fb@_7bwmfie^0IO}GAg zajz;b(K6zdgO-=&D|s5b8p1vKO1qEEA2++lqP%)d1W3dvZTwe~mS#OKiON^J+H>K5 zoDt_MSnn`!#qVUDbibtaXY2Hs2L00A=L#2yQxVpjSB&(9rLaI%1O0XUuh~1S zV`Lm#w+Xwd!{=jygT20Y^_vJS>8j@IQtu zhBVv=z$2_d@!0|M<^Gsin)S(Q+)vZA@Le!szQ0fUs>T6!iVN*!18) z68w{#l_H($vCr_cvGKaC6M5Q?$*lVKp~GoBT=6-pT6cCX>V$7Q*O}LCaA1W}$ruMl z+82B!8DF{v9vt+z#A<$Jpu@YGorZZ2#wA;){(P7gRb^lG$R_dw8-ZF2s-!#Vt3obuMScDYQCP)6}U}dTwCnK9M3Gc;=MecSG+EPrO@44Cla`T z{4R^Cfc(}#(oy9VS)B7*-sZqf59`svK$#7Vtr09oSC5c@yp(EAWp}V}TIP(Mbjo`F z=30DtvU|7JQP&ZZy+%f%f{vMGqe2zac_GNhrD&G83Gi`l*J5x zj;&dSDFcd2iCpVZk!r92?tPHwQO^vc>o>ne$^QG3t^u_?OyReCZRf$p_oLD|ubv$h zPIlp~$PY(t8E&SMlFrDSX|n;lmN0RhA0bg8V<)!NA9R6K9#B?2D|q(=yC7h{-=S!p z4)W;2N*W5ZKS8$uxuLyGOzc$@Om6T*t9e}XxyqPBbgBv{mV5z?4{pC%!C39>`l$7O zpsR&f+4lR75PhS?qA3sh#K1~{=3h$GYzVxD+Xh>Eawo!RJ@E2GX$(DvEi)(aQeJ>D z8KC&gfDYuDx^sO*dN=K)bbhV&>3h2fXoxc6wvSJfJ?wwCc~Iis+iHqNo6h3JG})>)@}%UjBd}V!LqS;oi0yhajp1s(6ClGOmA zWTEMCeCo&ZV7^DhFXso1Mt-Ku^6eX*Iwz|hGh0_~Nc#KaU(erfxqK9QHky~0^#ikx zV9BZMGb!ST4t_A}L1XBw>w6=ZJP#LWHLhn%c{4ezgBS*Q-#61MOSSGOBTsBcHL@p+&oqp0PoTJC$qs- zh32Ve7nbmFhM~JJ_As3Yjffhd_tPbg|Hfii9isL9UY7E!SSzysu|nH<7QIIiV-TM( zUe9z%w};72CP!cq>f=axh?S|chg^mDGO7PHOF&P*ceIjrQ2g9ZO#K*E2~YQm>?YAd zZM&@@)3C`*R$(p~4Bn;fu3NDdjci?}N@>Pu{cf`_o8_{W!Umuby58fwuNJ z<3OW7iKbs^?-1&A_InNq4Rf{GI<~Li2BL%FYjcX`bw-l+*j)@8#-42RZu<~wesYAy zAe`Eb0dt>xA=tAh{l}ph)1&w-a53V@2Xso%Ac>DWeZS?v%~!t;Qh)!ej)5uixC4`H zcjkR(;S^~B<~=JU_n8-ix|Pr}f~l)pddM;|P9WWtY25bKaU^u}NXl(hIFei;F>qGA ztlj`kj&RX;xlOqoPrjKZk$L}LSrxVQ?sMv-5{WTqc1Al@5vgiq0^s2pUdX|$$6yt& zN@S0$Q3{i8wwF`HyyD{~v6VG?U`xcDdb_$Ui-4rSG=`^!@E^b{gxt&aUJE@XTD_gS zz>asku}MTRhAVEHmQk~z+J!D5T@2-Rs#q0$+WX4?w)e#)oW<%Xt}Mf2%(Y2wBvB7C z5_>;{V=!Cb%+>r`XZoO~=?et>Vs;gtP7=CP(#6%)YZ7_N`_HsujsDbOypiKB^C!T&wC49)@Th@zz5jxZ57e~Wl zfksWEa&y)k7Tlr@U-r|a9YcNcK|fWG+M4OGqv_~Ab;xu`IBK7v`ephE?T9(k#$@Z; z-jWzj-x}@Cx|&o|W6!cOT9`Q#Cqwr|H`OSWq9!qoh9FADRv7XNd`zM!TGHpl-7BHw z2!Xo@Mh&i&jvgu`omi1BUsOz<8hg8z^6L|3^^4e(NA{pwy$TgW9Q*dqIq#YJvfRIS z8ipJytjuKy--6!;{=IXB?V~)CReG4DhXW<_BA3O|dt=1INbr}0UYt^&?Xaqu{<*h> z;$m}nr02G61xWO#xC_5Sth)iL71=rqM4D~=BcvL9+8yKL>WJ1jg?0jHOOsuSX=U^? z*L+X$kez*TIe&>bgPa^xJx{V@2*3P@b6$m>1Uz~_Bcch&dh%=E5+YB=@2nSkUWI1M zUWN$b2slMFr>U`a))`125RDQw=&2 z%;%5En)ug|EzcxgJd~oWM0w7HDXMFQ|5_)hb#>uZ9imtko#<73(dM827_#!GD4<(%K>6TM8gDu-OYMKB*3{**y z;;KAIh&9@~(RV-~u2qThD|^i%Vh+Ns-L(r&Bhps)*cJXa_*-LGxKP~judWR(%W7SgEOC|W}-(n7b9q$X-DP3X>I}P6WS9?jRj-0 z6hF;7)ksBy<76MNgTUuh!nQ?vJm%!v)3d}Mr{c( zoj15OWTJF@)xM-e8?Rresd!qOCWS8}}5l=6UeE!8DU*~UJu}0bmle__@qNBqh zA}X@9w~sk1hXr>P-RBeyr=kH)#eah2E^uDW6Z*NFu<8C}z2)TQV6lDg1slDp!ufJ~ z5lt++ZEmLI`ccgbie)WzD7IW{Zvsv#|KEW}+bR)P(yb7@Aj~Yf3GatBbI)D{QuBm` z0LrUYVZNIYxkaH%hKEq}cI+_$dL@wM*^jCbmR1pLk? zzdKcnkW%0z2O#P1f6)NGWH+%_nU)OI6RUaWjg_ax+x_p^Qu0lZp<-@N^zGG~-j1{S z$@3(Nw8sNj5dUsWVxo0-@UlFeNUPfI37%x)5svHkH(=}0eJ{QM zC-P--9+dZ8mV^gJ=XeBE`*-@Cu&}Mu;~(mT5iCVkL#RJ8R-;ax0i1|#?@5>y9jGxi zeff5>LJS6pN!k?ItLxJFvA+Y72L@qsKABkI;r^J&5@O;dC8c3nQ3;v>y#=a`YYQQ5 zJ|2RCWl%~*uU6dlW1f72IH&d!1{1hvGZl@H)U7o8VR;I~LcXuO|LzC@OtX_QGII+s zNR6>QC0a?Fehv};#S1e;zJSJ2CcM6Bo1KFbH8dn7Awn0z;d)&b&}vTMq|GcUcWd$o zH|1@A9HoEl73Jm$&d)|u3CVi|L7{a&^~ZlL>X)Qm&d)4sRS$d@pn|TQJuO@z@5ueA z{jvE>Pz>+QiARQ5cu5b0uYTHo(>_*%^%`bP4U|=%gD_t6g;9_wybis?y5kFjPkU58 zE#j5gQ`9oyNj=irji;Jyy>|EA4b_1=vv89wWrg@pgeB9|#Ie`a#^K%gLLjWC`a||Hd9FGBuJ6mF%rC7@%HTeb@Z_7X@tY}c34LZLsO^r^L z=qrh+#uteUywpjl{}45v8UnW3J8g(BU;4=ws^^heOjB3jCi!@M`vGy##GGUTycIt8 zW*SRGb7TYj?G=|JTE;`4>*BlxoEiyDjtk(QDW3c@S0BPI@qaPkg*VEOgNbpw-*t;8 z>>c5jT5GlJcsmv5W4~tW&-SDbG|ga0F6ww_(ibLmg5b&1c(FY*mmu77IIbNj;(Kw*eKs2T(FoEfvl}FReaaW4WP;z72Eh%AcZ9%;8RDqV z-s;aqw%CGNh=x*AE%bE6=Z#HxUI&O78Jkf@fiKpWBRQy&U#FHi^a$5}8jFfcQ;juF z=?<7e2lDGcQ!Q84*Y;m2uV~SKHA!fCGu&vN#Uv9(tq{1j_UORMjHzqH^kP?6mmngZ z_y%oQsF$V_Mcze%FUI7B?;uXw&7sQ^s($6M+#N=6@PZ0-`~eOdv}PJo|xc-QYedq!{>( z1i^N21m1wxREw!A?ChmGYZNr0oEo6TY3< z0wob?CnZh%Ko8w1E==d>CFX^eH&U4gW|QB&DQk1!Adm=^lDV2k$r0-)J+99CA^$<^ zea%R)v2`xQw`qQL9`Q3VsduB$(!SbKJtYf?YS?)W{&mzOEl)>>%zuW2u=0H=E7ICJZDWq4Th z+g(>z!X%wrJ=qt*yZCKv{0mhv$LgSbZNA0}x{Z-6WDjCO|M05pWrow(l3U7#qXV}e zCX|;H)AYmrmRYq&G98y2Qg&1&>2m?zS+F+M#JBf(`E;l1p0G-@rTeHy`1Bj&4>lI3 zH9LRU-PIQ)sLfWC1r;sqnc~Z@|6;ol6Pcbol}+;pk-?)gHw1P?$O{zDx+iRE8;Tlap&eV0ORH$7JpU%zv%uMNZmO6hWwun=}f1YM4&H^ z_XSAA_QlhDLWB;WXEs(l6kO(LDWuo)jvSwv(kg^)Sp}RaDEq z*@bJOA(a3|4;Ks~mS5B*?E#+VWsc1+cz*2}-tl!M+sNB!my;xeao6O+aL1Qb9e7(h zg4$6(n}knM(a?~LoSrHve+xzt_*inw^*cy-d{`Qsh0!~@a*mWPyq*1epXX>viS)Zq z1JOwIc?rCNOyS9|Ea)X6v+8NCDj&TE)uJWmwSAM9i|z>l?FHx_N3q%92AClV@(tIE z*<)*l)Ycq7EX48(Vrf;#42Wh%=oFD>1q^7+lS^?`0#B5%XZMYm9CKPOg@i$6HMZ;6 ztP2-e9Uz+WctoW0S@H zXgT$tj{UqPNBT?G-QW00xing%a?kij0!;yjf|+c_N&A}@=rZW5ov9w1p19e~#Uy0+Fu%7Z zGiz#44&`zfy*&seXAoKwwVkJ6LxJIQiZ3Rac(B7`!Hens-nwd8^~DI%WJttd!{irgt2-J(ivGJJ*^#)sy)w_@Z!#B*bR42TR=98jcpjR!We;&R4ppV4Q~J-(d4-U$$aoqiw8cz)ojrxSJ4&7C}y222#Mg16(4BPynE`#<{i67kFJs~LIiz&aE4FobnHq_=_1quI>4=?n8p>0 zYb`+c#acy-MOE-C1yMp%Q*>BYUb7?l`~CYh_65{;fzUY{CT`T$1&1BZq;$|?32#ah zf;0v#fIX>9>os)5Oc?SV^%kN=UlEm#Aw2%s6m7Fd8S`;NMISq|#J)#RQdLKewCN~F zcyhSN3z~+Ie<-Nu21km?LcGe~9@QKN$^3iexjiOU6%ka=9L0Y37odk*e^k+;bIIkj zM0Zeczn@WibgWYbvgN`q+!iP^?=Gn@BQ@UJn8XY$N=>DXT0bdP>n(|UI|zC-=g`P` ztR3O-TNCdlc<%SU18U%#t3@3(DI=m-n%UAVfVZswpyeOGQ?pvyf+=qdO*kHxFGPmpUgJaxtC||a?PN%?XjTxBOiNG?&LEde z_Z!9T;Sh8f1X9l0U;WUevEol7N>pzh7r<>}HpC>riKwD_byBG&|5?8C<9tvUm{02+ zJ2D$Z!+GmL!J7&%~HPuScI{IIzxiD8}^M0^r z0n!mXp#-&J{>$y`%kL{$ZjZyxq@ukF9Ddsra6oJ@uVs=n+cEeORz#njW<&;W1b4<@ zh{Mf^_Y9~I?%Mua3_jRu>>fZUorG-zJgz09cVfX8zy*Lv^iu>6e4Ai+2Vp?x{w~Y) z2WA#C*CS?@5a8ba)-#_j$bwn|<_-{BOm*n|eniB{u+k1o7zqkB`TZ+SKTn*T>3I__gYB>iRP!yqg-~g0sr#Ux=we z(*NmO18+m3#3XE&V)RvH^p`S)6@$7>d}{Xmy;WoMdJ2HD)@!U$8gUFS$s2Ku9LUO$ zX#Yx!Jg>$-FTy0xQyTxg@9!_i#Qw7=fBzql0b%@SA^-h;Aub>BG(>7ngjxjFo~%&` zb@EMg1kR^#e{DQC+hKbI?Jxe$01qc$#KnaXKj5l;X&5(-+Oe#%XSS2{qIsZ{GIq+g zi^G4g>}z(;O}TK#=Y2y)4!=5g%sc#mLhA(yFGM@uAfT6U2=VV2$HKQ4Ew$)k5)XVl zfQWj*dy*VK-|u|Rz^w?nn3J{X@DWJ%w} zd2*8w-c}Ja#2P$YTI<|ad5qpd)Wu^L1ebjB>5b-3*f-6;;8XGF0!~L%PV0`Gf9Xd`f3Q3nwnUON=>K{m~A*D~HWy`ilK)b>S121BzXdyB|qs)B^(-2WrW8!?%R_6+|4KDqlby_?DlYFZv9Ltw48Gc^Im5 zP+wSCGtN3xT!)J%ZBX1t3;iX{%v<_>aq~0DM%LQMSQ`CV4uuya%8u;UCR+!7zdNIP ziwqns7$rq~F?itf*lsyxt3mWm_N$(hBz(8Gk=TM~fv8OYCnh>Jz`X|BmVO#eW^pq9o`_zPBJ&4K zO16UD%(Xy=W&dW=O>oV+mBS^vB2c$tjOoF_;kjtS!cPxRK5sJJFYXE3bRj*#ZMolHRZB3dJdEk^ApqQY-6FH5%kLQG$Mlm&r;i%faIUNPG>0(2?7J zeyDJ!0~sNg^yYi2A3y~NTpY~J9nchlB#T>gs8387){CMcMKD0MOV+7p&R$S)VX%~v z{>QBJ?d!@Kuwv&Pjlm-~cB@pzuf-9Lxtr2cXd0?;ye-N3Da&&&3u%IE)p41S#=Z=3 za)m#$)#U?+_ z1{d9M|Lu|KKyfHoiF1*#sAe05`@b%=3lv*b6+i5ITU|>gSN@5sNuev9S*xrylq5B>3z-oF!8F2jc0obmBV;g@{`d&7Ppi95*X-qz=*6Fi3m#Hbg5+CG7If2j?-_$ir zdjEW%m;UreHWzb%bd7@IBDG&-HoU}pKs8h0#X|ZY6%=4pfxq5km}hW)iUO2brjA#S znRy1lzjhENW@%Ffi;_M**VCiZjo=4`J&G}0gR`Zi>2d#Li4>eJemnC>NGp7le(C{x zQy(*1^SK^(1@NXTO*4or{v}L)%tCGUmQB)By>q5KTeU8ZaH&?7|31iHs_GsPZW;7QhGVL0)6VpNQLgP%02j1--S=h zK~}cZt4Apwj+_!$KUit10EfftnzMkNJ0tbs$SA^4tjHhwK>gYTvb3bf&HyW;R@Av? zbAdqF3!DvR)gSLQ&XE=_>~UOacDNS+xFOX*nTru@d(a*ii=YP)e&AJms3{r1adXg8X-5Rztezw79VlWE4eWDx=eZUCF+2B z%l-WDnYIQg48A0Ppqa34lN&2F&129;pTbFH4o0dcYo5!u@X1FBgNgZ=`UrI%?~QsZ$xk~=;@qI+;wmUG?b1I!;DN~ zY<6Hi-7JhT)J0YLDIw}#`WfpEAk7J7bBcO31lwD?k1h%Y*QZp}5}81$k<0@`n^{o~ z*C}!^%qECgIJs$GHvm5=F7xa0u4CpVI*RWo2BF0&^IG2&MUI*8lX|-y#EM02-fklC z2SH>fDSi3pt%C!-FR~+Z#^^vCLloO<|Mh-Ropdn2Yrts;2-r0-Tn;^h3rC1Y#}p$A zHmj~yLf_8vgS(dp6i$jNp@f8l#E7Mj*ZQ^?i=3)IywSbgdhD3rWQyf=@L&}vIG+&M zB)@nU-g3HQXS+W-af2jO7Zih;y-Pd`9O|qWAeNpA`2X01{>(5lav31%uBj3*9XVG2 z@pHvY-eG9EP&-q7wRb-Ode;>% z%N_SeLt9vuNITRiFOZfuksHuO6K3qm@W6z*_x$}m;=xLGx5;qNaDJh~>#^OYfc?fa6k^6Z~zTZ~dCZQU=nMz%Q0ZG2T`B}iK?u`E3g ze_J>ECEwD#j!KQsH*+n7v(bhyd|2Tv>&qgJ0DrS#8H9u4F*N%1n3o#8 z9?G15a!S87L-hvkamfNv)BX;xi@P`51vs(Qb*l7i&tQl9HMZE8d{NUI^ZpY^A1iHo z_&fFBuv5q|C|Le3c#vs&a z>Ui@kjslDRypkUN|Hi0UcRmh-M7qCId$`;ZULFf~Z=_J;5^Pdkwo~xcj-xEA!oOzc z`1&IZmj&!9aH@I{zdeuA(%01Q1gXx zrAlL4a&DbV|N7?UcJ_%J8S;v1=FcKjZJ|AE6Tzt-#m<`qfo)6vFq|S#gxEP&c1{*1 zoNI^eyZy7WdL&j>*5CX469&}Qn~lDYt@RZOkb*j#RL{fcDwT}WA>}R5T_qwNo6g(2 zi)VxzFNuI|%cLXrj>^Phz;K!>SG;!5+|t0B)$q-)H5*c^tb*J#l>Rj1H8~M{oeC$f zEK?KJpj>Mvr7?OjcU^|&;IQZ_b5Pb!`N*T2{B)_4x_=devdvm#)=}sPn|PljJLnQM z%efTca6KxI(IdPurR+>u3WOh&N(DX0LlVJ#dhaFxrrz=-DF8K!T<_;He(u>0Cl|0= zl9_dU{1>DyqKDl18B(X0w0E_h>xp|stZR6c@H~seF|m8(rTB$x>Qh8$VPUCZe#Csa z^ool1{~OA!SKfj@E_|{l3Ze)hJ(TA-N|_63YO6+cN{yI1dN|P~46ItXTssN)s3qqe z+VG_&y1T!#oWp9`4D?-A?5U(G9K%~*wYqy-tFsh@KSv3_pqq8kM`dwR8I=8%L}9DV z5sZ3Xl|K6E96BB4n=Oa&E8itqeFFoIPF5FY)rS~=oR&Jul(W@OdO+fDh$T+51&9HQ zS=hk=!DJF2PU~Aef7fLB4e=PDu>tiFBp%9hG&l5P7g)|_B& z0u7ZrIJwWc3|J!W3~;RVP*8%w2xNW+A5FC1+F4L;&ue1T6jlkz!WfpF`%?4sBjy)T z;9O9)imiU1;&yOVDjNxdW>1wP3sHH}0~TCectc)F9KN zwVgx?=j>%ho)&CC%kv#tVU$H4h&S4u7PI-)lNs966cYRS`E^*ce_@T`b<-j0-9I$h z$@zT-9#wboKi5~=0v+Io=jAQcI_|TPhAY3{lv{6nReFX!U=)q!A!<8rb#RW|>a_X8 z=7<7xt;Ys`W3F`loAjHyz=-~#MgQI^u|2jVG6|%>6SK*ZJFlq>y+Li(e)xUsa3AKo z_A#%)NKQ2IO&<~|f(p@#AlHbS}bV9e5>%g*-lP6ZBrW z))V1NBAm-7`gd|_!k=L*O}(ypIWVsE(wh2eEl+DPN)X`P#->!FqM{z&?N#fsIPv;b z?W$`ioAb`P!*+~xprWtzhBKqxy{8?vh&$>m=#>6gbCI!eF1N`r*r5gR-LE8<+ouPO zYQL8%*?n7B1V?d9*3L_b_k>57SeSSd`CDE*Zr;%<0$9xsyQgDt4xqG5-7 zahSCzRX{P>lRTeUF4?p)+Tx^vOpwTN#n-21%eJ!iky_5G(_IM-r6 zV~+VeWBl%WnBkSQSa!b-BG8F~*a2e*C*2}>zlH-q<={0i%X9)F`B@On1*LnBUMM|l zU)9zYMFJQB#&q^MuqKISq&oI((rWD7=&-L*P-UU z{=3@)s9pL;CrLS9_?b`Y^lP(Oh~n_*)rQ-LY}mTqn@CI#`l38U(gWK;dqtr`-MoS! z_RIKBI91hye;L|6(Mat`u%n?NML)=)I@{Lct9B-y2x9fmsH85E2Z`iTkEZ>JpK?*| zV;%YJ(=*4+reXwKoBfsjj2H&3y@+Mu+W3pgHadE#^(1-q9i}gFwjNg@iMxKcrE}EF zb+^Ky+q1*t(NP5rEk<=vOLYb>Q$ds`(8VLr;?+yyT`7ejEy21=;_5QD8IRm_5pD8F z^0%vmGqvqh`?TQovCPs+LS}^_s;f&p*kLZUM+m=+vFW+t+o9TL(Zr@@5Kgzx=Tru1 z7qvsmWg7Kxg(a%bX~aKZo7U$=xvz>^wy=tNHY9gaDSX==oexj1*|0sT0Y*0;H7)tTuHnVyDo_NqnY`l+H{1ODRn)Bv8F-g-Jxd_HdS;e3`rhz42N=s55K;-RYj5oqx}jM%7?7 z_JkuKF`iWT_++(v%c?NoQkCi4UmzSR_*7J%Gti|YM*hC-N7xl6C>WnI65)lB$zso)KqsEJ6+w8*~_WQj99B-5aB~=eDEftKnX@CFSVCNl&IILch4a}YYaV*o=FV`-j zRkPwf5YMdDJX1zVRM_q}O`)`a_73-=t!ia2u{yKHXl^V%Ew5L2irffQ>*B+uo)kB7 zvH(SXKPZhkJ=m80Oa86)fNT$FaFTTM;4-|L4r=SsR5LOWoP6Wr*?sedYN&k}C38c@ zwnim~XSzV~Uo4*Z1}I{5UOR+$1J6LKEO0WS4m)3FMQ(9ByZQz_QN^=)IcUg&%KK6U zN_-LZSpj90{Jw2XB)-+>_A%#rJk*>4n096LNjxiRsk14!$5q)cd5Cm#`>T=u>%lX! zpP%Q)LFqS_FvN0uXl`iy-$QoJQAI(PTlfw;5Ww~f)>nd-s&+63_a9HPq6cOK5L(h6 ze*s3focjLP`zXZdX{ClwV$BuXdFoqHO{G`X_eo!r1$YfR3IfzOAxMZdPZM!#NmJ12 zRl_zO$A8syg>mEJI*9F=UclZo6#0%n|_KQrU;t9NM9yi-%AkpaUS zSwz3tGX(?%xu$1|T6c(Y1;UGm9UI)^61q0Tt7p71B;*J-Jn`c#2G@`fLGc)7rnw6W z;c|kHez%)jG2iQQNNkW%Vp3wWJ&MB?GRu^n`e_MS%jWb`!j-5_WJgEKKX*()W)Y!lar+DQj@_R0?O zvP4m5`_-;)<}#5dwOx+Qzu(cH8-G`4{C^noq`PT&c1iZs+rpQhthcpwOKoYU1Xy<6 zC`;xgcBE zw|{$>qMS?C<}pK==lI}A4IP9cK`~Y7=Kb{&yB+ZYgL$#15we||TApKZ_n0zgTjpYu zg(7y={k}Gq%K2o@Odbb~Me#R2W!?`&pN`Gwdj}49d(weG?_5&=!^8U~v|F#1V+9&E zBj?l75H&OYp%U+|dz}uDP9pZ7{yiG0QRvhIbUKgR$%ld3s`m-$+#I=&t7U}obyX_6 z7Vj(lws?DBlmvcqJp!N%5FFvrY8#hw-2=S-u0{V-_0w3)i91A8T%@mGaN{W1JyBvi z7ae*sU1erbEakew@BrM&(hU$@&C$LkC310TmOc&m6N_m*oNPuL1ipEGTeYlP;_luk z3=9m1r=JL43Aq2J155rnCll2$r_*}8I0p8dtp$a+dDeTPrjiKhzyJ&y-S{$$d{&Xp zfychl%6y4;cwfnQ9>@QLOoR}?L#Nunodi_x0DA68CGfiKu%WzZ)Lu3Ml|&rzu8V=pm@R*6|Xj_L(Z5_#YF6E8Kp+p6F7OhhSI4y z8)*d#H10{rOun(xtu$?D9kOAWBQfbny&bS!brvI5e4>?eIDz#$XEKaMXz%@ zchGEm*Pri#YNUp*QbfHylVj%X>a*!u+wPIH`z3Qpa!q&5LrMq^xU?cD_vdkya+fE! zms!Ki>KhVuZepkP-Kf0GtZ<}2stG)6FQjQlOuF>y@8$L@A!<6nP=%c#lE2hA7h8v3 z@6F(RPVjD=*zs-L-F^$H2dYh?FXfdA2?kDxP!WWs8XS=MiGYRMN7r?o(9Z~2ZFajd zF&^&@jCBH;Ds6PRvEbQ5b#CCx1BwzqnKWl=Ei(isze{l_{N-{LKhJbyR`z7|dDcVM zJB<#|1$-o;WZUO@htoU!lC-n6_0csHk&W-AG_)T_kbgC-&WRRM-8JeD0JjuuXkH)` z#f6t$ORt{_tKIrh@1!o9mNwsD_;ABZ?UZc+q+Kr}CF!PkKM2}$C4gL*R{ZTcys3#i zK5(yN`G@J7yB+UK0i{QDg*Kh^hIZ!_d`=y9az&|2xL3SboPEQ*6rk_g@+)$MXKyTEg8+!Fyhyr>;KliI}BIP-3ch#t(yWGV3V>pOjg-Ony|*y6kBL74}X zyYjBj*uzGl5hwM1;KCZc?&}`}tjbg5OnM!qHr=1-Vsa_;AuBkM_-IjK)uD(k*9tgP zA4<{~x(M#C&2M^~stCPVq<`S2@CI&M4)yuBS=eB`!;jC-@y6ibnK%`W0RdY_psfT0 z5t%7CARGBMJ+mDFjv{To?X z==M8=LcKNoV1d=mojc!k=cxDJxX+=#I*n?}ym9fSG|Y=?21nA=_>soVZOkenZ}3_rb6K92Y@tEO z;l|8!;R9DzaWU%c?e6s_Mp(H(7E(@APGF<;bMtFeR>KzRf>1-QLj=yo*=euxSffm5 z04YNVB{lXrXate6MX#OTNp}!87)NbA_4qv0XA=ofLBqOK3a;8cT-pNT zUU{eHH(#FL>TqKu2uX_45);?pg62B*+!bQ3au8g9esJlyR;a1J>lnRUDTQsdjQ;r6 zL?4W<-F{yo>p@1NY%!XzGiWwMSpI#zLAJl(9_Y&}k5R)={o&rf@0a>6 ziZg*`5Me|ZEX}@7IN3%@(C3pPZABv$f39Lv4KuBN(+mRL{-TjY(NO=a_$>U~D+hOX|>PgT7i}bH(^ay1x+g zZi&jec5XSvBm1X6%uZ74MapIk2)gZ` zi}qCaw-H=Ii%T$6fG$b&K_qEa%-JHG(HPLsMgCsd7LL%n%V;QPZ^}L!2L36=q(t_o z%$e=IGJ04_1wAa+Kp)#95uYE&QYws*F+5_r4p_OogMQ_$uWzf9H32YJO#c;1`xo`1 z=IB6&a)Pf5xm+$S3yWBIN@?uTspFJ@}ikRXr zX#C2gZ#Q7MLBYmDh+k1aX#zS!BV9zx|A8U7#XjYB%JxJ7=X+L+{M~redoL?yk2H;z z<<4Ol&k=Rc&LZI^hO@VP;jVNjK|9%dPYb^2P;<_fZaDg-O}abj?lEkf6|fOL+Yw@0 z45{)<=1U$5Q`EM1+AADoq2TAiu-{|Sx8%CHbK71`vStIA07$xS={>~LGAtB0j5Xbq z);lu(2(@iVx9`r1vqCsH%D==7A^S^McCMrDlzGK4Hj>DV$CFB%A;4|u!~2(XO%!X< zSsTGm6d(E&20W7+?;|(cLpQ;~0e{8+zQl(mWW)Q9p)#C3kSfFCk zY#}4&u~7}JEEnFLirbyyTQlOd)(-0lmP9(T^Y@EbKj$^vFzW)_ zkqLm#c54U4K{gU|fwo23o!3&G=jFXE4A|t@*~<`1ZehH|GmXye%Jgy5N*PZNPyMwT zEDOUG+6BU)@SaDH?oZ!Jh^l~<+xSZ{oOEM$8+i&+)g)ZlEU-DjczKX~5mqU?!Rac! z1~amT3DsTAsKu2JFz|7S8%d`D*N)wyY-9-8ng;+MueaAxnP>}3C*k!Zc?}#-3>>ve zlxi@Epqcc<%3w>mfJ*kN7}#@&S|pEG&SPimFzV6dLZqkpiM;vxMCDJb>4pm6GJ4o6 z?(9-P`>4~&Z2LQIamA2{Qi)DM-k*Dmz`N3WtF6(zqYi(4PS*U#))fLwbRg3EJlPxP zQj^@=KJC-?BhC#;B(z1gV-KaH=QcvXz+$fnnH3{R+AGki48Q(2#8QwzBy?F2JlW)ynF_U%XAGwR|#ag>9&UfPLmAo%;YrYq5pdc`C zMmurIoTz5}xn4B+|G_k7waj%aS8pMVoD{r2sY4MG`urR%(qnpaiDFeqXw&>EeCXi# z@cKah(kj2<8qi3>PHWNR68{WHX0<#|(>EawX`SNImMaWYXOgx#ctcfMga5glV4VNc z8v&v)Gkh&RV&Z}*ao{?@#jZsE33>!FuiF5Ql$f+SKWlrVq(!;ct*YfhBd%5rM+&de z&h?pkg9j$w6<^1&1d?(Uka-`zmq_G3B7n!~ag}0;IRvbei~W)YI)YC^1c}uJSh{DF z^J^17W9H{h7?x*qTaLv8rf#rb27|-?pO#OaB8KkEYkhd57vqJVgkdrz?_U(Q$ z3i=ti%=7I&qE=xCx~y1+_o|C%c6YdfQ;?_5JnCa{GzCnQ7!p*p%PgONC~>hXp?0oZ z^b9roHx;HW^X_ZP34+ULX%U^V4Ke63T0g%;xTr4_kWxfs*WECswm&fMgwA$^ky>P_ zMD;@d?IwS0H*{<-S!?P%)olxZ$tR8pxxV0M4BU@^BA!GsF=I!BM zjUW*D>n?Xrkm|aVEy*;i=a+_Oxjt~wGcX|+F0Cc=Uf0A3-Lz)CZ*j(q^n~c1<(^L4 zL>n+v2PFGQ3!57RD7SQnqg=;3NAPrG+%YaTgkG$vd~eS8bkVgc2;|zpi0r=17kY>L zkYGColD%ED$lp;$hWx}9NRZ`oy%1uUV&4mebRH;Xcs_eun8v-%(IfW*;2wd#&}}LK zNzau({y6I){l+81^|Fk7=6*WxhRh2y=r_LU|0auYuB zIUJ3>3S!60xKlVUzeH@ULY~KRJna#z!yJC{xG2!jwzQ$%2*)vcSymRCXmJ&CmaXz5 zV=+hsZ>kMs{);Tupl_Qb7}n(~uof>YA}Limhm@7#?#hKr^&Q&j#)h5jIgy2#e!>rr z17zzXegGpm?T`1CTp%7htm*^#!zyVM2{&w%i@buY+z=I|{^fvFv`5^h7`@~d@%V50 z_ixN4L`jd3yJ=krmKNm5Vd96fV;`Nvce@RDNYg(Jxg2|kdD$w^h&KHi!;1Z6Q4~E+ zSW~qj!TP3u?LED89np0CxIqUiCg&D737%4p%J@KizvHCf*W+Vf_|!Rq@8{|)4-ZFt z66eFiAw#mEUt1&)QAl`jbUaPncyoY*wkH%2doS3Y=F8CtekZm9&bUp@*o^#B%z1Yt z7027Y5^Go4jBnL+<`P2^1-I}7aJ}}H?~`Xc6K6>HUUx0Du)a#cDnLAqtZ*Eye2P~p z!VR%k0Jv5ypjwZ2abDXo-_Jt|;&+lmh>blVdD`_MFQM-@jVX5JFR~9^ zPhG%YbQ2NDu2KVu-8=Zt6qg{4IG5%d2JvX3>SgE8vGlkz z#oD(i3>;nhw_86Irrvn0HhG2BWYE04=6xJ8{DklReY^cNXUd*$^gYe;rK1z-XsoTZ zA4+_E;U8dGj1iHqR4Cvw?B27f`Kq-4Xx|>a-W`!1HZudT6c`3_Tl*o;aV1=h{`iq# zqnWYAJ&dny>1yy56zq2mZ1kv}DAwQEJ{LayHSwK`AFDy!^nOIE4_oXsjb&rp01z&& zY>w)Vjd@GSTG2De=ux+vau%dC(4JAG0j322WJ&t~S>}>~J|7*Z-(4W8RK1}9HwB+E zli8-MJ-*1RycEhNJll)7w55A&nvmQvoZ5_Rx<0ypnI(}9-qNB{K+bO@h#I;Hj93qS z+fA~LTuEXe>`gtP?Gf%!PV#j@^m#R2=JhaHQ3~gEXxMOhL>{gH~{oy#cay6hEB`K!)~SGF^Ka~*K+hRdfCRsCi0&u>NmrBo}16qRyfVugiS_Z_40yHN^K}w0mto+!3*yq&hrJiNJy-=?+v;QU809SkK|nHZHzrDu*Y~yW33-Avw_ovZdBMyQ2$L zT$l=(Sb1T*cjk-ei3?_Z-2e&0a($H>6(YzzD@OFpK!5EC$aS{NWD#!F5vytdK^IM8!eRwm|q1vMJ(Q{RQsVWTrZ z4<#r3kDb>-QJjU#^4E%Gm^@WfBV2aeWJ9KpBBMP zX{#PGrF;=H`9j=Ok7i+BAj-Z_3}eNzr15EPKD~b=*jD2g*2#uD^;Fj*6EW~X?=K$D zjsHny#^J@3wsT*YH!6+_WCKecSMSR!v?gKTyQH8Pn72;U=j_`a-J-hRfhFwZGrg`$eF$S>1S>C3v;QKYo|tlC!(foY;b(tVz0i-%=e9{7 zpT&eQ&o%mCG#Xz`+Le2}rSNUs)3-1za+sH_)Yd;}crKg37$qMt?Dk6ir8f(H4O(Hl zSUE!vDH$4`d4EBqh2wv4*6Y^=14h}C{rJt+f8o`78{@BeN-H28L557yQ=cagJ*<|O z){*Te$nh%g%FJEa;=#^-O-aY9<>D@dLs8%%*p`}5;lZ6`A^y(k^eqSQ2+Dk%XEe63 zH1)r6!rWLq`wj?<9QjRSh(HrRczy+7Qc93-S?iAX^bz`QcIMOlZwno2@S*)yd<-*J z)XIR8>|by)I6fsIy16UhFFd*I%g;1Yrihl?@Gv<#pdN6qrmg*4K|!Iag(Ro&G5AWG z4BM49{@r0{qkrt=LUxu|=(!X952c(Y(veW)#ug{61gfSbV5rubS$0EQ}i*R@Q8gSfC3;neDp15A-O{vcw;aAOqT+2x|o2&<(#U1TI+9 z*VlKi&^NZEv~JVtJ1Up-kIB=vtv-U*mGhncz+;_t%;@1v#pgXPsKD_n?#k<(;k8DQ zk>3?}HqiNuTA=mO%-s=AArdg8T5#}P{F%8Yk-qLkHiPD1gZDL5i*mGv%=adWX!3K6@xW2s=3G_0zO8*!{bpAXsmf&6X!PvCT4(mw>wNRIg% zd$eV<@Qj&?0*I#0P5y**8a>^y924bXsKh|81;feI=2?B9g*z3dN$y;AK{L3}dAhML z(uO>gQcBsA=kr%pY7;%dMh$PEX6vVt8dZVlj`@tv|?99Tc8@D-!C;TQZ3RxuFExKa@>%s z9CD2VVq6K2?tS%pL?v|cN^NQtJM^{Bqa1ON{g6e`4GifW8*xsB#lgQo>KrJb=O5&7 zk& zm4dy17M~mCsrIw|_`cr&!%zcb7R?^&Y>J9LefxXylvU|M(zcr;XxyWg zMI?gwAbE=XjEJjQraQz|4Sps(F3H?;EJ=xKh#$$xBGN$5oToyz@WXof@Xm*b?S!PB zrh04vwaZqY2ZZ~lYgPJS;qIkRCIQE3uR3`i804)HWqZE(gzN2(Xj!fs(&Z{)kyj$v z!2aA=5PW?@Cvv!4;trkNp{#2mMWmh|kLO064wT$j$f~F#t{7=}$&ZiBDlOkY4+v6O z{wszO_;~iqP^bOpH|&onYB0!kMcTcc$tgJ-Fan+`#JF#H^WiL`>M_CrjS3O*Go35q zYSLT8gi<^ z@10L|CI-T~HPW010!SlCN;T&ojG#EK>!n+KSZXTCsxb5GqXst*^DQw`1;%9ASUVHv zmvaNC6kH_5u`Aco$O-Z4?n(D6oBfR&?Kufu z1qE~&Sy@H3^LL-LZ9!`2#Cm>~9y+AF&D}47SLd&+J4KGrj5UhFEHWDzqo{*N5zX#VD|;EhysDDpZWAMHYyk$z$%nWx;a& zKr2iu)d8B8@dRpF!}Rlmg+zehH(IarG{YOHlpf z@b2!;+?!uc4KDSh?yKl?wDW9*i3qZ|Jz8nUvmS~a5qtmR1KMd9Ib zpSfa9t(K=681=X?fc2NzhRB;fU>Rve~@Eh zVvki3y2{4mGSi`Gl=ce{^I3~dclU{OM>yJ-i5XqRsO4S=wpV4Tp57czeAAR!^~_C6 zd%kDDYf5@9a_7HcwP#l7>8n+4kGbCpoTN*@_(7H}$ldErnF3_-w^jUqTV-4i$bp0yE6c&af^9IMP?;eTo%5=6I@r1~p(w z@vgo7w0%Z+0K#%Dih4$cY0m^#*Ccew@lxsx5?0%6C)`L9v>|??5y_U(g4v?u5pH-y z@uNam#h3*2@n^AT5TuiA=rvi2nn2L{hqWu)(|Wz00x{AZ{H9Rem2R5j%K~)r6TpNF zaMm9Mj={&TlxJXMpjR-8u>}|RN7xZLNf>7EB=OMV{>z*U@OGm3k{N>}1}s)`N{8Ih zZtnn&2`yD{IK1sCy5!Wt3+?_=P*8=^n6P};(U}Ft?!K^!R8Jql@m*2IW+03_1K3Wh z5FX3|^j{IhI!k5C2wJN5@SaH_||l~O`ZQBTT8>?*XB z-*LxW`0X*-CazwYXDCrcMX+A|zMKjC(9B}XgNt?+5fV|#J}0rz`kM8}h?~bieR#^O zcv)u$2~UpEM|rC`jTHY@??`@<<|9`1Z+EX1sO(HCE$OIAK4j&52#oxyvPuVU$kKq< z(XwGZdi}JxLe-S-6~6OU~sfKM3D{0964F&{{kKRU8Z)ybsYRLdvosp1K? zSJ%vfwJD)vg{F3fi%yp6RRnk7$TIfv`NOd63T;TE@TpTx*0Lw2u6^|w#O=JE zgHm3s{;!w9 zqZe6LZW`WkIrC;OuX*>pYJ$_6C~YhF(2q&hOwb?C+$yN2Ry&;}ZdNq4Z*{W~K3pR~ zmeQz#m96dRsdGtn<=4H5E-F4LFovJeevlq%tEP6I zl9Sv69d=5$gqo3Gpf8RAT7vz=xQj}WuU|J@9GtKx_)+v}R9FNQMN;|fqkK0G2w#@i zNUL=ytIXe$W?EP3XI`cqF(K`GfesSVvmDBZg@g{G-M4rx?J!%{1hEsc zb-R4N6y>01Fzv6^G*Kn7x!S$Zpk3jhv`;_t5>CUl@@ye;>-B}S!1EjBv~CKkM{WWd znhv*5xLQG=GRI50YP5thM;A1$pdo`DTUaL}2lc<+Bh6qOjn`bWsMgJGNFh`H5zsra zktS`y#)Qawmc5SVvlGnCl7Er9u@brhFC1NKn`jlSNp7ll`VXYlXk+y+oXm znLVu<7xMsy>9&)?Twx7hY%+dkqhe@VU(m}2tfw|VeLf+9;@r#G<-;{Yp2OWXZSHJ| zP5#EqIE#KG^IkVS#C>uFlYHx$R{udGDd!-T>)sysOZxgqBjQGk6`q)4;WMU~4SbZ0 zj;oheo1L%a@%myXIu^T#0=N6TVx6#ElV@Ek_Od}%YwBCsjok~Qkx?%{CT>%Xmm8gvQor~eU_iap)K3{qG~oG2p`rZ;4nrW9=MG+2WxdI|xdPSgssz*5X_)HeZ$8 zofA88w%B!c6?bfZpgeR`U08U}35;A9TwW!OvZpcp*0(*ZofK#vHiyAcV%@z2l|dZQou0Cya0SCJWTPU2cMlGX@Aj25eSP%XU1(SrI;FY}4L z-TmPadoxaLNaNkP+nWa|;)UHBEd+#Z%2Vd37odY)pg1-6_^poc-Mk=vVd}KDz6ie0 zv#U4ETd%!Arf<@BJ3`JD#20IFF2Ry#M}fD0$nGcs@&Z{Zi?PJ0?fbjeiO}856X>$* z2O5C%@{|$@Tf9nwHSp>^mO6A;&wi;uAR-2r)N`ckC3i>~EsuAml3m5sk#3l$lU;px z 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 Date: Sun, 5 Sep 2021 14:42:49 +0300 Subject: [PATCH 22/25] update summary --- docs/summary.PNG | Bin 45312 -> 0 bytes docs/summary.png | Bin 0 -> 66891 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/summary.PNG create mode 100644 docs/summary.png diff --git a/docs/summary.PNG b/docs/summary.PNG deleted file mode 100644 index 0274a8d687215a84f2903bd365ebe3d3a021fba1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45312 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

i|u&1CTKdKJkh9=W&QcdeV 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 tp diff --git a/docs/summary.png b/docs/summary.png new file mode 100644 index 0000000000000000000000000000000000000000..da405856c9f4bb6a0f7b415e64d07afbec38488d GIT binary patch literal 66891 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

wKdj0`nVD9D+AyFn16F_cC`N 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 JKH`1zKLAd!XGQ=3 literal 0 HcmV?d00001 From 6137aa5d8e1f7761eef2eccc26729ff5bc4e76ab Mon Sep 17 00:00:00 2001 From: dwertent Date: Thu, 9 Sep 2021 17:15:55 +0300 Subject: [PATCH 23/25] support fronegg --- cautils/customerloader.go | 167 ++++++++++++++++++ cautils/getter/armoapi.go | 42 +++-- cautils/getter/armoapiutils.go | 44 +++++ cmd/framework.go | 33 ++-- opaprocessor/processorhandler.go | 4 +- .../reporter/reporteventreceiverutils.go | 9 +- 6 files changed, 264 insertions(+), 35 deletions(-) create mode 100644 cautils/customerloader.go create mode 100644 cautils/getter/armoapiutils.go diff --git a/cautils/customerloader.go b/cautils/customerloader.go new file mode 100644 index 00000000..664c3ee2 --- /dev/null +++ b/cautils/customerloader.go @@ -0,0 +1,167 @@ +package cautils + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/url" + + "github.com/armosec/kubescape/cautils/getter" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/armosec/kubescape/cautils/k8sinterface" + corev1 "k8s.io/api/core/v1" +) + +const ( + configMapName = "kubescape" + configFileName = "config" +) + +type ConfigObj struct { + CustomerGUID string `json:"customerGUID"` + ClusterName string `json:"clusterName"` + Token string `json:"token"` +} +type IClusterConfig interface { + SetCustomerGUID() + SetClusterName() + + GetCustomerGUID() + GetClusterName() + + GenerateURL() string +} + +type ClusterConfig struct { + k8s *k8sinterface.KubernetesApi + defaultNS string + armoAPI *getter.ArmoAPI + configObj *ConfigObj +} + +func NewClusterConfig(k8s *k8sinterface.KubernetesApi, armoAPI *getter.ArmoAPI) *ClusterConfig { + return &ClusterConfig{ + k8s: k8s, + armoAPI: armoAPI, + defaultNS: "default", // TODO - load default namespace from k8s api + } +} +func (c *ClusterConfig) update(configObj *ConfigObj) { + c.configObj = configObj +} +func (c *ClusterConfig) SetClusterName() { + // k8sinterface.K8SConfig. +} +func (c *ClusterConfig) GenerateURL() string { + u := url.URL{} + u.Scheme = "https" + u.Host = getter.ArmoFEURL + u.Path = "account/signup" + q := u.Query() + q.Add("invitationToken", c.configObj.Token) + q.Add("customerGUID", c.configObj.CustomerGUID) + + u.RawQuery = q.Encode() + + return u.String() +} +func (c *ClusterConfig) GetClusterName() string { + return c.configObj.ClusterName +} +func (c *ClusterConfig) GetCustomerGUID() string { + return c.configObj.CustomerGUID +} +func (c *ClusterConfig) SetCustomerGUID() error { + + // get from configMap + if configObj, _ := c.loadConfigFromConfigMap(); configObj != nil { + c.update(configObj) + return nil + } + + // get from file + if configObj, _ := c.loadConfigFromFile(); configObj != nil { + c.update(configObj) + c.updateConfigMap() + return nil + } + + // get from armoBE + if tenantResponse, err := c.armoAPI.GetCustomerGUID(); tenantResponse != nil { + c.update(&ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token}) + return c.updateConfigMap() + } else { + return err + } +} + +func (c *ClusterConfig) loadConfigFromConfigMap() (*ConfigObj, error) { + if c.k8s == nil { + return nil, nil + } + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + if bData, err := json.Marshal(configMap.Data); err == nil { + return readConfig(bData) + } + return nil, nil +} + +func (c *ClusterConfig) updateConfigMap() error { + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + if err != nil { + configMap = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + }, + } + } + + c.updateConfigMapData(configMap) + + if err != nil { + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) + } else { + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(configMap.Namespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) + } + return err +} +func (c *ClusterConfig) updateConfigMapData(configMap *corev1.ConfigMap) { + if len(configMap.Data) == 0 { + configMap.Data = make(map[string]string) + } + m := c.ToMapString() + for k, v := range m { + if s, ok := v.(string); ok { + configMap.Data[k] = s + } + } +} +func (c *ClusterConfig) loadConfigFromFile() (*ConfigObj, error) { + dat, err := ioutil.ReadFile(configFileName) + if err != nil { + return nil, err + } + + return readConfig(dat) +} +func readConfig(dat []byte) (*ConfigObj, error) { + + if len(dat) == 0 { + return nil, nil + } + configObj := &ConfigObj{} + err := json.Unmarshal(dat, configObj) + + return configObj, err +} +func (c *ClusterConfig) ToMapString() map[string]interface{} { + m := map[string]interface{}{} + bc, _ := json.Marshal(c.configObj) + json.Unmarshal(bc, &m) + return m +} diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index f0e515ec..d9ae1b02 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -1,9 +1,7 @@ package getter import ( - "fmt" "net/http" - "strings" "github.com/armosec/kubescape/cautils/armotypes" "github.com/armosec/kubescape/cautils/opapolicy" @@ -13,16 +11,21 @@ import ( // =============================================== ArmoAPI =============================================================== // ======================================================================================================================= +const ( + ArmoBEURL = "eggdashbe.eudev3.cyberarmorsoft.com" + ArmoERURL = "report.eudev3.cyberarmorsoft.com" + ArmoFEURL = "armoui.eudev3.cyberarmorsoft.com" + // ArmoURL = "https://dashbe.euprod1.cyberarmorsoft.com" +) + // Armo API for downloading policies type ArmoAPI struct { httpClient *http.Client - baseURL string } func NewArmoAPI() *ArmoAPI { return &ArmoAPI{ httpClient: &http.Client{}, - baseURL: "https://dashbe.euprod1.cyberarmorsoft.com", } } func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) { @@ -40,15 +43,6 @@ func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) return framework, err } -func (armoAPI *ArmoAPI) getFrameworkURL(frameworkName string) string { - requestURI := "v1/armoFrameworks" - requestURI += fmt.Sprintf("?customerGUID=%s", "11111111-1111-1111-1111-111111111111") - requestURI += fmt.Sprintf("&frameworkName=%s", strings.ToUpper(frameworkName)) - requestURI += "&getRules=true" - - return urlEncoder(fmt.Sprintf("%s/%s", armoAPI.baseURL, requestURI)) -} - func (armoAPI *ArmoAPI) GetExceptions(customerGUID, clusterName string) ([]armotypes.PostureExceptionPolicy, error) { exceptions := []armotypes.PostureExceptionPolicy{} if customerGUID == "" { @@ -66,11 +60,21 @@ func (armoAPI *ArmoAPI) GetExceptions(customerGUID, clusterName string) ([]armot return exceptions, nil } -func (armoAPI *ArmoAPI) getExceptionsURL(customerGUID, clusterName string) string { - requestURI := "api/v1/armoPostureExceptions" - requestURI += fmt.Sprintf("?customerGUID=%s", customerGUID) - if clusterName != "" { - requestURI += fmt.Sprintf("&clusterName=%s", clusterName) +func (armoAPI *ArmoAPI) GetCustomerGUID() (*TenantResponse, error) { + respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getCustomerURL()) + if err != nil { + return nil, err } - return urlEncoder(fmt.Sprintf("%s/%s", armoAPI.baseURL, requestURI)) + tenant := &TenantResponse{} + if err = JSONDecoder(respStr).Decode(tenant); err != nil { + return nil, err + } + + return tenant, nil +} + +type TenantResponse struct { + TenantID string `json:"tenantId"` + Token string `json:"token"` + Expires string `json:"expires"` } diff --git a/cautils/getter/armoapiutils.go b/cautils/getter/armoapiutils.go new file mode 100644 index 00000000..30bbdafc --- /dev/null +++ b/cautils/getter/armoapiutils.go @@ -0,0 +1,44 @@ +package getter + +import ( + "net/url" + "strings" +) + +func (armoAPI *ArmoAPI) getFrameworkURL(frameworkName string) string { + u := url.URL{} + u.Scheme = "https" + u.Host = ArmoBEURL + u.Path = "v1/armoFrameworks" + q := u.Query() + q.Add("customerGUID", "11111111-1111-1111-1111-111111111111") + q.Add("frameworkName", strings.ToUpper(frameworkName)) + q.Add("getRules", "true") + u.RawQuery = q.Encode() + + return u.String() +} + +func (armoAPI *ArmoAPI) getExceptionsURL(customerGUID, clusterName string) string { + u := url.URL{} + u.Scheme = "https" + u.Host = ArmoBEURL + u.Path = "api/v1/armoPostureExceptions" + + q := u.Query() + q.Add("customerGUID", customerGUID) + if clusterName != "" { + q.Add("clusterName", clusterName) + } + u.RawQuery = q.Encode() + + return u.String() +} + +func (armoAPI *ArmoAPI) getCustomerURL() string { + u := url.URL{} + u.Scheme = "https" + u.Host = ArmoBEURL + u.Path = "api/v1/createTenant" + return u.String() +} diff --git a/cmd/framework.go b/cmd/framework.go index d5622148..59682b6d 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -10,6 +10,7 @@ import ( "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/armotypes" + "github.com/armosec/kubescape/cautils/getter" "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/armosec/kubescape/cautils/opapolicy" "github.com/armosec/kubescape/opaprocessor" @@ -115,11 +116,22 @@ func CliSetup() error { // policy handler setup policyHandler := policyhandler.NewPolicyHandler(&processNotification, k8s) - // cli handler setup - cli := NewCLIHandler(policyHandler) - if err := cli.Scan(); err != nil { - panic(err) + // load cluster config + clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI()) + if err := clusterConfig.SetCustomerGUID(); err != nil { + fmt.Println(err) } + cautils.CustomerGUID = clusterConfig.GetCustomerGUID() + cautils.ClusterName = "minikube" // clusterConfig.GetClusterName() + + // cli handler setup + go func() { + cli := NewCLIHandler(policyHandler) + if err := cli.Scan(); err != nil { + fmt.Println(err) + os.Exit(1) + } + }() // processor setup - rego run go func() { @@ -130,6 +142,9 @@ func CliSetup() error { resultsHandling := resultshandling.NewResultsHandler(&reportResults, reporter.NewReportEventReceiver(), printer.NewPrinter(scanInfo.Format, scanInfo.Output)) score := resultsHandling.HandleResults() + // print report url + fmt.Println(clusterConfig.GenerateURL()) + adjustedFailThreshold := float32(scanInfo.FailThreshold) / 100 if score < adjustedFailThreshold { return fmt.Errorf("Scan score is bellow threshold") @@ -156,12 +171,10 @@ func (clihandler *CLIHandler) Scan() error { } switch policyNotification.NotificationType { case opapolicy.TypeExecPostureScan: - go func() { - if err := clihandler.policyHandler.HandleNotificationRequest(policyNotification, clihandler.scanInfo); err != nil { - fmt.Printf("%v\n", err) - os.Exit(0) - } - }() + // + if err := clihandler.policyHandler.HandleNotificationRequest(policyNotification, clihandler.scanInfo); err != nil { + return err + } default: return fmt.Errorf("notification type '%s' Unknown", policyNotification.NotificationType) } diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 3be0c4ca..6fdea3f4 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -13,11 +13,11 @@ import ( "github.com/armosec/kubescape/cautils/opapolicy" "github.com/armosec/kubescape/cautils/opapolicy/resources" - "github.com/golang/glog" "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/rego" "github.com/open-policy-agent/opa/storage" + uuid "github.com/satori/go.uuid" ) const ScoreConfigPath = "/resources/config" @@ -92,6 +92,7 @@ func (opap *OPAProcessor) Process() error { } opap.PostureReport.FrameworkReports = frameworkReports + opap.PostureReport.ReportID = uuid.NewV4().String() opap.PostureReport.ReportGenerationTime = time.Now().UTC() // glog.Infof(fmt.Sprintf("Done 'Process'. reportID: %s", opap.PostureReport.ReportID)) cautils.StopSpinner() @@ -104,6 +105,7 @@ func (opap *OPAProcessor) processFramework(framework *opapolicy.Framework) (*opa frameworkReport := opapolicy.FrameworkReport{} frameworkReport.Name = framework.Name + controlReports := []opapolicy.ControlReport{} for i := range framework.Controls { controlReport, err := opap.processControl(&framework.Controls[i]) diff --git a/resultshandling/reporter/reporteventreceiverutils.go b/resultshandling/reporter/reporteventreceiverutils.go index d0ce0c43..ee26e203 100644 --- a/resultshandling/reporter/reporteventreceiverutils.go +++ b/resultshandling/reporter/reporteventreceiverutils.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/getter" "github.com/gofrs/uuid" ) @@ -36,12 +37,12 @@ func initEventReceiverURL() *url.URL { urlObj := url.URL{} urlObj.Scheme = "https" - urlObj.Host = "report.euprod1.cyberarmorsoft.com" + urlObj.Host = getter.ArmoERURL urlObj.Path = "/k8s/postureReport" - q := urlObj.Query() q.Add("customerGUID", uuid.FromStringOrNil(cautils.CustomerGUID).String()) q.Add("clusterName", cautils.ClusterName) + urlObj.RawQuery = q.Encode() return &urlObj @@ -49,9 +50,7 @@ func initEventReceiverURL() *url.URL { func hostToString(host *url.URL, reportID string) string { q := host.Query() - if reportID != "" { - q.Add("reportID", reportID) // TODO - do we add the reportID? - } + q.Add("reportID", reportID) // TODO - do we add the reportID? host.RawQuery = q.Encode() return host.String() } From b9e57822649bebfa0cbc5a7ace95fe9a5dc3bebe Mon Sep 17 00:00:00 2001 From: dwertent Date: Fri, 10 Sep 2021 00:56:51 +0300 Subject: [PATCH 24/25] support self registeration --- cautils/customerloader.go | 30 +++++----- cautils/getter/armoapi.go | 2 +- cautils/getter/downloadreleasedpolicy.go | 2 +- cautils/getter/getpoliciesutils.go | 4 +- cautils/k8sinterface/k8sconfig.go | 10 +++- cautils/opapolicy/datastructuresmethods.go | 59 +++++++++++++++++++ cautils/scaninfo.go | 2 +- cmd/download.go | 2 +- cmd/framework.go | 21 ++++++- resultshandling/printer/printresults.go | 2 +- .../reporter/reporteventreceiver.go | 1 + resultshandling/results.go | 4 +- 12 files changed, 112 insertions(+), 27 deletions(-) diff --git a/cautils/customerloader.go b/cautils/customerloader.go index 664c3ee2..359264b5 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -20,16 +20,19 @@ const ( type ConfigObj struct { CustomerGUID string `json:"customerGUID"` - ClusterName string `json:"clusterName"` Token string `json:"token"` } + +func (co *ConfigObj) Json() []byte { + if b, err := json.Marshal(co); err == nil { + return b + } + return []byte{} +} + type IClusterConfig interface { SetCustomerGUID() - SetClusterName() - GetCustomerGUID() - GetClusterName() - GenerateURL() string } @@ -49,9 +52,7 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, armoAPI *getter.ArmoAPI) } func (c *ClusterConfig) update(configObj *ConfigObj) { c.configObj = configObj -} -func (c *ClusterConfig) SetClusterName() { - // k8sinterface.K8SConfig. + ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), c.configObj.Json(), 0664) } func (c *ClusterConfig) GenerateURL() string { u := url.URL{} @@ -66,9 +67,7 @@ func (c *ClusterConfig) GenerateURL() string { return u.String() } -func (c *ClusterConfig) GetClusterName() string { - return c.configObj.ClusterName -} + func (c *ClusterConfig) GetCustomerGUID() string { return c.configObj.CustomerGUID } @@ -112,6 +111,9 @@ func (c *ClusterConfig) loadConfigFromConfigMap() (*ConfigObj, error) { } func (c *ClusterConfig) updateConfigMap() error { + if c.k8s == nil { + return nil + } configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) if err != nil { configMap = &corev1.ConfigMap{ @@ -121,7 +123,7 @@ func (c *ClusterConfig) updateConfigMap() error { } } - c.updateConfigMapData(configMap) + c.updateConfigData(configMap) if err != nil { _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) @@ -130,7 +132,7 @@ func (c *ClusterConfig) updateConfigMap() error { } return err } -func (c *ClusterConfig) updateConfigMapData(configMap *corev1.ConfigMap) { +func (c *ClusterConfig) updateConfigData(configMap *corev1.ConfigMap) { if len(configMap.Data) == 0 { configMap.Data = make(map[string]string) } @@ -142,7 +144,7 @@ func (c *ClusterConfig) updateConfigMapData(configMap *corev1.ConfigMap) { } } func (c *ClusterConfig) loadConfigFromFile() (*ConfigObj, error) { - dat, err := ioutil.ReadFile(configFileName) + dat, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) if err != nil { return nil, err } diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index d9ae1b02..ca60e2df 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -38,7 +38,7 @@ func (armoAPI *ArmoAPI) GetFramework(name string) (*opapolicy.Framework, error) if err = JSONDecoder(respStr).Decode(framework); err != nil { return nil, err } - SaveFrameworkInFile(framework, GetDefaultPath(name)) + SaveFrameworkInFile(framework, GetDefaultPath(name+".json")) return framework, err } diff --git a/cautils/getter/downloadreleasedpolicy.go b/cautils/getter/downloadreleasedpolicy.go index 837150c0..bfc06f72 100644 --- a/cautils/getter/downloadreleasedpolicy.go +++ b/cautils/getter/downloadreleasedpolicy.go @@ -43,7 +43,7 @@ func (drp *DownloadReleasedPolicy) GetFramework(name string) (*opapolicy.Framewo return framework, err } - SaveFrameworkInFile(framework, GetDefaultPath(name)) + SaveFrameworkInFile(framework, GetDefaultPath(name+".json")) return framework, err } diff --git a/cautils/getter/getpoliciesutils.go b/cautils/getter/getpoliciesutils.go index e0faadb1..8eba7a87 100644 --- a/cautils/getter/getpoliciesutils.go +++ b/cautils/getter/getpoliciesutils.go @@ -13,8 +13,8 @@ import ( "github.com/armosec/kubescape/cautils/opapolicy" ) -func GetDefaultPath(frameworkName string) string { - defaultfilePath := filepath.Join(DefaultLocalStore, frameworkName+".json") +func GetDefaultPath(name string) string { + defaultfilePath := filepath.Join(DefaultLocalStore, name) if homeDir, err := os.UserHomeDir(); err == nil { defaultfilePath = filepath.Join(homeDir, defaultfilePath) } diff --git a/cautils/k8sinterface/k8sconfig.go b/cautils/k8sinterface/k8sconfig.go index 79fda28a..dae322de 100644 --- a/cautils/k8sinterface/k8sconfig.go +++ b/cautils/k8sinterface/k8sconfig.go @@ -6,6 +6,8 @@ import ( "os" "strings" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" @@ -17,6 +19,7 @@ import ( // K8SConfig pointer to k8s config var K8SConfig *restclient.Config +var K8SCmdConfig clientcmd.ClientConfig // KubernetesApi - type KubernetesApi struct { @@ -51,13 +54,15 @@ var RunningIncluster bool // LoadK8sConfig load config from local file or from cluster func LoadK8sConfig() error { + kubeconfig, err := config.GetConfig() if err != nil { - return fmt.Errorf("failed to load kubernetes config: %s\n", strings.ReplaceAll(err.Error(), "KUBERNETES_MASTER", "KUBECONFIG")) + return fmt.Errorf("failed to load kubernetes config: %s", strings.ReplaceAll(err.Error(), "KUBERNETES_MASTER", "KUBECONFIG")) } if _, err := restclient.InClusterConfig(); err == nil { RunningIncluster = true } + K8SConfig = kubeconfig return nil } @@ -66,8 +71,7 @@ func LoadK8sConfig() error { func GetK8sConfig() *restclient.Config { if K8SConfig == nil { if err := LoadK8sConfig(); err != nil { - // print error - fmt.Printf("%s", err.Error()) + fmt.Println(err.Error()) os.Exit(1) } } diff --git a/cautils/opapolicy/datastructuresmethods.go b/cautils/opapolicy/datastructuresmethods.go index 5c81ddc2..c503707f 100644 --- a/cautils/opapolicy/datastructuresmethods.go +++ b/cautils/opapolicy/datastructuresmethods.go @@ -137,3 +137,62 @@ func (ruleReport *RuleReport) GetNumberOfWarningResources() int { } return sum } + +func (postureReport *PostureReport) RemoveData() { + for i := range postureReport.FrameworkReports { + postureReport.FrameworkReports[i].RemoveData() + } +} +func (frameworkReport *FrameworkReport) RemoveData() { + for i := range frameworkReport.ControlReports { + frameworkReport.ControlReports[i].RemoveData() + } +} +func (controlReport *ControlReport) RemoveData() { + for i := range controlReport.RuleReports { + controlReport.RuleReports[i].RemoveData() + } +} + +func (ruleReport *RuleReport) RemoveData() { + for i := range ruleReport.RuleResponses { + ruleReport.RuleResponses[i].RemoveData() + } +} + +func (r *RuleResponse) RemoveData() { + r.AlertObject.ExternalObjects = nil + + keepFields := []string{"kind", "apiVersion", "metadata"} + keepMetadataFields := []string{"name", "namespace", "labels"} + + for i := range r.AlertObject.K8SApiObjects { + deleteFromMap(r.AlertObject.K8SApiObjects[i], keepFields) + for k := range r.AlertObject.K8SApiObjects[i] { + if k == "metadata" { + if b, ok := r.AlertObject.K8SApiObjects[i][k].(map[string]interface{}); ok { + deleteFromMap(b, keepMetadataFields) + r.AlertObject.K8SApiObjects[i][k] = b + } + } + } + } +} + +func deleteFromMap(m map[string]interface{}, keepFields []string) { + for k := range m { + if StringInSlice(keepFields, k) { + continue + } + delete(m, k) + } +} + +func StringInSlice(strSlice []string, str string) bool { + for i := range strSlice { + if strSlice[i] == str { + return true + } + } + return false +} diff --git a/cautils/scaninfo.go b/cautils/scaninfo.go index 16ddfdac..0f1ac67c 100644 --- a/cautils/scaninfo.go +++ b/cautils/scaninfo.go @@ -48,7 +48,7 @@ func (scanInfo *ScanInfo) setUseFrom() { return } if scanInfo.UseDefault { - scanInfo.UseFrom = getter.GetDefaultPath(scanInfo.PolicyIdentifier.Name) + scanInfo.UseFrom = getter.GetDefaultPath(scanInfo.PolicyIdentifier.Name + ".json") } } diff --git a/cmd/download.go b/cmd/download.go index 5131ea33..dfe69a58 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -24,7 +24,7 @@ var downloadCmd = &cobra.Command{ downloadInfo.FrameworkName = args[1] g := getter.NewDownloadReleasedPolicy() if downloadInfo.Path == "" { - downloadInfo.Path = getter.GetDefaultPath(downloadInfo.FrameworkName) + downloadInfo.Path = getter.GetDefaultPath(downloadInfo.FrameworkName + ".json") } frameworks, err := g.GetFramework(downloadInfo.FrameworkName) if err != nil { diff --git a/cmd/framework.go b/cmd/framework.go index 59682b6d..7e0c1111 100644 --- a/cmd/framework.go +++ b/cmd/framework.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "os" "strings" @@ -122,7 +123,7 @@ func CliSetup() error { fmt.Println(err) } cautils.CustomerGUID = clusterConfig.GetCustomerGUID() - cautils.ClusterName = "minikube" // clusterConfig.GetClusterName() + cautils.ClusterName = generateClusterName() // cli handler setup go func() { @@ -180,3 +181,21 @@ func (clihandler *CLIHandler) Scan() error { } return nil } + +func generateClusterName() string { + name := fmt.Sprintf("%d", rand.Int()) + if k8sinterface.K8SConfig == nil { + return name + } + if k8sinterface.K8SConfig.Host != "" { + name = k8sinterface.K8SConfig.Host + } else if k8sinterface.K8SConfig.ServerName != "" { + name = k8sinterface.K8SConfig.ServerName + } + + name = strings.ReplaceAll(name, ".", "-") + name = strings.ReplaceAll(name, " ", "-") + name = strings.ReplaceAll(name, "https://", "") + name = strings.ReplaceAll(name, ":", "-") + return name +} diff --git a/resultshandling/printer/printresults.go b/resultshandling/printer/printresults.go index 78f52c3c..0e43ad86 100644 --- a/resultshandling/printer/printresults.go +++ b/resultshandling/printer/printresults.go @@ -247,7 +247,7 @@ func (printer *Printer) getSortedControlsNames() []string { } func getWriter(outputFile string) *os.File { - + os.Remove(outputFile) if outputFile != "" { f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { diff --git a/resultshandling/reporter/reporteventreceiver.go b/resultshandling/reporter/reporteventreceiver.go index 9fff9879..efe57f27 100644 --- a/resultshandling/reporter/reporteventreceiver.go +++ b/resultshandling/reporter/reporteventreceiver.go @@ -28,6 +28,7 @@ func (report *ReportEventReceiver) ActionSendReportListenner(opaSessionObj *caut if cautils.CustomerGUID == "" { return } + opaSessionObj.PostureReport.RemoveData() if err := report.Send(opaSessionObj.PostureReport); err != nil { fmt.Println(err) } diff --git a/resultshandling/results.go b/resultshandling/results.go index 31b95f82..64ace984 100644 --- a/resultshandling/results.go +++ b/resultshandling/results.go @@ -24,9 +24,9 @@ func (resultsHandler *ResultsHandler) HandleResults() float32 { opaSessionObj := <-*resultsHandler.opaSessionObj - resultsHandler.reporterObj.ActionSendReportListenner(opaSessionObj) - score := resultsHandler.printerObj.ActionPrint(opaSessionObj) + resultsHandler.reporterObj.ActionSendReportListenner(opaSessionObj) + return score } From c9ecb6c563c8c9ccc4f8e4f000693e827897ffc4 Mon Sep 17 00:00:00 2001 From: Daniel Grunberger <84905812+Daniel-GrunbergerCA@users.noreply.github.com> Date: Fri, 10 Sep 2021 00:57:33 +0300 Subject: [PATCH 25/25] Add version handling (#67) * start version handling * add version handling * update latest version check * update build.yaml * erase unused vars * fix build.yaml * fix var name * handle error --- .github/workflows/build.yaml | 6 ++--- cmd/version.go | 49 ++++++++++++++++++++++++++++++++++++ main.go | 18 ++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 cmd/version.go diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 17592e0d..d0aea435 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,7 +6,6 @@ on: pull_request: branches: [ master ] types: [ closed ] - jobs: once: name: Create release @@ -38,9 +37,10 @@ jobs: uses: actions/setup-go@v2 with: go-version: 1.16 - - name: Build - run: mkdir -p build/${{ matrix.os }} && go mod tidy && go build -ldflags "-w -s" -o build/${{ matrix.os }}/kubescape # && md5sum build/${{ matrix.os }}/kubescape > build/${{ matrix.os }}/kubescape.md5 + env: + RELEASE: v1.0.${{ github.run_number }} + run: mkdir -p build/${{ matrix.os }} && go mod tidy && go build -ldflags "-w -s -X github.com/armosec/kubescape/cmd.BuildNumber=$RELEASE" -o build/${{ matrix.os }}/kubescape # && md5sum build/${{ matrix.os }}/kubescape > build/${{ matrix.os }}/kubescape.md5 - name: Upload Release binaries id: upload-release-asset diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 00000000..e78a338f --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,49 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/spf13/cobra" +) + +var BuildNumber string + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Get current version", + Long: ``, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("Your current version is: " + BuildNumber) + return nil + }, +} + +func GetLatestVersion() (string, error) { + latestVersion := "https://api.github.com/repos/armosec/kubescape/releases/latest" + resp, err := http.Get(latestVersion) + if err != nil { + return "", fmt.Errorf("failed to get latest releases from '%s', reason: %s", latestVersion, err.Error()) + } + defer resp.Body.Close() + if resp.StatusCode < 200 || 301 < resp.StatusCode { + return "", fmt.Errorf("failed to download file, status code: %s", resp.Status) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed to read response body from '%s', reason: %s", latestVersion, err.Error()) + } + var data map[string]interface{} + err = json.Unmarshal(body, &data) + if err != nil { + return "", fmt.Errorf("failed to unmarshal response body from '%s', reason: %s", latestVersion, err.Error()) + } + return fmt.Sprintf("%v", data["tag_name"]), nil +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/main.go b/main.go index 978bbec4..114f855c 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,23 @@ package main -import "github.com/armosec/kubescape/cmd" +import ( + "fmt" + "os" + + "github.com/armosec/kubescape/cmd" +) func main() { + CheckLatestVersion() cmd.Execute() } + +func CheckLatestVersion() { + latest, err := cmd.GetLatestVersion() + if err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + } else if latest != cmd.BuildNumber { + fmt.Println("Warning: You are not updated to the latest release: " + latest) + } + +}