From 760132815ffd379d4c65a11530ec2678a8f3e800 Mon Sep 17 00:00:00 2001 From: Timothy Gerstel Date: Mon, 4 Apr 2022 23:27:04 -0400 Subject: [PATCH 1/7] npm audit fix Signed-off-by: Timothy Gerstel --- package-lock.json | 108 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index dfd11d4e..3b0054ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,90 @@ { "name": "zlux-app-server", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "zlux-app-server", + "version": "1.0.0", + "dependencies": { + "mkdirp": "~0.5.1", + "zlux-server-framework": "file:../zlux-server-framework" + } + }, + "../zlux-server-framework": { + "version": "0.0.0-zlux.version.replacement", + "license": "EPL-2.0", + "dependencies": { + "@rocketsoftware/eureka-js-client": "~4.5.3", + "@rocketsoftware/express-ws": "^5.0.0", + "accept-language-parser": "~1.5.0", + "axios": "~0.22.0", + "bluebird": "~3.5.1", + "body-parser": "~1.18.3", + "cookie-parser": "~1.4.3", + "diffie-hellman": "^5.0.3", + "express": "~4.16.3", + "express-session": "~1.15.6", + "express-static-gzip": "~1.1.3", + "glob": "~7.1.3", + "graceful-fs": "~4.1.15", + "ipaddr.js": "~1.8.0", + "js-yaml": "~3.13.1", + "lodash": "~4.17.21", + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "node-forge": "~1.3.0", + "normalize-url": "~7.0.0", + "require-from-string": "~2.0.2", + "rimraf": "~2.6.3", + "semver": "~5.5.1", + "swagger-parser": "~10.0.3", + "ws": "^6.2.2", + "yaml": "~1.10.2", + "yauzl": "~2.10.0" + }, + "devDependencies": { + "@types/connect": "3.4.32", + "@types/express": "~4.16.1", + "@types/express-serve-static-core": "4.17.7", + "@types/node": "~6.0.0", + "@types/qs": "6.9.3", + "chai": "~4.2.0", + "chai-http": "~4.2.0", + "mocha": "~8.4.0", + "typescript": "2.7.1" + }, + "optionalDependencies": { + "keyring_js": "~1.1.0" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/zlux-server-framework": { + "resolved": "../zlux-server-framework", + "link": true + } + }, "dependencies": { "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mkdirp": { "version": "0.5.5", @@ -20,12 +97,21 @@ "zlux-server-framework": { "version": "file:../zlux-server-framework", "requires": { + "@rocketsoftware/eureka-js-client": "~4.5.3", "@rocketsoftware/express-ws": "^5.0.0", + "@types/connect": "3.4.32", + "@types/express": "~4.16.1", + "@types/express-serve-static-core": "4.17.7", + "@types/node": "~6.0.0", + "@types/qs": "6.9.3", "accept-language-parser": "~1.5.0", + "axios": "~0.22.0", "bluebird": "~3.5.1", "body-parser": "~1.18.3", + "chai": "~4.2.0", + "chai-http": "~4.2.0", "cookie-parser": "~1.4.3", - "eureka-js-client": "~4.4.1", + "diffie-hellman": "^5.0.3", "express": "~4.16.3", "express-session": "~1.15.6", "express-static-gzip": "~1.1.3", @@ -33,14 +119,20 @@ "graceful-fs": "~4.1.15", "ipaddr.js": "~1.8.0", "js-yaml": "~3.13.1", + "keyring_js": "~1.1.0", + "lodash": "~4.17.21", "mkdirp": "~0.5.1", + "mocha": "~8.4.0", "ncp": "~2.0.0", - "normalize-url": "~4.3.0", + "node-forge": "~1.3.0", + "normalize-url": "~7.0.0", "require-from-string": "~2.0.2", "rimraf": "~2.6.3", "semver": "~5.5.1", - "swagger-parser": "~6.0.5", - "ws": "^6.0.0", + "swagger-parser": "~10.0.3", + "typescript": "2.7.1", + "ws": "^6.2.2", + "yaml": "~1.10.2", "yauzl": "~2.10.0" } } From 9e51181fb246ab80105ea5a5e6eaeeeaf88875a5 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 8 Apr 2022 16:22:29 -0400 Subject: [PATCH 2/7] Add json schema using latest info from docs site on how to follow our standard Signed-off-by: 1000TurquoisePogs --- manifest.yaml | 2 + schemas/app-server-config.json | 656 +++++++++++++++++++++++++++ schemas/plugindefinition-schema.json | 517 +++++++++++++++++++++ schemas/zowe-schema.json | 23 + 4 files changed, 1198 insertions(+) create mode 100644 schemas/app-server-config.json create mode 100644 schemas/plugindefinition-schema.json create mode 100644 schemas/zowe-schema.json diff --git a/manifest.yaml b/manifest.yaml index 956cd6cf..4ee0524f 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -14,6 +14,8 @@ keywords: - zlux - appfw license: EPL-2.0 +schemas: + configs: schemas/zowe-schema.json repository: type: git url: https://github.com/zowe/zlux-app-server.git diff --git a/schemas/app-server-config.json b/schemas/app-server-config.json new file mode 100644 index 00000000..12f1392a --- /dev/null +++ b/schemas/app-server-config.json @@ -0,0 +1,656 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/app-server-config", + "title": "app-server configuration", + "description": "Configuration properties for the app-server, as specified within a configuration file such as zowe.yaml", + "type": "object", + "required": [ "productDir", "siteDir", "instanceDir", "groupsDir", "usersDir", "pluginsDir", "dataserviceAuthentication", "node" ], + "additionalProperties": true, + "properties": { + "node": { + "type": "object", + "description": "Configuration options specific to the app-server and things it depends upon", + "additionalProperties": false, + "properties": { + "https": { + "type": "object", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "default": 7556 + }, + "pfx": { + "type": "string", + "deprecated": true, + "description": "Replaced with use of .p12 files within the key or certificate sections, this attribute was used to load certificates from a .pfx file" + }, + "keys": { + "$ref": "#/$defs/certObject" + }, + "certificates": { + "$ref": "#/$defs/certObject" + }, + "certificateAuthorities": { + "$ref": "#/$defs/certObject" + }, + "certificateRevocationLists": { + "$ref": "#/$defs/certObject" + }, + "secureOptions": { + "type": "integer", + "description": "Controls nodejs' use of OpenSSL via integers composed of the values in the references https://github.com/openssl/openssl/blob/master/include/openssl/ssl.h.in and https://nodejs.org/api/crypto.html#openssl-options" + }, + "secureProtocol": { + "type": "string", + "deprecated": true, + "description": "Passes through the secureProtocol attribute to TLS calls of nodeJS, as defined within https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions" + }, + "ciphers": { + "oneOf": [ + { "$ref": "#/$defs/nodejsDefaultCiphers" }, + { "$ref": "#/$defs/zoweDefaultCiphers" }, + { "$ref": "#/$defs/customCiphers" } + ] + }, + "enableTrace": { + "type": "boolean", + "default": false + }, + "passphrase": { + "type": "string", + "description": "Used to load encrypted key or certificate objects when needed" + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames", + "default": [ "0.0.0.0" ] + } + } + }, + "http": { + "type": "object", + "description": "Allows the app-server to run in HTTP mode. This should never be done without a TLS wrapper such as AT-TLS", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ] + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames" + } + } + }, + "mediationLayer": { + "type": "object", + "description": "Properties relating to how the app-server should interact with and find the API Mediation Layer components", + "additionalProperties": false, + "properties": { + "server": { + "type": "object", + "additionalProperties": false, + "properties": { + "isHttps": { + "type": "boolean", + "description": "Controls if connections to the API Mediation Layer gateway and/or discovery service should be HTTP or HTTPS" + }, + "gatewayHostname": { + "type": "string", + "format": "hostname", + "description": "The hostname or IP where the Zowe Gateway service is running. When not specified, the hostname property is used instead" + }, + "hostname": { + "type": "string", + "format": "hostname", + "description": "The hostname or IP where the Zowe Discovery service is running" + }, + "gatewayPort": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "description": "The port where the Zowe Gateway service is running" + }, + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "description": "The port where the Zowe Discovery service is running" + }, + "enabled": { + "type": "boolean", + "description": "Controls whether the app-server should register to the Zowe API Mediation Layer as a Eureka Client" + }, + "cachingService": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "description": "Controls whether the app-server storage API can store in the caching service" + } + } + } + } + } + } + }, + "internalRouting": { + "type": "boolean", + "description": "Controls if app-server should call one REST API from another by using a network call over a loopback address, or issue the request internal to the server by mimicking a network request", + "default": false + }, + "allowInvalidTLSProxy": { + "type": "boolean", + "description": "This boolean sets the inverse value of the nodeJS attribute 'rejectUnauthorized' on any TLS operation within the server. It will allow connections with certificates that cannot be validated for one reason or another.", + "default": false + }, + "childProcesses": { + "type": "array", + "description": "The app-server can start one or more processes as children of itself, and propagate signals sent to the app server to these. This can be used to start related servers at the same time as the app-server.", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "path": { + "type": "string", + "description": "The command to be started via the process spawn() command" + }, + "once": { + "type": "boolean", + "description": "When true, the child process will only be started from one worker rather than per-worker as would happen in cluster mode otherwise.", + "default": false + } + } + } + }, + "session": { + "type": "object", + "additionalProperties": false, + "properties": { + "timeoutMS": { + "type": "integer", + "deprecated": true, + "description": "No longer read by app-server" + }, + "cookie": { + "timeoutMS": { + "type": "integer", + "description": "Determines the expiration time of the app-server cookie. This does not control other cookies such as ZSS, APIML. The experation time is shown in the /auth response, not as a cookie property. The cookie does not expire but will be rejected after the server expiration time.", + "default": -1 + } + } + } + }, + "headers": { + "type": "object", + "description": "Allows customization of http response headers sent by all plugins except those headers that are set as 'override' within a plugin. Each attribute in the object is a header name.", + "patternProperties": { + "content-security-policy": { + "$ref": "#/$defs/headerCustomization", + "preset": { + "oneOf": [ + { "$ref": "#/$defs/cspPresetStrict" }, + { "$ref": "#/$defs/cspPresetFrameStrict" } + ] + } + }, + "^.*$": { + "$ref": "#/$defs/headerCustomization" + } + } + }, + "pluginScanIntervalSec": { + "type": "integer", + "description": "When set above 0, the app-server will scan pluginsDir every number of seconds to look for plugins to add, allowing you to install new plugins without restarting the server. Note this does not allow upgrade or removal, which need restart or RBAC-controlled management REST API invocation", + "default": 0 + }, + "rootRedirectURL": { + "type": "string", + "description": "The URL which the server will redirect to if a request is sent to '/'", + "default": "/ZLUX/plugins/org.zowe.zlux.bootstrap/web/" + }, + "noPrompt": { + "type": "boolean", + "description": "Whether to prompt for a passphrase when a passphrase is needed but not found for a pfx object", + "default": false + }, + "noChild": { + "type": "boolean", + "default": false, + "description": "Whether the childProcesses array should be skipped on startup." + }, + "loopbackAddress": { + "description": "The address the app-server should use to contact itself if a loopback request is needed by a call() operation from a plugin", + "$ref": "#/$defs/ipOrHostname" + }, + "hostname": { + "type": "string", + "format": "hostname", + "description": "When not specified, the nodejs value of os.hostname() is used. This value is used to tell clients and other servers the location of the app-server." + } + } + }, + "agent": { + "type": "object", + "description": "Configuration options specific to app-server agents, such as ZSS. These options are used to configure the agent, but also to tell app-server about the agent configuration", + "additionalProperties": false, + "properties": { + "host": { + "type": "string", + "description": "Tells app-server which hostname or ip to communicate with the agent at" + }, + "https": { + "type": "object", + "description": "Configures the agent to use HTTPS.", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "default": 7557 + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames", + "default": [ "0.0.0.0" ] + } + } + }, + "http": { + "type": "object", + "description": "Configures the agent to use HTTP. When using AT-TLS, this object should be defined but with http.attls=true. It is insecure and absolutely not recommended to use http without AT-TLS", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ] + }, + "attls": { + "type": "boolean", + "default": false, + "description": "Tells the app-server whether or not the agent should be reached using HTTPS or HTTP when contacting the HTTP port" + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames" + } + } + }, + "mediationLayer": { + "type": "object", + "additionalProperties": false, + "properties": { + "serviceName": { + "type": "string", + "description": "What the agent will be named when found on the API Mediation Layer" + }, + "enabled": { + "type": "boolean", + "description": "Controls whether the agent should register to the API Mediation Layer, and whether the app-server should contact it via the Mediation Layer" + } + } + }, + "handshakeTimeout": { + "type": "integer", + "default": 30000, + "description": "The timeout in milliseconds on the startup check the app-server will do to find its agent and check agent capabilities" + }, + "jwt": { + "type": "object", + "additionalProperties": false, + "properties": { + "fallback": { + "type": "boolean", + "description": "Whether the agent will issue and accept cookies from itself in the event a JWT cannot be provided" + } + } + } + } + }, + "productDir": { + "type": "string", + "description": "The location of the product scope of the configuration dataservice" + }, + "siteDir": { + "type": "string", + "description": "The location of the site scope of the configuration dataservice" + }, + "instanceDir": { + "type": "string", + "description": "The location of the instance scope of the configuration dataservice" + }, + "groupsDir": { + "type": "string", + "description": "The location of the groups scope of the configuration dataservice" + }, + "usersDir": { + "type": "string", + "description": "The location of the user scope of the configuration dataservice" + }, + "pluginsDir": { + "type": "string", + "description": "The location where plugin locator JSON files are found, which are used by the app-server and agent to locate and use plugins" + }, + "dataserviceAuthentication": { + "type": "object", + "description": "Describes how the app-server will utilize the auth plugins it finds and loads at startup", + "additionalProperties": false, + "properties": { + "rbac": { + "type": "boolean", + "description": "Determines whether or not the app-server will issue authorization requests to the authentication plugins for each HTTP(S) request to achieve Role Based Access Control", + "default": false + }, + "defaultAuthentication": { + "type": "string", + "description": "Instructs the app-server which authentication category to issue auth requests to if a specific one was not specified by the caller or plugin", + "default": "fallback" + }, + "implementationDefaults": { + "type": "object", + "deprecated": true, + "patternProperties": { + "^.*$": { + "type": "object", + "additionalProperties": false, + "properties": { + "plugins": { + "type": "array", + "items": { + "$ref": "/schemas/v2/server-common/#zoweReverseDomainNotation" + }, + "uniqueItems": true + } + } + } + } + } + } + }, + "logLevels": { + "type": "object", + "patternProperties": { + "_zsf.bootstrap": { + "description": "Logging that pertains to the startup of the server.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.auth": { + "description": "Logging for network calls that must be checked for authentication and authorization purposes.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.static": { + "description": "Logging of the serving of static files (such as images) from an application's /web folder.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.child": { + "description": "Logging of child processes, if any.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.utils": { + "description": "Logging for miscellaneous utilities that the server relies upon.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.proxy": { + "description": "Logging for proxies that are set up in the server.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.install": { + "description": "Logging for the installation of plug-ins.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.apiml": { + "description": "Logging for communication with the api mediation layer.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.routing": { + "description": "Logging for dispatching network requests to plug-in dataservices.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.network": { + "description": "Logging for the HTTPS server status (connection, ports, IP, and so on)", + "$ref": "#/$defs/logLevel" + }, + "^.*$": { + "$ref": "#/$defs/logLevel" + } + } + }, + "logLanguage": { + "type": "string", + "default": "en" + }, + "languages": { + "additionalProperties": false, + "properties": { + "java": { + "type": "object", + "additionalProperties": false, + "properties": { + "portRange": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "minItems": 2, + "maxItems": 2 + } + }, + "ports": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "uniqueItems": true + } + }, + "jar": { + "type": "object", + "properties": { + "runtimes": { + + }, + "runtimeMapping": { + + } + } + }, + "war" : { + "type": "object", + "required": [ "javaAppServer" ], + "additionalProperties": false, + "properties": { + "pluginGrouping": { + "type": "array", + "description": "A list of which java plugins should run in which java runtimes. If not present, all will run from one runtime", + "items": { + "type": "object", + "required": [ "plugins" ], + "additionalProperties": false, + "properties": { + "java": { + "type": "string" + }, + "plugins": { + "type": "array", + "items": { + "$ref": "/schemas/v2/server-common/#zoweReverseDomainNotation" + } + } + } + } + }, + "defaultGrouping": { + "type": "string", + "description": "Determines whether services should be grouped together in as few processes as possible or run as 1 process per service", + "enum": [ "microservice", "appserver" ] + }, + "javaAppServer": { + "type": "object", + "propeties": { + "type": { + "type": "string", + "enum": [ "tomcat" ] + }, + "path": { + "type": "string" + }, + "config": { + "type": "string", + "description": "The file path to the appserver config file" + }, + "https": { + "type": "object", + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/$defs/pathCertObject" + }, + "certificate": { + "$ref": "#/$defs/pathCertObject" + }, + "certificateChain": { + "$ref": "#/$defs/pathCertObject" + } + } + } + } + } + } + }, + "runtimes": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "required": [ "home" ], + "additionalProperties": false, + "properties": { + "home": { + "type": "string", + "description": "The path of the runtime's home directory" + } + } + } + } + } + } + } + } + }, + "instanceID": { + "type": "string", + "description": "The ID used in determining which set of RBAC resources to verify during authorization" + }, + "privilegedServerName": { + "type": "string", + "description": "The nickname of the ZIS server to be used" + } + }, + "$defs": { + "ipOrHostname": { + "type": "string" + }, + "ipsAndHostnames": { + "type": "array", + "items": { + "$ref": "#/$defs/ipOrHostname" + }, + "uniqueItems": true + }, + "nodejsDefaultCiphers": { + "const": "NODEJS", + "description": "Instructs app-server to use the default cipher list of nodejs when using TLS" + }, + "zoweDefaultCiphers": { + "const": "", + "description": "Instructs app-server to use its default cipher list when using TLS" + }, + "customCiphers": { + "type": "string", + "not": { + "anyOf": [ + { "$ref": "#/$defs/nodejsDefaultCiphers" }, + { "$ref": "#/$defs/zoweDefaultCiphers" } + ] + }, + "description": "Instructs app-server to use the list of ciphers in this string when using TLS. String must be in the form defined here https://nodejs.org/api/tls.html#modifying-the-default-tls-cipher-suite" + }, + "headerCustomization": { + "type": "object", + "additionalProperties": false, + "properties": { + "substitutions": { + "type": "object", + "patternProperties": { + "^.*$": { + "oneOf": [ + { "$ref": "#/$defs/headerSubstituteDomain" } + ] + } + } + } + } + }, + "headerSubstituteDomain": { + "const": "domain", + "description": "Substitute the variable referenced with the value of the domain seen on the request" + }, + "certObject": { + "type": "array", + "description": "The location of a file or keyring object", + "items": { + "anyOf": [ + { "$ref": "#/$defs/fileCertObject" }, + { "$ref": "#/$defs/pathCertObject" }, + { "$ref": "#/$defs/safKeyringCertObject" } + ] + }, + "uniqueItems": true + }, + "fileCertObject": { + "type": "string", + "pattern": "^file:\/\/.*$" + }, + "safKeyringCertObject": { + "type": "string", + "pattern": "^safkeyring:(\/\/)+.*$" + }, + "pathCertObject": { + "type": "string", + "not": { + "anyOf": [ + { "pattern": "^file:\/\/.*$" }, + { "pattern": "^safkeyring:(\/\/)+.*$" } + ] + } + }, + "cspPresetStrict": { + "const": "strict", + "description": "Applies builtin value 'default-src self req.hostname'" + }, + "cspPresetFrameStrict": { + "const": "frame-strict", + "description": "Applies builtin value 'frame-src self req.hostname'" + }, + "logLevel": { + "type": "integer", + "description": "Log level verbosity where 0 is least verbose (errors only), 5 is most verbose (trace) and 2 is default (info)", + "default": 2, + "minimum": 0, + "maximum": 5 + } + } +} diff --git a/schemas/plugindefinition-schema.json b/schemas/plugindefinition-schema.json new file mode 100644 index 00000000..6023cf17 --- /dev/null +++ b/schemas/plugindefinition-schema.json @@ -0,0 +1,517 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/appfw-plugin-definition", + "title": "Application Framework Plugin Definition", + "description": "Properties seen in a pluginDefinition.json file which describes a plugin of the Zowe Application Framework", + "type": "object", + "oneOf": [ + { "$ref": "#/$defs/bootstrapPlugin" }, + { "$ref": "#/$defs/desktopPlugin" }, + { "$ref": "#/$defs/libraryPlugin" }, + { "$ref": "#/$defs/applicationPlugin" }, + { "$ref": "#/$defs/nodeAuthenticationPlugin" } + ], + "$defs": { + "reverseDomainNotation": { + "type": "string", + "pattern": "^[A-Za-z]{2,6}((?!-)\\.[A-Za-z0-9-]{1,63}(?\\<]?)|(>=?)|(<=?))(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + }, + "appFwPlugin": { + "type": "object", + "required": ["identifier", "apiVersion", "pluginVersion", "pluginType"], + "propeties": { + "identifier": { + "$ref": "#/$defs/reverseDomainNotation", + "description": "Each plugin must have a zowe-wide unique ID in reverse domain name notation" + }, + "apiVersion": { + "$ref": "#/$defs/semverVersion", + "description": "Describes which version of this schema the plugin is compatible with" + }, + "pluginVersion": { + "$ref": "#/$defs/semverVersion", + "description": "Describes the plugin's version. The app-server only runs 1 version of each plugin." + }, + "pluginType": { + "type": "string", + "enum": [ "bootstrap", "desktop", "library", "application", "nodeAuthentication" ] + }, + "license": { + "type": "string", + "description": "An SPDX string describing which license the plugin is available under" + }, + "author": { + "type": "string", + "description": "States who the writers of the plugin are" + }, + "homepage": { + "type": "string", + "description": "A website URL of the writers of the plugin" + }, + "requirements": { + "type": "object", + "description": "Defining a list of requirements lets the app-server decide if your plugin should or should not be loaded according to if requirements are met in the environment.", + "additionalProperties": false, + "properties": { + "components": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "properties": { + "os": { + "type": "array", + "items": { + "type": "string", + "description": "An OS type as reported by nodejs os.platform()" + } + }, + "cpu": { + "type": "array", + "items": { + "type": "string", + "description": "A CPU architecture type as reported by nodejs os.arch()" + } + }, + "version": { + "type": "array", + "items": { + "$ref": "#/$defs/semverRange" + } + }, + "endpoints": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "dataServices": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "#/$defs/routerService" }, + { "$ref": "#/$defs/serviceService" }, + { "$ref": "#/$defs/importService" }, + { "$ref": "#/$defs/externalService" }, + { "$ref": "#/$defs/nodeService" } + ] + }, + "uniqueItems": true + }, + "configurationData": { + "type": "object", + "description": "TODO", + "properties": { + "resources": { + "type": "object" + } + } + } + } + }, + "libraryPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Library plugins are used for hosting static web content", + "deprecated": true, + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "library" + }, + "libraryName": { + "type": "string" + }, + "libraryVersion": { + "$ref": "#/$devs/semverVersion" + } + } + }, + "bootstrapPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Only one bootstrap plugin per server is intended, and its role is to bootstrap Desktop-type plugins for browser use", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "bootstrap" + }, + "webContent": { + "$ref": "#/$defs/genericWebContent" + } + } + }, + "desktopPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Desktop plugins are webcontent which embeds application-type plugins within a web browser, regardless of if resembles a 'desktop' or not.", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "desktop" + }, + "webContent": { + "$ref": "#/$defs/nativeWebContent" + } + } + }, + "applicationPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Application plugins contain web content and/or network APIs which are compatible with embedding in a Desktop plugin web page, but may also be used by themselves", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "application" + }, + "webContent": { + "type": "object", + "oneOf": [ + { "$ref": "#/$defs/iframeWebContent" }, + { "$ref": "#/$defs/genericWebContent" }, + { "$ref": "#/$defs/nativeWebContent" } + ] + }, + "isSystemPlugin": { + "type": "boolean", + "default": false, + "description": "Set this to true to make a plugin that cannot be opened directly by users, but may be invoked by other apps and the application framework itself via app2app communication as needed." + } + } + }, + "nodeAuthenticationPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "The app-server delegates to these plugins for user permission management tasks such as authentication and authorization", + "required": [ "filename" ], + "additionalProperties": false, + "properties": { + "filename": { + "type": "string", + "description": "The name of a nodejs file within the /lib directory of the plugin. This file contains a function that is provided with startup context and must contain methods according to its stated capabilities such as authentication and authorization" + }, + "authenticationCategories": { + "type": "array", + "items": { + "type": "string", + "description": "A short name describing what sort of authentication this plugin can provide, such as LDAP, SAF, etc. If the categories are not known until startup, this info can still be stated at runtime within the javascript code." + }, + "uniqueItems": true + } + } + }, + "genericWebContent": { + "type": "object", + "not": { + "anyOf": [ + { "$ref": "#/$defs/nativeWebContent" }, + { "$ref": "#/$defs/iframeWebContent" } + ] + }, + "description": "A webcontent object without the attributes of an application, such as framework, can be used to just serve a plugin's /web folder from the app-server" + }, + "nativeWebContent": { + "$ref": "#/$defs/appWebContent", + "description": "A Native application is one that provides a /web/main.js file which can be run within the Zowe Desktop when the user clicks its icon", + "additionalProperties": false, + "properties": { + "framework": { + "type": "string", + "enum": [ "angular2", "angular", "react" ] + } + } + }, + "iframeWebContent": { + "$ref": "#/$defs/appWebContent", + "description": "An iframe application is one that provides some html file either within the /web folder or found on another server at runtime, which can be embedded within the Zowe Desktop when the user clicks its icon", + "additionalProperties": false, + "properties": { + "framework": { + "const": "iframe" + }, + "oneOf": [ + "destination": { + "type": "string", + "description": "A URL with shell-style ${} subtitutions allowed which states which address the iframe should load." + }, + "startingPage": { + "type": "string", + "description": "A filename within the /web folder of the plugin, which the iframe should load." + } + ], + "standaloneUseFramework": { + "type": "boolean", + "default": false, + "description": "When true, iframe apps will be launched within the desktop framework so that features like notifications and app2app communication will function identically to the Desktop. When false, opening the iframe app in a standalone page will have it function like an independent website." + } + } + }, + "appWebContent": { + "type": "object", + "description": "A description of an application which can be run within the Zowe Desktop", + "required": [ "framework", "launchDefinition", "descriptionKey", "descriptionDefault", "defaultWindowStyle" ], + "additionalProperties": false, + "properties": { + "framework": { + "type": "string", + "enum": [ "angular2", "angular", "react", "iframe" ] + }, + "launchDefinition": { + "type": "object", + "required": [ "pluginShortNameKey", "pluginShortNameDefault", "imageSrc" ], + "properties": { + "pluginShortNameKey": { + "type": "string", + "description": "The internationalization key used to display the application's name in the user's chosen language." + }, + "pluginShortNameDefault": { + "type": "string", + "description": "The name of the application in the default language. Used as a fallback if the user's chosen language has no translation." + }, + "imageSrc": { + "type": "string", + "description": "A path relative to and within the 'web' folder of the plugin. This image is used as the application's icon" + } + } + }, + "descriptionKey": { + "type": "string", + "description": "The internationalization key used to display the application's description in the user's chosen language." + }, + "descriptionDefault": { + "type": "string", + "description": "The description of the application in the default language. Used as a fallback if the user's chosen language has no translation." + }, + "isSingleWindowApp": { + "type": "boolean", + "deprecated": true + }, + "defaultWindowStyle": { + "type": "object", + "description": "Properties that describe the default visuals of the application window, such as size", + "required": [ "width", "height" ], + "properties": { + "width": { + "type": "integer", + "minimum": 180, + "description": "The width of the Zowe Desktop window of the application when first opened" + }, + "height": { + "type": "integer", + "minimum": 100, + "description": "The height of the Zowe Desktop window of the application when first opened" + } + } + } + } + }, + "service": { + "type": "object", + "description": "A part of a plugin which adds a network API to a server such as a REST or websocket API", + "required": ["type", "version", "name"], + "properties": { + "type": { + "type": "string", + "enum": [ "router", "service", "external", "nodeService", "java" ] + }, + "version": { + "$ref": "#/$defs/semverVersion" + }, + "name": { + "type": "string" + } + } + }, + "externalService": { + "$ref": "#/$defs/service", + "description": "A proxy service which is hosted from the app-server", + "additionalProperties": false, + "properties": { + "type": { + "const": "external" + }, + "urlPrefix": { + "type": "string" + }, + "isHttps": { + "type": "boolean", + "deprecated": true, + "description": "Specifies if the proxy is to an HTTP or HTTPS server. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object" + }, + "host": { + "type": "string", + "deprecated": true, + "description": "Specifies which hostname or IP is being proxied. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object", + "format": "hostname" + }, + "port": { + "type": "integer", + "deprecated": true, + "description": "Specifies which port is being proxied. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object" + } + } + }, + "routerService": { + "$ref": "#/$defs/service", + "description": "An ExpressJS router service hosted from the app-server", + "required": ["type", "version", "name", "fileName", "routerFactory"], + "additionalProperties": false, + "properties": { + "type": { + "const": "router" + }, + "initializerLookupMethod": { + "type": "string", + "enum": ["external"], + "deprecated": true + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "fileName": { + "type": "string", + "description": "A javascript file located within the plugin's 'lib' folder which contains the router factory. The router is for a REST or Websocket API that the app-server will include." + }, + "routerFactory": { + "type": "string", + "description": "The name of a javascript function found in the file specified in 'fileName' which is given plugin context and must return an expressjs router" + }, + "httpCaching": { + "type": "boolean", + "default": false, + "description": "When false, the app-server will add headers to the service response to tell clients not to cache the response" + }, + "internalOnly": { + "type": "boolean", + "default": false, + "description": "When true, the service can only be reached by other services within the same server via the call() function" + } + } + }, + "nodeService": { + "$ref": "#/$defs/service", + "description": "A nodejs callback service that acts upon expressjs request and response objects. It runs within the app-server", + "required": ["type", "version", "name", "fileName", "methods", "handlerInstaller"], + "deprecated": true, + "additionalProperties": false, + "properties": { + "type": { + "const": "nodeService" + }, + "initializerLookupMethod": { + "type": "string", + "enum": [ "external" ] + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "fileName": { + "type": "string", + "description": "A javascript file located within the plugin's 'lib' folder which contains the handler factory. The handler is for a REST or Websocket API that the app-server will include." + }, + "handlerInstaller": { + "type": "string", + "description": "The name of a javascript function found in the file specified in 'fileName' which is given plugin context and must return a callback function" + }, + "methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ "GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD" ], + "description": "A list of HTTP methods this service will respond to" + }, + "uniqueItems": true + } + } + }, + "serviceService": { + "$ref": "#/$defs/service", + "description": "A service that runs within ZSS. It uses a callback written in C that recieves a request and response struct", + "required": ["type", "version", "name", "methods", "initializerName"], + "additionalProperties": false, + "properties": { + "type": { + "const": "service" + }, + "initializerLookupMethod": { + "type": "string", + "description": "States whether the service is to be found as a plugin or is built-in to ZSS already", + "enum": ["external", "internal"], + "deprecated": false + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "libraryName": { + "type": "string", + "description": "The path of a 31-bit or 64-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "libraryName31": { + "type": "string", + "description": "The path of a 31-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "libraryName64": { + "type": "string", + "description": "The path of a 64-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ "GET", "PUT", "POST", "DELETE" ], + "description": "A list of HTTP methods this service will respond to" + }, + "uniqueItems": true + }, + "initializerName": { + "type": "string", + "description": "The function name that will be called with plugin context to add the service routes to the agent" + } + } + }, + "importService": { + "type": "object", + "description": "A service which points to another service. The app-server will setup a URL which calls the source when accessed", + "required": [ "type", "sourceName", "localName", "sourcePlugin", "versionRange" ], + "additionalProperties": false, + "properties": { + "type": { + "const": "import" + }, + "sourceName": { + "type": "string", + "description": "The name of the service being imported" + }, + "localName": { + "type": "string", + "description": "The name of this service within this plugin" + }, + "sourcePlugin": { + "$ref": "#/$defs/reverseDomainNotation", + "description": "The ID of the plugin where the service is being imported from" + }, + "versionRange": { + "$ref": "#/$defs/semverRange", + "description": "A semver range that describes which version of the service to import" + } + } + } + } +} diff --git a/schemas/zowe-schema.json b/schemas/zowe-schema.json new file mode 100644 index 00000000..091495fd --- /dev/null +++ b/schemas/zowe-schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/app-server", + "allOf": [ + { "$ref": "/schemas/v2/server-base" }, + { "type": "object", + "properties": { + "components": { + "type": "object", + "properties": { + "additionalProperties": true, + "app-server": { + "allOf": [ + { "$ref": "/schemas/v2/server-base#zoweComponent" }, + { "$ref": "/schemas/v2/app-server-config"} + ] + } + } + } + } + } + ] +} From d2d09fb2dd3fd15d8a791849c52f66d2b8ac0a23 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 6 Apr 2022 14:47:33 -0400 Subject: [PATCH 3/7] Add manifest, update text files, update metadata Signed-off-by: 1000TurquoisePogs --- README.md | 197 ++++++++++++++++++++++++++++-------------------- lib/zluxArgs.js | 2 +- manifest.yaml | 2 - 3 files changed, 116 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index 21f2f445..dc6833f4 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Follow each step and you'll be on your way to your first App Server instance! ### Building & Developing To build the App Server and Apps, the following is required: -* **NodeJS** - v12.x minimum. The App Server and server plugins must support minimum v8.16.x at runtime, but v12.x is used for building. +* **NodeJS** - v14.x minimum. The App Server and server plugins must support minimum v8.16.x at runtime, but v14.x is used for building. * **npm** - v6.4 minimum @@ -80,7 +80,7 @@ To use the App Server, the following is required: * **NodeJS** - v8.16.x minimum up to v12.x is officially supported by the Zowe community. -Plugins may depend upon other technologies, such as Java or ZSS. An plugin's [pluginDefinition](https://github.com/zowe/zlux/wiki/Zlux-Plugin-Definition-&-Structure) or README will help you to understand if additional prerequisites are needed for that plugin. +Plugins may depend upon other technologies, such as Java or ZSS. An plugin's [pluginDefinition](https://docs.zowe.org/stable/extend/extend-desktop/mvd-plugindefandstruct) or README will help you to understand if additional prerequisites are needed for that plugin. ## 1. Acquire the source code @@ -90,7 +90,7 @@ If using git, the following commands should be used: ``` git clone --recursive git@github.com:zowe/zlux.git cd zlux -git submodule foreach "git checkout master" +git submodule foreach "git checkout v2.x/master" ``` For the initial setup, the default authentication is the "trivial authentication" plugin, which allows login to the App Server without valid credentials. At the end of this guide, you can customize the environment to switch to a secure authentication plugin instead, such as the ZSS authentication plugin, covered in [Section 7](#7-adding-zss-to-the-environment). @@ -102,7 +102,7 @@ The App Server framework & core plugins contain server and/or web components. Since these web components use webpack for packaging optimization, and server components may use typescript or other software that requires compiling, it is necessary to build the code before using the server and plugins. There are utilities within the zlux-build folder for initializing & building core plugins and the framework itself, which will be used. -However, those tools are not needed when building individual plugins, as it is faster to build them each as needed when [following this documentation.](https://github.com/zowe/zlux/wiki/Building-Plugins) +However, those tools are not needed when building individual plugins, as it is faster to build them each as needed when [following this documentation.](https://docs.zowe.org/stable/extend/extend-desktop/mvd-buildingplugins) On the host running the App Server, run the script that will automatically build all included Apps: @@ -141,7 +141,7 @@ When the App Server has started, one of the messages you will see as bootstrappi ### Server Logs When the server starts, it writes logs to a text file. On z/OS, Unix, and Linux, the server also logs to the terminal via stdout. -To view the entire logs, you can find the log file within ``, which will default to `~/.zowe/logs` or `%USERPROFILE%/.zowe/logs` (Windows) if ZWE_zowe_logDirectory is not specified. The log file starts with "appServer" and the filename may also include a timestamp. +To view the entire logs, you can find the log file within the location specified by the zowe server configuration parameter `zowe.logDirectory`, but will default to `~/.zowe/logs` or `%USERPROFILE%/.zowe/logs` (Windows) if not specified. The log file starts with "appServer" and the filename may also include a timestamp. ## 4. Connect in a browser With the App Server started, you can access Apps and the Zowe Desktop from it in a web browser. @@ -150,11 +150,15 @@ The URL for this is: https://\:7556/ZLUX/plugins/org.zowe.zlux.bootstrap/web/index.html +**Note: If you are using the API Mediation Layer, which is not covered here, it is preferred to access the app server through it. That URL would be https://\:\/zlux/ui/v1/ZLUX/plugins/org.zowe.zlux.bootstrap/web/index.html** + Once here, you should be greeted with a Login screen. By default trivial authentication is used which allows to login with arbitrary credentials. So, you can type in any username to get access to the desktop, which likely does not yet have any Apps. Next, the server should be configured, Apps added, and authentication set up. ## 5. Customizing configuration -Read the [Configuration](https://github.com/zowe/zlux/wiki/Configuration-for-zLUX-App-Server-&-ZSS) wiki page for a detailed explanation of the primary items that you'll want to configure for your server. +A default configuration file is present in zlux-app-server/defaults/serverConfig/zowe.yaml. In a development environment, you should move this somewhere and customize it and use it to start the server. + +Read the [Configuration](https://docs.zowe.org/stable/user-guide/mvd-configuration) page for anexplanation of interesting items that you'll want to configure for your server, as well as [the json-schema document for the app-server](https://github.com/zowe/zlux/blob/v2.x/staging/schemas/zlux-config-schema.json) which describes every possible value. In short, determine the location of your workspace directory (Environment variable `ZWE_zowe_workspaceDirectory`, or `~/.zowe/workspace` (Linux, Unix, z/OS) or `%USERPROFILE%/.zowe` when `ZWE_zowe_workspaceDirectory` is not defined) Within the workspace directory, create **app-server/serverConfig/zowe.yaml** by copying **zlux-app-server/defaults/serverConfig/zowe.yaml**, and edit it to change attributes such as the HTTPS port via **components.app-server.node.https.port**, or the location of plugins. @@ -166,9 +170,9 @@ Plugins, like the framework, can contain server and/or web components, either of The Plugins which have web components are also called "Apps" within the UI. To add a plugin to the server, it must first be built. Plugins that you download may already be pre-built. -[Click here to read about building plugins](https://github.com/zowe/zlux/wiki/Building-Plugins) +[Click here to read about building plugins](https://docs.zowe.org/stable/extend/extend-desktop/mvd-buildingplugins) -[Click here to read about installing plugins](https://github.com/zowe/zlux/wiki/Installing-Plugins) +[Click here to read about installing plugins](https://docs.zowe.org/stable/extend/extend-desktop/mvd-installplugins) ### Plugin Build & Add Example Following the references above, this is how you can add a TN3270 terminal emulator app to your App Server, for an App server installed in `~/my-zowe` @@ -235,15 +239,13 @@ A successful build will result in the ZSS binary being placed at `zss/bin/zssSer Before running, you must set also set program control attribute on the ZSS binary. It is needed to make the APIs run under the authenticated user's permissions. ``` -cp zssServer ../../zlux-app-server/bin -extattr +p ../../zlux-app-server/bin/zssServer +cp zssServer64 ../../zlux-app-server/bin +extattr +p ../../zlux-app-server/bin/zssServer64 ``` Finally, the ZSS Cross memory server must be installed and configured according to [This Install Guide](https://github.com/zowe/docs-site/blob/master/docs/user-guide/install-zos.md#manually-installing-the-zowe-cross-memory-server) -With ZSS built, you can now run it in one of two ways. -* Run it independently of the App Server via `zlux-app-server/bin/zssServer.sh` or -* Run the App Server and it will attempt to start `zssServer.sh` as a child process, due to it being defined as a child process in the zowe.yaml +With ZSS built, you can now run it in via `zss/bin/zssServer.sh` ### Configuring App Server to use ZSS In App Server terminology, ZSS is a **Agent**, where the Agent is responsible for fulfilling low-level & OS-specific APIs that the App Server delegates. In order to use the App Server and ZSS together, your App Server must be configured to use it as an Agent, and setup with a security plugin which uses ZSS as an App Server security provider. @@ -253,97 +255,128 @@ To add ZSS as a security provider, add the **sso-auth** plugin to the App Server 1. `./install-app.sh ~/my-zowe/zlux-server-framework/plugins/sso-auth` Then, you need set the configuration of the App Server to prefer that security provider. -Locate and edit zowe.yaml (Within ZWE_zowe_workspaceDirectory/app-server/serverConfig/zowe.yaml, such as `~/.zowe/workspace/app-server/serverConfig/zowe.yaml`) -Within that file, set `dataserviceAuthentication.defaultAuthentication = "saf"`. +Locate and edit the zowe configuration file such as zowe.yaml (such as ~/.zowe/workspace/app-server/ServerConfig/zowe.yaml) and within that file, set `components.app-server.dataserviceAuthentication.defaultAuthentication = "saf"`. Keep this file open to continue with agent setup. #### Agent Setup (App Server side) -Within the zowe.yaml file, you need to define or set **components.zss.agent.agent.host** to a hostname or ip address where ZSS is located that is also visible to the App Server. This could be '0.0.0.0' or the hostname of a z/OS system. -You must also define or set **components.zss.agent.agent.port**. This is the TCP port which ZSS will listen on to be contacted by the App Server. Define this in the configuration file as a value between 1024-65535. See [zss configuration](https://github.com/zowe/zlux/wiki/Configuration-for-ZLUX-App-Server-&-ZSS#zss-configuration) for more information and an example. +Within the Zowe configuration file, you need to define or set **components.zss.agent.host** to a hostname or ip address where ZSS is located that is also visible to the App Server. This should be the hostname of a z/OS system. +You must also define or set **component.zss..port**. This is the TCP port which ZSS will listen on to be contacted by the App Server. Define this in the configuration file as a value between 1024-65535. See [zss configuration](https://docs.zowe.org/stable/user-guide/mvd-configuration) for more information and an example. -As a result of the above edits to zowe.yaml, an example of what it may now look like is: +An example of a zowe configuration file that works for app-server when zss is available on a different system: ```yaml components: - app-server: - node: - https: - ipAddresses: - - 0.0.0.0 + app-server: port: 7556 - keys: - - "../defaults/serverConfig/zlux.keystore.key" - certificates: - - "../defaults/serverConfig/zlux.keystore.cer" - certificateAuthorities: - - "../defaults/serverConfig/apiml-localca.cer" - childProcesses: - - path: "../bin/zssServer.sh" - once: true - productDir: "../defaults" - siteDir: "~/.zowe/workspace/app-server/site" - groupsDir: "~/.zowe/workspace/app-server/groups" - usersDir: "~/.zowe/workspace/app-server/users" - pluginsDir: "~/.zowe/workspace/app-server/plugins" - dataserviceAuthentication: - defaultAuthentication: saf - rbac: false - zss: - agent: - host: localhost - https: - port: 7557 - + enabled: true + productDir: ../defaults + siteDir: ~/.zowe/workspace/app-server/site + instanceDir: ~/.zowe/workspace/app-server + groupsDir: ~/.zowe/workspace/app-server/groups + usersDir: ~/.zowe/workspace/app-server/users + pluginsDir: ~/.zowe/workspace/app-server/plugins + node: + https: + ipAddresses: + - 0.0.0.0 + keys: + - "../defaults/serverConfig/zlux.keystore.key" + certificates: + - "../defaults/serverConfig/zlux.keystore.cer" + certificateAuthorities: + - "../defaults/serverConfig/apiml-localca.cer" + agent: + host: "localhost" + https: + port: 7557 + dataserviceAuthentication: + defaultAuthentication: "saf" + rbac: false ``` #### Agent Setup (ZSS side) On z/OS, ZSS must be set to have the correct port, IP, and HTTP(S) configuration so that the app-server can reach it. -On a release install (not covered here, but described on docs.zowe.org), ZSS is already set up for use over HTTPS. You can update `ZWES_SERVER_PORT` in a Zowe zowe.yaml file to set which port it should use, to match the value you have on your dev install for `agent.https.port`. +On a release install (not covered here, but described on docs.zowe.org), ZSS is already set up for use over HTTPS. You can update `components.zss.port` in a Zowe configuration file to set which port it should use, to match the value you have on your dev install for `components.app-server.agent.https.port`. -On a dev install of ZSS, instead of zowe.yaml, server.json is used just like the dev install of the app-server. In fact if App Server and ZSS are on the same system, then this can be the same file. Otherwise, you must edit the server.json file where ZSS is and keep it in sync with the App Server one with regards to the **agent** settings. In a dev install, it is recommended to use a GSKIT compatible keyring or p12 file for using ZSS over HTTPS, or HTTPS via ATTLS, but HTTP is also possible. In that case, you simply configure `agent.http.port` instead of `agent.https.port`, and `agent.http.ipAddresses` instead of `agent.https.ipAddresses`. So, use server.json to set the port and IPs you need to make ZSS visible to the system where app-server runs. +On a dev install, app-server and zss may be on different systems, but the zowe configuration files for each must match so that app-server can reach zss. **Note: It is highly recommended to have HTTPS for ZSS. This is the default on a release install, but it is also possible to use AT-TLS to do this such as by following [configuring AT-TLS](https://zowe.github.io/docs-site/latest/user-guide/mvd-configuration.html#configuring-zss-for-https). It is most important when using ZSS externally, as the session security is essential for all but trivial development environments** -#### Agent swagger installation -If you intend to use the API Catalog as well, you will want to [install the plugin](https://github.com/zowe/zlux/wiki/Installing-Plugins) "zlux-agent", found in `zlux-server-framework/plugins/zlux-agent`. -This allows the app-server to serve agent swagger definitions, which are then visible in the API catalog. - - -### Starting App Server when using ZSS -When running the App Server with an Agent such as ZSS, you can either set the `server.json` with all info to connect to the Agent, or set that info via environment variable or command line arguments. The above sections detail `server.json` configuration, but the other ways to set the IP and port of the Agent are: - -1. Environment variable configuration -Items in server.json can be substitued by environment variables that have a name that corresponds to each item. The pattern is - -`ZWED_json_key=value` where `ZWED_` is the prefix, and `json_key` is the name of the key. For example, +Below is an example of a configuration file just for zss, for when app-server is elsewhere. +```yaml +components: + zss: + port: 7557 + enabled: true + tls: true + productDir: ../defaults + pluginsDir: ~/.zowe/workspace/app-server/plugins + agent: + https: + ipAddresses: + - 0.0.0.0 + keyring: "/path/to/keystore.p12" + password: "keyringpassword" + label: "keylabel" + dataserviceAuthentication: + rbac: false ``` -ZWED_agent_http_port=9999 -ZWED_node_https_ipAddresses=127.0.0.1,192.168.1.100 -``` - -This would override the `server.json` value of `agent.http.port` to be 9999, and `node.https.ipAddresses` to be ['127.0.0.1','192.168.1.100']. - -2. CLI argument configuration -Items in server.json can also be substituded by arguments and flags. The pattern for arguments is - -`-Djson.key=value`, where `-D` denotes an argument, and `json.key` is the name of the key. For example, - -`-Dagent.http.port=9999 -Dnode.https.ipAddresses=127.0.0.1,192.168.1.100` Would set `agent.http.port` to be 9999, and `node.https.ipAddresses` to be ['127.0.0.1,'192.168.1.100']. - -There are also specific flags used for well-known configuration items, such as: -- *-h*: Declares the host where ZSS can be found. Use as "-h \" -- *-P*: Declares the port at which ZSS is listening. -- *-s*: Declares the https port the App Server will listen on. +Below is an example of a unified configuration file for when app-server and zss are on the same system. +```yaml +components: + app-server: + port: 7556 + enabled: true + productDir: ../defaults + siteDir: ~/.zowe/workspace/app-server/site + instanceDir: ~/.zowe/workspace/app-server + groupsDir: ~/.zowe/workspace/app-server/groups + usersDir: ~/.zowe/workspace/app-server/users + pluginsDir: ~/.zowe/workspace/app-server/plugins + node: + https: + ipAddresses: + - 0.0.0.0 + keys: + - "../defaults/serverConfig/zlux.keystore.key" + certificates: + - "../defaults/serverConfig/zlux.keystore.cer" + certificateAuthorities: + - "../defaults/serverConfig/apiml-localca.cer" + agent: + host: "localhost" + https: + port: 7557 + dataserviceAuthentication: + defaultAuthentication: "saf" + rbac: false + + zss: + port: 7557 + enabled: true + tls: true + productDir: ../defaults + pluginsDir: ~/.zowe/workspace/app-server/plugins + agent: + https: + ipAddresses: + - 0.0.0.0 + keyring: "/path/to/keystore.p12" + password: "keyringpassword" + label: "keylabel" + dataserviceAuthentication: + rbac: false +``` -This program and the accompanying materials are -made available under the terms of the Eclipse Public License v2.0 which accompanies -this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html +#### Agent swagger installation +If you intend to use the API Catalog as well, you will want to [install the plugin](https://docs.zowe.org/stable/extend/extend-desktop/mvd-installplugins) "zlux-agent", found in `zlux-server-framework/plugins/zlux-agent`. +This allows the app-server to serve agent swagger definitions, which are then visible in the API catalog. -SPDX-License-Identifier: EPL-2.0 -Copyright Contributors to the Zowe Project. +### Starting App Server when using ZSS +When running the App Server with an Agent such as ZSS, you may need to start each independently. They both consume a standardized configuration file as shown in the above examples, but if you're using a development environment instead of a production install, you may need to start app-server and zss by running zlux-app-server/bin/app-server.sh and zss/bin/zssServer.sh respectively. diff --git a/lib/zluxArgs.js b/lib/zluxArgs.js index 2ee0305c..d4206243 100644 --- a/lib/zluxArgs.js +++ b/lib/zluxArgs.js @@ -78,7 +78,7 @@ if (!userInput.config) { } let configJSON = DEFAULT_CONFIG; //Overall config is a result of a heirarchy of overrides from defaults. -//CLI args > CLI -D arg > Env vars > JSON file > builtin defaults +//CLI args > CLI -D arg > Env vars > YAML file > builtin defaults const userConfig = yamlConfig.getConfig(userInput.config, haInstanceId, componentOrder); //Config JSON overrides hardcoded defaults configJSON = mergeUtils.deepAssign(configJSON, userConfig || {}); diff --git a/manifest.yaml b/manifest.yaml index 956cd6cf..2a150db3 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -1,10 +1,8 @@ --- name: app-server -# Component identifier. This identifier matches artifact path in Zowe Artifactory https://zowe.jfrog.io/. id: org.zowe.zlux.app-server # Without the v version: "{{build.version}}" -# Component version is defined in gradle.properties for Gradle project # Human readable component name title: Application Server # Human readable component description From 8993ed410496e12196672d5f95c52b9a4ed8805f Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 7 Apr 2022 16:31:09 -0400 Subject: [PATCH 4/7] Update README.md Signed-off-by: 1000TurquoisePogs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc6833f4..15e7c752 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Follow each step and you'll be on your way to your first App Server instance! ### Building & Developing To build the App Server and Apps, the following is required: -* **NodeJS** - v14.x minimum. The App Server and server plugins must support minimum v8.16.x at runtime, but v14.x is used for building. +* **NodeJS** - v14.x minimum. The App Server and server plugins must support minimum v12.x at runtime, but v14.x is used for building. * **npm** - v6.4 minimum From d50d14909c4b505cc180cf112f50240129f0019f Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 8 Apr 2022 16:22:29 -0400 Subject: [PATCH 5/7] Add json schema using latest info from docs site on how to follow our standard Signed-off-by: 1000TurquoisePogs --- manifest.yaml | 2 + schemas/app-server-config.json | 656 +++++++++++++++++++++++++++ schemas/plugindefinition-schema.json | 517 +++++++++++++++++++++ schemas/zowe-schema.json | 23 + 4 files changed, 1198 insertions(+) create mode 100644 schemas/app-server-config.json create mode 100644 schemas/plugindefinition-schema.json create mode 100644 schemas/zowe-schema.json diff --git a/manifest.yaml b/manifest.yaml index 2a150db3..2c7fca45 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -12,6 +12,8 @@ keywords: - zlux - appfw license: EPL-2.0 +schemas: + configs: schemas/zowe-schema.json repository: type: git url: https://github.com/zowe/zlux-app-server.git diff --git a/schemas/app-server-config.json b/schemas/app-server-config.json new file mode 100644 index 00000000..12f1392a --- /dev/null +++ b/schemas/app-server-config.json @@ -0,0 +1,656 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/app-server-config", + "title": "app-server configuration", + "description": "Configuration properties for the app-server, as specified within a configuration file such as zowe.yaml", + "type": "object", + "required": [ "productDir", "siteDir", "instanceDir", "groupsDir", "usersDir", "pluginsDir", "dataserviceAuthentication", "node" ], + "additionalProperties": true, + "properties": { + "node": { + "type": "object", + "description": "Configuration options specific to the app-server and things it depends upon", + "additionalProperties": false, + "properties": { + "https": { + "type": "object", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "default": 7556 + }, + "pfx": { + "type": "string", + "deprecated": true, + "description": "Replaced with use of .p12 files within the key or certificate sections, this attribute was used to load certificates from a .pfx file" + }, + "keys": { + "$ref": "#/$defs/certObject" + }, + "certificates": { + "$ref": "#/$defs/certObject" + }, + "certificateAuthorities": { + "$ref": "#/$defs/certObject" + }, + "certificateRevocationLists": { + "$ref": "#/$defs/certObject" + }, + "secureOptions": { + "type": "integer", + "description": "Controls nodejs' use of OpenSSL via integers composed of the values in the references https://github.com/openssl/openssl/blob/master/include/openssl/ssl.h.in and https://nodejs.org/api/crypto.html#openssl-options" + }, + "secureProtocol": { + "type": "string", + "deprecated": true, + "description": "Passes through the secureProtocol attribute to TLS calls of nodeJS, as defined within https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions" + }, + "ciphers": { + "oneOf": [ + { "$ref": "#/$defs/nodejsDefaultCiphers" }, + { "$ref": "#/$defs/zoweDefaultCiphers" }, + { "$ref": "#/$defs/customCiphers" } + ] + }, + "enableTrace": { + "type": "boolean", + "default": false + }, + "passphrase": { + "type": "string", + "description": "Used to load encrypted key or certificate objects when needed" + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames", + "default": [ "0.0.0.0" ] + } + } + }, + "http": { + "type": "object", + "description": "Allows the app-server to run in HTTP mode. This should never be done without a TLS wrapper such as AT-TLS", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ] + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames" + } + } + }, + "mediationLayer": { + "type": "object", + "description": "Properties relating to how the app-server should interact with and find the API Mediation Layer components", + "additionalProperties": false, + "properties": { + "server": { + "type": "object", + "additionalProperties": false, + "properties": { + "isHttps": { + "type": "boolean", + "description": "Controls if connections to the API Mediation Layer gateway and/or discovery service should be HTTP or HTTPS" + }, + "gatewayHostname": { + "type": "string", + "format": "hostname", + "description": "The hostname or IP where the Zowe Gateway service is running. When not specified, the hostname property is used instead" + }, + "hostname": { + "type": "string", + "format": "hostname", + "description": "The hostname or IP where the Zowe Discovery service is running" + }, + "gatewayPort": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "description": "The port where the Zowe Gateway service is running" + }, + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "description": "The port where the Zowe Discovery service is running" + }, + "enabled": { + "type": "boolean", + "description": "Controls whether the app-server should register to the Zowe API Mediation Layer as a Eureka Client" + }, + "cachingService": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "description": "Controls whether the app-server storage API can store in the caching service" + } + } + } + } + } + } + }, + "internalRouting": { + "type": "boolean", + "description": "Controls if app-server should call one REST API from another by using a network call over a loopback address, or issue the request internal to the server by mimicking a network request", + "default": false + }, + "allowInvalidTLSProxy": { + "type": "boolean", + "description": "This boolean sets the inverse value of the nodeJS attribute 'rejectUnauthorized' on any TLS operation within the server. It will allow connections with certificates that cannot be validated for one reason or another.", + "default": false + }, + "childProcesses": { + "type": "array", + "description": "The app-server can start one or more processes as children of itself, and propagate signals sent to the app server to these. This can be used to start related servers at the same time as the app-server.", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "path": { + "type": "string", + "description": "The command to be started via the process spawn() command" + }, + "once": { + "type": "boolean", + "description": "When true, the child process will only be started from one worker rather than per-worker as would happen in cluster mode otherwise.", + "default": false + } + } + } + }, + "session": { + "type": "object", + "additionalProperties": false, + "properties": { + "timeoutMS": { + "type": "integer", + "deprecated": true, + "description": "No longer read by app-server" + }, + "cookie": { + "timeoutMS": { + "type": "integer", + "description": "Determines the expiration time of the app-server cookie. This does not control other cookies such as ZSS, APIML. The experation time is shown in the /auth response, not as a cookie property. The cookie does not expire but will be rejected after the server expiration time.", + "default": -1 + } + } + } + }, + "headers": { + "type": "object", + "description": "Allows customization of http response headers sent by all plugins except those headers that are set as 'override' within a plugin. Each attribute in the object is a header name.", + "patternProperties": { + "content-security-policy": { + "$ref": "#/$defs/headerCustomization", + "preset": { + "oneOf": [ + { "$ref": "#/$defs/cspPresetStrict" }, + { "$ref": "#/$defs/cspPresetFrameStrict" } + ] + } + }, + "^.*$": { + "$ref": "#/$defs/headerCustomization" + } + } + }, + "pluginScanIntervalSec": { + "type": "integer", + "description": "When set above 0, the app-server will scan pluginsDir every number of seconds to look for plugins to add, allowing you to install new plugins without restarting the server. Note this does not allow upgrade or removal, which need restart or RBAC-controlled management REST API invocation", + "default": 0 + }, + "rootRedirectURL": { + "type": "string", + "description": "The URL which the server will redirect to if a request is sent to '/'", + "default": "/ZLUX/plugins/org.zowe.zlux.bootstrap/web/" + }, + "noPrompt": { + "type": "boolean", + "description": "Whether to prompt for a passphrase when a passphrase is needed but not found for a pfx object", + "default": false + }, + "noChild": { + "type": "boolean", + "default": false, + "description": "Whether the childProcesses array should be skipped on startup." + }, + "loopbackAddress": { + "description": "The address the app-server should use to contact itself if a loopback request is needed by a call() operation from a plugin", + "$ref": "#/$defs/ipOrHostname" + }, + "hostname": { + "type": "string", + "format": "hostname", + "description": "When not specified, the nodejs value of os.hostname() is used. This value is used to tell clients and other servers the location of the app-server." + } + } + }, + "agent": { + "type": "object", + "description": "Configuration options specific to app-server agents, such as ZSS. These options are used to configure the agent, but also to tell app-server about the agent configuration", + "additionalProperties": false, + "properties": { + "host": { + "type": "string", + "description": "Tells app-server which hostname or ip to communicate with the agent at" + }, + "https": { + "type": "object", + "description": "Configures the agent to use HTTPS.", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "default": 7557 + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames", + "default": [ "0.0.0.0" ] + } + } + }, + "http": { + "type": "object", + "description": "Configures the agent to use HTTP. When using AT-TLS, this object should be defined but with http.attls=true. It is insecure and absolutely not recommended to use http without AT-TLS", + "additionalProperties": false, + "properties": { + "port": { + "oneOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ] + }, + "attls": { + "type": "boolean", + "default": false, + "description": "Tells the app-server whether or not the agent should be reached using HTTPS or HTTP when contacting the HTTP port" + }, + "ipAddresses": { + "$ref": "#/$defs/ipsAndHostnames" + } + } + }, + "mediationLayer": { + "type": "object", + "additionalProperties": false, + "properties": { + "serviceName": { + "type": "string", + "description": "What the agent will be named when found on the API Mediation Layer" + }, + "enabled": { + "type": "boolean", + "description": "Controls whether the agent should register to the API Mediation Layer, and whether the app-server should contact it via the Mediation Layer" + } + } + }, + "handshakeTimeout": { + "type": "integer", + "default": 30000, + "description": "The timeout in milliseconds on the startup check the app-server will do to find its agent and check agent capabilities" + }, + "jwt": { + "type": "object", + "additionalProperties": false, + "properties": { + "fallback": { + "type": "boolean", + "description": "Whether the agent will issue and accept cookies from itself in the event a JWT cannot be provided" + } + } + } + } + }, + "productDir": { + "type": "string", + "description": "The location of the product scope of the configuration dataservice" + }, + "siteDir": { + "type": "string", + "description": "The location of the site scope of the configuration dataservice" + }, + "instanceDir": { + "type": "string", + "description": "The location of the instance scope of the configuration dataservice" + }, + "groupsDir": { + "type": "string", + "description": "The location of the groups scope of the configuration dataservice" + }, + "usersDir": { + "type": "string", + "description": "The location of the user scope of the configuration dataservice" + }, + "pluginsDir": { + "type": "string", + "description": "The location where plugin locator JSON files are found, which are used by the app-server and agent to locate and use plugins" + }, + "dataserviceAuthentication": { + "type": "object", + "description": "Describes how the app-server will utilize the auth plugins it finds and loads at startup", + "additionalProperties": false, + "properties": { + "rbac": { + "type": "boolean", + "description": "Determines whether or not the app-server will issue authorization requests to the authentication plugins for each HTTP(S) request to achieve Role Based Access Control", + "default": false + }, + "defaultAuthentication": { + "type": "string", + "description": "Instructs the app-server which authentication category to issue auth requests to if a specific one was not specified by the caller or plugin", + "default": "fallback" + }, + "implementationDefaults": { + "type": "object", + "deprecated": true, + "patternProperties": { + "^.*$": { + "type": "object", + "additionalProperties": false, + "properties": { + "plugins": { + "type": "array", + "items": { + "$ref": "/schemas/v2/server-common/#zoweReverseDomainNotation" + }, + "uniqueItems": true + } + } + } + } + } + } + }, + "logLevels": { + "type": "object", + "patternProperties": { + "_zsf.bootstrap": { + "description": "Logging that pertains to the startup of the server.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.auth": { + "description": "Logging for network calls that must be checked for authentication and authorization purposes.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.static": { + "description": "Logging of the serving of static files (such as images) from an application's /web folder.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.child": { + "description": "Logging of child processes, if any.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.utils": { + "description": "Logging for miscellaneous utilities that the server relies upon.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.proxy": { + "description": "Logging for proxies that are set up in the server.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.install": { + "description": "Logging for the installation of plug-ins.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.apiml": { + "description": "Logging for communication with the api mediation layer.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.routing": { + "description": "Logging for dispatching network requests to plug-in dataservices.", + "$ref": "#/$defs/logLevel" + }, + "_zsf.network": { + "description": "Logging for the HTTPS server status (connection, ports, IP, and so on)", + "$ref": "#/$defs/logLevel" + }, + "^.*$": { + "$ref": "#/$defs/logLevel" + } + } + }, + "logLanguage": { + "type": "string", + "default": "en" + }, + "languages": { + "additionalProperties": false, + "properties": { + "java": { + "type": "object", + "additionalProperties": false, + "properties": { + "portRange": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "minItems": 2, + "maxItems": 2 + } + }, + "ports": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "/schemas/v2/server-common/#zoweTcpPort" }, + { "$ref": "/schemas/v2/server-common/#zoweReservedTcpPort" }, + ], + "uniqueItems": true + } + }, + "jar": { + "type": "object", + "properties": { + "runtimes": { + + }, + "runtimeMapping": { + + } + } + }, + "war" : { + "type": "object", + "required": [ "javaAppServer" ], + "additionalProperties": false, + "properties": { + "pluginGrouping": { + "type": "array", + "description": "A list of which java plugins should run in which java runtimes. If not present, all will run from one runtime", + "items": { + "type": "object", + "required": [ "plugins" ], + "additionalProperties": false, + "properties": { + "java": { + "type": "string" + }, + "plugins": { + "type": "array", + "items": { + "$ref": "/schemas/v2/server-common/#zoweReverseDomainNotation" + } + } + } + } + }, + "defaultGrouping": { + "type": "string", + "description": "Determines whether services should be grouped together in as few processes as possible or run as 1 process per service", + "enum": [ "microservice", "appserver" ] + }, + "javaAppServer": { + "type": "object", + "propeties": { + "type": { + "type": "string", + "enum": [ "tomcat" ] + }, + "path": { + "type": "string" + }, + "config": { + "type": "string", + "description": "The file path to the appserver config file" + }, + "https": { + "type": "object", + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/$defs/pathCertObject" + }, + "certificate": { + "$ref": "#/$defs/pathCertObject" + }, + "certificateChain": { + "$ref": "#/$defs/pathCertObject" + } + } + } + } + } + } + }, + "runtimes": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "required": [ "home" ], + "additionalProperties": false, + "properties": { + "home": { + "type": "string", + "description": "The path of the runtime's home directory" + } + } + } + } + } + } + } + } + }, + "instanceID": { + "type": "string", + "description": "The ID used in determining which set of RBAC resources to verify during authorization" + }, + "privilegedServerName": { + "type": "string", + "description": "The nickname of the ZIS server to be used" + } + }, + "$defs": { + "ipOrHostname": { + "type": "string" + }, + "ipsAndHostnames": { + "type": "array", + "items": { + "$ref": "#/$defs/ipOrHostname" + }, + "uniqueItems": true + }, + "nodejsDefaultCiphers": { + "const": "NODEJS", + "description": "Instructs app-server to use the default cipher list of nodejs when using TLS" + }, + "zoweDefaultCiphers": { + "const": "", + "description": "Instructs app-server to use its default cipher list when using TLS" + }, + "customCiphers": { + "type": "string", + "not": { + "anyOf": [ + { "$ref": "#/$defs/nodejsDefaultCiphers" }, + { "$ref": "#/$defs/zoweDefaultCiphers" } + ] + }, + "description": "Instructs app-server to use the list of ciphers in this string when using TLS. String must be in the form defined here https://nodejs.org/api/tls.html#modifying-the-default-tls-cipher-suite" + }, + "headerCustomization": { + "type": "object", + "additionalProperties": false, + "properties": { + "substitutions": { + "type": "object", + "patternProperties": { + "^.*$": { + "oneOf": [ + { "$ref": "#/$defs/headerSubstituteDomain" } + ] + } + } + } + } + }, + "headerSubstituteDomain": { + "const": "domain", + "description": "Substitute the variable referenced with the value of the domain seen on the request" + }, + "certObject": { + "type": "array", + "description": "The location of a file or keyring object", + "items": { + "anyOf": [ + { "$ref": "#/$defs/fileCertObject" }, + { "$ref": "#/$defs/pathCertObject" }, + { "$ref": "#/$defs/safKeyringCertObject" } + ] + }, + "uniqueItems": true + }, + "fileCertObject": { + "type": "string", + "pattern": "^file:\/\/.*$" + }, + "safKeyringCertObject": { + "type": "string", + "pattern": "^safkeyring:(\/\/)+.*$" + }, + "pathCertObject": { + "type": "string", + "not": { + "anyOf": [ + { "pattern": "^file:\/\/.*$" }, + { "pattern": "^safkeyring:(\/\/)+.*$" } + ] + } + }, + "cspPresetStrict": { + "const": "strict", + "description": "Applies builtin value 'default-src self req.hostname'" + }, + "cspPresetFrameStrict": { + "const": "frame-strict", + "description": "Applies builtin value 'frame-src self req.hostname'" + }, + "logLevel": { + "type": "integer", + "description": "Log level verbosity where 0 is least verbose (errors only), 5 is most verbose (trace) and 2 is default (info)", + "default": 2, + "minimum": 0, + "maximum": 5 + } + } +} diff --git a/schemas/plugindefinition-schema.json b/schemas/plugindefinition-schema.json new file mode 100644 index 00000000..6023cf17 --- /dev/null +++ b/schemas/plugindefinition-schema.json @@ -0,0 +1,517 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/appfw-plugin-definition", + "title": "Application Framework Plugin Definition", + "description": "Properties seen in a pluginDefinition.json file which describes a plugin of the Zowe Application Framework", + "type": "object", + "oneOf": [ + { "$ref": "#/$defs/bootstrapPlugin" }, + { "$ref": "#/$defs/desktopPlugin" }, + { "$ref": "#/$defs/libraryPlugin" }, + { "$ref": "#/$defs/applicationPlugin" }, + { "$ref": "#/$defs/nodeAuthenticationPlugin" } + ], + "$defs": { + "reverseDomainNotation": { + "type": "string", + "pattern": "^[A-Za-z]{2,6}((?!-)\\.[A-Za-z0-9-]{1,63}(?\\<]?)|(>=?)|(<=?))(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + }, + "appFwPlugin": { + "type": "object", + "required": ["identifier", "apiVersion", "pluginVersion", "pluginType"], + "propeties": { + "identifier": { + "$ref": "#/$defs/reverseDomainNotation", + "description": "Each plugin must have a zowe-wide unique ID in reverse domain name notation" + }, + "apiVersion": { + "$ref": "#/$defs/semverVersion", + "description": "Describes which version of this schema the plugin is compatible with" + }, + "pluginVersion": { + "$ref": "#/$defs/semverVersion", + "description": "Describes the plugin's version. The app-server only runs 1 version of each plugin." + }, + "pluginType": { + "type": "string", + "enum": [ "bootstrap", "desktop", "library", "application", "nodeAuthentication" ] + }, + "license": { + "type": "string", + "description": "An SPDX string describing which license the plugin is available under" + }, + "author": { + "type": "string", + "description": "States who the writers of the plugin are" + }, + "homepage": { + "type": "string", + "description": "A website URL of the writers of the plugin" + }, + "requirements": { + "type": "object", + "description": "Defining a list of requirements lets the app-server decide if your plugin should or should not be loaded according to if requirements are met in the environment.", + "additionalProperties": false, + "properties": { + "components": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "properties": { + "os": { + "type": "array", + "items": { + "type": "string", + "description": "An OS type as reported by nodejs os.platform()" + } + }, + "cpu": { + "type": "array", + "items": { + "type": "string", + "description": "A CPU architecture type as reported by nodejs os.arch()" + } + }, + "version": { + "type": "array", + "items": { + "$ref": "#/$defs/semverRange" + } + }, + "endpoints": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "dataServices": { + "type": "array", + "items": { + "anyOf": [ + { "$ref": "#/$defs/routerService" }, + { "$ref": "#/$defs/serviceService" }, + { "$ref": "#/$defs/importService" }, + { "$ref": "#/$defs/externalService" }, + { "$ref": "#/$defs/nodeService" } + ] + }, + "uniqueItems": true + }, + "configurationData": { + "type": "object", + "description": "TODO", + "properties": { + "resources": { + "type": "object" + } + } + } + } + }, + "libraryPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Library plugins are used for hosting static web content", + "deprecated": true, + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "library" + }, + "libraryName": { + "type": "string" + }, + "libraryVersion": { + "$ref": "#/$devs/semverVersion" + } + } + }, + "bootstrapPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Only one bootstrap plugin per server is intended, and its role is to bootstrap Desktop-type plugins for browser use", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "bootstrap" + }, + "webContent": { + "$ref": "#/$defs/genericWebContent" + } + } + }, + "desktopPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Desktop plugins are webcontent which embeds application-type plugins within a web browser, regardless of if resembles a 'desktop' or not.", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "desktop" + }, + "webContent": { + "$ref": "#/$defs/nativeWebContent" + } + } + }, + "applicationPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "Application plugins contain web content and/or network APIs which are compatible with embedding in a Desktop plugin web page, but may also be used by themselves", + "additionalProperties": false, + "properties": { + "pluginType": { + "const": "application" + }, + "webContent": { + "type": "object", + "oneOf": [ + { "$ref": "#/$defs/iframeWebContent" }, + { "$ref": "#/$defs/genericWebContent" }, + { "$ref": "#/$defs/nativeWebContent" } + ] + }, + "isSystemPlugin": { + "type": "boolean", + "default": false, + "description": "Set this to true to make a plugin that cannot be opened directly by users, but may be invoked by other apps and the application framework itself via app2app communication as needed." + } + } + }, + "nodeAuthenticationPlugin": { + "$ref": "#/$defs/appFwPlugin", + "description": "The app-server delegates to these plugins for user permission management tasks such as authentication and authorization", + "required": [ "filename" ], + "additionalProperties": false, + "properties": { + "filename": { + "type": "string", + "description": "The name of a nodejs file within the /lib directory of the plugin. This file contains a function that is provided with startup context and must contain methods according to its stated capabilities such as authentication and authorization" + }, + "authenticationCategories": { + "type": "array", + "items": { + "type": "string", + "description": "A short name describing what sort of authentication this plugin can provide, such as LDAP, SAF, etc. If the categories are not known until startup, this info can still be stated at runtime within the javascript code." + }, + "uniqueItems": true + } + } + }, + "genericWebContent": { + "type": "object", + "not": { + "anyOf": [ + { "$ref": "#/$defs/nativeWebContent" }, + { "$ref": "#/$defs/iframeWebContent" } + ] + }, + "description": "A webcontent object without the attributes of an application, such as framework, can be used to just serve a plugin's /web folder from the app-server" + }, + "nativeWebContent": { + "$ref": "#/$defs/appWebContent", + "description": "A Native application is one that provides a /web/main.js file which can be run within the Zowe Desktop when the user clicks its icon", + "additionalProperties": false, + "properties": { + "framework": { + "type": "string", + "enum": [ "angular2", "angular", "react" ] + } + } + }, + "iframeWebContent": { + "$ref": "#/$defs/appWebContent", + "description": "An iframe application is one that provides some html file either within the /web folder or found on another server at runtime, which can be embedded within the Zowe Desktop when the user clicks its icon", + "additionalProperties": false, + "properties": { + "framework": { + "const": "iframe" + }, + "oneOf": [ + "destination": { + "type": "string", + "description": "A URL with shell-style ${} subtitutions allowed which states which address the iframe should load." + }, + "startingPage": { + "type": "string", + "description": "A filename within the /web folder of the plugin, which the iframe should load." + } + ], + "standaloneUseFramework": { + "type": "boolean", + "default": false, + "description": "When true, iframe apps will be launched within the desktop framework so that features like notifications and app2app communication will function identically to the Desktop. When false, opening the iframe app in a standalone page will have it function like an independent website." + } + } + }, + "appWebContent": { + "type": "object", + "description": "A description of an application which can be run within the Zowe Desktop", + "required": [ "framework", "launchDefinition", "descriptionKey", "descriptionDefault", "defaultWindowStyle" ], + "additionalProperties": false, + "properties": { + "framework": { + "type": "string", + "enum": [ "angular2", "angular", "react", "iframe" ] + }, + "launchDefinition": { + "type": "object", + "required": [ "pluginShortNameKey", "pluginShortNameDefault", "imageSrc" ], + "properties": { + "pluginShortNameKey": { + "type": "string", + "description": "The internationalization key used to display the application's name in the user's chosen language." + }, + "pluginShortNameDefault": { + "type": "string", + "description": "The name of the application in the default language. Used as a fallback if the user's chosen language has no translation." + }, + "imageSrc": { + "type": "string", + "description": "A path relative to and within the 'web' folder of the plugin. This image is used as the application's icon" + } + } + }, + "descriptionKey": { + "type": "string", + "description": "The internationalization key used to display the application's description in the user's chosen language." + }, + "descriptionDefault": { + "type": "string", + "description": "The description of the application in the default language. Used as a fallback if the user's chosen language has no translation." + }, + "isSingleWindowApp": { + "type": "boolean", + "deprecated": true + }, + "defaultWindowStyle": { + "type": "object", + "description": "Properties that describe the default visuals of the application window, such as size", + "required": [ "width", "height" ], + "properties": { + "width": { + "type": "integer", + "minimum": 180, + "description": "The width of the Zowe Desktop window of the application when first opened" + }, + "height": { + "type": "integer", + "minimum": 100, + "description": "The height of the Zowe Desktop window of the application when first opened" + } + } + } + } + }, + "service": { + "type": "object", + "description": "A part of a plugin which adds a network API to a server such as a REST or websocket API", + "required": ["type", "version", "name"], + "properties": { + "type": { + "type": "string", + "enum": [ "router", "service", "external", "nodeService", "java" ] + }, + "version": { + "$ref": "#/$defs/semverVersion" + }, + "name": { + "type": "string" + } + } + }, + "externalService": { + "$ref": "#/$defs/service", + "description": "A proxy service which is hosted from the app-server", + "additionalProperties": false, + "properties": { + "type": { + "const": "external" + }, + "urlPrefix": { + "type": "string" + }, + "isHttps": { + "type": "boolean", + "deprecated": true, + "description": "Specifies if the proxy is to an HTTP or HTTPS server. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object" + }, + "host": { + "type": "string", + "deprecated": true, + "description": "Specifies which hostname or IP is being proxied. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object", + "format": "hostname" + }, + "port": { + "type": "integer", + "deprecated": true, + "description": "Specifies which port is being proxied. It is recommended to use a remote.json file within the workspace instead, as pluginDefinition is a read only object" + } + } + }, + "routerService": { + "$ref": "#/$defs/service", + "description": "An ExpressJS router service hosted from the app-server", + "required": ["type", "version", "name", "fileName", "routerFactory"], + "additionalProperties": false, + "properties": { + "type": { + "const": "router" + }, + "initializerLookupMethod": { + "type": "string", + "enum": ["external"], + "deprecated": true + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "fileName": { + "type": "string", + "description": "A javascript file located within the plugin's 'lib' folder which contains the router factory. The router is for a REST or Websocket API that the app-server will include." + }, + "routerFactory": { + "type": "string", + "description": "The name of a javascript function found in the file specified in 'fileName' which is given plugin context and must return an expressjs router" + }, + "httpCaching": { + "type": "boolean", + "default": false, + "description": "When false, the app-server will add headers to the service response to tell clients not to cache the response" + }, + "internalOnly": { + "type": "boolean", + "default": false, + "description": "When true, the service can only be reached by other services within the same server via the call() function" + } + } + }, + "nodeService": { + "$ref": "#/$defs/service", + "description": "A nodejs callback service that acts upon expressjs request and response objects. It runs within the app-server", + "required": ["type", "version", "name", "fileName", "methods", "handlerInstaller"], + "deprecated": true, + "additionalProperties": false, + "properties": { + "type": { + "const": "nodeService" + }, + "initializerLookupMethod": { + "type": "string", + "enum": [ "external" ] + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "fileName": { + "type": "string", + "description": "A javascript file located within the plugin's 'lib' folder which contains the handler factory. The handler is for a REST or Websocket API that the app-server will include." + }, + "handlerInstaller": { + "type": "string", + "description": "The name of a javascript function found in the file specified in 'fileName' which is given plugin context and must return a callback function" + }, + "methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ "GET", "PUT", "POST", "DELETE", "OPTIONS", "HEAD" ], + "description": "A list of HTTP methods this service will respond to" + }, + "uniqueItems": true + } + } + }, + "serviceService": { + "$ref": "#/$defs/service", + "description": "A service that runs within ZSS. It uses a callback written in C that recieves a request and response struct", + "required": ["type", "version", "name", "methods", "initializerName"], + "additionalProperties": false, + "properties": { + "type": { + "const": "service" + }, + "initializerLookupMethod": { + "type": "string", + "description": "States whether the service is to be found as a plugin or is built-in to ZSS already", + "enum": ["external", "internal"], + "deprecated": false + }, + "dependenciesIncluded": { + "type": "boolean", + "default": true, + "deprecated": true + }, + "libraryName": { + "type": "string", + "description": "The path of a 31-bit or 64-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "libraryName31": { + "type": "string", + "description": "The path of a 31-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "libraryName64": { + "type": "string", + "description": "The path of a 64-bit DLL file relative to and within the plugin's 'lib' folder. It contains a REST or Websocket API that the agent will include." + }, + "methods": { + "type": "array", + "items": { + "type": "string", + "enum": [ "GET", "PUT", "POST", "DELETE" ], + "description": "A list of HTTP methods this service will respond to" + }, + "uniqueItems": true + }, + "initializerName": { + "type": "string", + "description": "The function name that will be called with plugin context to add the service routes to the agent" + } + } + }, + "importService": { + "type": "object", + "description": "A service which points to another service. The app-server will setup a URL which calls the source when accessed", + "required": [ "type", "sourceName", "localName", "sourcePlugin", "versionRange" ], + "additionalProperties": false, + "properties": { + "type": { + "const": "import" + }, + "sourceName": { + "type": "string", + "description": "The name of the service being imported" + }, + "localName": { + "type": "string", + "description": "The name of this service within this plugin" + }, + "sourcePlugin": { + "$ref": "#/$defs/reverseDomainNotation", + "description": "The ID of the plugin where the service is being imported from" + }, + "versionRange": { + "$ref": "#/$defs/semverRange", + "description": "A semver range that describes which version of the service to import" + } + } + } + } +} diff --git a/schemas/zowe-schema.json b/schemas/zowe-schema.json new file mode 100644 index 00000000..091495fd --- /dev/null +++ b/schemas/zowe-schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://zowe.org/schemas/v2/app-server", + "allOf": [ + { "$ref": "/schemas/v2/server-base" }, + { "type": "object", + "properties": { + "components": { + "type": "object", + "properties": { + "additionalProperties": true, + "app-server": { + "allOf": [ + { "$ref": "/schemas/v2/server-base#zoweComponent" }, + { "$ref": "/schemas/v2/app-server-config"} + ] + } + } + } + } + } + ] +} From 25e6ecd0ee79fee4702346376de5987456fa9720 Mon Sep 17 00:00:00 2001 From: James Struga Date: Mon, 11 Apr 2022 17:44:16 -0400 Subject: [PATCH 6/7] Update build-core.yml --- .github/workflows/build-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-core.yml b/.github/workflows/build-core.yml index d9addb79..27f96216 100644 --- a/.github/workflows/build-core.yml +++ b/.github/workflows/build-core.yml @@ -64,7 +64,7 @@ jobs: - name: '[Prep 2] Setup Node' uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 16 - name: '[Prep 3] Setup jFrog CLI' uses: jfrog/setup-jfrog-cli@v2 From 0185f81ddfed46ef4d182ad874f36fa83f81b6bf Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Tue, 12 Apr 2022 15:03:56 -0400 Subject: [PATCH 7/7] Remove sections of code being migrated into zowe-install-packaging Signed-off-by: 1000TurquoisePogs --- bin/init/plugins-init.sh | 3 -- bin/utils/plugin-utils.sh | 60 --------------------------------------- 2 files changed, 63 deletions(-) diff --git a/bin/init/plugins-init.sh b/bin/init/plugins-init.sh index f4e89cc0..902fb800 100644 --- a/bin/init/plugins-init.sh +++ b/bin/init/plugins-init.sh @@ -38,9 +38,6 @@ for installed_component in $(echo "${ZWE_INSTALLED_COMPONENTS}" | sed "s/,/ /g") # NOTE: relativeTo does not need to be handled here because this process occurs every start so the results should be "portable" by update on restart INSTALL_NO_NODE=$1 ../install-app.sh "$fullpath" "${plugins_dir}" - if [ -n $2 ]; then - check_zss_pc_bit "$fullpath" - fi else echo "Deregistering plugin ${fullpath}" ../uninstall-app.sh "$fullpath" "${plugins_dir}" diff --git a/bin/utils/plugin-utils.sh b/bin/utils/plugin-utils.sh index ee721b15..e97bb691 100644 --- a/bin/utils/plugin-utils.sh +++ b/bin/utils/plugin-utils.sh @@ -42,63 +42,3 @@ hasApp2App() { fi } -check_zss_pc_bit() { - appfw_plugin_path=${1} - - services=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices" 2>/dev/null) - if [ -n "${services}" ]; then - echo "Checking ZSS services in plugin path=${1}" - service_iterator_index=0 - service_type=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices[${service_iterator_index}].type" 2>/dev/null) - while [ -n "${service_type}" ]; do - if [ "${service_type}" = "service" ]; then - libraryName31=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices[${service_iterator_index}].libraryName31" 2>/dev/null) - libraryName64=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices[${service_iterator_index}].libraryName64" 2>/dev/null) - libraryName=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices[${service_iterator_index}].libraryName" 2>/dev/null) - if [ -n "${libraryName31}" ]; then - test_or_set_pc_bit "${appfw_plugin_path}/lib/${libraryName31}" - if [ "$?" = "1" ]; then - break - fi - fi - if [ -n "${libraryName64}" ]; then - test_or_set_pc_bit "${appfw_plugin_path}/lib/${libraryName64}" - if [ "$?" = "1" ]; then - break - fi - fi - if [ -n "${libraryName}" ]; then - test_or_set_pc_bit "${appfw_plugin_path}/lib/${libraryName}" - if [ "$?" = "1" ]; then - break - fi - fi - fi - service_iterator_index=`expr $service_iterator_index + 1` - service_type=$(read_json "${appfw_plugin_path}/pluginDefinition.json" ".dataServices[${service_iterator_index}].type 2>/dev/null") - done - fi -} - - - -test_or_set_pc_bit() { - path="${1}" - - testpc=`extattr $path | sed -n '3 p'` - if [ "$testpc" = "Program controlled = YES" ]; then - # normal - return 0 - else - echo "Plugin ZSS API not program controlled. Attempting to add PC bit." - extattr +p $path - testpc2=$(extattr $path | sed -n '3 p') - if [ "$testpc2" = "Program controlled = YES" ]; then - echo "PC bit set successfully." - return 0 - else - echo "PC bit not set. This must be set such as by executing 'extattr +p $COMPONENT_HOME/lib/sys.so' as a user with sufficient privilege." - return 1 - fi - fi -}