kibana/x-pack/plugins/licensing
Spencer fecdba7eba
[eslint] add rule to prevent export* in plugin index files (#109357)
* [eslint] add rule to prevent export* in plugin index files

* deduplicate export names for types/instances with the same name

* attempt to auto-fix duplicate exports too

* capture exported enums too

* enforce no_export_all for core too

* disable rule by default, allow opting-in for help fixing

* update tests

* reduce yarn.lock duplication

* add rule but no fixes

* disable all existing violations

* update api docs with new line numbers

* revert unnecessary changes to yarn.lock which only had drawbacks

* remove unnecessary eslint-disable

* rework codegen to split type exports and use babel to generate valid code

* check for "export types" deeply

* improve test by using fixtures

* add comments to some helper functions

* disable fix for namespace exports including types

* label all eslint-disable comments with related team-specific issue

* ensure that child exports of `export type` are always tracked as types

Co-authored-by: spalger <spalger@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2021-09-01 18:05:45 -07:00
..
common
public [eslint] add rule to prevent export* in plugin index files (#109357) 2021-09-01 18:05:45 -07:00
server [eslint] add rule to prevent export* in plugin index files (#109357) 2021-09-01 18:05:45 -07:00
jest.config.js
kibana.json
README.md
tsconfig.json

Licensing plugin

API:

Server-side

The licensing plugin retrieves license data from Elasticsearch at regular configurable intervals.

  • license$: Observable<ILicense> Provides a steam of license data ILicense. Plugin emits new value whenever it detects changes in license info. If the plugin cannot retrieve a license from Elasticsearch, it will emit an empty license object.
  • refresh: () => Promise<ILicense> allows a plugin to enforce license retrieval.

Client-side

The licensing plugin retrieves license data from licensing Kibana plugin and does not communicate with Elasticsearch directly.

  • license$: Observable<ILicense> Provides a steam of license data ILicense. Plugin emits new value whenever it detects changes in license info. If the plugin cannot retrieve a license from Kibana, it will emit an empty license object.
  • refresh: () => Promise<ILicense> allows a plugin to enforce license retrieval.

Migration example

The new platform licensing plugin became stateless now. It means that instead of storing all your data from checkLicense within the plugin, you should react on license data change on both the client and server sides.

Before

// my_plugin/server/plugin.ts
function checkLicense(xpackLicenseInfo: XPackInfo){
  if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) {
     return {
      isAvailable: false,
      showLinks: true,
     }
  }
  if (!xpackLicenseInfo.feature('name').isEnabled()) {
    return {
      isAvailable: false,
      showLinks: false,
    }
  }
  const hasRequiredLicense = xPackInfo.license.isOneOf([
    'gold',
    'platinum',
    'trial',
  ]);
  return {
    isAvailable: hasRequiredLicense,
    showLinks: hasRequiredLicense,
  }
}
xpackMainPlugin.info.feature(pluginId).registerLicenseCheckResultsGenerator(checkLicense);

// my_plugin/client/plugin.ts
chrome.navLinks.update('myPlugin', {
  hidden: !xpackInfo.get('features.myPlugin.showLinks', false)
});

After

// kibana.json
"requiredPlugins": ["licensing"],

// my_plugin/server/plugin.ts
import { LicensingPluginSetup } from '../licensing/server'

interface SetupDeps {
  licensing: LicensingPluginSetup;
}

class MyPlugin {
  setup(core: CoreSetup, deps: SetupDeps) {
    deps.licensing.license$.subscribe(license => {
      const { state, message } = license.check('myPlugin', 'gold')
      const hasRequiredLicense = state === 'valid';
      if (hasRequiredLicense && license.getFeature('name').isAvailable) {
        // enable some server side logic 
      } else {
        log(message);
        // disable some server side logic 
      }
    })
  }
}

// my_plugin/public/plugin.ts
import { LicensingPluginSetup } from '../licensing/public'
class MyPlugin {
  setup(core: CoreSetup, deps: SetupDeps) {
    const appUpdater$ = new BehaviorSubject<AppUpdater>(() => {});
    core.application.register({
      id: 'myApp',
      updater$: appUpdater$,
    });

    deps.licensing.license$.subscribe(license => {
      const { state, message } = license.check('myPlugin', 'gold')
      const hasRequiredLicense = state === 'valid';
      const showLinks = hasRequiredLicense && license.getFeature('name').isAvailable;

      appUpdater$.next(() => {
        navLinkStatus: showLinks ? AppNavLinkStatus.visible : AppNavLinkStatus.hidden
      });
    })
  }
}

The list of breaking changes

state

LP: The plugin allows consumers to calculate state on license change event and store this The signature calculation is based on this state + license content NP: We decided that license service doesn't keep plugins state https://github.com/elastic/kibana/pull/49345#issuecomment-553451472. Plugins have to react on license change and calculate license state on every license change. If another plugin needs that information, it should be exposed via a plugin contract. This change makes NP & LP licensing service not compatible. We have to keep both until all plugins migrate to the new platform service. The legacy plugin consumes license data from the LP plugin.

Network request failures

LP: The licensing plugin didnt emit a license in case of network errors. NP: Emits the license even if the request failed.

clusterSource

LP: Allows specifying cluster source to perform polling. NP: The plugin always uses a data client. Provides createLicensePoller on the server-side to create a license poller with custom ES cluster.

Initial value on the client

LP: Passed on the page via inlined xpackInitialInfo NP: Should be fetched

Config

LP: xpack.xpack_main.xpack_api_polling_frequency_millis NP: xpack.licensing.api_polling_frequency

License

NP: mode field is provided, but deprecated.

sessionStorage

LP: License and signature were stored under different keys in session storage NP: License and signature were stored under one key xpack.licensing

isOneOf

isOneOf removed, use check or hasAtLeast instead

Endpoint

/api/xpack/v1/info API endpoint is going to be removed. switch to /api/licensing/info instead

Fetch error

getUnavailableReason doesn't return Error object anymore, but string