Merge branch 'dev'

This commit is contained in:
dwertent
2021-09-12 17:34:27 +03:00
19 changed files with 434 additions and 52 deletions

View File

@@ -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

169
cautils/customerloader.go Normal file
View File

@@ -0,0 +1,169 @@
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"`
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()
GetCustomerGUID()
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
ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), c.configObj.Json(), 0664)
}
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) 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 {
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{
ObjectMeta: metav1.ObjectMeta{
Name: configMapName,
},
}
}
c.updateConfigData(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) updateConfigData(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(getter.GetDefaultPath(configFileName + ".json"))
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
}

View File

@@ -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) {
@@ -35,20 +38,11 @@ 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
}
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"`
}

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -42,6 +42,7 @@ type FrameworkReport struct {
type ControlReport struct {
armotypes.PortalBase `json:",inline"`
Name string `json:"name"`
ID string `json:"id"`
RuleReports []RuleReport `json:"ruleReports"`
Remediation string `json:"remediation"`
Description string `json:"description"`
@@ -100,6 +101,7 @@ type PolicyRule struct {
// Control represents a collection of rules which are combined together to single purpose
type Control struct {
armotypes.PortalBase `json:",inline"`
ID string `json:"id"`
CreationTime string `json:"creationTime"`
Description string `json:"description"`
Remediation string `json:"remediation"`

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -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 {

View File

@@ -5,11 +5,13 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"strings"
"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 +117,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 = generateClusterName()
// 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 +143,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,14 +172,30 @@ 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)
}
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
}

49
cmd/version.go Normal file
View File

@@ -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)
}

18
main.go
View File

@@ -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)
}
}

View File

@@ -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"
@@ -70,7 +70,7 @@ func (opaHandler *OPAProcessorHandler) ProcessRulesListenner() {
opap.updateResults()
// update score
opap.updateScore()
// opap.updateScore()
// report
*opaHandler.reportResults <- opaSessionObj
@@ -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])
@@ -123,6 +125,7 @@ func (opap *OPAProcessor) processControl(control *opapolicy.Control) (*opapolicy
controlReport.PortalBase = control.PortalBase
controlReport.Name = control.Name
controlReport.ID = control.ID
controlReport.Description = control.Description
controlReport.Remediation = control.Remediation

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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()
}

View File

@@ -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
}