Skip to content

Commit

Permalink
multiple aws accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
mlabouardy committed May 30, 2019
1 parent 458468f commit 96987c7
Show file tree
Hide file tree
Showing 81 changed files with 4,043 additions and 445 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ jobs:
chmod +x komiser_windows_amd64.exe komiser_darwin_amd64 komiser_linux_amd64
- run:
name: Push Linux binary
command: aws s3 cp komiser_linux_amd64 s3://komiser/2.1.0/linux/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
command: aws s3 cp komiser_linux_amd64 s3://komiser/2.2.0/linux/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
- run:
name: Push Windows binary
command: aws s3 cp komiser_windows_amd64.exe s3://komiser/2.1.0/windows/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
command: aws s3 cp komiser_windows_amd64.exe s3://komiser/2.2.0/windows/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
- run:
name: Push Mac OS X binary
command: aws s3 cp komiser_darwin_amd64 s3://komiser/2.1.0/osx/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
command: aws s3 cp komiser_darwin_amd64 s3://komiser/2.2.0/osx/komiser --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
- run:
name: Upload IAM policy
command: aws s3 cp policy.json s3://komiser/policy.json --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM alpine:3.9.4
MAINTAINER mlabouardy <mohamed@labouardy.com>

ENV VERSION 2.1.0
ENV VERSION 2.2.0
ENV PORT 3000
ENV DURATION 30

Expand All @@ -11,4 +11,4 @@ RUN curl -L https://s3.us-east-1.amazonaws.com/komiser/$VERSION/linux/komiser -o
mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

EXPOSE $PORT
ENTRYPOINT komiser start --port $PORT
ENTRYPOINT ["komiser", "start"]
43 changes: 38 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@ Stay under budget by uncovering hidden costs, monitoring increases in spend, and

## Download

Below are the available downloads for the latest version of Komiser (2.1.0). Please download the proper package for your operating system and architecture.
Below are the available downloads for the latest version of Komiser (2.2.0). Please download the proper package for your operating system and architecture.

### Linux:

```
wget https://cli.komiser.io/2.1.0/linux/komiser
wget https://cli.komiser.io/2.2.0/linux/komiser
```

### Windows:

```
wget https://cli.komiser.io/2.1.0/windows/komiser
wget https://cli.komiser.io/2.2.0/windows/komiser
```

### Mac OS X:

```
wget https://cli.komiser.io/2.1.0/osx/komiser
wget https://cli.komiser.io/2.2.0/osx/komiser
```

Docker for Mac is best installed with Homebrew:
Expand All @@ -60,7 +60,7 @@ _Note_: make sure to add the execution permission to Komiser `chmod +x komiser`
### Docker:

```
docker run -d -p 3000:3000 -e AWS_ACCESS_KEY_ID="" -e AWS_SECRET_ACCESS_KEY="" -e AWS_DEFAULT_REGION="" --name komiser mlabouardy/komiser:2.1.0
docker run -d -p 3000:3000 -e AWS_ACCESS_KEY_ID="" -e AWS_SECRET_ACCESS_KEY="" -e AWS_DEFAULT_REGION="" --name komiser mlabouardy/komiser:2.2.0
```

## How to use
Expand Down Expand Up @@ -100,6 +100,38 @@ komiser start --port 3000 --redis localhost:6379 --duration 30
<img src="https://s3.eu-west-3.amazonaws.com/komiser-assets/images/dashboard-aws.png"/>
</p>

#### Multiple AWS Accounts Support

Komiser support multiple AWS accounts through named profiles that are stored in the `config` and `credentials files`. You can configure additional profiles by using `aws configure` with the `--profile` option, or by adding entries to the `config` and `credentials` files.

The following example shows a credentials file with 3 profiles (production, staging & sandbox accounts):

```
[Production]
aws_access_key_id=<AWS_ACCESS_KEY_ID>
aws_secret_access_key=<AWS_SECRET_ACCESS_KEY>
[Staging]
aws_access_key_id=<AWS_ACCESS_KEY_ID>
aws_secret_access_key=<AWS_SECRET_ACCESS_KEY>
[Sandbox]
aws_access_key_id=<AWS_ACCESS_KEY_ID>
aws_secret_access_key=<AWS_SECRET_ACCESS_KEY>
```

To enable multiple AWS accounts feature, add the --multiple option to Komiser:

```
komiser start --port 3000 --redis localhost:6379 --duration 30 --multiple
```

* If you point your browser to http://localhost:3000, you should be able to see your accounts:

<p align="center">
<img src="https://s3.eu-west-3.amazonaws.com/komiser-assets/images/dashboard-aws-multiple.png"/>
</p>

### GCP

* Create a service account with *Viewer* permission, see [Creating and managing service accounts](https://cloud.google.com/iam/docs/creating-managing-service-accounts) docs.
Expand Down Expand Up @@ -153,6 +185,7 @@ komiser start [OPTIONS]
--duration value, -d value Cache expiration time (default: 30 minutes)
--redis value, -r value Redis server (localhost:6379)
--dataset value, -ds value BigQuery dataset name (project-id.dataset-name.table-name)
--multiple, -m Enable multiple AWS accounts feature
```

## Configuring Credentials
Expand Down
14 changes: 11 additions & 3 deletions dashboard/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
</div>
</li>
<li>
<a class="see-all" href="javascript:void(0);">
<a class="see-all" routerLink="/notifications">
<strong>See all notifications</strong>
<i class="la la-angle-right"></i>
</a>
Expand Down Expand Up @@ -138,11 +138,19 @@
bottom: 0vh;
display: block;
width: 100%;">
<label for="exampleFormControlSelect1">
<i class="la la-cloud" style="margin-left:10px"></i> Select Cloud Provider</label>
<label for="exampleFormControlSelect1" style="font-weight: 700">
<i class="la la-cloud" style="margin-left:10px;"></i> Cloud Provider: </label>
<select class="form-control" (change)="onCloudProviderSelected($event.target.value)">
<option *ngFor="let provider of availableProviders" [value]="provider.value" [selected]="provider.value == currentProvider.value">{{provider.label}}</option>
</select>
<div *ngIf="currentProvider.value == 'aws' && profiles.length > 1" style="margin-top:10px;">
<label for="exampleFormControlSelect1" style="font-weight: 700">
<i class="devicon-redhat-plain" style="margin-left:10px;"></i> AWS Account: </label>
<select class="form-control" (change)="onProfileSelected($event.target.value)">
<option *ngFor="let profile of profiles" [value]="profile" [selected]="profile == currentProfile">{{profile}}</option>
</select>
</div>

</div>

</div>
Expand Down
69 changes: 49 additions & 20 deletions dashboard/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { GcpService } from './gcp.service';
import { StoreService } from './store.service';
import { not } from '@angular/compiler/src/output/output_ast';
import { Subscription } from 'rxjs';
import { Subject } from "rxjs/Subject";
import * as moment from 'moment';

declare var ga: Function;
Expand All @@ -17,10 +18,12 @@ export class AppComponent implements OnDestroy {

public accountName: string = 'Username';
public redAlarms: number;
public profiles: Array<string> = [];
public currentProfile: string;
public notifications: Array<Object> = [];
public _subscription: Subscription;
public currentProvider: any;
public availableProviders : Array<any> = [
public availableProviders: Array<any> = [
{
label: 'Amazon Web Services',
value: 'aws'
Expand All @@ -29,13 +32,13 @@ export class AppComponent implements OnDestroy {
label: 'Google Cloud Platform',
value: 'gcp'
}
]
];

private _storeService: StoreService;

private providers: Map<String, Object> = new Map<String, Object>();

constructor(private awsService: AwsService, private gcpService: GcpService, private storeService: StoreService){
constructor(private awsService: AwsService, private gcpService: GcpService, private storeService: StoreService) {

this.providers['aws'] = {
label: 'Amazon Web Services',
Expand All @@ -49,6 +52,26 @@ export class AppComponent implements OnDestroy {
logo: 'https://cdn.komiser.io/images/gcp.png'
};

//if (this.storeService.getProvider() == 'aws') {
if (localStorage.getItem('profile')) {
this.currentProfile = localStorage.getItem('profile');
} else {
this.currentProfile = 'default';
localStorage.setItem('profile', this.currentProfile);
}

this.awsService.getProfiles().subscribe(profiles => {
this.profiles = profiles;
if (this.profiles.length > 0 && this.profiles.indexOf(this.currentProfile) == -1) {
this.currentProfile = this.profiles[0];
localStorage.setItem('profile', this.currentProfile);
}
}, err => {
this.profiles = [];
})
// }


this.currentProvider = this.providers[this.storeService.getProvider()];
this.storeService.onProviderChanged(this.storeService.getProvider());

Expand All @@ -64,22 +87,21 @@ export class AppComponent implements OnDestroy {
})
}

private getAccountName(){
console.log(this.currentProvider);
if (this.currentProvider.value == 'aws'){
private getAccountName() {
if (this.currentProvider.value == 'aws') {
this.awsService.getAccountName().subscribe(data => {
this.accountName = data.username;
}, err => {
this.accountName = 'Username';
});

this.awsService.getCloudwatchAlarms().subscribe(data => {
this.redAlarms = data.ALARM;
}, err => {
this.redAlarms = 0;
});
} else {
this.redAlarms = 0;
this.redAlarms = 0;

this.gcpService.getProjects().subscribe(data => {
this.accountName = data[0].name;
Expand All @@ -90,17 +112,24 @@ export class AppComponent implements OnDestroy {
}

ngOnDestroy() {
this._subscription.unsubscribe();
}

public calcMoment(timestamp){
return moment(timestamp).fromNow();
}

public onCloudProviderSelected(provider){
this.currentProvider = this.providers[provider];
this._storeService.onProviderChanged(provider);
this.getAccountName();
}
this._subscription.unsubscribe();
}

public calcMoment(timestamp) {
return moment(timestamp).fromNow();
}

public onCloudProviderSelected(provider) {
this.currentProvider = this.providers[provider];
this._storeService.onProviderChanged(provider);
this.getAccountName();
}

public onProfileSelected(profile) {
this.currentProfile = profile;
localStorage.setItem('profile', this.currentProfile);
this._storeService.onProfileChanged(profile);
this.getAccountName();
}

}
9 changes: 8 additions & 1 deletion dashboard/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { AwsLimitsComponent } from './limits/aws/aws.component';
import { GcpLimitsComponent } from './limits/gcp/gcp.component';
import { AwsProfileComponent } from './profile/aws/aws.component';
import { GcpProfileComponent } from './profile/gcp/gcp.component';
import { NotificationsComponent } from './notifications/notifications.component';



Expand Down Expand Up @@ -76,6 +77,11 @@ const appRoutes: Routes = [
component: LimitsComponent,
data: { title: 'Service Limits Checks - Komiser' }
},
{
path: 'notifications',
component: NotificationsComponent,
data: { title: 'Notifications - Komiser' }
},
{ path: '',
component: DashboardComponent,
data: { title: 'Dashboard - Komiser' }
Expand Down Expand Up @@ -108,7 +114,8 @@ const appRoutes: Routes = [
AwsLimitsComponent,
GcpLimitsComponent,
AwsProfileComponent,
GcpProfileComponent
GcpProfileComponent,
NotificationsComponent
],
imports: [
RouterModule.forRoot(
Expand Down
Loading

0 comments on commit 96987c7

Please sign in to comment.