zowe / zowe-cli

Zowe CLI
Eclipse Public License 2.0
114 stars 86 forks source link

VSCode Explorer using mergeArgsForProfile - returns incorrect result when used in conjunction with a zowe.config.user.json file #2316

Open davidkjackson54 opened 5 days ago

davidkjackson54 commented 5 days ago

I have a VSCode Explorer that needs to create a session. my zowe.config.json contains this

{
    "$schema": "./zowe.schema.json",
    "profiles": {
        "base": {
            "type": "base",
            "properties": {
                "host": "myHost.com",
                "rejectUnauthorized": true
            },
            "secure": [
                "user",
                "password"
            ]
        },
        "zmf_a": {
            "type": "zmf",
            "properties": {
                "protocol": "http",
                "host": "myHost.com",
                "port": 8280,
                "basePath": "/zmfa",
                "rejectUnauthorized": false
            },
            "secure": [
                "user",
                "password"
            ]
        }
    },
    "defaults": {
        "zmf": "zmf_a",
        "base": "base"
    },
    "autoStore": true
}

I have user and password both saved in the Credentials vault: D:\saved source\vault>node vault.js

{
  'C:\\Users\\david\\.zowe\\zowe.config.json': {
    'profiles.base.properties.user': 'MYUSER',
    'profiles.base.properties.password': 'myPass',
    'profiles.zmf_a.properties.user': 'MYUSER',
    'profiles.zmf_a.properties.password': 'myPass'
  }
}

I initially do this:

const requireKeytar = () => require("@zowe/secrets-for-zowe-sdk").keyring;
    this.profInfo = new ProfileInfo("zowe", {
      credMgrOverride: ProfileCredentials.defaultCredMgrWithKeytar(requireKeytar),
    });

Then I retriever my profiles

this.zmfProfNames = this.profInfo.getAllProfiles("zmf"); // retrieve ZMF from all profile location sources
 this.baseProfNames = this.profInfo.getAllProfiles("base");

Then for each profile in the array, I call mergeArgsForProfile

const profileArgs: IZmfParms[] = [];
    for (const [index, element] of profileNames.entries()) {
     profileArgs[index] = {
        // array of all profile parms
        mergedArgs: this.profInfo.mergeArgsForProfile(element, { getSecureVals: true }), 
        name: element.profName, // save profile name
        type: element.profType, // save profile type - just in case
        jsonLoc: element.profLoc.jsonLoc, // save the json file location - just in case
      };
   }

When I inspect profileArgs, it correctly shows knownArgs and no missingArgs

0 ={mergedArgs: {…}, name: 'zmf_a', type: 'zmf', jsonLoc: 'profiles.zmf_a'}
jsonLoc ='profiles.zmf_a'
mergedArgs ={knownArgs: Array(7), missingArgs: Array(0)}
knownArgs =
0 ={argName: 'protocol', dataType: 'string', argValue: 'http', argLoc: {…}, secure: false, …}
1 ={argName: 'host', dataType: 'string', argValue: 'myHost.com', argLoc: {…}, secure: false, …}
2 ={argName: 'port', dataType: 'number', argValue: 8280, argLoc: {…}, secure: false, …}
3 ={argName: 'basePath', dataType: 'string', argValue: '/zmfrestn', argLoc: {…}, secure: false, …}
4 ={argName: 'rejectUnauthorized', dataType: 'boolean', argValue: false, argLoc: {…}, secure: false, …}
5 ={argName: 'user', dataType: 'string', argLoc: {…}, secure: true, inSchema: true, …}
6 ={argName: 'password', dataType: 'string', argLoc: {…}, secure: true, inSchema: true, …}
length =7

missingArgs =(0) []

If I now add an empty zowe.config.user.json file:

{
    "$schema": "./zowe.schema.json",
     "profiles": {},   
     "defaults": {},
    "autoStore": true
} 

and test again, I am now seeing profileArgs report user and password as missingArgs.

0 ={mergedArgs: {…}, name: 'zmf_a', type: 'zmf', jsonLoc: 'profiles.zmf_a'}
jsonLoc ='profiles.zmf_a'
mergedArgs ={knownArgs: Array(5), missingArgs: Array(2)}
knownArgs =(5) [{…}, {…}, {…}, {…}, {…}]
missingArgs =(2) 
0 ={argName: 'user', dataType: 'string', argValue: undefined, argLoc: {…}, inSchema: true, …}
1 ={argName: 'password', dataType: 'string', argValue: undefined, argLoc: {…}, inSchema: true, …}
length =2

Either I am misunderstanding how the zowe.config.user.json is used or this is a bug. as both user and password are present in the vault.

As a further test, I then copied the zowe.config.,json into the zowe.config.user.json - so they are now identical and then reran the test again. Once again, it reports both user and password in missingArgs.

I then changed the defaults in the zowe.config.user.json file to now be:

"defaults": {},
 "autoStore": true

and reran the test again. This time, I am seeing no missingArgs but the knownArgs are incorrect and show this:

0 ={mergedArgs: {…}, name: 'zmf_a', type: 'zmf', jsonLoc: 'profiles.zmf_a'}
jsonLoc ='profiles.zmf_a'
mergedArgs ={knownArgs: Array(7), missingArgs: Array(0)}
knownArgs =(7)
0 ={argName: 'protocol', dataType: 'string', argValue: 'http', argLoc: {…}, secure: false, …}
1 ={argName: 'host', dataType: 'string', argValue: 'myHost.com', argLoc: {…}, secure: false, …}
2 ={argName: 'port', dataType: 'number', argValue: 8280, argLoc: {…}, secure: false, …}
3 ={argName: 'basePath', dataType: 'string', argValue: '/zmfrestn', argLoc: {…}, secure: false, …}
4 ={argName: 'rejectUnauthorized', dataType: 'boolean', argValue: false, argLoc: {…}, secure: false, …}
5 ={argName: 'user', dataType: 'string', argLoc: {…}, secure: true, inSchema: true, …}
  argLoc ={locType: 1, osLoc: Array(1), jsonLoc: 'profiles.zmf_a.properties.user'}
  argName ='user'
  argValue =undefined
  dataType ='string'
  inSchema =true
  secure =true
6 ={argName: 'password', dataType: 'string', argLoc: {…}, secure: true, inSchema: true, …}
  argLoc ={locType: 1, osLoc: Array(1), jsonLoc: 'profiles.zmf_a.properties.password'}
  argName ='password'
  argValue =undefined
  dataType ='string'
  inSchema =true
  secure =true

Notice that now user and password are considered to be knownArgs but the argValues are undefined.

Something isn't quite right here.

github-actions[bot] commented 5 days ago

Thank you for creating a bug report. We will investigate the bug and evaluate its impact on the product. If you haven't already, please ensure you have provided steps to reproduce the bug and as much context as possible.

t1m0thyj commented 3 days ago

@davidkjackson54 I assume your zowe.config.json and zowe.config.user.json file both located in your Zowe home directory (C:\Users\david\.zowe). Is this assumption correct? Also can you confirm that you don't have any zowe.config.json files in a project directory?

I've tried to reproduce both issues with exactly the same config, except I used profile type zosmf instead of zmf because I don't have the zmf profile defined in my schema JSON file. I see the second issue (no missingArgs but the knownArgs are incorrect), however I'm unable to reproduce the first one (profileArgs report user and password as missingArgs) because user and password still show as knownArgs for me.

davidkjackson54 commented 3 days ago

Hi TImothy, I can confirm that the 2 config files reside in my /.zowe folder within my user folder and that no other copies of the config files exist anywhere else.

I ran through the test again making sure that only the user and password defined in profile in the zowe.config.json have their secure Args stored in the vault. D:\saved source\vault>node vault.js

{
  'C:\\Users\\david\\.zowe\\zowe.config.json': {
    'profiles.base.properties.user': 'DJ',
    'profiles.base.properties.password': 'djpw',
    'profiles.zmf_a.properties.user': 'DJ2',
    'profiles.zmf_a.properties.password': 'djpw2'
  }
}

After mergeArgsForProfile with the empty zowe.config.user.,json file present, I see this: Here is element expanded:

profLoc = {locType: 1, osLoc: Array(1), jsonLoc: 'profiles.zmf_a'}
jsonLoc ='profiles.zmf_a'
locType =1
osLoc =(1) ['C:\\Users\\david\\.zowe\\zowe.config.json']
0 ='C:\\Users\\david\\.zowe\\zowe.config.json'
length =1
profName ='zmf_a'
profType ='zmf'

Then I expand profArgs after the call to mergeArgsForProfile

0 = {mergedArgs: {…}, name: 'zmf_a', type: 'zmf', jsonLoc: 'profiles.zmf_a'}
jsonLoc = 'profiles.zmf_a'
mergedArgs = {knownArgs: Array(5), missingArgs: Array(2)}
knownArgs =(5) [{…}, {…}, {…}, {…}, {…}]
0 ={argName: 'protocol', dataType: 'string', argValue: 'http', argLoc: {…}, secure: false, …}
1 ={argName: 'host', dataType: 'string', argValue: 'myHost.com', argLoc: {…}, secure: false, …}
2 ={argName: 'port', dataType: 'number', argValue: 8280, argLoc: {…}, secure: false, …}
3 ={argName: 'basePath', dataType: 'string', argValue: '/zmfa', argLoc: {…}, secure: false, …}
4 ={argName: 'rejectUnauthorized', dataType: 'boolean', argValue: false, argLoc: {…}, secure: false, …}

missingArgs =(2) [{…}, {…}]
0 ={argName: 'user', dataType: 'string', argValue: undefined, argLoc: {…}, inSchema: true, …}
argLoc = {locType: 1, osLoc: Array(1), jsonLoc: 'profiles.zmf_a.properties.user'}
jsonLoc = 'profiles.zmf_a.properties.user'
locType =1
osLoc =(1) ['C:\\Users\\david\\.zowe\\zowe.config.json']
argName = 'user'
argValue =undefined
dataType ='string'
inSchema =true
secure =true
1 ={argName: 'password', dataType: 'string', argValue: undefined, argLoc: {…}, inSchema: true, …}
argLoc = {locType: 1, osLoc: Array(1), jsonLoc: 'profiles.zmf_a.properties.password'}

jsonLoc ='profiles.zmf_a.properties.password'
locType =1
osLoc =(1) ['C:\\Users\\david\\.zowe\\zowe.config.json']
argName = 'password'
argValue = undefined
dataType ='string'
inSchema =true
secure =true

name ='zmf_a'
type ='zmf'

This does not occur if the empty user config is not present.

Are there any additional diagnostics that might help here?

davidkjackson54 commented 1 day ago

I have sent you via slack a slimmed down sample program that helps highlight the missingArg issue