-
Notifications
You must be signed in to change notification settings - Fork 892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Introduce Application Configuration Service to support hot reloading #5796
Comments
The application config service provide a way to load dynamic application config after OSD process started compare to the way current osd.yaml support. That make OSD application config support multi-tenancy ready at application config tier. To help the design, we could brainstorming user cases that could leverage the application config service
CC: @dagneyb @kgcreative |
@tianleh, while we are collecting more user cases, would you please come up with the initial proposal soon? |
Sure. This is my priority. |
We need to abstract to a interface and webapi in order decouple with storage, while we need a implementation of this interface for opensearch. |
any reason we put verb (GET, UPDATE, DELETE) part of endpoint? |
I will switch to use |
Explicitly called this out in the problem statement. |
Removed |
Talked with @seraphjiang and @bandinib-amzn about generic and specific APIs/interfaces. I have updated the RFC to prefer generic style and moved specific style to alternative approach. Will collect more input from @lezzago and @abbyhu2000 |
are we going to save the configurations as saved objects? does customer need some permission to manage the configs? |
Do we think we need to break out the config or the APIs into "on setup" or run time. Some configurations might require at least on browser reload depending if it's trying to intercept all requests. |
curl -X POST 'http://localhost:5601/api/appconfig/ to create the index with the mappings as expected so a privileged user can just do a POST call. Or have a "hidden" public part of the plugin that allows navigating to and has a button to create the plugin? Sort of like this hidden route https://playground.opensearch.org/app/status |
I like the generic APIs were we get the value instead of targetting like CSPs specfic. But perhaps theres an inbetween layer like stated before like "before load" or on load that we define. or need to subset them in a different way like "httpConfig" "appConfig" etc. Then I can just getHttpConfig |
While providing flexibility how are we making sure that documentName is unique? Also can we use something more generic for |
Comments from Yan: check whether we could extend the existing config plugin |
There are some confusions around whether each plugin will have their own storage or all components will use a single storage. I will update the doc to address this confusion. |
By default, these configurations will be stored into a new OpenSearch index. Each entity will become a document in the index instead of saved objects. Use
For permission control, the customers will require write permission to this index to call the update API. This is achieved through using scoped If there is an external configuration client, e.g based on DynamoDB, then it will be up to the client to perform permission check. |
As follow up of @bandinib-amzn 's request, shared my previous POC work in the issue #5796 (comment) |
Added contents to emphasize that a different storage is for both OSD core and plugins to use and not for each plugin to use their own storage. #5796 (comment) |
Plugin should not own their own storage for meta shared cross OSD. @tianleh would you help to create issue in each plugin repo remind plugin maintainer to review the proposal and raise concern if they had different ideas. |
Tracking issues are created. #5796 (comment) |
Hi @tianleh Thank you for creating issue. I think Dynamic Configuration will greatly help customers. I have few questions regarding design.
|
For # 3, the application configuration plugin solves the problem of storage of the configurations and doesn't solve how the stored configurations will be used. With this said, below is the experience of your example of The more I read the comments, the more I understand where the confusion comes from. The way I write the RFC might give readers an impression that my proposal is an enhancement/extension of the existing YML configurations. Then it will take care of the aggregation of the value from YML and index. Actually it is more providing a runtime configuration which is irrelevant whether the configuration is part of YML or not. There could be a use case where they have no such thing in YML at all. Each use case will implement their code logic about how to use their configurations. @bandinib-amzn cc @seraphjiang |
Switched to call it an {entity}. There is no unique constraint applied. We will need to add documentations about using unique entity names when making the configuration changes. One potential way to reduce the risk is that we add a namespace in the path to make it look cc @seraphjiang |
Since we plan to start parallel work to develop an external plugin for providing a DynamoDB based configuration client, let me know whether the API and interfaces part are concerning from your perspective. @bandinib-amzn cc @seraphjiang |
For point # 2, when there is no default OpenSearch, an external storage plugin (say based on DynamoDB) will provide a configuration client and register to the |
For point # 1, @zengyan-amazon has a similar comment as well #5796 (comment) There are two reasons not to extend it.
Below is the code snippet from the
Currently This is why we create a new plugin to host the dynamic configuration logic. |
I understand your perspective. I'm curious, however, about the added value of this feature beyond offering flexibility in storing configurations, especially considering that each use case would need to implement their own code logic for utilizing their configurations. |
Part of the flexibility is that use case owners now have the option to only use dynamic configurations. |
FYI The security-dashboards-plugin already has its own mechanism for supporting dynamic configuration via the security index. This section of the security config powers some (but not all) of the dashboards security configuration. The security plugin has a |
Thanks @cwperks for sharing this! Since your configurations are stored in the security index, does security plugin have a plan to support a different backend storage, say if there is no default opensearch? cc @seraphjiang |
Problem Statement #
OpenSearch Dashboards (OSD) currently provides two ways to make configuration changes. The first one is to use OSD YML file
opensearch_dashboards.yml
(one example is to configure the OSD index name). The second is to use advanced settings page (one example is to configure dark mode). Recently there is an emerging requirement to have an application level configuration mechanism. These configurations may need to take effect without system restart and are not user level configuration. Besides supporting use cases from OSD core, we also plan to support OSD plugins use cases. The last factor to consider is the storage database. While current OSD assumes a default OpenSearch as database, we plan to have an extensible solution where other databases can be used.We will use this issue to explain why the existing features won't meet the requirements and proposal a new solution which will abstract an interface and web APIs in order to decouple with storage, while we need a implementation of this interface for opensearch. The solution is not a direct extension of existing configurations in YML. Instead each use case developer will decide whether they want to pick YML configurations or dynamic configuration (or have both) and implement logic to use these configurations.
Desired State #
Out of Scope #
Existing Limitations #
We will take a close look at the current limitations.
OSD YML #
Only system administrators who have access to OSD YML could update the values. The changes need a server restart to take effect. It will cause the risk of service availability interruption. Use a cluster with 10 hosts running OSD as an example. The system administrator will need to connect to each of the host, update the YML with new value and then restart OSD. Note that regular OSD customers only need to access OSD through endpoint without even knowing the OSD's running environment under the hood.
Also OSD YML controls the static application level configurations and doesn't support user specific configurations.
Advanced Settings #
Advanced Settings have a page on OSD to configure user specific settings. The changes will take effect immediately without a server start. The values are stored in the OSD system index (
.kibana
). When FGAC is enabled, the values will be stored into tenant specific system index. (e.g.kibana_{tenant name}
) where each tenant could have different configuration values. This doesn't meet the requirement of application level configuration service where the values shall not be user specific.Proposed Approach #
We propose to introduce a new index (
.opensearch_dashboards_config
) to store application configurations. Each entity could be put in a document inside the index. (E.g Content security policy rule configurations can be put in a document whose doc ID iscsp.rules
. ) We will make abstractions to a interface and web APIs in order to decouple with storage, while we will provide a implementation of this interface for OpenSearch.The index won’t exist by default. When the OSD process reads it empty, there is no dynamic configuration. We will implement APIs at OSD to allow customers to read and write the content of the index. Note that the OSD process won’t create this index and thus there is no concern for race condition. When FGAC is enabled, similar to how regular indices are access controlled, only customers with the write permission could perform the update. OSD admins could delegate the work to others by assigning them a role which has write permission to the new index.
Below is how a document looks like in the index (use
csp.rules
as an example).APIs #
There will be two types of APIs mentioned in this issue. One type is about the configuration level APIs which will be implemented as part of this issue. The other type is about the document level (or use case specific) APIs which will be designed and implemented by whoever onboards their use cases on to this configuration service.
Below is the list of index level APIs customers can call.
Below is the list of document level APIs customers can call.
Note that we do not provide
update
ordelete
API at the index level to avoid accidental mistakes. Also nocreate
API is provided at index level as document level update has been provided. See this section Onboard More Use Cases for the onboarding instruction.New Plugin #
We will introduce a new plugin
ApplicationConfiguration
to implement the APIs above. The plugin will only have aserver
side. It could be extended to have apublic
side when the team decides to add UX to manage the application configurations. Inside the plugin, we will add a serviceApplicationConfigurationService
which enables other plugins to use the configurations.Multiple Storage Types #
Multiple data sources and metadata storage have decoupled from OpenSearch as database. Our proposal will be extensible for different types of configuration storage (e.g DynamoDB, Postgres) instead of hard coding the dependence on OpenSearch. Note that a different storage to replace OpenSearch is for the whole OSD core and plugins and is not for each plugin to have their own storage. Thus at most one plugin to provide different storage is allowed.
Thus an interface abstracting operations for this configuration would be introduced. Below is the proposed interface for configuration level APIs.
A default implementation to this interface will be based on OpenSearch. The
ApplicationConfiguration
plugin would expose a set function to allow other plugins (external to OSD core) to provide different implementations to this interface. Specifically, theApplicationConfiguration
has a member variableconfigurationClient
which is of the typeConfigurationClient
mentioned above. It also has a member methodsetConfigurationClient
to set the value of theconfigurationClient
. ThissetConfigurationClient
function would be exposed as return value ofApplicationConfiguration
’s setup function. TheApplicationConfiguration
has another member methodgetConfigurationClient
to return the client to use. See below class skeleton for references.Now an external plugin, e.g
MyConfigurationPlugin
could inject its version ofConfigurationClient
into the classApplicationConfigurationPlugin
in the following way.Define
AppPluginSetupDependencies
as follows.It will import the type
ApplicationConfigurationPluginSetup
from the directory of the classApplicationConfigurationPlugin
.Next add
AppPluginSetupDependencies
to its own setup input.(Note that the second variable in
setup
function must be exactlyapplicationConfig
which is the ID of the configuration plugin.)Onboard More Use Cases #
There is no need to add more APIs or interfaces for new use cases since path parameters could be leveraged. Use CSP rules as an example. Customers can use the APIs as follows.
Alternative Approach #
The proposed approach provides a generic way for all use cases. One constraint is that all storage systems will have to use the same name for the document and filed. Use CSP rules as an example, they will have to use the same string
csp.rules
. (One workaround would be maintaining a mapping from the inputcsp.rules
to the actual schema name. This would be a tedious to maintain.)A alternative approach has the use case name in the APIs and interfaces. Below is the list of APIs.
Below is the interface.
This means that any future use case will need to make changes in OSD core package and add more APIs and interfaces.
Use the number of parameters in OSD YML file (~70) to estimate the potential number of use cases to onboard the application configuration. Each of them would have three functions which totally results in ~210 functions into the interface and the APIs. This still doesn't include the use cases from OSD plugins.
One advantage of this alternative approach is that it can avoid accidental updates. Since each use case has its own API path, there is no chance one use case would accidentally update another use case. As a comparison, in the generic approach, since each use case just uses a string, there is a chance for one use case to accidentally modify the configurations of another use case.
In a summary, the gain of the flexibility of naming the table schema is trivial compared to the cost of increasing APIs and interfaces to support. Thus this alternative approach is not preferred.
Comparison Chart #
Appendix #
Clickjacking use case to onboard #
This is one use case to store CSP rules into the application configurations. #5639
POC of plugin registration #
This plugin
csp_storage_provider
is an example where it can create its own configuration client and register to the configuration pluginxframeOptions
. The POC code is pushed to https://github.com/tianleh/OpenSearch-Dashboards/tree/cj-dev/plugins/csp_storage_providerCollect input from all plugin teams #
The text was updated successfully, but these errors were encountered: