Skip to content

Commit

Permalink
Feature/release 0.5.0 (#95)
Browse files Browse the repository at this point in the history
* feat: Add tutorial links directly in README. (#52)

* feat: Add tutorial links directly in README.

* And removed GitOps section, which is not supported yet.

* Update README.md

* Update README.md

Added a different caption

* feat: Avoid cli setup checks when not required (#68)

* feat: Avoid cli setup checks when not required

In order to optimize startup time, especially when only issuing a non
cloud-cli required command, collie now only checks cloud cli configuration
when required.

* fix: setup logger before running commands and await it

not awaiting the logger configuration can cause loosing logs

* feat: run cli checks concurrently

see discussion in #68

* feat: add debug logs to ShellRunner for every command

* style: deno fmt

Co-authored-by: Johannes Rudolph <[email protected]>

* Feature/issue 56 (#71)

* feat: detect installed cli versions match expectations

if not, give installation hints via collie readme.

fixes #56

* fix: handle GCP projects with empty IAM policies (#80)

fixes #67

* fix: use azure subscription id instead of name to prevent word-splitting (#79)

fixes #76

* Feature/cache statistics (#78)

* refactor: generate entries summary generically for all platforms

* feat: add query statistics to tty table output

This lets users know whether results are served from cache or
if they're queried from the cloud. At the moment only "tenant list"
command supports this.

Fixes #72

* feat: add query statistics to all tenant commands

Fixes #72

* refactor: extract QueryStatistics class into its own module

* test: add a tests for query statistics

* feat: slightly tweak the query stats message.

* feat: correctly print cache and cloud query statistics for hybrid query

hybrid queries can occur when e.g. running
- collie tenant list -> partially fills the tenant cache
- collie tenant iam -> uses tenants from cache, adds IAM info

* refactor: Uses OOP patterns

Simplifies the statistics decorator to be less intrusive.

Co-authored-by: Thomas Felix <[email protected]>

* Update issue templates

* Update issue templates

* fix: Spinner animation overwrites error message (#85)

Improves the spinner animation termination to avoid part of the error message
writing into the spinner animation text.

* feat: Tags are shown in table cost view (#90)

* fix: Fix costs / IAM missing in cached tenants. (#91)

* Feature/add windows support (#87)

* feat: add windows support for collie

* feat: add windows binary to releases

* fix: differentiation in posix and win32 path

* fix: Replaces var with let

* Fixed issue found while testing Windows

* Added global `isWindows` var for consistency

Co-authored-by: Thomas Felix <[email protected]>
Co-authored-by: Jelle den Burger <[email protected]>

* Bump version to 0.5.0

Co-authored-by: Thomas Felix <[email protected]>
Co-authored-by: Johannes Rudolph <[email protected]>
Co-authored-by: Thomas Felix <[email protected]>
Co-authored-by: Dennis Murtic <[email protected]>
  • Loading branch information
5 people committed Jul 30, 2021
1 parent f46fa55 commit b40427d
Show file tree
Hide file tree
Showing 47 changed files with 562 additions and 141 deletions.
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Bug report
about: Create a bug report to help us improve Collie CLI
title: ''
labels: bug
assignees: Jelledb, tfelix

---

**Describe the bug**
A clear and concise description of what the bug is.

**Reach of the bug**
Who is impacted by the bug? All users of Collie? Only a subset, e.g. only AWS users?

**Impact of the bug**
What is the bug preventing users from doing? How are they impacted?

**To Reproduce**
Steps to reproduce the behavior:
1. Run `az logout`.
2. Run `collie tenant list`.
3. An error is thrown.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. Mac OS X]
- Version [e.g. v0.4.0]

(optional) **Implementation Hints**
Do you have any ideas on how to solve the problem? A particular code file to check out? A solution pattern proposal?
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Feature request
about: Suggest an idea that can improve Collie CLI
title: ''
labels: idea
assignees: Jelledb, tfelix

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Reach of the feature request**
Who else has this problem?

**Impact of the feature request**
What are you (and others) not able to do? How are you impacted by the problem?

**How would a solution look like?**
What do you expect the solution to be to solve your problem? (attaching mockups or prototypes is helpful!)

(optional) **Implementation Hints**
Any hints that could help implementation?
4 changes: 1 addition & 3 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ curl -sf -L https://raw.githubusercontent.com/meshcloud/collie-cli/main/install.

**Windows**

We sadly do not support Windows at the moment. Follow
[this issue](https://github.com/meshcloud/collie-cli/issues/2) to get updated on
the progress of Collie for Windows.
Simply copy the content of [`install.ps1`](https://github.com/meshcloud/collie-cli/blob/develop/install.ps1) and run it in your PowerShell console.

## 👋 Need help or have feedback?

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ jobs:
with:
name: collie
path: |
bin/collie-*
bin/**/collie-*
14 changes: 8 additions & 6 deletions .github/workflows/releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ jobs:
event: push
path: bin/

- name: zip-artifacts
- name: preparing-artifacts
shell: bash
run: |
mkdir bin/gz
cd bin/collie
tar -czvf ../gz/collie-x86_64-apple-darwin.tar.gz collie-x86_64-apple-darwin
tar -czvf ../gz/collie-x86_64-unknown-linux-gnu.tar.gz collie-x86_64-unknown-linux-gnu
mkdir bin/artifacts
cd bin/collie/unix
tar -czvf ../../artifacts/collie-x86_64-apple-darwin.tar.gz collie-x86_64-apple-darwin
tar -czvf ../../artifacts/collie-x86_64-unknown-linux-gnu.tar.gz collie-x86_64-unknown-linux-gnu
cd ../../..
cp -a bin/collie/windows/. bin/artifacts
- name: build-changelog
id: build_changelog
Expand All @@ -75,7 +77,7 @@ jobs:
- name: create-release
uses: ncipollo/release-action@v1
with:
artifacts: bin/gz/*
artifacts: bin/artifacts/*
body: ${{ steps.github_release.outputs.changelog }}
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.version.outputs.version }}
Expand Down
26 changes: 12 additions & 14 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,23 @@ cli_name="collie"

deno_flags="--unstable --allow-read --allow-write --allow-env --allow-run"

mkdir -p bin
mkdir -p bin/unix bin/windows

compile(){
compile_unix(){
target="$1"

deno compile $deno_flags --target "$target" --output "./bin/$cli_name-$target" src/main.ts
deno compile $deno_flags --target "$target" --output "./bin/unix/$cli_name-$target" src/main.ts
}

deno test $deno_flags
compile_windows(){
target="$1"

compile "x86_64-unknown-linux-gnu"
compile "x86_64-apple-darwin"
#compile "x86_64-pc-windows-msvc"
deno compile $deno_flags --target "$target" --output "./bin/windows/$cli_name-$target" src/main.ts
}

# first grep filters for the first line of the output "deno 1.8.1 (release, x86_64-apple-darwin)"
# second grep extracts the architecture string, but can't get rid of the trailing ): "x86_64-apple-darwin)"
# sed then removes the last trailing character: "x86_64-apple-darwin"
arch=$(deno --version | grep deno | grep -o "[a-z0-9_-]*)" | sed 's/.$//')
deno test $deno_flags

echo "currently running on $arch, creating symlink at ./bin/$cli_name"
ln -fs "./$cli_name-$arch" "./bin/$cli_name"
chmod +x "./bin/$cli_name"
compile_unix "x86_64-unknown-linux-gnu"
compile_unix "x86_64-apple-darwin"
compile_windows "x86_64-pc-windows-msvc"
6 changes: 6 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$url=(Invoke-WebRequest -Uri https://api.github.com/repos/meshcloud/collie-cli/releases/latest | Select-String -Pattern '.*\"browser_download_url\":\"(.*windows-msvc.exe).*' | ForEach-Object {($_.matches.groups[1]).Value})

New-Item -ItemType directory -Path "${HOME}\collie-cli"
Invoke-WebRequest -Uri $url -OutFile "${HOME}\collie-cli\collie"

Write-Host "Please add ${HOME}\collie-cli\ to your path environemnt variable."
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ case "$(uname -s)" in
name="collie-x86_64-unknown-linux-gnu"
;;
CYGWIN*|MINGW32*|MSYS*|MINGW*)
echo 'Collie currently does not support Windows. Please have a look at https://github.com/meshcloud/collie-cli/issues/2 to follow progress.'
echo 'Please execute the install.ps1 script as mentioned in our README. Go to https://github.com/meshcloud/collie-cli#-install-and-usage'
exit 1
;;
*)
Expand Down
4 changes: 2 additions & 2 deletions src/aws/aws-mesh-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export class AwsMeshAdapter implements MeshAdapter {

const costItem: MeshTenantCost = {
currency: "",
from: from.toDate().toUTCString(),
to: to.toDate().toUTCString(),
from: from.toDate(),
to: to.toDate(),
cost: "0",
details: [],
};
Expand Down
8 changes: 4 additions & 4 deletions src/azure/azure-mesh-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ export class AzureMeshAdapter implements MeshAdapter {
t.costs.push({
currency: currencySymbol,
cost: summedCost.toString(),
from: startDate.toUTCString(),
to: endDate.toUTCString(),
from: startDate,
to: endDate,
details: [],
});
}
Expand Down Expand Up @@ -201,8 +201,8 @@ export class AzureMeshAdapter implements MeshAdapter {
currency: currencySymbol,
cost: totalUsagePretaxCost.toFixed(2),
details: [], // Can hold daily usages
from: timeWindow.from.toUTCString(),
to: timeWindow.to.toUTCString(),
from: timeWindow.from,
to: timeWindow.to,
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/azure/basic-azure-cli-facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class BasicAzureCliFacade implements AzureCliFacade {
subscription: Subscription,
): Promise<RoleAssignment[]> {
const cmd =
`az role assignment list --subscription ${subscription.name} --include-inherited --all --output json`;
`az role assignment list --subscription ${subscription.id} --include-inherited --all --output json`;

const result = await this.shellRunner.run(cmd);
this.checkForErrors(result);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/config.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,5 @@ function showConfig() {
// that would be a bit overengineering.
const tableFactory = new MeshTableFactory(isatty);
const meshTable = tableFactory.buildMeshTable();
meshTable.draw(viewGenerator);
meshTable.draw(viewGenerator, null);
}
7 changes: 6 additions & 1 deletion src/commands/init-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import { registerTenantCommand } from "./tenant.command.ts";
import { CLICommand, CLIName } from "../config/config.model.ts";
import { registerCreateIssueCommand } from "./create-issue.command.ts";
import { VERSION } from "../config/version.ts";
import { isWindows } from "../os.ts";

export function initCommands(): Command {
const program = new Command()
.name(CLICommand)
.help({
// The darkblue of Cliffy doesn't look great on the blue of PowerShell.
colors: !isWindows,
})
.version(VERSION)
.type("output", OutputFormatType)
.option(
Expand All @@ -34,7 +39,7 @@ export function initCommands(): Command {
global: true,
},
)
.description(`${CLIName} CLI - Herd your cloud 🐑 environments with Collie`);
.description(`${CLIName} CLI - Herd your cloud environments with Collie`);

registerConfigCmd(program);
registerTenantCommand(program);
Expand Down
11 changes: 0 additions & 11 deletions src/commands/io.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { readLines } from "../deps.ts";

export function writeFile(path: string, text: string) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
Expand All @@ -10,12 +8,3 @@ export function readFile(path: string): string {
const decoder = new TextDecoder();
return decoder.decode(Deno.readFileSync(path));
}

export async function askYesNo(question: string): Promise<boolean> {
console.log(`${question} [y,N]:`);

for await (const line of readLines(Deno.stdin)) {
return line.toLowerCase() === "y";
}
return false;
}
39 changes: 32 additions & 7 deletions src/commands/tenant.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { CLICommand, loadConfig } from "../config/config.model.ts";
import { isatty } from "./tty.ts";
import { MeshTableFactory } from "../presentation/mesh-table-factory.ts";
import { verifyCliAvailability } from "../init.ts";
import { QueryStatistics } from "../mesh/query-statistics.ts";
import { MeshError } from "../errors.ts";

interface CmdListCostsOptions extends CmdGlobalOptions {
from: string;
Expand Down Expand Up @@ -117,14 +119,21 @@ async function listTenantAction(options: CmdGlobalOptions) {

const config = loadConfig();
const meshAdapterFactory = new MeshAdapterFactory(config);
const meshAdapter = meshAdapterFactory.buildMeshAdapter(options);
const queryStatistics = new QueryStatistics();
const meshAdapter = meshAdapterFactory.buildMeshAdapter(
options,
queryStatistics,
);

const allTenants = await meshAdapter.getMeshTenants();

const tableFactory = new MeshTableFactory(isatty);

const presenterFactory = new TenantListPresenterFactory(tableFactory);
const presenter = presenterFactory.buildPresenter(
options.output,
allTenants,
queryStatistics,
);
presenter.present();
}
Expand All @@ -136,7 +145,10 @@ async function listIamAction(options: CmdIamOptions) {
const config = loadConfig();
const meshAdapterFactory = new MeshAdapterFactory(config);
const meshAdapter = meshAdapterFactory.buildMeshAdapter(options);

const stats = new QueryStatistics();
const allTenants = await meshAdapter.getMeshTenants();

await meshAdapter.attachTenantRoleAssignments(allTenants);

const tableFactory = new MeshTableFactory(isatty);
Expand All @@ -146,6 +158,7 @@ async function listIamAction(options: CmdIamOptions) {
options.output,
options.includeAncestors,
allTenants,
stats,
)
.present();
}
Expand All @@ -156,28 +169,39 @@ export async function listTenantsCostAction(options: CmdListCostsOptions) {

const config = loadConfig();
const meshAdapterFactory = new MeshAdapterFactory(config);
const meshAdapter = meshAdapterFactory.buildMeshAdapter(options);
const queryStatistics = new QueryStatistics();
const meshAdapter = meshAdapterFactory.buildMeshAdapter(
options,
queryStatistics,
);

// We create UTC dates because we do not work with time, hence we do not care about timezones.
const start = moment.utc(options.from).startOf("day").toDate();
if (isNaN(start.valueOf())) {
throw new MeshError(
`You have entered an invalid date for '--from': ${options.from}`,
);
}
const end = moment.utc(options.to).endOf("day").toDate();
if (isNaN(start.valueOf())) {
throw new MeshError(
`You have entered an invalid date for '--to': ${options.to}`,
);
}

// Every of these methods can throw e.g. because a CLI tool was not installed we should think about
// how to do error management to improve UX.
const allTenants = await meshAdapter.getMeshTenants();

await meshAdapter.attachTenantCosts(
allTenants,
start,
end,
);
await meshAdapter.attachTenantCosts(allTenants, start, end);

const tableFactory = new MeshTableFactory(isatty);
const presenterFactory = new TenantUsagePresenterFactory(tableFactory);
// FIXME this now poses a problem. The presenter must only display the asked time range from the exisiting costs.
const presenter = presenterFactory.buildPresenter(
options.output,
allTenants,
queryStatistics,
);
presenter.present();
}
Expand All @@ -204,6 +228,7 @@ async function analyzeTagsAction(options: CmdAnalyzeTagsOptions) {
];
}

// todo: this does not follow the presenter pattern we usually use
const totalTenantCount = allTenants.length;
const result: AnalyzeTagResult[] = [];
console.log(`We analyzed ${totalTenantCount} tenants for tags.`);
Expand Down
14 changes: 9 additions & 5 deletions src/config/config.model.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { readFile, writeFile } from "../commands/io.ts";
import { dirname, ensureDir, os } from "../deps.ts";
import { dirname, ensureDir, join } from "../deps.ts";
import { parseJsonWithLog } from "../json.ts";
import { isWindows } from "../os.ts";

export const configPath = getConfigPath();
export const configFilePath = configPath + "/config.json";
export const configFilePath = join(configPath, "config.json");
// Use the CLI Name when mentioning it somewhere in a sentence, e.g.: Have fun using ${CLIName}!
export const CLIName = "Collie";
// Use the CLI Command when mentioning it as a command to run, e.g.: Please run "${CLICommand} -h" to see more.
Expand Down Expand Up @@ -50,11 +51,14 @@ export const emptyConfig: Config = {
};

function getConfigPath(): string {
if (os.default.platform() === "windows") {
return Deno.env.get("%APPDATA%") + "/.config/collie-cli";
const path = join(".config", "collie-cli");
let home = "";
if (isWindows) {
home = Deno.env.get("APPDATA") || "";
} else {
return Deno.env.get("HOME") + "/.config/collie-cli";
home = Deno.env.get("HOME") || "";
}
return join(home, path);
}

export function loadConfig(): Config {
Expand Down
2 changes: 1 addition & 1 deletion src/config/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = "0.4.0";
export const VERSION = "0.5.0";
Loading

0 comments on commit b40427d

Please sign in to comment.