diff --git a/CHANGELOG.md b/CHANGELOG.md index 7796b7b..c15aeb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,13 @@ **Updates** +* Ability to override Statistics->Resource in server.conf.yaml * Improved the logging for metrics when authentication is not enabled * Includes IT39515 * Includes IT39573 +* Includes IT39917 +* Remove need for python +* Fix for CVE-2022-21698 ## 12.0.3.0-r1 diff --git a/ace_config_setdbparms.sh b/ace_config_setdbparms.sh index b524dfa..0c40dda 100755 --- a/ace_config_setdbparms.sh +++ b/ace_config_setdbparms.sh @@ -7,21 +7,6 @@ # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v20.html -function argStrings { - shlex() { - python -c $'import sys, shlex\nfor arg in shlex.split(sys.stdin):\n\tsys.stdout.write(arg)\n\tsys.stdout.write(\"\\0\")' - } - args=() - while IFS='' read -r -d ''; do - args+=( "$REPLY" ) - done < <(shlex <<<$1) - - log "${args[0]}" - log "${args[1]}" - log "${args[2]}" - -} - if [ -z "$MQSI_VERSION" ]; then source /opt/ibm/ace-12/server/bin/mqsiprofile fi @@ -41,19 +26,17 @@ if [ -s "/home/aceuser/initial-config/setdbparms/setdbparms.txt" ]; then continue fi IFS=${OLDIFS} - if [[ $line == mqsisetdbparms* ]]; then + if [[ $line == mqsisetdbparms* ]]; then log "Running suppplied mqsisetdbparms command" OUTPUT=`eval "$line"` else - shlex() { - python -c $'import sys, shlex\nfor arg in shlex.split(sys.stdin):\n\tsys.stdout.write(arg)\n\tsys.stdout.write(\"\\0\")' - } - args=() - while IFS='' read -r -d ''; do - args+=( "$REPLY" ) - done < <(shlex <<<$line) - log "Setting user and password for resource: ${args[0]}" - cmd="mqsisetdbparms -w /home/aceuser/ace-server -n \"${args[0]}\" -u \"${args[1]}\" -p \"${args[2]}\" 2>&1" + + printf "%s" "$line" | xargs -n 1 printf "%s\n" > /tmp/creds + IFS=$'\n' read -d '' -r -a lines < /tmp/creds + + + log "Setting user and password for resource: ${lines[0]}" + cmd="mqsisetdbparms -w /home/aceuser/ace-server -n \"${lines[0]}\" -u \"${lines[1]}\" -p \"${lines[2]}\" 2>&1" OUTPUT=`eval "$cmd"` echo $OUTPUT fi diff --git a/cmd/chkacehealthy/.gitignore b/cmd/chkacehealthy/.gitignore new file mode 100644 index 0000000..1349ec4 --- /dev/null +++ b/cmd/chkacehealthy/.gitignore @@ -0,0 +1 @@ +chkacehealthy \ No newline at end of file diff --git a/cmd/chkacehealthy/main.go b/cmd/chkacehealthy/main.go index 4735c53..987633e 100644 --- a/cmd/chkacehealthy/main.go +++ b/cmd/chkacehealthy/main.go @@ -18,17 +18,97 @@ limitations under the License. package main import ( + "context" "fmt" + "log" "net" + "net/http" "os" "time" + + "k8s.io/apimachinery/pkg/api/errors" ) +var checkACE = checkACElocal +var httpCheck = httpChecklocal +var socketCheck = socketChecklocal +var osExit = os.Exit + const restartIsTimeoutInSeconds = 60 +var netDial = net.Dial +var httpGet = http.Get + func main() { + + err := checkACE() + if err != nil { + log.Fatal(err) + } + + // If knative service also check FDR is up + knative := os.Getenv("KNATIVESERVICE") + if knative == "true" || knative == "1" { + fmt.Println("KNATIVESERVICE set so checking FDR container") + err := checkDesignerHealth() + if err != nil { + log.Fatal(err) + } + } else { + fmt.Println("KNATIVESERVICE is not set so skipping FDR checks") + } + +} + +func checkDesignerHealth() error { + // HTTP LMAP endpoint + err := httpCheck("LMAP Port", "http://localhost:3002/admin/ready") + if err != nil { + return err + } + + isConnectorService := os.Getenv("CONNECTOR_SERVICE") + if isConnectorService == "true" || isConnectorService == "1" { + // HTTP LCP Connector service endpoint + err = httpCheck("LCP Port", "http://localhost:3001/admin/ready") + if err != nil { + return err + } + } + + // LCP api flow endpoint + lcpsocket := "/tmp/lcp.socket" + if value, ok := os.LookupEnv("LCP_IPC_PATH"); ok { + lcpsocket = value + } + err = socketCheck("LCP socket", lcpsocket) + if err != nil { + return err + } + + // LMAP endpoint + lmapsocket := "/tmp/lmap.socket" + if value, ok := os.LookupEnv("LMAP_IPC_PATH"); ok { + lmapsocket = value + } + err = socketCheck("LMAP socket", lmapsocket) + if err != nil { + return err + } + + return nil +} + +func isEnvExist(key string) bool { + if _, ok := os.LookupEnv(key); ok { + return true + } + return false +} + +func checkACElocal() error { // Check if the integration server has started the admin REST endpoint - conn, err := net.Dial("tcp", "127.0.0.1:7600") + conn, err := netDial("tcp", "127.0.0.1:7600") if err != nil { @@ -38,10 +118,10 @@ func main() { if os.IsNotExist(statErr) { fmt.Println("Integration server is not active") - os.Exit(1) - } else if statErr != nil { + return errors.NewBadRequest("Integration server is not active") + } else if statErr != nil { fmt.Println(statErr) - os.Exit(1) + return errors.NewBadRequest("stat error " + statErr.Error()) } else { fmt.Println("Integration server restart file found") timeNow := time.Now() @@ -49,13 +129,49 @@ func main() { if timeDiff.Seconds() < restartIsTimeoutInSeconds { fmt.Println("Integration server is restarting") - os.Exit(0) } else { fmt.Println("Integration restart time elapsed") - os.Exit(1) + return errors.NewBadRequest("Integration restart time elapsed") } } + } else { + fmt.Println("ACE ready check passed") } conn.Close() + return nil +} + +func httpChecklocal(name string, addr string) error { + resp, err := httpGet(addr) + if err != nil { + return err + } + if resp.StatusCode != 200 { + fmt.Println(name + " ready check failed - HTTP Status is not 200 range") + return errors.NewBadRequest(name + " ready check failed - HTTP Status is not 200 range") + } else { + fmt.Println(name + " ready check passed") + } + return nil +} +func socketChecklocal(name string, socket string) error { + httpc := http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", socket) + }, + }, + } + response, err := httpc.Get("http://dummyHostname/admin/ready") + if err != nil { + return err + } + if response.StatusCode != 200 { + log.Fatal(name + " ready check failed - HTTP Status is not 200 range") + return errors.NewBadRequest(name + " ready check failed - HTTP Status is not 200 range") + } else { + fmt.Println(name + " ready check passed") + } + return nil } diff --git a/cmd/chkacehealthy/main_test.go b/cmd/chkacehealthy/main_test.go new file mode 100644 index 0000000..4406566 --- /dev/null +++ b/cmd/chkacehealthy/main_test.go @@ -0,0 +1,134 @@ +/* +© Copyright IBM Corporation 2018 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// chkacelively checks that ACE is still runing, by checking if the admin REST endpoint port is available. +package main + +import ( + "net/http" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/api/errors" +) + +func Test_httpChecklocal(t *testing.T) { + + t.Run("http get succeeds", func(t *testing.T) { + + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{ + StatusCode: 200, + } + return response, nil + } + + err := httpChecklocal("LMAP Port", "http://localhost:3002/admin/ready") + assert.Nil(t, err) + }) + + t.Run("http get fails with err on get", func(t *testing.T) { + + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{} + return response, errors.NewBadRequest("mock err") + } + + err := httpChecklocal("LMAP Port", "http://localhost:3002/admin/ready") + assert.Error(t, err, "mock err") + }) + + t.Run("http get fails with non 200", func(t *testing.T) { + + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{ + StatusCode: 404, + } + return response, nil + } + + err := httpChecklocal("Test", "http://localhost:3002/admin/ready") + assert.Error(t, err, "Test ready check failed - HTTP Status is not 200 range") + }) +} + +func Test_checkDesignerHealth(t *testing.T) { + t.Run("connector service enabled and health check is successful", func(t *testing.T) { + os.Setenv("CONNECTOR_SERVICE", "true") + defer os.Unsetenv("CONNECTOR_SERVICE") + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{ + StatusCode: 200, + } + return response, nil + } + + oldSocketCheck := socketCheck + defer func() { socketCheck = oldSocketCheck }() + socketCheck = func(string, string) (err error) { + return nil + } + err := checkDesignerHealth() + assert.Nil(t, err) + }) + + t.Run("connector service enabled and health check fails", func(t *testing.T) { + os.Setenv("CONNECTOR_SERVICE", "true") + defer os.Unsetenv("CONNECTOR_SERVICE") + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{} + return response, errors.NewBadRequest("mock err") + } + + oldSocketCheck := socketCheck + defer func() { socketCheck = oldSocketCheck }() + socketCheck = func(string, string) (err error) { + return nil + } + err := checkDesignerHealth() + assert.Error(t, err, "mock err") + }) + + t.Run("health check fails for socket http server", func(t *testing.T) { + oldhttpGet := httpGet + defer func() { httpGet = oldhttpGet }() + httpGet = func(string) (resp *http.Response, err error) { + response := &http.Response{ + StatusCode: 200, + } + return response, nil + } + + oldSocketCheck := socketCheck + defer func() { socketCheck = oldSocketCheck }() + socketCheck = func(string, string) (err error) { + return errors.NewBadRequest("mock err") + } + err := checkDesignerHealth() + assert.Error(t, err, "mock err") + }) +} diff --git a/cmd/runaceserver/integrationserver.go b/cmd/runaceserver/integrationserver.go index 232a8aa..e2da12c 100644 --- a/cmd/runaceserver/integrationserver.go +++ b/cmd/runaceserver/integrationserver.go @@ -64,6 +64,9 @@ var yamlUnmarshal = yaml.Unmarshal var yamlMarshal = yaml.Marshal var writeServerConfFile = writeServerConfFileLocal var getConfigurationFromContentServer = getConfigurationFromContentServerLocal +var commandRunCmd = command.RunCmd +var packageBarFile = packageBarFileLocal +var deployBarFile = deployBarFileLocal // initialIntegrationServerConfig walks through the /home/aceuser/initial-config directory // looking for directories (each containing some config data), then runs a shell script @@ -122,7 +125,10 @@ func initialIntegrationServerConfig() error { return err } } - if file.Name() != "webusers" { + + // do not generate script for webusers dir or designerflowyaml + // designerflowyaml is where we mount the ConfigMaps containing the IntegrationFlow resources + if file.Name() != "webusers" && file.Name() != "designerflowyaml" && file.Name() != "generated-bar" { cmd := exec.Command("ace_config_" + file.Name() + ".sh") out, _, err := command.RunCmd(cmd) if err != nil { @@ -198,6 +204,17 @@ func initialIntegrationServerConfig() error { log.Printf("Not Forcing all flows to be https as FORCE_FLOW_HTTPS=%v", forceFlowHttps) } + isEnabled, checkGlobalCacheError := checkGlobalCacheConfigurations() + if checkGlobalCacheError != nil { + log.Errorf("Error checking global cache configurations in server.conf.yaml: %v", checkGlobalCacheError) + return checkGlobalCacheError + } + if isEnabled { + log.Printf("*******") + log.Printf("The embedded global cache is enabled. This configuration is not supported in a containerized environment. For more information, see https://ibm.biz/aceglobalcache.") + log.Printf("*******") + } + log.Println("Initial configuration of integration server complete") return nil @@ -408,7 +425,14 @@ func addMetricsToServerConf(serverconfContent []byte) ([]byte, error) { statistics["Snapshot"] = snapshotObj } - statistics["Resource"] = resourceObj + if statistics["Resource"] != nil { + resource := statistics["Resource"].(map[interface{}]interface{}) + if resource["reportingOn"] == nil { + resource["reportingOn"] = true + } + } else { + statistics["Resource"] = resourceObj + } } else { serverconfMap["Statistics"] = map[string]interface{}{ @@ -443,7 +467,7 @@ func addOpenTracingToServerConf(serverconfContent []byte) ([]byte, error) { userExits["userExitPath"] = "/opt/ACEOpenTracing" } else { - serverconfMap["UserExits"] = map[interface{}]interface{} { + serverconfMap["UserExits"] = map[interface{}]interface{}{ "activeUserExitList": "ACEOpenTracingUserExit", "userExitPath": "/opt/ACEOpenTracing", } @@ -712,7 +736,12 @@ func waitForIntegrationServer() error { cmd := exec.Command("chkaceready") _, rc, err := command.RunCmd(cmd) if rc != 0 || err != nil { - log.Printf("Integration server not ready yet") + knative := os.Getenv("KNATIVESERVICE") + if knative == "true" || knative == "1" { + log.Printf("Integration server & FDR not ready yet") + } else { + log.Printf("Integration server not ready yet") + } } if rc == 0 { break @@ -730,15 +759,45 @@ func stopIntegrationServer(integrationServerProcess command.BackgroundCmd) { } func createWorkDir() error { - log.Printf("Attempting to initialise /home/aceuser/ace-server") - cmd := exec.Command("/opt/ibm/ace-12/server/bin/mqsicreateworkdir", "/home/aceuser/ace-server") + if _, err := os.Stat("/home/aceuser/ace-server/server.conf.yaml"); errors.Is(err, os.ErrNotExist) { + log.Printf("Attempting to initialise /home/aceuser/ace-server") + + // Run mqsicreateworkdir code + cmd := exec.Command("/opt/ibm/ace-12/server/bin/mqsicreateworkdir", "/home/aceuser/ace-server") + _, _, err := command.RunCmd(cmd) + if err != nil { + log.Printf("Error initializing work dir") + return err + } + log.Printf("Work dir initialization complete") + } else { + log.Printf("/home/aceuser/ace-server/server.conf.yaml found, not initializing Work dir") + } + return nil +} + +func createWorkDirSymLink() error { + log.Printf("Attempting to move / symlink /home/aceuser/ace-server to shared mount") + cmd := exec.Command("cp", "-r", "/home/aceuser/ace-server", "/workdir-shared/") _, _, err := command.RunCmd(cmd) if err != nil { - log.Printf("Error initializing work dir") + log.Printf("Error copying workdir to shared work dir") + return err + } + cmd = exec.Command("rm", "-rf", "/home/aceuser/ace-server") + _, _, err = command.RunCmd(cmd) + if err != nil { + log.Printf("Error deleting original work dir") + return err + } + cmd = exec.Command("ln", "-s", "/workdir-shared/ace-server", "/home/aceuser/") + _, _, err = command.RunCmd(cmd) + if err != nil { + log.Printf("Error creating symlink") return err } - - log.Printf("Work dir initialization complete") + + log.Printf("Work dir symlink complete") return nil } @@ -905,6 +964,37 @@ func addforceFlowsHttpsToServerConf(serverconfContent []byte) ([]byte, error) { return serverconfYaml, nil } +func checkGlobalCacheConfigurations() (bool, error) { + isEmbeddedCacheEnabled := false + serverconfContent, readError := readServerConfFile() + if readError != nil { + if !os.IsNotExist(readError) { + // Error is different from file not existing (if the file does not exist we will create it ourselves) + log.Errorf("Error reading server.conf.yaml: %v", readError) + return isEmbeddedCacheEnabled, readError + } + } + + serverconfMap := make(map[interface{}]interface{}) + unmarshallError := yaml.Unmarshal([]byte(serverconfContent), &serverconfMap) + if unmarshallError != nil { + log.Errorf("Error unmarshalling server.conf.yaml: %v", unmarshallError) + return isEmbeddedCacheEnabled, unmarshallError + } + + if serverconfMap["ResourceManagers"] != nil { + resourceManagers := serverconfMap["ResourceManagers"].(map[interface{}]interface{}) + if resourceManagers["GlobalCache"] != nil { + globalCache := resourceManagers["GlobalCache"].(map[interface{}]interface{}) + if globalCache["cacheOn"] == true && globalCache["enableCatalogService"] == true && globalCache["enableContainerService"] == true { + isEmbeddedCacheEnabled = true + } + } + } + + return isEmbeddedCacheEnabled, nil +} + func generatePassword(length int64) string { var i, e = big.NewInt(length), big.NewInt(10) bigInt, _ := rand.Int(rand.Reader, i.Exp(e, i, nil)) @@ -1035,4 +1125,106 @@ func localPatchHTTPSConnector(uds string) { } else { log.Println("Call made to restart HTTPSConnector for Force Flows HTTPS") } + } + +func deployIntegrationFlowResources() error { + log.Println("Deploying IntegrationFlow resources") + err := packageBarFile() + if err != nil { + log.Println(err) + return err + } + + err = deployBarFile() + if err != nil { + log.Println(err) + return err + } + + return nil +} + +func packageBarFileLocal() error { + cmd := exec.Command("/opt/ibm/ace-12/common/node/bin/node", "/opt/ibm/acecc-bar-gen/acecc-bar-gen.js", "2>&1") + out, _, err := commandRunCmd(cmd) + if err != nil { + log.Println("Error packaging BAR file :", err) + return err + } + log.Print(out) + + return nil +} + +func deployBarFileLocal() error { + mqsiCommand := exec.Command("/bin/sh", "-c", "source /opt/ibm/ace-12/server/bin/mqsiprofile; /opt/ibm/ace-12/server/bin/ibmint deploy --input-bar-file /home/aceuser/initial-config/generated-bar/integrationFlowResources.bar --output-work-directory /home/aceuser/ace-server") + out, _, err := commandRunCmd(mqsiCommand) + if err != nil { + fmt.Println("Error deploying BAR file :", err) + return err + } + log.Print(out) + return nil +} + +func deployCSAPIFlows() error { + csAPIProxy := os.Getenv("CONNECTOR_SERVICE") + if csAPIProxy == "true" || csAPIProxy == "1" { + log.Println("Deploying Connector Service API Proxy Flow") + cpCommand := exec.Command("cp", "--recursive", "/home/aceuser/deps/CSAPI", "/home/aceuser/ace-server/run/CSAPI") + out, _, err := commandRunCmd(cpCommand) + if err != nil { + log.Println("Error deploying copy CS API flow files :", err) + return err + } + log.Print(out) + log.Println("Connector Service API flow deployed") + } + return nil +} + +// This function updates the server.conf.yaml with the fields required to +// force basic auth on all flows +func forceflowbasicauthServerConfUpdate() error { + + log.Println("Enabling basic auth on all flows in server.conf.yaml") + + serverconfContent, readError := readServerConfFile() + if readError != nil { + if !os.IsNotExist(readError) { + // Error is different from file not existing (if the file does not exist we will create it ourselves) + log.Errorf("Error reading server.conf.yaml: %v", readError) + return readError + } + } + + serverconfMap := make(map[interface{}]interface{}) + unmarshallError := yamlUnmarshal([]byte(serverconfContent), &serverconfMap) + if unmarshallError != nil { + log.Errorf("Error unmarshalling server.conf.yaml: %v", unmarshallError) + return unmarshallError + } + + if serverconfMap["forceServerHTTPSecurityProfile"] == nil { + serverconfMap["forceServerHTTPSecurityProfile"] = "{DefaultPolicies}:SecProfLocal" + } else { + log.Println("WARNING: You have asked to force basic auth on all flows but already have forceServerHTTPSecurityProfile set") + log.Println("WARNING: We will not override this existing value which may prevent the basic working. ") + } + + serverconfYaml, marshallError := yamlMarshal(&serverconfMap) + if marshallError != nil { + log.Errorf("Error marshalling server.conf.yaml: %v", marshallError) + return marshallError + } + + writeError := writeServerConfFile(serverconfYaml) + if writeError != nil { + return writeError + } + + log.Println("forceServerHTTPSecurityProfile enabled in server.conf.yaml") + + return nil +} \ No newline at end of file diff --git a/cmd/runaceserver/integrationserver_internal_test.go b/cmd/runaceserver/integrationserver_internal_test.go index 54ed559..1d02e01 100644 --- a/cmd/runaceserver/integrationserver_internal_test.go +++ b/cmd/runaceserver/integrationserver_internal_test.go @@ -131,6 +131,35 @@ Statistics: publicationOn: mockValue3 threadDataLevel: mockValue4 `}, +{ // User's yaml has accountingOrigin in Statistics.Snapshot and overriden outputFormat. It keeps these values. +` +Statistics: + Resource: + outputFormat: file`, +`Statistics: + Resource: + outputFormat: file + reportingOn: true + Snapshot: + accountingOrigin: none + nodeDataLevel: basic + outputFormat: json + publicationOn: active + threadDataLevel: none +`}, +{ // User's yaml has bare minimum. Our defaults added. +` +Statistics:`, +`Statistics: + Resource: + reportingOn: true + Snapshot: + accountingOrigin: none + nodeDataLevel: basic + outputFormat: json + publicationOn: active + threadDataLevel: none +`}, } func TestAddMetricsToServerConf(t *testing.T) { @@ -356,6 +385,70 @@ func TestAddforceFlowsHttpsToServerConf(t *testing.T) { } } +func TestCheckGlobalCacheConfigurations(t *testing.T) { + t.Run("When global cache is not configured, no warning message is issued.", func(t *testing.T) { + serverConfigYaml := `ResourceManagers:` + + readServerConfFile = func() ([]byte, error) { + return []byte(serverConfigYaml), nil + } + + isEmbeddedCacheEnabled, err := checkGlobalCacheConfigurations() + assert.NoError(t, err) + assert.Equal(t, isEmbeddedCacheEnabled, false, "The WXS server should be disabled.") + }) + + t.Run("When global cache is disabled, no warning message is issued.", func(t *testing.T) { + serverConfigYaml := +`ResourceManagers: + GlobalCache: + cacheOn: false + enableCatalogService: false + enableContainerService: false` + + readServerConfFile = func() ([]byte, error) { + return []byte(serverConfigYaml), nil + } + + isEmbeddedCacheEnabled, err := checkGlobalCacheConfigurations() + assert.NoError(t, err) + assert.Equal(t, isEmbeddedCacheEnabled, false, "The WXS server should be disabled.") + }) + + t.Run("When global cache is enabled without the WXS server, no warning message is issued.", func(t *testing.T) { + serverConfigYaml := +`ResourceManagers: + GlobalCache: + cacheOn: true + enableCatalogService: false + enableContainerService: false` + + readServerConfFile = func() ([]byte, error) { + return []byte(serverConfigYaml), nil + } + + isEmbeddedCacheEnabled, err := checkGlobalCacheConfigurations() + assert.NoError(t, err) + assert.Equal(t, isEmbeddedCacheEnabled, false, "The WXS server should be disabled.") + }) + + t.Run("When both global cache and the WXS server are enabled, a warning message is issued.", func(t *testing.T) { + serverConfigYaml := +`ResourceManagers: + GlobalCache: + cacheOn: true + enableCatalogService: true + enableContainerService: true` + + readServerConfFile = func() ([]byte, error) { + return []byte(serverConfigYaml), nil + } + + isEmbeddedCacheEnabled, err := checkGlobalCacheConfigurations() + assert.NoError(t, err) + assert.Equal(t, isEmbeddedCacheEnabled, true, "The WXS server should be enabled.") + }) +} func TestGetConfigurationFromContentServer(t *testing.T) { diff --git a/cmd/runaceserver/integrationserver_test.go b/cmd/runaceserver/integrationserver_test.go index a8afb58..98b4fe5 100644 --- a/cmd/runaceserver/integrationserver_test.go +++ b/cmd/runaceserver/integrationserver_test.go @@ -3,10 +3,12 @@ package main import ( "errors" "os" + "os/exec" "testing" "github.com/ot4i/ace-docker/common/logger" "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v2" ) func Test_initialIntegrationServerConfig(t *testing.T) { @@ -171,3 +173,266 @@ func Test_createSHAServerConfYamlLocal(t *testing.T) { writeServerConfFile = oldWriteServerConfFile }) } + +func Test_deployIntegrationFlowResources(t *testing.T) { + t.Run("deployIntegrationFlowResources returns nil as both commands returned without error", func(t *testing.T) { + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + return "success", 0, nil + } + err := deployIntegrationFlowResources() + assert.NoError(t, err) + }) + + t.Run("deployIntegrationFlowResources error running acecc-bar-gen.js", func(t *testing.T) { + oldpackageBarFile := packageBarFile + defer func() { packageBarFile = oldpackageBarFile }() + packageBarFile = func() error { + err := errors.New("Error running acecc-bar-gen.js") + return err + } + + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + err := errors.New("Error running acecc-bar-gen.js") + return "Error running acecc-bar-gen.js", 1, err + } + + err := deployIntegrationFlowResources() + assert.Error(t, err) + }) + + t.Run("deployIntegrationFlowResources error deploying BAR file - non zero return code", func(t *testing.T) { + oldpackageBarFile := packageBarFile + defer func() { packageBarFile = oldpackageBarFile }() + packageBarFile = func() error { + return nil + } + + olddeployBarFile := deployBarFile + defer func() { deployBarFile = olddeployBarFile }() + deployBarFile = func() error { + err := errors.New("Error deploying BAR file") + return err + } + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + err := errors.New("Error deploying BAR file") + return "Error deploying BAR file", 1, err + } + + err := deployIntegrationFlowResources() + assert.Error(t, err) + }) +} + +func Test_PackageBarFile(t *testing.T) { + t.Run("Success running acecc-bar-gen.js", func(t *testing.T) { + + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + return "Success", 0, nil + } + err := packageBarFile() + assert.NoError(t, err) + + }) + t.Run("Error running acecc-bar-gen.js", func(t *testing.T) { + + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + err := errors.New("Error running acecc-bar-gen.js") + return "Error running acecc-bar-gen.js", 1, err + } + err := packageBarFile() + assert.Error(t, err) + }) +} + +func Test_DeployBarFile(t *testing.T) { + t.Run("Success deploying BAR file", func(t *testing.T) { + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + return "Success", 0, nil + } + err := deployBarFile() + assert.NoError(t, err) + + }) + t.Run("Error deploying BAR file", func(t *testing.T) { + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + err := errors.New("Error running deploying BAR file") + return "Error running deploying BAR file", 1, err + } + err := deployBarFile() + assert.Error(t, err) + }) + +} + +func Test_deployCSAPIFlows(t *testing.T) { + + t.Run("Env var not set", func(t *testing.T) { + called := 0 + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + called++ + return "Success", 0, nil + } + err := deployCSAPIFlows() + assert.NoError(t, err) + assert.Equal(t, 0, called) + }) + + t.Run("Env var not set", func(t *testing.T) { + os.Setenv("CONNECTOR_SERVICE", "true") + + t.Run("Success deploying copyied files", func(t *testing.T) { + var command []string + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + command = cmd.Args + return "Success", 0, nil + } + err := deployCSAPIFlows() + assert.NoError(t, err) + assert.Contains(t, command, "/home/aceuser/deps/CSAPI") + assert.Contains(t, command, "/home/aceuser/ace-server/run/CSAPI") + + }) + t.Run("Error copying files", func(t *testing.T) { + oldcommandRunCmd := commandRunCmd + defer func() { commandRunCmd = oldcommandRunCmd }() + commandRunCmd = func(cmd *exec.Cmd) (string, int, error) { + err := errors.New("Error running deploying BAR file") + return "Error running deploying BAR file", 1, err + } + err := deployCSAPIFlows() + assert.Error(t, err) + }) + os.Unsetenv("CONNECTOR_SERVICE") + }) + +} + + +func Test_forceflowbasicauthServerConfUpdate(t *testing.T) { + t.Run("Golden path - Empty file gets populated with the right values", func(t *testing.T) { + + oldReadServerConfFile := readServerConfFile + readServerConfFile = func() ([]byte, error) { + return []byte{}, nil + } + oldWriteServerConfFileLocal := writeServerConfFile + writeServerConfFile = func(content []byte) error { + return nil + } + + err := forceflowbasicauthServerConfUpdate() + assert.NoError(t, err) + readServerConfFile = oldReadServerConfFile + writeServerConfFile = oldWriteServerConfFileLocal + }) + + t.Run("Existing value in server.conf.yaml", func(t *testing.T) { + + serverconfMap := make(map[interface{}]interface{}) + serverconfMap["forceServerHTTPSecurityProfile"] = "{DefaultPolicies}:SecProfLocal" + serverconfYaml, _ := yaml.Marshal(&serverconfMap) + + oldReadServerConfFile := readServerConfFile + readServerConfFile = func() ([]byte, error) { + return serverconfYaml, nil + } + oldWriteServerConfFileLocal := writeServerConfFile + writeServerConfFile = func(content []byte) error { + return nil + } + + err := forceflowbasicauthServerConfUpdate() + assert.NoError(t, err) + readServerConfFile = oldReadServerConfFile + writeServerConfFile = oldWriteServerConfFileLocal + }) + + t.Run("Error reading server.conf.yaml file", func(t *testing.T) { + oldReadServerConfFile := readServerConfFile + readServerConfFile = func() ([]byte, error) { + return nil, errors.New("Error reading server.conf.yaml") + } + oldWriteServerConfFileLocal := writeServerConfFile + writeServerConfFile = func(content []byte) error { + return nil + } + + err := forceflowbasicauthServerConfUpdate() + assert.Error(t, err) + readServerConfFile = oldReadServerConfFile + writeServerConfFile = oldWriteServerConfFileLocal + }) + t.Run("yaml.Marshal fails to execute properly", func(t *testing.T) { + oldYamlUnmarshal := yamlUnmarshal + yamlUnmarshal = func(in []byte, out interface{}) (err error) { + return errors.New("Error unmarshalling yaml") + } + oldYamlMarshal := yamlMarshal + yamlMarshal = func(in interface{}) (out []byte, err error) { + return nil, nil + } + + err := forceflowbasicauthServerConfUpdate() + assert.Error(t, err) + assert.Equal(t, "Error unmarshalling yaml", err.Error()) + + yamlUnmarshal = oldYamlUnmarshal + yamlMarshal = oldYamlMarshal + }) + t.Run("yaml.Marshal fails to execute properly", func(t *testing.T) { + oldYamlUnmarshal := yamlUnmarshal + yamlUnmarshal = func(in []byte, out interface{}) (err error) { + return nil + } + oldYamlMarshal := yamlMarshal + yamlMarshal = func(in interface{}) (out []byte, err error) { + return nil, errors.New("Error marshalling yaml") + } + + err := forceflowbasicauthServerConfUpdate() + assert.Error(t, err) + assert.Equal(t, "Error marshalling yaml", err.Error()) + + yamlUnmarshal = oldYamlUnmarshal + yamlMarshal = oldYamlMarshal + }) + t.Run("yaml.Marshal fails to execute properly", func(t *testing.T) { + oldYamlUnmarshal := yamlUnmarshal + yamlUnmarshal = func(in []byte, out interface{}) (err error) { + return nil + } + oldYamlMarshal := yamlMarshal + yamlMarshal = func(in interface{}) (out []byte, err error) { + return nil, nil + } + oldWriteServerConfFile := writeServerConfFile + writeServerConfFile = func(content []byte) error { + return errors.New("Error writing server.conf.yaml") + } + err := forceflowbasicauthServerConfUpdate() + assert.Error(t, err) + assert.Equal(t, "Error writing server.conf.yaml", err.Error()) + + yamlUnmarshal = oldYamlUnmarshal + yamlMarshal = oldYamlMarshal + writeServerConfFile = oldWriteServerConfFile + }) +} diff --git a/cmd/runaceserver/main.go b/cmd/runaceserver/main.go index 3a04ec6..add15c8 100644 --- a/cmd/runaceserver/main.go +++ b/cmd/runaceserver/main.go @@ -115,7 +115,7 @@ func doMain() error { runOnly := os.Getenv("ACE_RUN_ONLY") if runOnly == "true" || runOnly == "1" { - log.Println("Run selected so skipping setup") + log.Println("Run selected so skipping setup") } else { log.Println("Checking for valid working directory") err = createWorkDir() @@ -125,6 +125,17 @@ func doMain() error { return err } + workdirShared := os.Getenv("WORKDIR-SHARED") + if workdirShared == "true" || workdirShared == "1" { + log.Println("Add symlink into shared workdir") + err = createWorkDirSymLink() + if err != nil { + logTermination(err) + performShutdown() + return err + } + } + // Note: this will do nothing if there are no crs set in the environment err = configuration.SetupConfigurationsFiles(log, "/home/aceuser") if err != nil { @@ -163,6 +174,35 @@ func doMain() error { performShutdown() return err } + + // Deploy Connector Service API + err = deployCSAPIFlows() + if err != nil { + logTermination(err) + performShutdown() + return err + } + + designerIntegrationFlows := os.Getenv("DESIGNER_INTEGRATION_FLOWS") + if designerIntegrationFlows == "true" { + err = deployIntegrationFlowResources() + if err != nil { + logTermination(err) + performShutdown() + return err + } + } + + forceflowbasicauth := os.Getenv("FORCEFLOWBASICAUTH") + if forceflowbasicauth == "true" || forceflowbasicauth == "1" { + err = forceflowbasicauthServerConfUpdate() + if err != nil { + logTermination(err) + performShutdown() + return err + } + } + } setupOnly := os.Getenv("ACE_SETUP_ONLY") diff --git a/deps/CSAPI/META-INF/bar-refresh.links b/deps/CSAPI/META-INF/bar-refresh.links new file mode 100644 index 0000000..44e994c --- /dev/null +++ b/deps/CSAPI/META-INF/bar-refresh.links @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/deps/CSAPI/META-INF/broker.xml b/deps/CSAPI/META-INF/broker.xml new file mode 100644 index 0000000..1526b46 --- /dev/null +++ b/deps/CSAPI/META-INF/broker.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/deps/CSAPI/META-INF/manifest.mf b/deps/CSAPI/META-INF/manifest.mf new file mode 100644 index 0000000..55f313d --- /dev/null +++ b/deps/CSAPI/META-INF/manifest.mf @@ -0,0 +1 @@ +srcSelected=false;showSrc=true;esql21VersionSelected=false; \ No newline at end of file diff --git a/deps/CSAPI/META-INF/service.log b/deps/CSAPI/META-INF/service.log new file mode 100644 index 0000000..e6de405 --- /dev/null +++ b/deps/CSAPI/META-INF/service.log @@ -0,0 +1,36 @@ + +============================================== + +!Wed Mar 23 13:16:28 GMT 2022 +Message flow CSAPI/Proxy.msgflow successfully loaded +Message flow CSAPI/Proxy.msgflow successfully compiled +Message flow CSAPI/Proxy.msgflow successfully added to archive file + +Node Flow Version Reason +---------------------------------------------------------------------------------------------------- +Failure Handler Proxy 5.0 Generate 5.0 compatible ESQL by default. +This compatibility level supports ESQL source code debugging. +Deploying 5.0 compatible ESQL code will cause a syntax error on version 2.1 or previous brokers. +Configure Request Proxy 5.0 Generate 5.0 compatible ESQL by default. +This compatibility level supports ESQL source code debugging. +Deploying 5.0 compatible ESQL code will cause a syntax error on version 2.1 or previous brokers. +Message flow CSAPI/Proxy.msgflow successfully loaded +Message flow CSAPI/Proxy.msgflow successfully compiled +Message flow CSAPI/Proxy.msgflow successfully added to archive file + +Node Flow Version Reason +---------------------------------------------------------------------------------------------------- +Failure Handler Proxy 5.0 Generate 5.0 compatible ESQL by default. +This compatibility level supports ESQL source code debugging. +Deploying 5.0 compatible ESQL code will cause a syntax error on version 2.1 or previous brokers. +Configure Request Proxy 5.0 Generate 5.0 compatible ESQL by default. +This compatibility level supports ESQL source code debugging. +Deploying 5.0 compatible ESQL code will cause a syntax error on version 2.1 or previous brokers. + +Successfully added file CSAPI/application.descriptor to BAR file. + +Successfully added file CSAPI/application.descriptor to BAR file. + +Successfully added file CSAPI/application.descriptor to BAR file. + +Successfully added file CSAPI/application.descriptor to BAR file. diff --git a/deps/CSAPI/META-INF/user.log b/deps/CSAPI/META-INF/user.log new file mode 100644 index 0000000..1257a13 --- /dev/null +++ b/deps/CSAPI/META-INF/user.log @@ -0,0 +1,37 @@ + +============================================== + +!Wed Mar 23 13:16:28 GMT 2022 + +Processing file CSAPI/Proxy.msgflow +Successfully added file CSAPI/Proxy.msgflow to archive file +Elapsed time: 0.082 second(s). + +Processing file CSAPI/Proxy.msgflow +Successfully added file CSAPI/Proxy.msgflow to archive file +Elapsed time: 0.082 second(s). + +Processing file CSAPI/Proxy.msgflow +Message flow "Proxy.msgflow" can be deployed as source since it does not include any subflows defined in the MSGFLOW files +or any nodes unsupported by the source deploy. You may select -deployAsSource flag when building the +BAR with MQSICREATEBAR command or do not select "Compile and in-line resources" build option on the BAR editor. + +============================================== + +!Wed Mar 23 13:16:28 GMT 2022 + +Processing file CSAPI/application.descriptor. +Successfully added file CSAPI/application.descriptor to BAR file. +Elapsed time: 0 second(s). + +Successfully added file CSAPI/application.descriptor to BAR file. + +============================================== + +!Wed Mar 23 13:16:28 GMT 2022 + +Processing file CSAPI/application.descriptor. +Successfully added file CSAPI/application.descriptor to BAR file. +Elapsed time: 0 second(s). + +Successfully added file CSAPI/application.descriptor to BAR file. diff --git a/deps/CSAPI/Proxy.cmf b/deps/CSAPI/Proxy.cmf new file mode 100644 index 0000000..3f91329 --- /dev/null +++ b/deps/CSAPI/Proxy.cmf @@ -0,0 +1,75 @@ + + +CREATE SCHEMA "" PATH "" + +CREATE COMPUTE MODULE Proxy_Configure_Request + CREATE FUNCTION Main() RETURNS BOOLEAN + BEGIN + + SET OutputRoot = InputRoot; + + /* +LE section when "Set destination list" is checked on the input node: + + (0x01000000:Name):HTTP = ( + (0x01000000:Name):Input = ( + (0x01000000:Name):RequestLine = ( + (0x03000000:NameValue):Method = 'GET' (CHARACTER) + (0x03000000:NameValue):RequestURI = '/csapi/abc/def' (CHARACTER) + (0x03000000:NameValue):HTTPVersion = 'HTTP/1.1' (CHARACTER) + ) + ) + ) +*/ + -- Keep everything after /csapi (include the slash) + IF LENGTH( InputRoot.HTTPInputHeader."X-Query-String" ) > 0 THEN + SET OutputLocalEnvironment.Destination.HTTP.RequestLine.RequestURI = SUBSTRING(InputLocalEnvironment.HTTP.Input.RequestLine.RequestURI FROM 7) || '?' || InputRoot.HTTPInputHeader."X-Query-String"; + ELSE + SET OutputLocalEnvironment.Destination.HTTP.RequestLine.RequestURI = SUBSTRING(InputLocalEnvironment.HTTP.Input.RequestLine.RequestURI FROM 7); + END IF; + SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = InputLocalEnvironment.HTTP.Input.RequestLine.Method; + + RETURN TRUE; + END; + +END MODULE; +CREATE SCHEMA "" PATH "" + +CREATE COMPUTE MODULE Proxy_Failure_Handler + CREATE FUNCTION Main() RETURNS BOOLEAN + BEGIN + SET OutputRoot = InputRoot; + + -- Set response code + SET OutputLocalEnvironment.Destination.HTTP.ReplyStatusCode = 500; + + if InputExceptionList IS NOT NULL THEN + -- Check the BIP message and put out an appropriate error message + DECLARE messageNumber INTEGER; + DECLARE messageText char; + CALL getLastExceptionDetail(InputExceptionList, messageNumber, messageText); + + SET OutputRoot.JSON.Data.BIP.Number = messageNumber; + SET OutputRoot.JSON.Data.BIP.Message = messageText; + END IF; + + -- Just forward on the original message + + + END; +END MODULE;CREATE PROCEDURE getLastExceptionDetail(IN InputTree reference, OUT messageNumber integer, OUT messageText char) +BEGIN + -- Create a reference to the first child of the exception list + declare ptrException reference to InputTree.*[1]; + -- keep looping while the moves to the child of exception list work + WHILE lastmove(ptrException) DO + -- store the current values for the error number and text + IF ptrException.Number is not null THEN + SET messageNumber = ptrException.Number; + SET messageText = ptrException.Text; + END IF; + -- now move to the last child which should be the next exceptionlist + move ptrException lastchild; + END WHILE; +END; + \ No newline at end of file diff --git a/deps/CSAPI/application.descriptor b/deps/CSAPI/application.descriptor new file mode 100644 index 0000000..166bf9e --- /dev/null +++ b/deps/CSAPI/application.descriptor @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/go.mod b/go.mod index 2ec7fa2..ec8fd03 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/gorilla/websocket v1.4.2 github.com/imdario/mergo v0.3.12 - github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/client_golang v1.11.1 github.com/prometheus/client_model v0.2.0 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 diff --git a/go.sum b/go.sum index 05206e3..2d1ae38 100644 --- a/go.sum +++ b/go.sum @@ -280,6 +280,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= diff --git a/internal/configuration/configuration.go b/internal/configuration/configuration.go index e34d1f5..693dfb6 100644 --- a/internal/configuration/configuration.go +++ b/internal/configuration/configuration.go @@ -3,6 +3,7 @@ package configuration import ( "archive/zip" "bytes" + "context" "crypto/tls" "crypto/x509" "encoding/base64" @@ -18,7 +19,6 @@ import ( "strconv" "strings" "time" - "context" "github.com/Jeffail/gabs" @@ -466,6 +466,7 @@ func runCommand(log logger.LoggerInterface, command string, params []string) err err := cmd.Run() if err != nil { log.Printf("Error executing command: %s %s", stdout.String(), stderr.String()) + } else { log.Printf("Successfully executed command.") } diff --git a/internal/configuration/techConnectorsConfiguration.go b/internal/configuration/techConnectorsConfiguration.go index 67e14b6..ae18732 100644 --- a/internal/configuration/techConnectorsConfiguration.go +++ b/internal/configuration/techConnectorsConfiguration.go @@ -148,7 +148,7 @@ func SetupTechConnectorsConfigurations(log logger.LoggerInterface, basedir strin log.Printf("Connector %s accounts processed %v", connector, len(connectorAccounts)) } } else { - log.Printf("No accounts found for connector %s\n", connector) + log.Printf("No accounts found for connector %s", connector) } } diff --git a/test-and-coverage.sh b/test-and-coverage.sh new file mode 100755 index 0000000..d07730d --- /dev/null +++ b/test-and-coverage.sh @@ -0,0 +1,38 @@ +#!/bin/bash -e + +# Array of packages at 100% test coverage - Once a package has been fully covered it will be added to this list +COVERED_PACKAGES=('webadmin') +TEST_OUTPUT=$(go test $(go list ./... | grep -v /test/) -covermode=atomic -coverprofile cover.out) +COVERAGE_REGRESSION=false + +for i in ${COVERED_PACKAGES[@]}; do + COV=$(echo "$TEST_OUTPUT" | grep "$i" | awk '{ print $5 }') + if [[ "$COV" != "100.0%" ]]; then + echo "$i is not at 100% test coverage." + COVERAGE_REGRESSION=true + fi +done + +if [[ $COVERAGE_REGRESSION == true ]]; then + echo "Please address the coverage regression." + exit 1 +fi + + +# This is the current expected code coverage +CURRENT_COVERAGE=58.1 +LATEST=$(go tool cover -func cover.out | grep total | awk '{print substr($3, 1, length($3)-1)}') +echo "Latest coverage: $LATEST" +echo "Expected Coverage: $CURRENT_COVERAGE" +result=$(echo "$LATEST >= $CURRENT_COVERAGE" | bc -l) +if [ $result -gt 0 ]; then + echo "PASSED - Coverage Check" +else + echo "Failed to meet required coverage value: $CURRENT_COVERAGE" + exit 1 + +fi +if [ "$LATEST" != "$CURRENT_COVERAGE" ]; then + echo "\nFAILED - You must update the CURRENT_COVERAGE in travis to match the new benchmark: $LATEST" + exit 1 +fi diff --git a/ubi/Dockerfile-legacy.aceonly b/ubi/Dockerfile-legacy.aceonly index ba6d440..4648f0f 100644 --- a/ubi/Dockerfile-legacy.aceonly +++ b/ubi/Dockerfile-legacy.aceonly @@ -55,7 +55,7 @@ LABEL summary="$SUMMARY" \ # Add required license as text file in Liceses directory (GPL, MIT, APACHE, Partner End User Agreement, etc) COPY /licenses/ /licenses/ -RUN microdnf update && microdnf install findutils util-linux unzip python3 tar procps openssl && microdnf clean all \ +RUN microdnf update && microdnf install findutils util-linux unzip python39 tar procps openssl && microdnf clean all \ && ln -s /usr/bin/python3 /usr/local/bin/python \ && mkdir /etc/ACEOpenTracing /opt/ACEOpenTracing /var/log/ACEOpenTracing && chmod 777 /var/log/ACEOpenTracing /etc/ACEOpenTracing diff --git a/ubi/Dockerfile.aceonly b/ubi/Dockerfile.aceonly index fdb85dd..aa57586 100644 --- a/ubi/Dockerfile.aceonly +++ b/ubi/Dockerfile.aceonly @@ -33,8 +33,8 @@ RUN tar -xzf $ACE_INSTALL --absolute-names --exclude ace-12.\*/tools --exclude a # This is to delete any flash files which some customers consider a vulnerability - mostly used by googlelibs RUN echo "Removing the following swf files" \ - && find . -name "*.swf" -type f \ - && find . -name "*.swf" -type f -delete + && find . -name "*.swf" -type f \ + && find . -name "*.swf" -type f -delete FROM registry.access.redhat.com/ubi8/ubi-minimal @@ -61,9 +61,8 @@ LABEL summary="$SUMMARY" \ # Add required license as text file in Liceses directory (GPL, MIT, APACHE, Partner End User Agreement, etc) COPY /licenses/ /licenses/ -RUN microdnf update && microdnf install findutils util-linux unzip python3 tar procps openssl && microdnf clean all \ - && ln -s /usr/bin/python3 /usr/local/bin/python \ - && mkdir /etc/ACEOpenTracing /opt/ACEOpenTracing /var/log/ACEOpenTracing && chmod 777 /var/log/ACEOpenTracing /etc/ACEOpenTracing +RUN microdnf update && microdnf install findutils util-linux unzip tar procps openssl && microdnf clean all \ + && mkdir /etc/ACEOpenTracing /opt/ACEOpenTracing /var/log/ACEOpenTracing && chmod 777 /var/log/ACEOpenTracing /etc/ACEOpenTracing # Force reinstall tzdata package to get zoneinfo files RUN microdnf reinstall tzdata -y @@ -86,6 +85,7 @@ COPY *.sh /usr/local/bin/ COPY ubi/generic_invalid/invalid_license.msgflow /home/aceuser/temp/gen COPY ubi/generic_invalid/InvalidLicenseJava.jar /home/aceuser/temp/gen COPY ubi/generic_invalid/application.descriptor /home/aceuser/temp +COPY deps/CSAPI /home/aceuser/deps/CSAPI # Create a user to run as, create the ace workdir, and chmod script files RUN /opt/ibm/ace-12/ace make registry global accept license silently \ @@ -116,4 +116,4 @@ USER 1000 # Set entrypoint to run management script -ENTRYPOINT ["runaceserver"] +ENTRYPOINT ["runaceserver"] \ No newline at end of file diff --git a/ubi/create-default-mq-kdb.sh b/ubi/create-default-mq-kdb.sh old mode 100644 new mode 100755 index dadbee3..68ac10c --- a/ubi/create-default-mq-kdb.sh +++ b/ubi/create-default-mq-kdb.sh @@ -42,4 +42,3 @@ else $MQSI_JREPATH/bin/keytool -importkeystore -srckeystore $MQSI_JREPATH/lib/security/cacerts -srcstorepass changeit -destkeystore /tmp/java-cacerts.p12 -deststoretype pkcs12 -deststorepass changeit /opt/mqm/bin/runmqakm -keydb -convert -db /tmp/java-cacerts.p12 -old_format p12 -new_format kdb -pw changeit -target /tmp/mqcacerts.kdb -stash fi - diff --git a/ubi/install-mq-client-prereqs.sh b/ubi/install-mq-client-prereqs.sh old mode 100644 new mode 100755 diff --git a/ubi/install-mq.sh b/ubi/install-mq.sh old mode 100644 new mode 100755 index be096bd..cc8b077 --- a/ubi/install-mq.sh +++ b/ubi/install-mq.sh @@ -109,3 +109,4 @@ rm -rf ${DIR_TMP} # Create the directory for MQ configuration files install --directory --mode 2775 --owner 1001 --group root /etc/mqm +