-
Notifications
You must be signed in to change notification settings - Fork 27
Design Proposal for Zowe Profile Information API #556
Comments
This is a long post. What is the preferred way to provide feedback so that it can stay organised and not get lost in the sheer volume of text? Should I add comments here, open new issues and link here or do something else? |
This design document was created as a Git Issue instead of a Google Doc to enable squad members who do not work at Broadcom to be able to access the design document. Even though there is a lot of text, I suggest that we add comments to this issue, so that all ideas can be found in one place. |
I would like to ask for a bit more rationale behind this because it is a breaking change for existing and future functionality of our VSCode extensions. Existing functionality
In development functionality
Going forward
Environment variables Unlike in a CLI our VSCode extensions do not use nor have the desire to use environment variables for profile properties. Because of that I do not see
as an issue. |
I agree with @VitGottwald. I also had discussion with @dkelosky on this topic. The "read" API is complex in the sense that it is going to merge and combine the config and provide the callers a comprehensive/merged config file. The same thing need not be true for write or update. It is fair to have more granular write API(s) to handle the various cases. |
I have some questions for VSCode extension implementers. Your responses can affect how we implement some items.
|
no. not really. we are importing it and use the SDK functions.
No. as far as I know, we are importing Logger from imperative and this writes a log in .vscode > Zowe Explorer > logs
I don't think we are using any Zowe environment variables
We use this to search for the schema
I'm not sure.
It would be great to share that 'profile data stored in memory'. Currently we are storing it ourselves and this is probably the same for other extensions. So if we can access the memory from CLI then that would be easier for all of us |
Thanks @jellypuno. The key point here is, we need to take into consideration all the other extensions in play here as well - and not just Zowe Explorer. |
I've started implementation for I intend to modify the interface to make If there is any feedback or considerations on this proposed change, it would be greatly appreciated. |
@awharn We are hoping that we could use
So based on my understanding on your modifications, |
If this change is made, |
@awharn ok. that makes sense. I could imagine a scenario where I have a global config where the system's host and port are located. Then I have a user config that contains my credentials. One issue that I'm thinking is that I shouldn't be able to edit my global config but that is another story. |
@jellypuno Regarding logging: Our current implementation accepts an "appName" on its constructor. We use the appName to:
This seems quite different from (what I assume is a VS Code convention of) .vscode > Zowe Explorer > logs. Would it be preferable to allow the consuming app to pass an Imperative Logger object as another, optional argument on our constructor? If supplied, we would just use that logger object instead of creating one with the characteristics that I described above. |
In Endevor Explorer and Bridge For Git explorer we only import CliProfileManager from imperative and use it to read and write profiles. We have a boundary module that encapsulates all we need from profiles, merges base and service profile data and performs data validation to return properly typed values. I put it here so that you can look at it. |
As far as logging goes, I think it would be more natural to use VSCode output channel like we do for the Endevor extensions' logging here . Having the ability to supply our own logger that would log into vscode channel would be helpful. We also currently mock a Console module in tests because they were polluted by many imperative logs and we did not find a better way to disable it. Having the ability to provide a mock module directly, would make the tests cleaner. From Gene on Mar 16:There are enough separate threads in this issue that I have chosen to edit this comment, solely to add my additional thoughts. Let me know if doing such edits is a problem. I failed to describe the reason for the logging initialization currently done by the ProfileInfo constructor. When I ran some unit tests, log messages from underlying Imperative functions were displayed in my command window. This was because I had not initialized the Zowe Logger class, and messages went to stdout. Historically, for Windows GUI apps, such stdout messages silently disappear. Either displaying log messages to stdout or completely losing messages would be undesirable behavior. I initialized the logger so that those messages would go to an imperative log file. I think the ProfileInfo constructor could automatically determine if an Imperative Logger has already been initialized, and only perform a Logger initialization if needed. I can see how VSCode apps would want to write logs in a VSCode-compliant fashion. It seems unrealistic to get every underlying Imperative utility function to adhere to VSCode logging conventions. I suggest that we let VSCode apps log messages from their app in their own VSCode-compliant fashion. Depending on whether Imperative Logging has already been initialized, ProfileInfo would either use the existing Imperative Logger, or initialize a default location. If ProfileInfo initializes logging, it would choose the location as I described in a previous comment. If you need to call a different Imperative function before ProfileInfo, and want to have ProfileInfo initialize logging for you, you could create a new ProfileInfo object (which will initialize the Imperative logger), call the other Imperative functions, and then later use the ProfileInfo object. For Example:
|
Regarding profile cache, I will have to look at the implementation in Zowe Explorer that @phaumer mentioned to better understand how it is used. In Endevor explorer we try to stay as close to the real values on disk as possible and avoid managing our own copy of profiles in memory. From Gene on Mar 16:We may be inching into mutually exclusive requirements. We heard from the Zowe Explorer team that it was really important to only read from disk when requested. This current comment implies that direct input from disk for every action is important. It was our intention that you could control how frequently you read from disk by calling ProfileInfo.readProfilesFromDisk as frequently as you need. Functions that provided various attributes and argument values would deliver that information from what was already read from disk. |
@awharn what is the meaning of
would it, perhaps, be better to have two interfaces that each focus on a given concern? |
@VitGottwald @venkatzhub @dkelosky Are you planning on implementing the SDK on E4E as well? Does the consideration that you intend here is to look at all the different extensions and mold the architecture of the SDK based on all those extensions? Or should the architecture be focused on Zowe Explorer and then the extenders will make use of that? |
We talked about doing this for E4E, but I'm not sure if it's explicitly captured in our backlog. The SDK is intended for use by all clients; not just Zowe Explorer. Eventually we would plan to use this SDK for other VS Code extensions, like our JCL extension and sample / template extensions which are yet to be created. I don't think all Zowe VS Code extensions would pre-req Zowe Explorer. On the CLI, we require all plugins to be installed into the CLI, i.e. plugins must not run standalone. However, Zowe Explorer itself is an extension to VS Code; it's like a plugin itself. Other Zowe-related extensions (like E4E) can provide value even without Zowe Explorer in the picture. Perhaps pre-req'ing Zowe Explorer would be a "best practice" but not a hard requirement. |
Once the single config is rolled out, there will be a natural pressure to use it in other extensions. Having a strategy where some extensions use the old yaml files and some use the new config does not sound like a good idea long term. |
So we should really take a look a what the impact is for other extensions while it is being worked on. And raise requirements. If we do not do this homework we will be putting ourselves into a difficult position in the future. |
More than natural pressure; we'll eventually require it for conformance 😄 We'll be testing the SDK with an internal VS Code Extension - perhaps you can try for E4E as well. Once we're fairly confident we have something that is workable for a few types of extensions, we'll again get feedback from the broader community. |
@jellypuno - I agree that we cannot afford to have a mixed bag, and the current direction is for every extension to use the new config. We absolutely have to look at the other extensions (I was under the impression that it was done already, but looks like it was not :( ) |
@venkatzhub It was not part of our plan. The plan (at least for us) is to implement it in Zowe Explorer first then test it in zFTP extension. make sure that it is working. If we are planning to add E4E in the picture then our engineers don't have capacity for that. Maybe other extensions like what @dkelosky said or next PI? |
It depends on what is meant by "look at". We're aware of and track as many Zowe VS Code extensions as we have access to. We have looked into repos ourselves or otherwise contacted those responsible for the repos to share our plans. We're also communicating in the Zowe community about our SDK plans and asked for input from all workstation clients (not just VS Code extensions). We're fairly confident that we (collectively) know our SDK will support early adopters. If we've missed some team, please direct them here 😄. This is all still in validation phase; we can accommodate changes as we develop. Even after, if there is something we miss, we should be able to accommodate then as well. We've demonstrated that we can roll out changes to all CLI plugins, and I don't see this as being that different. Of course, we had an advantage there with our conformance criteria to ensure consistency. We don't have this yet for extensions, but we're working on it. |
@jellypuno - I'm fine with the plan of handling ZE first. My comment was more from a design and architecture point of view - where the understanding of the requirements from other extensions like E4E etc. should be taken into account. As @dkelosky said, the teams have been contacted, but what is not clear to me is if the teams got a chance to think thru all the aspects - and if they were able to articulate the requirements. If that is done, we are in good shape, if not - I think we need to evaluate if the teams have time to at least understand what the new config would mean to them. |
Likely they have not gone through all aspects - this stuff isn't on peoples radar until it's time to use it. Internally - I tagged a few other folks to take another look and provide feedback here. We'll also make a point to mention it on a few sync meetings this week. Thank you |
The IProfAttrs.profLoc.jsonLoc property is ONLY used when the item in question comes from a Team Configuration. In a team config, one needs to know where in the JSON document an item exists, for example, "ca11.myDefaultZosmfProfile.port". We anticipate that profLoc would typically be needed if you choose to write data back to disk. I originally had profile location and argument location as two separate interfaces. Most of the properties were identical between the two, so much so, that I found that I was frequently confused between the two. That is when I combined them into one interface, with a couple of property values not used for one of the types. For a profile, only ProfLocType.OLD_PROFILE or ProfLocType.TEAM_CONFIG apply. For an argument value, any of ProfLocType.OLD_PROFILE, ProfLocType.TEAM_CONFIG, ProfLocType.ENV, or ProfLocType.DEFAULT would apply. |
As the devil is usually in the details, I think it would be good to make sure, that whoever looks a this understands the inheritance structure in service profiles and the complexity it adds to the solution - making updates through API very difficult to perform. I think this is an aspect that is not really emphasised in presentations. |
To keep some of my responses associated with your original comments, I edited some of those comments and added my responses. However, it appears that no notifications are sent by doing an edit, so I will not do that anymore. To find those replies, you can search this issue for the following text: "From Gene on Mar 16" |
As I remember, in order to access secure password storage, a user may be asked to provide an access password. |
@ishche Are you referring to this kind of prompt that Zowe CLI/Explorer shows on macOS when accessing passwords? If so, this is OS behavior that we don't have control over. macOS automatically prompts for the keychain password whenever Zowe CLI attempts to load secure passwords. Although we're not able to directly cover this interaction with an API, we have taken steps to reduce the number of prompts. If you're using the new team config, you should only be prompted for a keychain password once, since secure credentials for all profiles are loaded all at once from a single vault entry. This hopefully provides a better UX on macOS than the old profiles, which prompted for a password many times for each secure credential being accessed. |
We are interested in your opinions about calling Imperative.init.We understand that your VSCode apps do not currently call Imperative.init. In fact, we believe that some of you have removed a call to that function from your app. We are interested in hearing whether you have serious objections if the ProfileInfo API were to automatically call Imperative.init for you. The following are the trade-offs that we are considering. We would like to know if you have strong objections to either of the following approaches for gathering profile definitions. The problem to be solvedProfiles themselves contain argument names and values. Information about what arguments are required, their data types, and their default values are contained within profile definitions. The ProfileInfo API must obtain those profile definitions. Read profile definitions from disk filesWe can read the profile definitions from disk files (the schema file for Team-config, and XXX_meta.yaml files for old profiles).
Read profile definitions through Imperative.initWe can obtain the profile definitions by calling Imperative.init. It reads the command definitions and profile definitions for the Zowe commands and plugin commands. This is the original source of profile definitions for the team-config schema file and the old-style XXX_meta.yaml files.
Our current plansWe have partially implemented an approach for reading profile definitions from schema and meta files.
If you have a strong business case for either of the two suggested approaches, voice your opinion. |
@gejohnston What is your recommended approach? The PROs indicated in option 2 is attractive to me because it means that we are going to remove some processes that we implemented in ZE and rely on the SDK. But I am concerned about some of the CONs 😄
Dependency meaning that the user needs to install Zowe CLI and the appropriate plugins before they can use ZE?
If for example option 2 is chosen, Can we still start the development for our beta version? or does this mean that we need to pause and wait? |
@jellypuno Creating a dependency on the CLI is what we are worried about with an approach of using a scaled-back Imperative.init. It is not an expectation. I heard information in a meeting this morning that top levels of Product Management do NOT want ZE to depend on the CLI being installed. If our efforts to create a scaled-back version of Imperative.init for this API resulted in a dependency on the CLI, we would abandon the Imperative.init approach and resort to the disk-only approach. Your interest in a scaled-back Imperative.init approach might justify some initial research for us. We may proceed with the disk-only approach for now, and if desireable, replace it with an Imperative-Init approach later when we have worked out any undesirable side-effects. I think the ProfileInfo API may hide most of such an implementation change, but some of the end-user limitations might change if we can later plug in a fully functional Imperative.init replacement. I think this would enable you to start development on your beta version sooner rather than later. Neither approach is implemented yet, but the disk-only approach will probably be faster to produce than the Imperative.init approach. Some of our choices will also be driven by time-to-market concerns and Product Management priorities. We have not really discussed these particular alternatives with our own Product Management team yet. |
We welcome your feedback on how we present missing arguments to youOur API has a couple of functions (mergeArgsForXXX) that return an array of known arguments (knownArgs) and an array of missing arguments (missingArgs). We want to give you the opportunity to influence how we interpret "missing" arguments. Current implementationIf no value is specified for a required argument within the profile, but that argument has a default value, the argument is placed into the missingArgs array with its default value. The location of that argument will be marked as DEFAULT. Before we return from mergeArgsForXXX, if the length of missingArgs is greater than Zero, we throw an exception containing an error code of MISSING_REQ_PROP. All data that we gathered will be available in knownArgs and missingArgs. Since this approach is already implemented, this will remain the implementation, unless you voice a preference for different behavior. Alternate implementation choiceInstead of placing such a default value in missingArgs, we could instead place the default value into knownArgs. Such an argument would still be marked as DEFAULT. Your program could then detect if all required arguments have some value by testing whether the length of missingArgs is zero. Do you prefer this approach? Do you want an exception to be thrown?Regardless of whether we use the current or alternate implementation, do you want:
Ensuring that @jellypuno @VitGottwald and @t1m0thyj are notified. |
@gejohnston can this issue be closed? |
@MikeBauerCA I believe this issue can be closed. The material was reviewed by external teams. We made some changes to address feedback. An API with those changes was published and is being used by other teams. I should have closed this issue during the last merge of API changes, but I probably just lost track of this issue along the way. |
API to access Zowe Profile Information
The Zowe CLI will deprecate its older style profiles for configuring the Zowe CLI, Zowe plugins, and Zowe VS Code extensions. Eventually the old style profiles will be removed from the product. Those old profiles will be replaced by a team configuration file (also referred to as single configuration file, project configuration, and Zowe V2 configuration).
There are several variations to provide flexibility, but in its simplest form, a team configuration is a file named "zowe.config.json" in a user’s ZOWE home directory. The config file contains connection arguments and profile arguments for the Zowe command groups, including every installed plugin. A few fundamental actions are performed on the team configuration with the “zowe config” command group. Users will perform most of their modifications to the configuration by editing zowe.config.json in a text editor.
One must understand the purpose of a team configuration before being able to fully appreciate the functionality of an API that accesses the team configuration. An introduction to the functionality and use of a team configuration can be found in "Zowe CLI — Getting Started, Made Easy!".
While some APIs existed for old style profiles, the Zowe CLI commands, plugins, and VS Code extensions pieced together those APIs differently, or accessed the profiles directly. This led to inconsistent interpretation of the profile information. As new capabilities were written in one component, other components did not demonstrate that new functionality.
During the same time-frame that the new team configuration will be rolled out, we also plan to deliver an API to provide profile information to Zowe components. This document describes the intended functionality of the ProfileInfo API.
Requirements
Ability to read the configuration as stored by the user.
Team configurations have multiple layers. Resolve the value overrides from those layers into a final set of values.
Provide an indicator for a team config, specifying whether the profile is global or project-based.
When searching for a project team config, a caller should be able to specify the starting directory (instead of only searching from the current directory).
Provide a list of all typed profiles.
Provide the default profile choice for each type of profile.
Optionally limit the list to a specific type of profile.
Retrieve the name of the default profile for a given type of profile.
Apps have the need to resolve the arguments for a particular type of profile. They use this to display a set of choices to the end user.
During the period of deprecation of old style profiles, automatically detect whether team config or old profiles are in use.
Automatically read the right style (old profiles or team config) for the API consumer.
Provide an indicator of whether old profiles or team config is being used.
Provide file paths to config files so they can be launched for editing.
One existing function that should be augmented is getDefaultProfile( ).
This method loads the default old-style profile of type X.
It also looks for a default base profile, and if it exists then merges values between base and service profiles.
An enhanced version of getDefaultProfile should also handle team config.
If zowe.config.json does not exist, fall back to current implementation for loading old-style profiles
If zowe.config.json does exist, load the default service and base profile out of the team config JSON file(s)
Automatically resolve the order of precedence overrides of argument values.
A profile’s argument values are set with this precedence:
Command line options or GUI input directly from a user.
User-supplied options in a CLI are known up-front.
User-supplied options in a GUI would typically be acquired after the values merged from all of the other sources below have been shown to the user, and then provide the ability to add to (or override) the existing values.
Environment variables.
Values stored in a service profile within a Zowe configuration on disk (old profiles or team config).
Values stored in a base profile within a Zowe configuration on disk (old profiles or team config).
Default values specified in a profile’s definition.
Perhaps accept custom args and env objects as input, with default values of process.argv and process.env
Need the ability to reload the configuration from disk and re-resolve the order of precedence on demand.
Ensure that the "zowe auth login" action stores the resulting token in the correct profile.
Credential management is strongly related to the management of configuration arguments. Supply a method that appropriately handles the loading of keytar.
If zowe.config.json does not exist, it would conditionally load CredentialManager based on the properties in "settings.json"
Check in ~/.zowe/imperative/settings.json if CredentialManager is enabled
Override keytar module on the DefaultCredentialManager class with VS Code's bundled Keytar
Initialize CredentialManagerFactory class to load/save secure credentials with the service name "Zowe-Plugin"
If zowe.config.json does exist, it would always load CredentialManager
Accepts an optional callback to require a custom Keytar module
Returns boolean to indicate whether secure credential manager initialized successfully (or maybe it should throw error if initialization fails?)
Use case considerations
Considerations for GUI config vs editing the config in an editor:
Saving user values back to disk is likely the most difficult operation to support in the API and implement in the GUI.
How does a GUI save a config value if the user overrode a value that was originally obtained from an environment variable or from the default value within a profile definition?
The flexibility of team config is greater than old profiles. It seems problematic to represent the full functionality of both very different sets of capabilities in a single representation.
A single representation would increase the complexity of the data structure needed for a GUI to store values back to disk.
Returning two different representations puts the burden on the API consumer to implement two sets of processing logic for the two representations.
There has been some discussion that a GUI for accepting configuration values from a user might be limited to the most simple case configuration.
Do we need to allow a GUI to read and save all configurations in all of their complexities?
Should a GUI create a configuration only from scratch, and use a very simple structure?
Should we limit GUI editing to only configurations that were created by that GUI?
Should a GUI place the user into an editor window to directly edit the config file?
Current imperative functions automatically prompt (on the console) for missing connection arguments. An API should not do console prompting. Possible solutions include:
Structure the API so that the caller can retrieve a list of all missing connection arguments so that the caller can prompt for those arguments. The caller then supplies all of the arguments provided by the user in a request to perform an action.
Use callbacks to the caller when a connection argument is missing.
In addition to known connection properties, we can provide a list of any required profile arguments that do not have values assigned, so that the caller can prompt for all missing arguments.
We could use the "required" property of an argument to add any required, but missing profile arguments to the list of missing arguments.
If we use this design, we may be able to restore the "required" property to our set of known connection arguments (like host, port, etc).
Note that additional arguments are often required for a command, which are not part of a profile. For example, a "list dataset" command requires a “datasetName” argument. However, datasetName is not an argument defined in a zosmf profile.
The ProfileInfo API is limited to arguments that have been defined for a profile itself.
Since our current business direction is to have users edit the team config files, the ProfileInfo API will not support writing values to a Team configuration. The lower-level Config class will be the only means for saving values to the Team configuration.
Similarly the ProfileInfo API will not save values to old-style profiles. Existing (but deprecated) functions must be used to store values in old-style profiles. If callers of the ProfileInfo API need to save to both old profiles and new team configurations, they must write dual-path logic to handle both conditions.
Note that both the old style profile CLI commands to set profiles, and the new "config set" CLI commands will be available.
API functions
The ProfileInfo functions provide the following functionality:
Read configuration from disk.
Transparently read either new team configuration or old style profiles.
Resolve order of precedence for profile argument values.
Provide information to enable callers to prompt for missing, but required profile arguments.
The following detailed API documentation was generated from source files which reside in the "profInfo-for-next" branch of the imperative repository (https://github.com/zowe/imperative).
I think that the best way to read the ProfileInfo API is to read the "Pseudocode examples" at the beginning of the ProfileInfo API doc, and then look for the details about any function that interests you.
The API details are listed below in this order:
Recommended ProfileInfo API
This class provides functions to retrieve profile-related information.
It can load the relevant configuration files, merge all possible profile
argument values using the Zowe order-of-precedence, and access desired
profile attributes from the Zowe configuration settings.
Pseudocode examples:
Hierarchy
Index
Properties
Methods
Properties
Private mLoadedConfig
mLoadedConfig:
Config
= null
packages/config/src/ProfileInfo.ts:86
Private mUsingTeamConfig
mUsingTeamConfig: boolean = false
packages/config/src/ProfileInfo.ts:87
Methods
Private ensureReadFromDisk
ensureReadFromDisk(): void
packages/config/src/ProfileInfo.ts:258
Ensures that ProfileInfo.readProfilesFromDisk() is called before an
operation that requires that information.
Returns void
getAllProfiles
getAllProfiles(profileType?: string):
IProfAttrs[]
packages/config/src/ProfileInfo.ts:106
Get all of the typed profiles in the configuration.
Parameters
Optional profileType: string
Returns IProfAttrs[]
An array of profile attribute objects. In addition to the name, you
get the profile type, an indicator of whether the profile is the
default profile for that type, and the location of that profile.
getDefaultProfile
getDefaultProfile(profileType: string):
IProfAttrs
packages/config/src/ProfileInfo.ts:120
Get the default profile for the specified profile type.
Parameters
profileType: string
Returns IProfAttrs
The default profile. If no profile exists for the specified type, we
return null;
getTeamConfig
getTeamConfig():
Config
packages/config/src/ProfileInfo.ts:151
Get the Config object used to manipulate the team configuration on
disk.
Our current market direction is to encourage customers to edit the
team configuration files in their favorite text editor.
If you must ignore this recommended practice, you must use the
Config class to manipulate the team config files. This class has a
more detailed and therefore more complicated API, but it does
contain functions to write data to the team configuration files.
You must call ProfileInfo.readProfilesFromDisk() before calling this
function.
Returns Config
An instance of the Config class that can be used to manipulate the
team configuration on disk.
mergeArgsForProfile
mergeArgsForProfile(profile:
IProfAttrs):
IProfMergedArg
packages/config/src/ProfileInfo.ts:180
Merge all of the available values for arguments defined for the
specified profile. Values are retrieved from the following sources.
Each successive source will override the previous source.
definition.
service profile values will be overridden with values from a
zowe.config.user.json file (if it exists).
Parameters
profile: IProfAttrs
Returns IProfMergedArg
An object that contains an array of known profile argument values
and an array of required profile arguments which have no value
assigned. Either of the two arrays could be of zero length,
depending on the user's configuration and environment.
mergeArgsForProfileType
mergeArgsForProfileType(profileType: string):
IProfMergedArg
packages/config/src/ProfileInfo.ts:204
Merge all of the available values for arguments defined for the
specified profile type. See mergeArgsForProfile() for details about
the merging algorithm. The intended use is when no profile of a
specific type exists. The consumer app can prompt for values for
missing arguments and then perform the desired operation.
Parameters
profileType: string
Returns IProfMergedArg
The complete set of required properties;
readProfilesFromDisk
readProfilesFromDisk(appName: string, teamCfgOpts?:
IConfigOpts):
Promise<void>
packages/config/src/ProfileInfo.ts:231
Read either the new team configuration files (if any exist) or read
the old-school profile files.
todo: Does our consumer need to call this function for old-school
profiles?
Parameters
appName: string
Optional teamCfgOpts: IConfigOpts
Returns Promise<void>
usingTeamConfig
usingTeamConfig(): boolean
packages/config/src/ProfileInfo.ts:248
Returns an indicator of whether we are using a team configuration or
old-school profiles.
You must call ProfileInfo.readProfilesFromDisk() before calling this
function.
Returns boolean
True when we are using a team config. False means old-school
profiles.
Data structures used by ProfileInfo
The following data structures describe the content of various objects used by the ProfileInfo API.
Low-level Config API
The Config class provides facilities for reading and writing team
configuration files. It is used by Imperative to perform low-level
operations on a team configuration. The intent is that consumer apps
will not typically use the Config class, since end-users are expected
to write team configuration files by directly editing them in an editor
like VSCode.
Hierarchy
Index
Constructors
Properties
Accessors
Methods
Constructors
Private constructor
new Config(opts?:
IConfigOpts):
Config
packages/config/src/Config.ts:96
Constructor for Config class. Don't use this directly. Await
Config.load
instead.Parameters
Optional opts: IConfigOpts
Options to control how Config class behaves
Returns Config
Properties
mActive
mActive: object
packages/config/src/Config.ts:81
Currently active layer whose properties will be manipulated
internal
:
Type declaration
global: boolean
user: boolean
mApp
mApp: string
packages/config/src/Config.ts:63
App name used in config filenames (e.g., my_cli.config.json)
internal
:
mHome
mHome: string
packages/config/src/Config.ts:75
Directory where global config files are located. Defaults to
~/.appName
.internal
:
mLayers
mLayers:
IConfigLayer[]
packages/config/src/Config.ts:69
List to store each of the config layers enumerated in
layers
enuminternal
:
mSecure
mSecure:
IConfigSecure
packages/config/src/Config.ts:96
Secure properties object stored in credential vault
internal
:
mVault
mVault:
IConfigVault
packages/config/src/Config.ts:90
Vault object with methods for loading and saving secure credentials
internal
:
Optional opts
opts:
IConfigOpts
packages/config/src/Config.ts:104
Options to control how Config class behaves
Static Private END_OF_TEAM_CONFIG
END_OF_TEAM_CONFIG: ".config.json" = ".config.json"
packages/config/src/Config.ts:52
The trailing portion of a shared config file name
Static Private END_OF_USER_CONFIG
END_OF_USER_CONFIG: ".config.user.json" = ".config.user.json"
packages/config/src/Config.ts:57
The trailing portion of a user-specific config file name
Accessors
api
get api(): object
packages/config/src/Config.ts:238
Access the config API for manipulating profiles, plugins, layers,
and secure values.
Returns object
layers: ConfigLayers
plugins: ConfigPlugins
profiles: ConfigProfiles
secure: ConfigSecure
appName
get appName(): string
packages/config/src/Config.ts:287
App name used in config filenames (e.g., my_cli.config.json)
Returns string
configName
get configName(): string
packages/config/src/Config.ts:295
Filename used for config JSONC files
Returns string
exists
get exists(): boolean
packages/config/src/Config.ts:251
True if any config layers exist on disk, otherwise false.
Returns boolean
layers
get layers():
IConfigLayer[]
packages/config/src/Config.ts:270
List of all config layers. Returns a clone to prevent accidental
edits of the original object.
Returns IConfigLayer[]
maskedProperties
get maskedProperties():
IConfig
packages/config/src/Config.ts:341
The properties object with secure values masked.
type
: {IConfig}
memberof
: Config
Returns IConfig
paths
get paths(): string[]
packages/config/src/Config.ts:261
List of absolute file paths for all config layers.
Returns string[]
properties
get properties():
IConfig
packages/config/src/Config.ts:279
List of properties across all config layers. Returns a clone to
prevent accidental edits of the orignal object.
Returns IConfig
schemaName
get schemaName(): string
packages/config/src/Config.ts:311
Filename used for config schema JSON files
Returns string
userConfigName
get userConfigName(): string
packages/config/src/Config.ts:303
Filename used for user config JSONC files
Returns string
Methods
delete
delete(path: string, opts?: object): void
packages/config/src/Config.ts:400
Unset value of a property in the active config layer.
Parameters
path: string
Property path
Optional opts: object
Include
secure: false
to preserve property in secure arrayOptional secure?: boolean
Returns void
findLayer
findLayer(user: boolean, global: boolean):
IConfigLayer
packages/config/src/Config.ts:509
Find the layer with the specified user and global properties.
internal
:
Parameters
user: boolean
True specifies that you want the user layer.
global: boolean
True specifies that you want the layer at the global level.
Returns IConfigLayer
The desired layer object. Null if no layer matches.
formMainConfigPathNm
formMainConfigPathNm(options: any): string
packages/config/src/Config.ts:543
Form the path name of the team config file to display in messages.
Always return the team name (not the user name). If the a team
configuration is active, return the full path to the config file.
Parameters
options: any
a map containing option properties. Currently, the only property
supported is a boolean named addPath. {addPath: true | false}
Returns string
The path (if requested) and file name of the team config file.
layerActive
layerActive():
IConfigLayer
packages/config/src/Config.ts:524
Obtain the layer object that is currently active.
internal
:
Returns IConfigLayer
The active layer object
Private layerMerge
layerMerge(maskSecure?: boolean):
IConfig
packages/config/src/Config.ts:442
Merge the properties from multiple layers into a single Config
object.
internal
:
Parameters
Optional maskSecure: boolean
Indicates whether we should mask off secure properties.
Returns IConfig
The resulting Config object
Private layerPath
layerPath(layer:
Layers):
string
packages/config/src/Config.ts:221
Get absolute file path for a config layer. For project config files,
We search up from our current directory and ignore the Zowe hone
directory (in case our current directory is under Zowe home.). For
golbal config files we only retrieve config files from the Zowe home
directory.
internal
:
Parameters
layer: Layers
Enum value for config layer
Returns string
layerProfiles
layerProfiles(layer:
IConfigLayer,
maskSecure?: boolean): object
packages/config/src/Config.ts:489
Obtain the profiles object for a specified layer object.
internal
:
Parameters
layer: IConfigLayer
The layer for which we want the profiles.
Optional maskSecure: boolean
If true, we will mask the values of secure properties.
Returns object
The resulting profile object
[key: string]: IConfigProfile
save
save(allLayers?: boolean): Promise<void>
packages/config/src/Config.ts:189
Save config files to disk and store secure properties in vault.
Parameters
Optional allLayers: boolean
Specify false to save only the active config layer
Returns Promise<void>
set
set(path: string, value: any, opts?: object): void
packages/config/src/Config.ts:354
Set value of a property in the active config layer. TODO: more
validation
Parameters
path: string
Property path
value: any
Property value
Optional opts: object
Include
secure: true
to store the property securelyOptional secure?: boolean
Returns void
setSchema
setSchema(schema: string | object): void
packages/config/src/Config.ts:419
Set the $schema value at the top of the config JSONC. Also save the
schema to disk if an object is provided.
Parameters
schema: string | object
The URI of JSON schema, or a schema object to use
Returns void
Static empty
empty():
IConfig
packages/config/src/Config.ts:110
Return a Config interface with required fields initialized as empty.
Returns IConfig
Static load
load(app: string, opts?:
IConfigOpts):
Promise<Config>
packages/config/src/Config.ts:125
Load config files from disk and secure properties from vault.
Parameters
app: string
App name used in config filenames (e.g., my_cli.config.json)
Optional opts: IConfigOpts
Options to control how Config class behaves
Returns Promise<Config>
Static search
search(file: string, opts?: object): string
packages/config/src/Config.ts:326
Search for up the directory tree for the directory containing the
specified config file.
Parameters
file: string
Contains the name of the desired config file
Optional opts: object
Optional ignoreDirs?: string[]
Contains an array of direcory names to be ignored (skipped)
during the search.
Returns string
The full path name to config file or null if not found.
The text was updated successfully, but these errors were encountered: