-
Notifications
You must be signed in to change notification settings - Fork 136
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
Improve local settings when creating templates #3924
Changes from 6 commits
587b574
39f7726
6783e5c
3184e49
bdb8ee5
ab23bf1
f25be51
970c2d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,10 @@ export abstract class AzureConnectionCreateStepBase<T extends IBindingWizardCont | |
progress.report({ message: localize('retrieving', 'Retrieving connection string...') }); | ||
|
||
const result: IConnection = await this.getConnection(context); | ||
let appSettingKey: string = `${result.name}_${nonNullProp(this._setting, 'resourceType').toUpperCase()}`; | ||
let appSettingKey: string = context.useStorageEmulator ? | ||
// if using the storage emulator, don't append the resource type to the app setting key | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: The comment explains what we're doing but not why. I think it's more helpful if the why was included. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, I'm not really sure why @ejizba did this in the first place. https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings#azurewebjobsstorage Here's the documentation about the setting The old behavior would take the name of the azure resource and append the resource type (so like, naturins-storage_STORAGE) as the key. I'm wondering if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if he's talking about what I did or what you did @nturinski. The "_STORAGE" thing was just a random naming convention and I feel like I was probably just following an existing pattern from docs or the portal In any case, I'm confused about what you're doing just like Alex probably is. Like, what does the emulator have to do with appending "_STORAGE"? Seems like both "AzureWebJobsStorage" and "randomkey_STORAGE" could use or not use the emulator, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue is when I pass in Is it pretty common to have other storage connection strings outside of |
||
result.name : | ||
`${result.name}_${nonNullProp(this._setting, 'resourceType').toUpperCase()}`; | ||
appSettingKey = appSettingKey.replace(/[^a-z0-9_\.]/gi, ''); // remove invalid chars | ||
setBindingSetting(context, this._setting, appSettingKey); | ||
await setLocalAppSetting(context, context.projectPath, appSettingKey, result.connectionString); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ | |
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import { StorageAccountKind, StorageAccountListStep, StorageAccountPerformance, StorageAccountReplication } from '@microsoft/vscode-azext-azureutils'; | ||
import { type AzureWizardExecuteStep, type AzureWizardPromptStep, type IAzureQuickPickItem, type ISubscriptionActionContext, type IWizardOptions } from '@microsoft/vscode-azext-utils'; | ||
import * as path from 'path'; | ||
import { localSettingsFileName } from '../../../constants'; | ||
|
@@ -20,7 +19,7 @@ import { BindingSettingStepBase } from './BindingSettingStepBase'; | |
import { LocalAppSettingCreateStep } from './LocalAppSettingCreateStep'; | ||
import { LocalAppSettingNameStep } from './LocalAppSettingNameStep'; | ||
import { LocalAppSettingValueStep } from './LocalAppSettingValueStep'; | ||
import { StorageConnectionCreateStep } from './StorageConnectionCreateStep'; | ||
import { StorageTypePromptStep } from './StorageTypePromptStep'; | ||
import { CosmosDBConnectionCreateStep } from './cosmosDB/CosmosDBConnectionCreateStep'; | ||
import { CosmosDBListStep } from './cosmosDB/CosmosDBListStep'; | ||
import { EventHubAuthRuleListStep } from './eventHub/EventHubAuthRuleListStep'; | ||
|
@@ -33,10 +32,11 @@ export class LocalAppSettingListStep extends BindingSettingStepBase { | |
public async promptCore(context: IBindingWizardContext): Promise<BindingSettingValue> { | ||
const localSettingsPath: string = path.join(context.projectPath, localSettingsFileName); | ||
const settings: ILocalSettingsJson = await getLocalSettingsJson(context, localSettingsPath); | ||
const existingSettings: string[] = settings.Values ? Object.keys(settings.Values) : []; | ||
const existingSettings: [string, string][] = settings.Values ? Object.entries(settings.Values) : []; | ||
|
||
let picks: IAzureQuickPickItem<string | undefined>[] = [{ label: localize('newAppSetting', '$(plus) Create new local app setting'), data: undefined }]; | ||
picks = picks.concat(existingSettings.map((s: string) => { return { data: s, label: s }; })); | ||
const placeHolder: string = localize('selectAppSetting', 'Select setting from "{0}"', localSettingsFileName); | ||
picks = picks.concat(existingSettings.map((s: [string, string]) => { return { data: s[0], label: s[0], description: s[1] }; })); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The value can be a secret, though. You could add an option or something to show values, but they should be hidden by default just to be safe. Just like how app settings are currently displayed in the tree view There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
const placeHolder: string = localize('selectAppSetting', 'Select the app setting with your {1} string from "{0}"', localSettingsFileName, this._setting.label); | ||
return (await context.ui.showQuickPick(picks, { placeHolder })).data; | ||
} | ||
|
||
|
@@ -50,11 +50,7 @@ export class LocalAppSettingListStep extends BindingSettingStepBase { | |
azureExecuteSteps.push(new CosmosDBConnectionCreateStep(this._setting)); | ||
break; | ||
case ResourceType.Storage: | ||
azurePromptSteps.push(new StorageAccountListStep( | ||
{ kind: StorageAccountKind.Storage, performance: StorageAccountPerformance.Standard, replication: StorageAccountReplication.LRS }, | ||
{ kind: [StorageAccountKind.BlobStorage], learnMoreLink: 'https://aka.ms/T5o0nf' } | ||
)); | ||
azureExecuteSteps.push(new StorageConnectionCreateStep(this._setting)); | ||
azurePromptSteps.push(new StorageTypePromptStep(this._setting)); | ||
break; | ||
case ResourceType.ServiceBus: | ||
azurePromptSteps.push(new ServiceBusListStep()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import { StorageAccountKind, StorageAccountListStep, StorageAccountPerformance, StorageAccountReplication } from "@microsoft/vscode-azext-azureutils"; | ||
import { AzureWizardPromptStep, type AzureWizardExecuteStep, type IAzureQuickPickItem, type ISubscriptionActionContext, type IWizardOptions } from "@microsoft/vscode-azext-utils"; | ||
import { localize } from "../../../localize"; | ||
import { type IBindingSetting } from "../../../templates/IBindingTemplate"; | ||
import { type IEventHubsConnectionWizardContext } from "../../appSettings/connectionSettings/eventHubs/IEventHubsConnectionWizardContext"; | ||
import { type IBindingWizardContext } from "../IBindingWizardContext"; | ||
import { StorageConnectionCreateStep } from "./StorageConnectionCreateStep"; | ||
|
||
export class StorageTypePromptStep extends AzureWizardPromptStep<IBindingWizardContext> { | ||
private readonly _setting: IBindingSetting; | ||
|
||
constructor(setting: IBindingSetting) { | ||
super(); | ||
this._setting = setting; | ||
} | ||
|
||
public async prompt(context: IBindingWizardContext): Promise<void> { | ||
const picks: IAzureQuickPickItem<boolean>[] = [ | ||
{ label: localize('useAzurite', 'Use Azurite emulator for local storage'), data: true }, | ||
{ label: localize('useAzureStorage', 'Use Azure Storage for remote storage'), data: false } | ||
]; | ||
|
||
context.useStorageEmulator = (await context.ui.showQuickPick(picks, { placeHolder: localize('selectStorage', 'Select a storage account type for development') })).data; | ||
return; | ||
} | ||
|
||
public shouldPrompt(context: IBindingWizardContext): boolean { | ||
return context.useStorageEmulator === undefined; | ||
} | ||
|
||
public async getSubWizard(context: IBindingWizardContext): Promise<IWizardOptions<IBindingWizardContext> | undefined> { | ||
const promptSteps: AzureWizardPromptStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = []; | ||
const executeSteps: AzureWizardExecuteStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = []; | ||
|
||
if (!context.useStorageEmulator) { | ||
promptSteps.push(new StorageAccountListStep( | ||
{ kind: StorageAccountKind.Storage, performance: StorageAccountPerformance.Standard, replication: StorageAccountReplication.LRS }, | ||
{ kind: [StorageAccountKind.BlobStorage], learnMoreLink: 'https://aka.ms/T5o0nf' } | ||
)); | ||
} | ||
|
||
executeSteps.push(new StorageConnectionCreateStep(this._setting)); | ||
|
||
return { | ||
promptSteps, | ||
executeSteps | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,6 @@ import { deleteServiceConnector } from '../serviceConnector/deleteServiceConnect | |
import { validateServiceConnector } from '../serviceConnector/validateServiceConnector'; | ||
import { ResolvedFunctionAppResource } from '../tree/ResolvedFunctionAppResource'; | ||
import { addBinding } from './addBinding/addBinding'; | ||
import { setAzureWebJobsStorage } from './appSettings/connectionSettings/azureWebJobsStorage/setAzureWebJobsStorage'; | ||
import { downloadAppSettings } from './appSettings/downloadAppSettings'; | ||
import { decryptLocalSettings } from './appSettings/localSettings/decryptLocalSettings'; | ||
import { encryptLocalSettings } from './appSettings/localSettings/encryptLocalSettings'; | ||
|
@@ -93,7 +92,6 @@ export function registerCommands(): void { | |
registerCommandWithTreeNodeUnwrapping('azureFunctions.pickProcess', pickFuncProcess); | ||
registerCommandWithTreeNodeUnwrapping('azureFunctions.redeploy', redeployDeployment); | ||
registerCommandWithTreeNodeUnwrapping('azureFunctions.restartFunctionApp', restartFunctionApp); | ||
registerCommandWithTreeNodeUnwrapping('azureFunctions.setAzureWebJobsStorage', setAzureWebJobsStorage); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we still need this for the command palette to work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are absolutely correct. Forgot to revert that one. 🤦 |
||
registerCommandWithTreeNodeUnwrapping('azureFunctions.startFunctionApp', startFunctionApp); | ||
registerCommandWithTreeNodeUnwrapping('azureFunctions.startJavaRemoteDebug', remoteDebugJavaFunctionApp); | ||
registerCommandWithTreeNodeUnwrapping('azureFunctions.startRemoteDebug', startRemoteDebug); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use it a decent amount please don't remove it 🥺 If you clone a function app repo or just accidentally delete your "local.settings.json" it's a fast way to get the file back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hahaha okay. I figured the only entry point was through the command palette, so who could even be using it...? But I guess you are 1 of 85 people per month.