un-cli 0.0.60 → 0.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adminlog.mjs +2 -2
- package/cmd.txt +1 -3
- package/index.mjs +43 -11
- package/package.json +1 -1
- package/portal.mjs +49 -28
package/adminlog.mjs
CHANGED
|
@@ -13,10 +13,10 @@ export class AdminLog {
|
|
|
13
13
|
this.token = token;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
query (codes, serviceName ="*", pageSize = 100000, startTime = null, endTime = null)
|
|
16
|
+
query (codes, serviceName ="*", pageSize = 100000, startTime = null, endTime = null, logLevel = "DEBUG")
|
|
17
17
|
{
|
|
18
18
|
const url = this.adminServerUrl + "/logs/query?f=pjson"
|
|
19
|
-
const level =
|
|
19
|
+
const level = logLevel
|
|
20
20
|
const filterType="json"
|
|
21
21
|
const token = this.token
|
|
22
22
|
const filter = {
|
package/cmd.txt
CHANGED
package/index.mjs
CHANGED
|
@@ -6,15 +6,11 @@ import { AdminLog } from "./adminlog.mjs"
|
|
|
6
6
|
|
|
7
7
|
import { logger } from "./logger.mjs"
|
|
8
8
|
import fetch from "node-fetch"
|
|
9
|
-
import { DH_NOT_SUITABLE_GENERATOR } from "constants";
|
|
10
9
|
//update version
|
|
11
|
-
let version = "0.0.
|
|
10
|
+
let version = "0.0.63";
|
|
12
11
|
const GENERATE_TOKEN_TIME_MIN = 30;
|
|
13
12
|
|
|
14
13
|
let rl = null;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
//uncli --portal https://utilitynetwork.esri.com/portal --service AllStar_oracle --user unadmin --password unadmin.108
|
|
18
14
|
let portal = null;
|
|
19
15
|
let un = null;
|
|
20
16
|
let adminLog = null;
|
|
@@ -30,9 +26,11 @@ function parseInput(){
|
|
|
30
26
|
"--command",
|
|
31
27
|
"--gdbversion",
|
|
32
28
|
"--file",
|
|
33
|
-
"--verify"
|
|
29
|
+
"--verify",
|
|
30
|
+
"--server"
|
|
34
31
|
]
|
|
35
|
-
|
|
32
|
+
|
|
33
|
+
//null marked parmaters are required
|
|
36
34
|
const params = {
|
|
37
35
|
"portal": null,
|
|
38
36
|
"service": null,
|
|
@@ -41,7 +39,8 @@ function parseInput(){
|
|
|
41
39
|
"command": "",
|
|
42
40
|
"gdbversion": "SDE.DEFAULT",
|
|
43
41
|
"file": "",
|
|
44
|
-
"verify": "true"
|
|
42
|
+
"verify": "true",
|
|
43
|
+
"server": undefined
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
for (let i = 0; i < process.argv.length ; i++){
|
|
@@ -54,9 +53,10 @@ function parseInput(){
|
|
|
54
53
|
|
|
55
54
|
if (Object.values(params).includes(null))
|
|
56
55
|
{
|
|
57
|
-
console.log ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password [--gdbversion* user.version --file commandfile* --verify true|false]")
|
|
56
|
+
console.log ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password [--gdbversion* user.version --server https://federatedserver.domain.com/server --file commandfile* --verify true|false]")
|
|
58
57
|
console.log("--file commandfile is optional and you can pass a path to a file with a list of command to execute. ")
|
|
59
58
|
console.log("--gdbversion is optional and allows the UN to be opened in that version. When not specified sde.DEFAULT is used.")
|
|
59
|
+
console.log("--server is optional except when there are more than one federated server sites to the portal. If the portal only has one server it will be selected.")
|
|
60
60
|
process.exit();
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -65,7 +65,7 @@ function parseInput(){
|
|
|
65
65
|
|
|
66
66
|
//
|
|
67
67
|
async function getToken(parameters) {
|
|
68
|
-
portal = new Portal(parameters.portal, parameters.user, parameters.password)
|
|
68
|
+
portal = new Portal(parameters.portal, parameters.user, parameters.password,300, parameters.server)
|
|
69
69
|
logger.info("About to connect..")
|
|
70
70
|
const token = await portal.connect()
|
|
71
71
|
logger.info(`Token generanted successfully.`)
|
|
@@ -178,6 +178,7 @@ const inputs = {
|
|
|
178
178
|
"count": "Lists the number of rows in all feature layers.",
|
|
179
179
|
"count --system": "Lists the number of rows in system layers.",
|
|
180
180
|
"connect --service": "Connects to the another service",
|
|
181
|
+
"tracelogs --m <minutes>": "Lists utility network trace summary logs for the last x minutes (requires admin)",
|
|
181
182
|
"arlogs": "Lists attribute rules execution logs (requires admin)",
|
|
182
183
|
"arlogs --byrule [--minguid --maxguid]": "Lists attribute rules execution summary by rule (requires admin), --maxguid and --minguid show the GUID of the feature",
|
|
183
184
|
"whoami": "Lists the current login info",
|
|
@@ -714,6 +715,37 @@ const inputs = {
|
|
|
714
715
|
},
|
|
715
716
|
|
|
716
717
|
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
"^tracelogs --m": async input => {
|
|
721
|
+
const topLogCount = 1000;
|
|
722
|
+
const pageSize = 10000
|
|
723
|
+
|
|
724
|
+
const inputParam = input.match(/--m .*/gm)
|
|
725
|
+
let mins = 30; //query logs for the last 30 minutes
|
|
726
|
+
if (inputParam != null && inputParam.length > 0)
|
|
727
|
+
mins = inputParam[0].replace("--m ", "")
|
|
728
|
+
|
|
729
|
+
console.log(`Querying trace logs for ${parameters.service} for the last ${mins} minutes ...`)
|
|
730
|
+
const startTime = Date.now() - mins*60*1000
|
|
731
|
+
const endTime = Date.now();
|
|
732
|
+
let result= await adminLog.query([102002], [parameters.service+ ".MapServer"], topLogCount, startTime ,endTime , "VERBOSE")
|
|
733
|
+
let jsonRes = await result.json()
|
|
734
|
+
let allMessages = [].concat(jsonRes.logMessages)
|
|
735
|
+
allMessages = allMessages.filter(m => m.message.indexOf(" Environment -") > -1)
|
|
736
|
+
while (jsonRes.hasMore)
|
|
737
|
+
{
|
|
738
|
+
//start paging
|
|
739
|
+
logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
|
|
740
|
+
result= await adminLog.query([102002], [parameters.service + ".MapServer"], pageSize, jsonRes.endTime)
|
|
741
|
+
jsonRes = await result.json()
|
|
742
|
+
|
|
743
|
+
allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf(" Environment -") > -1))
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
allMessages.forEach(m => console.log(m.message))
|
|
747
|
+
|
|
748
|
+
},
|
|
717
749
|
"^arlogs --byrule": async input => {
|
|
718
750
|
//--minguid to show min guid
|
|
719
751
|
//--maxguid to show max guid
|
|
@@ -812,7 +844,7 @@ const inputs = {
|
|
|
812
844
|
"^version$": () => console.log(version),
|
|
813
845
|
"^clear$|^cls$": () => console.clear(),
|
|
814
846
|
"^quit$": () => {
|
|
815
|
-
rl.close();
|
|
847
|
+
if (rl) rl.close();
|
|
816
848
|
process.exit();
|
|
817
849
|
},
|
|
818
850
|
"^exit$|^quit$|^bye$": () => {
|
package/package.json
CHANGED
package/portal.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import { logger } from "./logger.mjs"
|
|
|
3
3
|
|
|
4
4
|
export class Portal{
|
|
5
5
|
|
|
6
|
-
constructor(url, username, password, expiration = 300)
|
|
6
|
+
constructor(url, username, password, expiration = 300, serverUrl = undefined)
|
|
7
7
|
{
|
|
8
8
|
this.url = url;
|
|
9
9
|
this.username = username;
|
|
10
10
|
this.password = password;
|
|
11
11
|
this.expiration = expiration;
|
|
12
|
-
this.serverUrl =
|
|
12
|
+
this.serverUrl = serverUrl;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
|
|
@@ -20,7 +20,6 @@ export class Portal{
|
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
22
|
|
|
23
|
-
//https://utilitynetwork.esri.com/portal/sharing/rest/portals/self/servers?f=json
|
|
24
23
|
const tokenUrl = self.url + "/sharing/rest/generateToken";
|
|
25
24
|
|
|
26
25
|
const postJson = {
|
|
@@ -44,9 +43,9 @@ export class Portal{
|
|
|
44
43
|
|
|
45
44
|
}
|
|
46
45
|
catch(ex){
|
|
47
|
-
logger.error(ex
|
|
48
|
-
console.error(ex
|
|
49
|
-
reject(`Failed to connect to portal, check your username or password or add --verify false if you are using a self-signed certificate. Normally a production system should have a valid certificate signed by a CA and you should NOT disable verification in that case.)`)
|
|
46
|
+
logger.error(ex?.status?.message)
|
|
47
|
+
console.error(ex?.status?.errno)
|
|
48
|
+
reject(`Failed to connect to portal, check your username or password or add --verify false if you are using a self-signed certificate. Normally a production system should have a valid certificate signed by a CA and you should NOT disable verification in that case.) \n\n${ex}`)
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
}
|
|
@@ -55,32 +54,54 @@ export class Portal{
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
async updateServices () {
|
|
57
|
+
const self = this;
|
|
58
|
+
return new Promise( async (resolve, reject) => {
|
|
59
|
+
//if the user specified a serverUrl no need to do anything
|
|
60
|
+
if (self.serverUrl !== undefined) {
|
|
61
|
+
logger.info(`Using server ${self.serverUrl} supplied in the --server parameter`)
|
|
62
|
+
resolve(self.serverUrl);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
//else we need to calculate it
|
|
67
|
+
try {
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
const postJsonServers= {
|
|
70
|
+
f: "json",
|
|
71
|
+
token: self.token
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const serversUrl = self.url + "/sharing/rest/portals/self/servers"
|
|
75
|
+
logger.info( "About to query federated servers");
|
|
76
|
+
|
|
77
|
+
//query for federated servers.
|
|
78
|
+
const servers = await makeRequest({method: 'POST', url: serversUrl, params: postJsonServers });
|
|
79
|
+
|
|
80
|
+
//if we don't have any federated servers quit.
|
|
81
|
+
if (servers.servers.length === 0)
|
|
82
|
+
{
|
|
83
|
+
reject( "No federeated servers");
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//if we have more than one then we let the user pick.
|
|
88
|
+
if (servers.servers.length > 1){
|
|
89
|
+
let serverUrls = "";
|
|
90
|
+
servers.servers.forEach(s => serverUrls += '\n * ' + s.url + '\n' )
|
|
91
|
+
reject("more than one federated server found, run the command with --server and specify one of the servers below\n" + serverUrls)
|
|
92
|
+
}
|
|
93
|
+
this.serverUrl = servers.servers[0].url;
|
|
94
|
+
resolve(self.serverUrl)
|
|
95
|
+
logger.info(`Found one federate server, using server url ${self.serverUrl} by default`)
|
|
64
96
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//get the first one
|
|
73
|
-
if (servers.servers.length === 0)
|
|
74
|
-
reject( "No federeated servers");
|
|
75
|
-
|
|
76
|
-
this.serverUrl = servers.servers[0].url;
|
|
77
|
-
logger.info(`Found server url ${this.serverUrl}`)
|
|
78
|
-
}
|
|
79
|
-
catch(ex){
|
|
80
|
-
logger.error(ex)
|
|
81
|
-
}
|
|
97
|
+
catch(ex){
|
|
98
|
+
logger.error(ex)
|
|
99
|
+
reject(ex)
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
}
|
|
82
104
|
|
|
83
|
-
}
|
|
84
105
|
//get the feature service definition
|
|
85
106
|
async serviceDef(serviceName) {
|
|
86
107
|
this.token = this.token;
|