Skip to content

Commit

Permalink
Merge pull request #3 from Microsoft/saw/wizard
Browse files Browse the repository at this point in the history
Add wizard and website creation code from vscode-azurewebservice
  • Loading branch information
StephenWeatherford authored Oct 24, 2017
2 parents d6273ff + ea09ef8 commit d65cc05
Show file tree
Hide file tree
Showing 9 changed files with 1,176 additions and 4 deletions.
7 changes: 4 additions & 3 deletions appservice/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vscode-azureappservice",
"author": "Microsoft Corporation",
"version": "0.1.1",
"version": "0.2.0",
"description": "Common tools for developing Azure App Service extensions for VS Code",
"tags": [
"azure",
Expand Down Expand Up @@ -40,9 +40,10 @@
"typescript": "^2.5.3",
"tslint": "^5.7.0",
"tslint-microsoft-contrib": "5.0.1",
"vscode": "^1.1.5"
"vscode": "^1.1.5",
"azure-arm-resource": "^2.0.0-preview"
},
"engines": {
"vscode": "^1.16.0"
}
}
}
725 changes: 725 additions & 0 deletions appservice/src/WebsiteCreatorBase.ts

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions appservice/src/azure-account.api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Event } from 'vscode';
import { ServiceClientCredentials } from 'ms-rest';
import { AzureEnvironment } from 'ms-rest-azure';
import { SubscriptionModels } from 'azure-arm-resource';

export type AzureLoginStatus = 'Initializing' | 'LoggingIn' | 'LoggedIn' | 'LoggedOut';

export interface AzureAccount {
readonly status: AzureLoginStatus;
readonly onStatusChanged: Event<AzureLoginStatus>;
readonly sessions: AzureSession[];
readonly onSessionsChanged: Event<void>;
readonly filters: AzureResourceFilter[];
readonly onFiltersChanged: Event<void>;
}

export interface AzureSession {
readonly environment: AzureEnvironment;
readonly userId: string;
readonly tenantId: string;
readonly credentials: ServiceClientCredentials;
}

export interface AzureResourceFilter {
readonly session: AzureSession;
readonly subscription: SubscriptionModels.Subscription;
}

export interface Credentials {
readSecret(service: string, account: string): Thenable<string | undefined>;
writeSecret(service: string, account: string, secret: string): Thenable<void>;
deleteSecret(service: string, account: string): Thenable<boolean>;
}
103 changes: 103 additions & 0 deletions appservice/src/azureAccountWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// TEMPORARILY DISABLE
// tslint:disable:ordered-imports
// tslint:disable:no-unexternalized-strings
// tslint:disable:no-require-imports
// tslint:disable:no-parameter-properties
// tslint:disable:member-ordering
// tslint:disable:typedef
// tslint:disable:triple-equals
// tslint:disable:variable-name
// tslint:disable:member-access
// tslint:disable:prefer-const
// tslint:disable:max-classes-per-file
// tslint:disable:no-var-keyword
// tslint:disable:no-multiline-string
// tslint:disable:prefer-template
// tslint:disable:semicolon
// tslint:disable:no-consecutive-blank-lines
// tslint:disable:no-shadowed-variable
// tslint:disable:no-constant-condition
// tslint:disable:no-increment-decrement
// tslint:disable:align
// tslint:disable:no-empty
// tslint:disable:no-non-null-assertion
// tslint:disable:no-unnecessary-local-variable
// tslint:disable:no-any

// tslint:disable:newline-before-return
// tslint:disable:no-single-line-block-comment
// tslint:disable:interface-name
// tslint:disable:function-name

import { ExtensionContext, extensions, Disposable } from 'vscode';
import { ServiceClientCredentials } from 'ms-rest';
import { SubscriptionClient, SubscriptionModels } from 'azure-arm-resource';
import { AzureAccount, AzureSession, AzureLoginStatus } from './azure-account.api';

export class NotSignedInError extends Error { }

export class CredentialError extends Error { }

export class AzureAccountWrapper {
readonly accountApi: AzureAccount;

constructor(readonly extensionConext: ExtensionContext) {
this.accountApi = extensions.getExtension<AzureAccount>('ms-vscode.azure-account')!.exports;
}

getAzureSessions(): AzureSession[] {
const status = this.signInStatus;
if (status !== 'LoggedIn') {
throw new NotSignedInError(status)
}
return this.accountApi.sessions;
}

getCredentialByTenantId(tenantId: string): ServiceClientCredentials {
const session = this.getAzureSessions().find(s => s.tenantId.toLowerCase() === tenantId.toLowerCase());

if (session) {
return session.credentials;
}

throw new CredentialError(`Failed to get credential, tenant ${tenantId} not found.`);
}

get signInStatus(): AzureLoginStatus {
return this.accountApi.status;
}

getFilteredSubscriptions(): SubscriptionModels.Subscription[] {
return this.accountApi.filters.map<SubscriptionModels.Subscription>(filter => {
return {
id: filter.subscription.id,
subscriptionId: filter.subscription.subscriptionId,
tenantId: filter.session.tenantId,
displayName: filter.subscription.displayName,
state: filter.subscription.state,
subscriptionPolicies: filter.subscription.subscriptionPolicies,
authorizationSource: filter.subscription.authorizationSource
};
});
}

async getLocationsBySubscription(subscription: SubscriptionModels.Subscription): Promise<SubscriptionModels.Location[]> {
const credential = this.getCredentialByTenantId(subscription.tenantId);
const client = new SubscriptionClient(credential);
const locations = <SubscriptionModels.Location[]>(await client.subscriptions.listLocations(subscription.subscriptionId));
return locations;
}

registerStatusChangedListener(listener: (e: AzureLoginStatus) => any, thisArg: any): Disposable {
return this.accountApi.onStatusChanged(listener, thisArg, this.extensionConext.subscriptions);
}

registerFiltersChangedListener(listener: (e: void) => any, thisArg: any): Disposable {
return this.accountApi.onFiltersChanged(listener, thisArg, this.extensionConext.subscriptions);
}
}
17 changes: 17 additions & 0 deletions appservice/src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export class UserCancelledError extends Error { }

export class WizardFailedError extends Error {
public readonly stepTitle: string;
public readonly stepIndex: number;
constructor(error: Error, stepTitle: string, stepIndex: number) {
super();
this.message = error.message;
this.stepTitle = stepTitle;
this.stepIndex = stepIndex;
}
}
21 changes: 21 additions & 0 deletions appservice/src/utils/random.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// TEMPORARILY DISABLE
// tslint:disable:export-name
// tslint:disable:typedef

// tslint:disable:newline-before-return

import * as crypto from "crypto";

export namespace randomUtils {

export function getRandomHexString(length: number): string {
const buffer = crypto.randomBytes(Math.ceil(length / 2));
return buffer.toString('hex').slice(0, length);
}

}
35 changes: 35 additions & 0 deletions appservice/src/utils/ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// TEMPORARILY DISABLE
// tslint:disable:export-name
// tslint:disable:typedef
// tslint:disable:strict-boolean-expressions
// tslint:disable:no-unsafe-any

// tslint:disable:newline-before-return
// tslint:disable:interface-name

export namespace uiUtils {

export interface PartialList<T> extends Array<T> {
nextLink?: string;
}

export async function listAll<T>(client: { listNext(nextPageLink: string): Promise<PartialList<T>>; }, first: Promise<PartialList<T>>): Promise<T[]> {
const all: T[] = [];

for (let list = await first; list.length || list.nextLink; list = list.nextLink ? await client.listNext(list.nextLink) : []) {
all.push(...list);
}

return all;
}

export function getSignInCommandString(): string {
return 'azure-account.login';
}

}
Loading

0 comments on commit d65cc05

Please sign in to comment.