Skip to content
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

Konveyor and OLM add-ons #711

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/addons/konveyor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Konveyor Amazon EKS Blueprints AddOn

This add-on installs [Konveyor](https://konveyor.github.io/).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate on the use cases answering the question of why the customer would use this addon, expanding on scenarios where this product is applicable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this point to a different doc portal for tackle2 operator? The documentation page here is misleading and calls out the unmaintained repo as the source which is confusing (to me and I assume the target audience).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://konveyor.github.io/ is good to use for Konveyor documentation. The repo was stale and needed attention, hence we updated it ~2 weeks ago and are working to revamp this as the central documentation for Konveyor going forward.


Konveyor helps large organizations modernize enterprise java applications to Kubernetes. It serves as a platform providing a view of an organization's applications, allowing Assessment and Analysis capabilities to be executed at scale to help Architects get a better feel of the issues present in application source code in regard to deploying to a new environment such as Kubernetes, or other technologies.

It is structured around the concept of a [Unified Experience](https://github.com/konveyor/enhancements/tree/master/enhancements/unified_experience) to aid multiple personas such as Enterprise Architects who manage modernization engagements as well as the Migrators, or developers who carry out the specific refactoring development work.

Konveyor [is released as an Operator](https://github.com/konveyor/tackle2-operator).

The Konveyor operator deploys the components below:

- [Analysis](https://github.com/windup/windup)
- [Hub](https://github.com/konveyor/tackle2-hub)
- [UI](https://github.com/konveyor/tackle2-ui)
- [Assessments](https://github.com/konveyor/tackle-pathfinder)


## Dependencies

The add-on depends on the following components:
- Operator Lifecycle Manager add-on (_OlmAddOn_)
- [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/) add-on (_AwsLoadBalancerControllerAddOn_), which will instantiate an [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html) to fulfill the Ingress deployed by this add-on
- [EBS CSI Driver Amazon EKS add-on](https://aws-quickstart.github.io/cdk-eks-blueprints/addons/ebs-csi-driver/) (_EbsCsiDriverAddOn_), to provide Persistent Volumes (PVs) fulfilling Konveyor's Persistent Volume Claims (PVCs)
- a subdomain for the Konveyor application
- a certificate for the subdomain, made available by the either _CreateCertificateProvider_ or _ImportCertificateProvider_, to be assigned to the load balancer

## Setup

For a fully working setup, please see the Konveyor pattern in the EKS Blueprints Pattern [repository](https://github.com/aws-samples/cdk-eks-blueprints-patterns).
7 changes: 7 additions & 0 deletions docs/addons/olm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Operator Lifecycle Manager Amazon EKS Blueprints AddOn

This add-on installs [Operator Lifecycle Manager](https://olm.operatorframework.io/) (OLM).

## Setup

OLM defines Custom Resource Definitions (CRDs). Operators relying on those CRDs should be deployed once the CRDs are defined, to avoid deployment errors from Kubernetes. To avoid such errors, you can create a KubernetesObjectValue and add a dependency on that. For a working example, please see the Konveyor add-on.
2 changes: 2 additions & 0 deletions lib/addons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export * from './fluxcd';
export * from './grafana-operator';
export * from './helm-addon';
export * from './karpenter';
export * from './konveyor';
export * from './kube-proxy';
export * from './kube-state-metrics';
export * from './metrics-server';
export * from './nested-stack';
export * from './nginx';
export * from './olm';
export * from './opa-gatekeeper';
export * from './prometheus-node-exporter';
export * from './secrets-store';
Expand Down
176 changes: 176 additions & 0 deletions lib/addons/konveyor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { ClusterAddOn, ClusterInfo } from "../../spi";
import { Construct } from 'constructs';
import { readYamlDocument, loadYaml, dependable } from "../../utils";
import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider";
import { KubernetesObjectValue } from "aws-cdk-lib/aws-eks";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";

export interface KonveyorAddOnProps {
/**
* Namespace for Konveyor/Tackle.
* @default 'konveyor-operator'
*/
namespace?: string;
/**
* Konveyor/Tackle name.
* @default 'tackle'
*/
konveyorName?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default '100Gi'
*/
cacheDataVolumeSize?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default '100Gi'
*/
hubBucketVolumeSize?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default 'false'
*/
rwxSupported?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default 'false'
*/
featureAuthRequired?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default 'true'
*/
featureIsolateNamespace?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default '5Gi'
*/
hubDatabaseVolumeSize?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default '1Gi'
*/
keycloakDatabaseDataVolumeSize?: string;
/**
* See https://github.com/konveyor/tackle2-operator
* @default '100Gi'
*/
pathfinderDatabaseDataVolumeSize?: string;
/**
* Ingress name
* @default 'http-ingress'
*/
ingressName?: string;
/**
* Service name for the Ingress configuration
* @default 'tackle-ui'
*/
serviceName?: string;
/**
* Service port for the Ingress configuration
* @default '8080'
*/
servicePort?: number;
/**
* Certificate resource name for the Ingress HTTPS configuration
*/
certificateResourceName: string;
/**
* Subdomain to be assigned to the Load Balancer
*/
subdomain: string;
/**
* URL of the Konveyor Operator Manifest
*/
konveyorOperatorManifestUrl?: string;
}

/**
* Default Konveyor/Tackle properties
*/
const defaultProps = {
namespace: "konveyor-operator",
konveyorName: "tackle",
cacheDataVolumeSize: "100Gi",
hubBucketVolumeSize: "100Gi",
rwxSupported: "false",
featureAuthRequired: "false",
featureIsolateNamespace: "true",
hubDatabaseVolumeSize: "5Gi",
keycloakDatabaseDataVolumeSize: "1Gi",
pathfinderDatabaseDataVolumeSize: "100Gi",
ingressName: "http-ingress",
serviceName: "tackle-ui",
servicePort: 8080,
konveyorOperatorManifestUrl: "https://operatorhub.io/install/konveyor-0.1/konveyor-operator.yaml"
};

export class KonveyorAddOn implements ClusterAddOn {
readonly props: KonveyorAddOnProps;

constructor(props?: KonveyorAddOnProps) {
this.props = { ...defaultProps, ...props } as KonveyorAddOnProps;
}

@dependable('AwsLoadBalancerControllerAddOn')
@dependable("EbsCsiDriverAddOn")
@dependable("OlmAddOn")
deploy(clusterInfo: ClusterInfo): void | Promise<Construct> {
const kubectlProvider = new KubectlProvider(clusterInfo);

// load Konveyor operator from URL
/* eslint-disable */
const request = require('sync-request');
const response = request('GET', this.props.konveyorOperatorManifestUrl);
const konveyorOperatorDoc: string = response.getBody().toString();
const konveyorOperatorDocReplacedNamespace = konveyorOperatorDoc.replace(/my-konveyor-operator/g, this.props.namespace!);
const konveyorOperatorManifest = konveyorOperatorDocReplacedNamespace.split("---").map(e => loadYaml(e));

const konveyorOperatorDeployment: ManifestDeployment = {
name: "konveyor-operator-deployment",
namespace: this.props.namespace!,
manifest: konveyorOperatorManifest,
values: {}
};

const konveyorOperatorStatement = kubectlProvider.addManifest(konveyorOperatorDeployment);

// wait for OLM to be deployed otherwise CRDs are not found
const waitOLMDeployment = new KubernetesObjectValue(konveyorOperatorStatement, 'WaitOLMDeployment', {
cluster: clusterInfo.cluster,
objectType: "Service",
objectName: "operatorhubio-catalog",
objectNamespace:"olm",
jsonPath: ".metadata.name"
});

konveyorOperatorStatement.node.addDependency(waitOLMDeployment);

// load Tackle and Ingress resources
const doc = readYamlDocument(__dirname + "/tackle-manifest.ytpl");
const konveyorManifest = doc.split("---").map(e => loadYaml(e));

const certificateArn = clusterInfo.getResource<ICertificate>(this.props.certificateResourceName)?.certificateArn;
const subdomain = this.props.subdomain;
const konveyorManifestDeployment: ManifestDeployment = {
name: "konveyor-deployment",
namespace: this.props.namespace!,
manifest: konveyorManifest,
values: { ...this.props, certificateArn, subdomain }
};

const konveyorStatement = kubectlProvider.addManifest(konveyorManifestDeployment);

// wait for Konveyor to be deployed otherwise CRDs are not found
const waitKonveyorOperatorDeployment = new KubernetesObjectValue(konveyorStatement, 'WaitKonveyorOperatorDeployment', {
cluster: clusterInfo.cluster,
objectType: "CustomResourceDefinition",
objectName: "tackles.tackle.konveyor.io",
jsonPath: ".spec.group"
});

konveyorStatement.node.addDependency(waitKonveyorOperatorDeployment);

return Promise.resolve(konveyorStatement);
}
}
39 changes: 39 additions & 0 deletions lib/addons/konveyor/tackle-manifest.ytpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
kind: Tackle
apiVersion: tackle.konveyor.io/v1alpha1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v1alpha1 makes me think this product is not production ready.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,

I'm a maintainer of Konveyor and can provide some more context of Konveyor's status.
Konveyor is an actively developed and maintained CNCF sandbox project that is the upstream for Red Hat's Migration Toolkit for Applications .

The code is in production at multiple large organizations being used to aid modernization engagements of enterprise java applications to Kubernetes. The code that makes up Konveyor began ~10 years ago on the Analysis side with the latest version of the platform being developed ~2 years ago, the solution was called Tackle2.

After being accepted into CNCF, there has been an effort to refocus Konveyor onto a Unified vision of bringing the functionality that used to be in separate projects together into a common solution which is Konveyor.

As part of this refocus, we decided to release Konveyor as a "v0.1" as opposed to continuing with the Tackle 2.1+ scheme that was in place prior.

It is possible for the API surface to change as we are working with the community to shape what the future will be. In regard to the API surface for the operator CR, we are careful to keep upgrades working and stable and have automated tests and QE resources actively helping to ensure stability.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @jwmatthews, thank you for your feedback, it surely helps. Understand the comment related to the CR API version and upgrades. It is not as intuitive but it surely matches the saying "there is nothing more permanent than temporary" when it comes versioning.

I assume we should change the source references to https://github.com/konveyor/tackle2-operator, please confirm.

Is https://konveyor.github.io/ still the right documentation entry point? I saw a reference to tackle document here pointing to what appears to be the right page: https://konveyor.github.io/tackle. This url, however, is not functioning.

Understand that doc maintenance may not be the top priority, I was a lot more interesting in dev activities, which you confirmed. Thank you.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, https://konveyor.github.io/ is the right documentation entry point, we are bringing back usage of this as the central spot for developers to contribute to.

The source code for the Konveyor operator is located at: https://github.com/konveyor/tackle2-operator

If you want to reference source code, use: https://github.com/konveyor/tackle2-operator
If you want to reference documentation use: https://konveyor.github.io/

As to https://konveyor.github.io/tackle, that is an older link and not intended.

metadata:
name: "{{konveyorName}}"
namespace: "{{namespace}}"
spec:
cache_data_volume_size: "{{cacheDataVolumeSize}}"
hub_bucket_volume_size: "{{hubBucketVolumeSize}}"
rwx_supported: "{{rwxSupported}}"
feature_auth_required: "{{featureAuthRequired}}"
feature_isolate_namespace: "{{featureIsolateNamespace}}"
hub_database_volume_size: "{{hubDatabaseVolumeSize}}"
keycloak_database_data_volume_size: "{{keycloakDatabaseDataVolumeSize}}"
pathfinder_database_data_volume_size: "{{pathfinderDatabaseDataVolumeSize}}"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "{{ingressName}}"
namespace: "{{namespace}}"
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: "{{certificateArn}}"
spec:
ingressClassName: alb
tls:
- hosts:
- "{{subdomain}}"
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: "{{serviceName}}"
port:
number: 8080
76 changes: 76 additions & 0 deletions lib/addons/olm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ClusterAddOn, ClusterInfo } from "../../spi";
import { Construct } from 'constructs';
import { loadYaml } from "../../utils/yaml-utils";
import { KubectlProvider, ManifestDeployment } from "../helm-addon/kubectl-provider";
import * as assert from "assert";

const OLMDownloadURL = "https://github.com/operator-framework/operator-lifecycle-manager/releases/download/";

export interface OlmAddOnProps {
/**
* OLM version
*/
version?: string
}

/**
* Default OLM properties
*/
const defaultProps = {
version: "v0.21.2"
};

export class OlmAddOn implements ClusterAddOn {
readonly props: OlmAddOnProps;
readonly manifestUrls: string[];

constructor(props?: OlmAddOnProps) {
this.props = {...defaultProps, ...props};
this.manifestUrls = [
OLMDownloadURL+this.props.version+"/crds.yaml",
OLMDownloadURL+this.props.version+"/olm.yaml"
];
}

deploy(clusterInfo: ClusterInfo): void | Promise<Construct> {
let previousResource: Construct;
const resources: Construct[] = [];

/* eslint-disable */
const request = require('sync-request');
const kubectlProvider = new KubectlProvider(clusterInfo);

this.manifestUrls!.map((manifestUrl, urlIndex) => {
const response = request('GET', manifestUrl);
// workaround: KubectlProvider is based on Lambda, which fails if the manifests are too large, so we:
// 1. break the YAMLs
// 2. remove descriptions
const doc: string = response.getBody().toString();
const trimmedDoc = doc.replace(/description:.*[a-zA-Z0-9].*\n/g, 'description: removed\n');
const manifests = trimmedDoc.split("---").filter(e=>e.length>0).map(e => loadYaml(e));

const batchResources = manifests.map((manifest, docIndex) => {
const manifestDeployment: ManifestDeployment = {
name: "olmIdx"+urlIndex+docIndex,
namespace: "olm",
manifest: [manifest],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why manifest is an array here? should be an actual doc.

Copy link
Collaborator Author

@freschri freschri Jun 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addManifest ends up instantiating KubernetesManifest and it looks to me "manifest" is an array type in the param list, as per here: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_eks.KubernetesManifest.html#construct-props ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nm, I think we should do a better job on reflecting the types.

values: {}
};

const resource = kubectlProvider.addManifest(manifestDeployment);

if (previousResource != undefined) {
resource.node.addDependency(previousResource);
}
previousResource = resource;
return resource;
});

resources.push(...batchResources);
});

assert(resources.length > 0, "No OLM manifest found");

return Promise.resolve(resources.at(-1)!);
}
}
Loading
Loading