Skip to content

Latest commit

 

History

History
165 lines (150 loc) · 8.06 KB

File metadata and controls

165 lines (150 loc) · 8.06 KB

OLM operator plugins development

Existing plugins

How to implement a new OLM operator plugin

To implement support for a new OLM operator plugin you need to make following changes:

  1. Introduce new validation IDs for the new operator in the swagger specification:
    • for host validation:
      host-validation-id:
        type: string
        enum:
          - 'connected'
          ...
          - 'lso-requirements-satisfied'
          - 'cnv-requirements-satisfied'
          - 'odf-requirements-satisfied'
          - 'lvm-requirements-satisfied'
    • for cluster validation:
      cluster-validation-id:
        type: string
        enum:
          - 'machine-cidr-defined'
          ...
          - 'lso-requirements-satisfied'
          - 'cnv-requirements-satisfied'
          - 'odf-requirements-satisfied'
          - 'lvm-requirements-satisfied'
  2. Introduce new feature support ID in the swagger specification:
feature-support-level-id:
  type: string
  enum:
    - 'SNO'
    ...
    - 'LVM'
    - 'ODF'
    - 'LSO'
    - 'CNV'
  1. Add the operator's name to the enum list for /v2/supported-operators endpoint swagger specification:
  type: array
  items:
    type: string
    enum:
    - 'amd-gpu'
    - 'lso'
    - 'mtv'
    - 'openshift-ai'
    ...
    - 'osc'
    - 'servicemesh'
  1. Regenerate code by running
skipper make generate
  1. Create and add the new validation IDs to proper category - "operators":

    • for cluster validation:
      func (v validationID) category() (string, error) {
      ...
        case IsCnvRequirementsSatisfied, IsLsoRequirementsSatisfied, IsOdfRequirementsSatisfied, IsLvmRequirementsSatisfied:
           return "operators", nil
    • for host validaton:
      func (v validationID) category() (string, error) {
      ...
        case AreLsoRequirementsSatisfied, AreCnvRequirementsSatisfied, AreOdfRequirementsSatisfied, AreLvmRequirementsSatisfied:
      		return "operators", nil
  2. Modify the installation state machine by adding the new validationIDs to the list of required checks:

    • for cluster:
      var requiredForInstall = stateswitch.And(...,
         ..., If(IsLsoRequirementsSatisfied), If(IsCnvRequirementsSatisfied), If(IsOdfRequirementsSatisfied), If(IsLvmRequirementsSatisfied))
    • for host:
      	var isSufficientForInstall = stateswitch.And(...,
      		...,
      		If(AreLsoRequirementsSatisfied), If(AreCnvRequirementsSatisfied), If(AreOdfRequirementsSatisfied), If(AreLvmRequirementsSatisfied))
  3. Add the new feature to the OLM operators list and implement the SupportLevelFeature interface

    • add feature to the support level list:
          // Olm Operators features
          models.FeatureSupportLevelIDLVM:                  (&LvmFeature{}).New(),
        ...
          models.FeatureSupportLevelIDMCE:                  (&MceFeature{}).New(),
          models.FeatureSupportLevelIDODF:                  (&OdfFeature{}).New(),
          models.FeatureSupportLevelIDMTV:                  (&MtvFeature{}).New(),
          models.FeatureSupportLevelIDOSC:                  (&OscFeature{}).New(),
    • implement the interface at the end of olm operators Your custom code shall reflect the requirements of this new feature by means of Openshift version and target platform (getSupportLevel), CPU architecture (getIncompatibleArchitectures), and compatibility with existing features (getIncompatibleFeatures).
    • in case of any such incompatibilities, add the feature also to the getIncompatibleFeatures methods of all the affected types:
  4. Implement the Operator interface

  5. Plug the new Operator implementation in the OperatorManager constructor:

func NewManager(log logrus.FieldLogger) Manager {
  return NewManagerWithOperators(log, lso.NewLSOperator(), cnv.NewCnvOperator(log), odf.NewOdfOperator(log), lvm.NewLvmOperator(log))
}

Notes about the Operator interface

Manifests generation

A plugin can generate two distinct set of manifests, specified by the two return values of the GenerateManifests(*common.Cluster) (map[string][]byte, []byte, error) method. They are required to:

  1. Install the operator
  2. Configure the operator

The first return value could be used to specify a set of manifests that will be applied directly to the control plane during the bootstrap phase. This set is usually composed by a manifest for creating a new namespace, a new subscription and a new operator group CR for the involved operator.

The second return value it's a manifest used to configure the freshly installed operator, and it will be applied by the assisted-installer-controller job, only after the cluster have been successfully created and the OLM operators are all ready (currently the assisted-installer-controller retrieves the whole list of configurations by downloading the custom_manifests.json file fetched from the Assisted Service).

Validation Lifecycle

Operator validations via ValidateHost() and ValidateCluster() are only executed during cluster creation (day1). For day2 clusters (adding hosts to already-installed clusters), operator validations are skipped since:

  • The cluster is already installed with its chosen operators
  • The cluster state since installation is unknown to the service
  • Install-time operator requirements don't apply to post-installation host additions

General Notes

Cluster Monitoring

When adding a new operator:

  1. Check the operator's CSV for the openshift.io/cluster-monitoring=true annotation. If the annotation is present, add the openshift.io/cluster-monitoring=true namespace label.
  2. Check if the operator already includes its own Prometheus Role and RoleBinding. If not, add the logic to the installer to create them.