diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..414206a --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +/dist +/tmp diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..1dfcfc4 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["oclif", "oclif-typescript", "prettier"] +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0ef035d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'weekly' + day: 'saturday' + versioning-strategy: 'increase' + labels: + - 'dependencies' + open-pull-requests-limit: 5 + pull-request-branch-name: + separator: '-' + commit-message: + # cause a release for non-dev-deps + prefix: fix(deps) + # no release for dev-deps + prefix-development: chore(dev-deps) + ignore: + - dependency-name: '@salesforce/dev-scripts' + - dependency-name: '*' + update-types: ['version-update:semver-major'] diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..796eafa --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,10 @@ +name: automerge +on: + workflow_dispatch: + schedule: + - cron: '17 2,5,8,11 * * *' + +jobs: + automerge: + uses: oclif/github-workflows/.github/workflows/automerge.yml@main + secrets: inherit diff --git a/.github/workflows/failureNotifications.yml b/.github/workflows/failureNotifications.yml new file mode 100644 index 0000000..9243031 --- /dev/null +++ b/.github/workflows/failureNotifications.yml @@ -0,0 +1,43 @@ +name: failureNotifications + +on: + workflow_run: + workflows: + - version, tag and github release + - publish + types: + - completed + +jobs: + failure-notify: + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + steps: + - name: Announce Failure + id: slack + uses: slackapi/slack-github-action@v1.24.0 + env: + # for non-CLI-team-owned plugins, you can send this anywhere you like + SLACK_WEBHOOK_URL: ${{ secrets.CLI_ALERTS_SLACK_WEBHOOK }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + with: + payload: | + { + "text": "${{ github.event.workflow_run.name }} failed: ${{ github.event.workflow_run.repository.name }}", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": ":bh-alert: ${{ github.event.workflow_run.name }} failed: ${{ github.event.workflow_run.repository.name }} :bh-alert:" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Repo: ${{ github.event.workflow_run.repository.html_url }}\nWorkflow name: `${{ github.event.workflow_run.name }}`\nJob url: ${{ github.event.workflow_run.html_url }}" + } + } + ] + } diff --git a/.github/workflows/manualRelease.yml b/.github/workflows/manualRelease.yml new file mode 100644 index 0000000..8d8f05c --- /dev/null +++ b/.github/workflows/manualRelease.yml @@ -0,0 +1,36 @@ +name: manual release + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + - name: Conventional Changelog Action + id: changelog + uses: TriPSs/conventional-changelog-action@d360fad3a42feca6462f72c97c165d60a02d4bf2 + # overriding some of the basic behaviors to just get the changelog + with: + git-user-name: svc-cli-bot + git-user-email: svc_cli_bot@salesforce.com + github-token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + output-file: false + # always do the release, even if there are no semantic commits + skip-on-empty: false + tag-prefix: '' + - uses: notiz-dev/github-action-json-property@7a701887f4b568b23eb7b78bb0fc49aaeb1b68d3 + id: packageVersion + with: + path: 'package.json' + prop_path: 'version' + - name: Create Github Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + with: + tag_name: ${{ steps.packageVersion.outputs.prop }} + release_name: ${{ steps.packageVersion.outputs.prop }} diff --git a/.github/workflows/notify-slack-on-pr-open.yml b/.github/workflows/notify-slack-on-pr-open.yml new file mode 100644 index 0000000..13b5c9e --- /dev/null +++ b/.github/workflows/notify-slack-on-pr-open.yml @@ -0,0 +1,23 @@ +name: Pull Request Slack Notification + +on: + pull_request: + types: [opened, reopened] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Notify Slack on PR open + env: + WEBHOOK_URL : ${{ secrets.CLI_TEAM_SLACK_WEBHOOK_URL }} + PULL_REQUEST_AUTHOR_ICON_URL : ${{ github.event.pull_request.user.avatar_url }} + PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }} + PULL_REQUEST_AUTHOR_PROFILE_URL: ${{ github.event.pull_request.user.html_url }} + PULL_REQUEST_BASE_BRANCH_NAME : ${{ github.event.pull_request.base.ref }} + PULL_REQUEST_COMPARE_BRANCH_NAME : ${{ github.event.pull_request.head.ref }} + PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }} + PULL_REQUEST_REPO: ${{ github.event.pull_request.head.repo.name }} + PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }} + PULL_REQUEST_URL : ${{ github.event.pull_request.html_url }} + uses: salesforcecli/github-workflows/.github/actions/prNotification@main diff --git a/.github/workflows/onPushToMain.yml b/.github/workflows/onPushToMain.yml new file mode 100644 index 0000000..61eda8a --- /dev/null +++ b/.github/workflows/onPushToMain.yml @@ -0,0 +1,18 @@ +# test +name: version, tag and github release + +on: + push: + branches: [main] + +jobs: + release: + uses: oclif/github-workflows/.github/workflows/githubRelease.yml@main + secrets: inherit + + # most repos won't use this + # depends on previous job to avoid git collisions, not for any functionality reason + # docs: + # uses: salesforcecli/github-workflows/.github/workflows/publishTypedoc.yml@main + # secrets: inherit + # needs: release diff --git a/.github/workflows/onRelease.yml b/.github/workflows/onRelease.yml new file mode 100644 index 0000000..8876db4 --- /dev/null +++ b/.github/workflows/onRelease.yml @@ -0,0 +1,19 @@ +name: publish + +on: + release: + types: [released] + # support manual release in case something goes wrong and needs to be repeated or tested + workflow_dispatch: + inputs: + tag: + description: tag that needs to publish + type: string + required: true +jobs: + npm: + uses: oclif/github-workflows/.github/workflows/npmPublish.yml@main + with: + tag: latest + githubTag: ${{ github.event.release.tag_name || inputs.tag }} + secrets: inherit diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4286a55 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,9 @@ +name: tests +on: + push: + branches-ignore: [main] + workflow_dispatch: + +jobs: + unit-tests: + uses: oclif/github-workflows/.github/workflows/unitTest.yml@main diff --git a/.gitignore b/.gitignore index a8ec542..d05954a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,13 @@ -!jest.config.js -*.d.ts +**/.DS_Store +*-debug.log +*-error.log +/.idea +/.nyc_output +/dist +/lib +/package-lock.json +/tmp +/yarn.lock node_modules -.vscode -.local-pack -.classpath.txt -.idea -.settings -.vscode -*.iml -.code -unzipped* -aws-sleek-transformer -# CDK asset staging directory -.cdk.staging -cdk.out -dist -*.swp -cdk.context.json -package-lock.json -yarn.lock -docs/api -# mkdocs artifact -site -# macOS extraneous file -.DS_STORE +oclif.lock +oclif.manifest.json diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000..fa25f20 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,15 @@ +{ + "require": [ + "ts-node/register" + ], + "watch-extensions": [ + "ts" + ], + "recursive": true, + "reporter": "spec", + "timeout": 60000, + "node-option": [ + "loader=ts-node/esm", + "experimental-specifier-resolution=node" + ] +} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..6314335 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +"@oclif/prettier-config" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4688782 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Execute Command", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/bin/dev.js", + "args": [ + "hello", + "world", + ], + } + ] +} diff --git a/README.md b/README.md index ab430a0..5999e52 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -# Sleek Marketplace validator +AWS Sleek Transformer CLI +================= + +[![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io) +[![CircleCI](https://circleci.com/gh/oclif/hello-world/tree/main.svg?style=shield)](https://circleci.com/gh/oclif/hello-world/tree/main) +[![GitHub license](https://img.shields.io/github/license/oclif/hello-world)](https://github.com/oclif/hello-world/blob/main/LICENSE) + + +* [Usage](#usage) +* [Commands](#commands) + ## Introduction @@ -7,92 +17,171 @@ Sleek Marketplace validator is solution provide pre-launch validations of the pa 1. Installs project dependencies such as `kubectl`, `eksctl`, `helm` utilities to the terminal. 2. Grabs the following user inputs : - Addon Name - - Helm Url of the Addon + - Helm Url of the Addon - Addon version - Deployment namespace - Account id of the marketplace account - AWS region 3. Authenticates to ECR Repo and downloads the helm chart from the specified Helm repo url. -4. Performs static validations to find occurences of : +4. Performs static validations to find occurrences of: - `.Capabilities` - `helm.sh/hook` -5. Reads GitHub Token secret from AWS Secrets Manager. -6. Clones the GitHub repo `aws-sleek-transformer` -7. Submits a PR with the Addon tar to the repo. +5. Sends the addon and the report of the validation to the AWS Marketplace team to start getting the addon listed on the + EKS console marketplace. -## Pre-requisites +### Pre-requisites To implement this solution, you need the following prerequisites: * The [AWS Command Line Interface](http://aws.amazon.com/cli) (AWS CLI) [installed](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html). The AWS CLI is a unified tool to manage your AWS services. -* AWS CLI default profile should be configured to access your AWS Account with region `us-east-1`. +* AWS CLI default profile should be configured to access your AWS Account. * [Node](https://nodejs.org/en/download/current/) version 18.12.1 or later. * [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) version 8.19.2 or later. -* A secret by name `github-access-token-secret` with your github token as plain text should be created in AWS Secrets Manager in `us-east-1` region. -## Deployment -Download the npm module for aws-sleek-transformer using following command : +# Usage + +```sh-session +$ npm install -g aws-sleek-transformer +$ aws-sleek-transformer COMMAND +running command... +$ aws-sleek-transformer (--version) +aws-sleek-transformer/0.0.0 darwin-arm64 node-v20.10.0 +$ aws-sleek-transformer --help [COMMAND] +USAGE + $ aws-sleek-transformer COMMAND +... +``` + +# Commands + +* [`aws-sleek-transformer configure`](#aws-sleek-transformer-configure) +* [`aws-sleek-transformer submit`](#aws-sleek-transformer-submit) +* [`aws-sleek-transformer validate`](#aws-sleek-transformer-validate) + +## `aws-sleek-transformer configure` + +Sets up the Sleek CLI to work with a given helm chart + +``` +USAGE + $ aws-sleek-transformer configure [--addonName ] [--addonVersion ] [--helmUrl ] + [--marketplaceId ] [--namespace ] [--region ] + +FLAGS + --addonName= Name of the addon + --addonVersion= Version of the addon + --helmUrl= Helm URL of the addon + --marketplaceId= Marketplace AWS Account ID + --namespace= Namespace of the addon + --region= AWS Region + +DESCRIPTION + Sets up the Sleek CLI to work with a given helm chart + + + Extracts information from the environment to populate information required for the Sleek CLI to function. If + certain information is not found, prompts the user for it and asks them to validate the information extracted from + the environment. + + This information is stored ~/.sleek/config.json + + The CLI requires the following: + * AWS Region - can be extracted from the env + * Marketplace AWS Account ID - can be extracted from the env + * Addon Name - requires user input + * Addon Version - requires user input + * Addon Helm Url - requires user input + * Deployment Namespace - requires user input + + Each of these can be passed as flags to this command with the following flags: + * --region + * --marketplace_id + * --addon_name + * --addon_version + * --helm_url + * --namespace + + +EXAMPLES + $ aws-sleek-transformer configure +``` + +_See code: [src/commands/configure.ts](https://github.com/elaramas/aws-sleek-transformer/blob/v0.0.0/src/commands/configure.ts)_ + +## `aws-sleek-transformer submit` + +Uses the pre-existing configurations to submit the addon to the AWS marketplace -```bash -npm i aws-sleek-transformer ``` -## Testing - -Run the `node aws-sleek-transformer` command to see the below command line to input parameters : - -```bash -❯ node aws-sleek-transformer -(node:447500) NOTE: We are formalizing our plans to enter AWS SDK for JavaScript (v2) into maintenance mode in 2023. - -Please migrate your code to use AWS SDK for JavaScript (v3). -For more information, check the migration guide at https://a.co/7PzMCcy -(Use `node --trace-warnings ...` to show where the warning was created) -kubectl version: Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"linux/amd64"} -Kustomize Version: v4.5.7 - -eksctl is already installed. -Helm is already installed. -? What's your Addon Name? datree -? Whats your Helm URL of the Addon? oci://.dkr.ecr.us-east-1.amazonaws.com/datree/datree-free-admission-webhook-awsmp -? Whats your Addon Version? 1.0.1-rc.1 -? Whats your deployment namespace? datree -? Whats your AWS Account id? -? Whats your AWS Region ? us-east-1 +USAGE + $ aws-sleek-transformer submit [--addonName ] [--addonVersion ] + +FLAGS + --addonName= Name of the addon to submit + --addonVersion= Version of the addon to submit + +DESCRIPTION + Uses the pre-existing configurations to submit the addon to the AWS marketplace + + + Sends the selected addon, version to the marketplace for final submission and upload it to Project Sleek. + + It reads from the addons stored in the config: ~/.sleek/config.json and presents them as options to the user to + submit. + + The CLI requires the configure command to be run before hand to ensure there are correct configurations for each of + the addons. + + This command requires the following: + * Addon Name - as used in the configure command + * Addon Version - as used in the configure command + + If no flags are provided, the CLI will launch an interactive menu which let's you select which addon to submit to + the marketplace. + + +EXAMPLES + $ aws-sleek-transformer submit ``` -Below is the output of the execution : +_See code: [src/commands/submit.ts](https://github.com/elaramas/aws-sleek-transformer/blob/v0.0.0/src/commands/submit.ts)_ + +## `aws-sleek-transformer validate` + +Validates a given addon from the configuration provided through the 'configure' command ``` -All User Inputs are Valid! -{ - "addonName": "datree", - "helmUrl": "oci://.dkr.ecr.us-east-1.amazonaws.com/datree/datree-free-admission-webhook-awsmp", - "addonVersion": "1.0.1-rc.1", - "namespace": "datree", - "aws_accountid": "", - "aws_region": "us-east-1" -} -Helm Url : oci://.dkr.ecr.us-east-1.amazonaws.com/datree/datree-free-admission-webhook-awsmpHelm Version : 1.0.1-rc.1 -registryUrl : https://.dkr.ecr.us-east-1.amazonaws.com -WARNING: Using --password via the CLI is insecure. Use --password-stdin. -Login Succeeded - -Pulled: .dkr.ecr.us-east-1.amazonaws.com/datree/datree-free-admission-webhook-awsmp:1.0.1-rc.1 -Digest: sha256:ca9bb6e5063f4065d5883756ce062add8585110f2dd4c16507ac08f4cf63f950 - -Helm Chart Pull is Successful! -No occurrences of .Capabilities or helm.sh/hook found in Helm chart -Function done -Cloning into '.'... -Already on 'main' -error: branch 'feature/datree' not found. -Switched to a new branch 'feature/datree' -remote: -remote: Create a pull request for 'feature/datree' on GitHub by visiting: -remote: https://github.com/elamaran11/aws-sleek-transformer/pull/new/feature/datree -remote: -To https://github.com/elamaran11/aws-sleek-transformer.git - * [new branch] feature/datree -> feature/datree +USAGE + $ aws-sleek-transformer validate [--addonName ] [--addonVersion ] + +FLAGS + --addonName= Name of the addon to validate + --addonVersion= Version of the addon to validate + +DESCRIPTION + Validates a given addon from the configuration provided through the 'configure' command + + + This performs pre-launch validations of the partner software on compatibility with Sleek guidelines, covering static + and dynamic (deployment/runtime) aspects. + + Runs the static analysis to find occurrences of: + * .Capabilities + * helm.sh/hook + + This command requires the "configure" command to have been run, it needs: + * Helm URL + * Namespace + to be configured correctly. + + It will perform a static validation on the device and then give you the option to submit it to the marketplace for + runtime and further validation before it can be included in the EKS Console marketplace. + + +EXAMPLES + $ aws-sleek-transformer validate ``` +_See code: [src/commands/validate.ts](https://github.com/elaramas/aws-sleek-transformer/blob/v0.0.0/src/commands/validate.ts)_ + diff --git a/bin/dev.cmd b/bin/dev.cmd new file mode 100644 index 0000000..cec553b --- /dev/null +++ b/bin/dev.cmd @@ -0,0 +1,3 @@ +@echo off + +node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %* diff --git a/bin/dev.js b/bin/dev.js new file mode 100755 index 0000000..6dfeff7 --- /dev/null +++ b/bin/dev.js @@ -0,0 +1,9 @@ +#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning + +// eslint-disable-next-line node/shebang +async function main() { + const {execute} = await import('@oclif/core') + await execute({development: true, dir: import.meta.url}) +} + +await main() diff --git a/bin/run.cmd b/bin/run.cmd new file mode 100644 index 0000000..968fc30 --- /dev/null +++ b/bin/run.cmd @@ -0,0 +1,3 @@ +@echo off + +node "%~dp0\run" %* diff --git a/bin/run.js b/bin/run.js new file mode 100755 index 0000000..58ca6bf --- /dev/null +++ b/bin/run.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +async function main() { + const {execute} = await import('@oclif/core') + await execute({dir: import.meta.url}) +} + +await main() diff --git a/package.json b/package.json index 3137241..77c7639 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,77 @@ { - "name": "aws-sleek-transformer", - "version": "0.2", - "main": "src/index.ts", - "type": "module", - "bin": "src/index.ts", + "author": "Shardul Vaidya @5herlocked", + "bin": { + "aws-sleek-transformer": "./bin/run.js" + }, "dependencies": { - "@octokit/rest": "^19.0.7", - "@types/node": "^20.10.0", - "aws-sdk": "^2.1351.0", - "child_process": "^1.0.2", - "inquirer": "^9.1.5", - "readline": "^1.3.0", - "typescript": "^5.3.2" + "@oclif/core": "^3", + "@oclif/plugin-help": "^5", + "@oclif/plugin-plugins": "^4", + "aws-sdk": "^2.1351.0" }, + "description": "Sleek Marketplace validator is solution provide pre-launch validations of the partner software on compatibility with Sleek guidelines, covering static and dynamic (deployment/runtime) aspects.", "devDependencies": { - "@types/inquirer": "^9.0.7" - } + "@oclif/prettier-config": "^0.2.1", + "@oclif/test": "^3", + "@types/chai": "^4", + "@types/mocha": "^10", + "@types/node": "^18", + "chai": "^4", + "eslint": "^8", + "eslint-config-oclif": "^5", + "eslint-config-oclif-typescript": "^3", + "eslint-config-prettier": "^9.0.0", + "mocha": "^10", + "oclif": "^4.0.3", + "shx": "^0.3.4", + "ts-node": "^10.9.1", + "typescript": "^5" + }, + "engines": { + "node": ">=18.0.0" + }, + "files": [ + "/bin", + "/dist", + "/oclif.manifest.json" + ], + "homepage": "https://github.com/elaramas/aws-sleek-transformer", + "main": "", + "name": "aws-sleek-transformer", + "oclif": { + "bin": "aws-sleek-transformer", + "dirname": "aws-sleek-transformer", + "commands": "./dist/commands", + "topicSeparator": " ", + "topics": { + "configure": { + "description": "Sets up the Sleek CLI to work with a given helm chart" + }, + "validate": { + "description": "Validates the addons you want to validate" + }, + "submit": { + "description": "Submits the addons to the marketplace team to place in the EKS console marketplace" + } + } + }, + "repository": "elaramas/aws-sleek-transformer", + "scripts": { + "build": "shx rm -rf dist && tsc -b", + "lint": "eslint . --ext .ts", + "postpack": "shx rm -f oclif.manifest.json", + "posttest": "npm run lint", + "prepack": "npm run build && oclif manifest && oclif readme", + "prepare": "npm run build", + "test": "mocha --forbid-only \"test/**/*.test.ts\"", + "version": "oclif readme && git add README.md" + }, + "version": "0.0.0", + "bugs": "https://github.com/elaramas/aws-sleek-transformer/issues", + "keywords": [ + "oclif" + ], + "types": "dist/index.d.ts", + "exports": "./lib/index.js", + "type": "module" } diff --git a/src/commands/configure.ts b/src/commands/configure.ts new file mode 100644 index 0000000..533de07 --- /dev/null +++ b/src/commands/configure.ts @@ -0,0 +1,53 @@ +import { Command, Flags } from '@oclif/core'; + +export default class Configure extends Command { + + static description = ` + Extracts information from the environment to populate information required for the Sleek CLI to function. If + certain information is not found, prompts the user for it and asks them to validate the information extracted from + the environment. + + This information is stored ~/.sleek/config.json + + The CLI requires the following: + * AWS Region - can be extracted from the env + * Marketplace AWS Account ID - can be extracted from the env + * Addon Name - requires user input + * Addon Version - requires user input + * Addon Helm Url - requires user input + * Deployment Namespace - requires user input + + Each of these can be passed as flags to this command with the following flags: + * --region + * --marketplace_id + * --addon_name + * --addon_version + * --helm_url + * --namespace + ` + + static examples = [ + '<%= config.bin %> <%= command.id %>', + ] + + static flags = { + addonName: Flags.string({description: 'Name of the addon'}), + addonVersion: Flags.string({description: 'Version of the addon'}), + helmUrl: Flags.string({description: 'Helm URL of the addon'}), + marketplaceId: Flags.string({description: 'Marketplace AWS Account ID'}), + namespace: Flags.string({description: 'Namespace of the addon'}), + region: Flags.string({description: 'AWS Region'}), + } + + static summary = "Sets up the Sleek CLI to work with a given helm chart" + + public async run(): Promise { + const {args, flags} = await this.parse(Configure) + + const name = flags.name ?? 'world' + this.log(`hello ${name} from /Users/vshardul/source/aws-sleek-transformer-refactor/src/commands/configure.ts`) + if (args.file && flags.force) { + this.log(`you input --force and --file: ${args.file}`) + } + } +} diff --git a/src/commands/submit.ts b/src/commands/submit.ts new file mode 100644 index 0000000..2c0079a --- /dev/null +++ b/src/commands/submit.ts @@ -0,0 +1,42 @@ +import { Command, Flags } from '@oclif/core' + +export default class Submit extends Command { + + static description = ` + Sends the selected addon, version to the marketplace for final submission and upload it to Project Sleek. + + It reads from the addons stored in the config: ~/.sleek/config.json and presents them as options to the user to + submit. + + The CLI requires the configure command to be run before hand to ensure there are correct configurations for each of + the addons. + + This command requires the following: + * Addon Name - as used in the configure command + * Addon Version - as used in the configure command + + If no flags are provided, the CLI will launch an interactive menu which let's you select which addon to submit to + the marketplace. + ` + + static examples = [ + '<%= config.bin %> <%= command.id %>', + ] + + static flags = { + addonName: Flags.string({description: "Name of the addon to submit"}), + addonVersion: Flags.string({description: "Version of the addon to submit"}), + } + + static summary = "Uses the pre-existing configurations to submit the addon to the AWS marketplace" + + public async run(): Promise { + const {args, flags} = await this.parse(Submit) + + const name = flags.name ?? 'world' + this.log(`hello ${name} from /Users/vshardul/source/aws-sleek-transformer-refactor/src/commands/submit.ts`) + if (args.file && flags.force) { + this.log(`you input --force and --file: ${args.file}`) + } + } +} diff --git a/src/commands/validate.ts b/src/commands/validate.ts new file mode 100644 index 0000000..8b6ac37 --- /dev/null +++ b/src/commands/validate.ts @@ -0,0 +1,41 @@ +import { Command, Flags } from '@oclif/core' + +export default class Validate extends Command { + static description = ` + This performs pre-launch validations of the partner software on compatibility with Sleek guidelines, covering static + and dynamic (deployment/runtime) aspects. + + Runs the static analysis to find occurrences of: + * .Capabilities + * helm.sh/hook + + This command requires the "configure" command to have been run, it needs: + * Helm URL + * Namespace + to be configured correctly. + + It will perform a static validation on the device and then give you the option to submit it to the marketplace for + runtime and further validation before it can be included in the EKS Console marketplace. + ` + + static examples = [ + '<%= config.bin %> <%= command.id %>', + ] + + static flags = { + addonName: Flags.string({description: "Name of the addon to validate"}), + addonVersion: Flags.string({description: "Version of the addon to validate"}), + } + + static summary = "Validates a given addon from the configuration provided through the 'configure' command"; + + public async run(): Promise { + const {args, flags} = await this.parse(Validate) + + const name = flags.name ?? 'world' + this.log(`hello ${name} from /Users/vshardul/source/aws-sleek-transformer-refactor/src/commands/validate.ts`) + if (args.file && flags.force) { + this.log(`you input --force and --file: ${args.file}`) + } + } +} diff --git a/src/index.ts b/src/index.ts old mode 100755 new mode 100644 index b4f9ef4..21c366d --- a/src/index.ts +++ b/src/index.ts @@ -1,67 +1 @@ -#!/usr/bin/env node -/***************************************************************/ -/* Grab imports of internal modules used */ -/***************************************************************/ -import checkAndInstallDependencies from './modules/installDependencies'; -import getUserInputs from "./modules/getUserInputs"; -import validateUserInputs from "./modules/validateUserInputs"; -import pullHelmChartAndValidate from "./modules/pullHelmChartAndValidate"; - -/***************************************************************/ -/* We will install following dependencies to the terminal : */ -/* 1. kubectl */ -/* 2. eksctl */ -/* 3. helm */ -/***************************************************************/ -try { - await checkAndInstallDependencies(); -} catch (error) { - console.error(error.message); - process.exit(100); -} - -/***************************************************************/ -/* We will now grab following inputs from the terminal */ -/* 1. What's your Addon Name? */ -/* 2. Whats your Helm URL of the Addon? */ -/* 3. Whats your Addon Version? */ -/* 4. Whats your deployment namespace? */ -/* 5. Whats your AWS Account id? */ -/* 6. Whats your AWS Region ? */ -/***************************************************************/ -let inputParameters = await getUserInputs(); - -/***************************************************************/ -/* We will now validate the inputs from the user */ -/***************************************************************/ -try { - validateUserInputs(inputParameters); - console.log('All User Inputs are Valid!'); -} catch (error) { - console.error(error.message); - process.exit(200); -} - -/***************************************************************/ -/* We will now do the following: */ -/* 1. Authenticate user to ECR Repo */ -/* 2. Pull and Untar the Helm chart from ECR */ -/* 3. Perform static validations to find occurences of : */ -/* a. `.Capabilities` */ -/* b. `helm.sh/hook` */ -/***************************************************************/ -try { - await pullHelmChartAndValidate(inputParameters); - - console.log("Validations successful"); -} catch (error) { - console.error(error.message); - process.exit(300); -} - - - - - - - +export {run} from '@oclif/core'; \ No newline at end of file diff --git a/src/index.ts.bak b/src/index.ts.bak new file mode 100755 index 0000000..fc4e603 --- /dev/null +++ b/src/index.ts.bak @@ -0,0 +1,67 @@ +#!/usr/bin/env node +/***************************************************************/ +/* Grab imports of internal modules used */ +/***************************************************************/ +import checkAndInstallDependencies from './modules/installDependencies.js'; +import getUserInputs from "./modules/getUserInputs.js"; +import validateUserInputs from "./modules/validateUserInputs.js"; +import pullHelmChartAndValidate from "./modules/pullHelmChartAndValidate.js"; + +/***************************************************************/ +/* We will install following dependencies to the terminal : */ +/* 1. kubectl */ +/* 2. eksctl */ +/* 3. helm */ +/***************************************************************/ +try { + await checkAndInstallDependencies(); +} catch (error) { + console.error(error.message); + process.exit(100); +} + +/***************************************************************/ +/* We will now grab following inputs from the terminal */ +/* 1. What's your Addon Name? */ +/* 2. Whats your Helm URL of the Addon? */ +/* 3. Whats your Addon Version? */ +/* 4. Whats your deployment namespace? */ +/* 5. Whats your AWS Account id? */ +/* 6. Whats your AWS Region ? */ +/***************************************************************/ +let inputParameters = await getUserInputs(); + +/***************************************************************/ +/* We will now validate the inputs from the user */ +/***************************************************************/ +try { + validateUserInputs(inputParameters); + console.log('All User Inputs are Valid!'); +} catch (error) { + console.error(error.message); + process.exit(200); +} + +/***************************************************************/ +/* We will now do the following: */ +/* 1. Authenticate user to ECR Repo */ +/* 2. Pull and Untar the Helm chart from ECR */ +/* 3. Perform static validations to find occurences of : */ +/* a. `.Capabilities` */ +/* b. `helm.sh/hook` */ +/***************************************************************/ +try { + await pullHelmChartAndValidate(inputParameters); + + console.log("Validations successful"); +} catch (error) { + console.error(error.message); + process.exit(300); +} + + + + + + + diff --git a/src/modules/getUserInputs.ts b/src/modules/getUserInputs.js similarity index 100% rename from src/modules/getUserInputs.ts rename to src/modules/getUserInputs.js diff --git a/src/modules/installDependencies.ts b/src/modules/installDependencies.js similarity index 100% rename from src/modules/installDependencies.ts rename to src/modules/installDependencies.js diff --git a/src/modules/installEksctl.ts b/src/modules/installEksctl.js similarity index 100% rename from src/modules/installEksctl.ts rename to src/modules/installEksctl.js diff --git a/src/modules/installHelm.ts b/src/modules/installHelm.js similarity index 100% rename from src/modules/installHelm.ts rename to src/modules/installHelm.js diff --git a/src/modules/installKubectl.ts b/src/modules/installKubectl.js similarity index 100% rename from src/modules/installKubectl.ts rename to src/modules/installKubectl.js diff --git a/src/modules/pullHelmChartAndValidate.ts b/src/modules/pullHelmChartAndValidate.js similarity index 100% rename from src/modules/pullHelmChartAndValidate.ts rename to src/modules/pullHelmChartAndValidate.js diff --git a/src/modules/validateUserInputs.ts b/src/modules/validateUserInputs.js similarity index 100% rename from src/modules/validateUserInputs.ts rename to src/modules/validateUserInputs.js diff --git a/test/commands/configure.test.ts b/test/commands/configure.test.ts new file mode 100644 index 0000000..5f6d09d --- /dev/null +++ b/test/commands/configure.test.ts @@ -0,0 +1,17 @@ +import {expect, test} from '@oclif/test' + +describe('configure', () => { + test + .stdout() + .command(['configure']) + .it('runs hello', ctx => { + expect(ctx.stdout).to.contain('hello world') + }) + + test + .stdout() + .command(['configure', '--name', 'jeff']) + .it('runs hello --name jeff', ctx => { + expect(ctx.stdout).to.contain('hello jeff') + }) +}) diff --git a/test/commands/hello/index.test.ts b/test/commands/hello/index.test.ts new file mode 100644 index 0000000..f4e5ebe --- /dev/null +++ b/test/commands/hello/index.test.ts @@ -0,0 +1,10 @@ +import {expect, test} from '@oclif/test' + +describe('hello', () => { + test + .stdout() + .command(['hello', 'friend', '--from=oclif']) + .it('runs hello cmd', ctx => { + expect(ctx.stdout).to.contain('hello friend from oclif!') + }) +}) diff --git a/test/commands/hello/world.test.ts b/test/commands/hello/world.test.ts new file mode 100644 index 0000000..8096cba --- /dev/null +++ b/test/commands/hello/world.test.ts @@ -0,0 +1,10 @@ +import {expect, test} from '@oclif/test' + +describe('hello world', () => { + test + .stdout() + .command(['hello:world']) + .it('runs hello world cmd', ctx => { + expect(ctx.stdout).to.contain('hello world!') + }) +}) diff --git a/test/commands/submit.test.ts b/test/commands/submit.test.ts new file mode 100644 index 0000000..b4d1e0b --- /dev/null +++ b/test/commands/submit.test.ts @@ -0,0 +1,17 @@ +import {expect, test} from '@oclif/test' + +describe('submit', () => { + test + .stdout() + .command(['submit']) + .it('runs hello', ctx => { + expect(ctx.stdout).to.contain('hello world') + }) + + test + .stdout() + .command(['submit', '--name', 'jeff']) + .it('runs hello --name jeff', ctx => { + expect(ctx.stdout).to.contain('hello jeff') + }) +}) diff --git a/test/commands/validate.test.ts b/test/commands/validate.test.ts new file mode 100644 index 0000000..f1cbce4 --- /dev/null +++ b/test/commands/validate.test.ts @@ -0,0 +1,17 @@ +import {expect, test} from '@oclif/test' + +describe('validate', () => { + test + .stdout() + .command(['validate']) + .it('runs hello', ctx => { + expect(ctx.stdout).to.contain('hello world') + }) + + test + .stdout() + .command(['validate', '--name', 'jeff']) + .it('runs hello --name jeff', ctx => { + expect(ctx.stdout).to.contain('hello jeff') + }) +}) diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..95898fc --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "noEmit": true + }, + "references": [ + {"path": ".."} + ] +} diff --git a/tsconfig.json b/tsconfig.json index 7bb5eee..e144b78 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,15 @@ { "compilerOptions": { - "module": "node16", - "outDir": "./built", - "allowJs": true, - "target": "es2022" + "declaration": true, + "module": "Node16", + "outDir": "dist", + "rootDir": "src", + "strict": true, + "target": "es2022", + "moduleResolution": "node16" }, - "include": ["./src/**/*"] -} \ No newline at end of file + "include": ["./src/**/*"], + "ts-node": { + "esm": true + } +}