AzureMonitor: remove default workspace from configuration editor (#36910)

This commit is contained in:
Andres Martinez Gotor 2021-07-21 11:28:43 +02:00 committed by GitHub
parent 14274a960e
commit 3b728ed78a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 748 deletions

View File

@ -32,6 +32,10 @@ describe('AzureLogAnalyticsDatasource', () => {
});
describe('When performing testDatasource', () => {
beforeEach(() => {
ctx.instanceSettings.jsonData.azureAuthType = 'msi';
});
describe('and an error is returned', () => {
const error = {
data: {
@ -45,7 +49,6 @@ describe('AzureLogAnalyticsDatasource', () => {
};
beforeEach(() => {
ctx.instanceSettings.jsonData.azureAuthType = 'msi';
ctx.ds.azureLogAnalyticsDatasource.getResource = jest.fn().mockRejectedValue(error);
});
@ -58,6 +61,13 @@ describe('AzureLogAnalyticsDatasource', () => {
});
});
});
it('should not include double slashes when getting the resource', async () => {
ctx.ds.azureLogAnalyticsDatasource.firstWorkspace = '/foo/bar';
ctx.ds.azureLogAnalyticsDatasource.getResource = jest.fn().mockResolvedValue(true);
await ctx.ds.azureLogAnalyticsDatasource.testDatasource();
expect(ctx.ds.azureLogAnalyticsDatasource.getResource).toHaveBeenCalledWith('loganalytics/v1/foo/bar/metadata');
});
});
describe('When performing getSchema', () => {
@ -307,4 +317,39 @@ describe('AzureLogAnalyticsDatasource', () => {
expect(annotationResults[1].tags[0]).toBe('tag2');
});
});
describe('When performing getWorkspaces', () => {
beforeEach(() => {
ctx.ds.azureLogAnalyticsDatasource.getWorkspaceList = jest
.fn()
.mockResolvedValue({ value: [{ name: 'foobar', id: 'foo', properties: { customerId: 'bar' } }] });
});
it('should return the workspace id', async () => {
const workspaces = await ctx.ds.azureLogAnalyticsDatasource.getWorkspaces('sub');
expect(workspaces).toEqual([{ text: 'foobar', value: 'foo' }]);
});
});
describe('When performing getFirstWorkspace', () => {
beforeEach(() => {
ctx.ds.azureLogAnalyticsDatasource.getDefaultOrFirstSubscription = jest.fn().mockResolvedValue('foo');
ctx.ds.azureLogAnalyticsDatasource.getWorkspaces = jest
.fn()
.mockResolvedValue([{ text: 'foobar', value: 'foo' }]);
ctx.ds.azureLogAnalyticsDatasource.firstWorkspace = undefined;
});
it('should return the stored workspace', async () => {
ctx.ds.azureLogAnalyticsDatasource.firstWorkspace = 'bar';
const workspace = await ctx.ds.azureLogAnalyticsDatasource.getFirstWorkspace();
expect(workspace).toEqual('bar');
expect(ctx.ds.azureLogAnalyticsDatasource.getDefaultOrFirstSubscription).not.toHaveBeenCalled();
});
it('should return the first workspace', async () => {
const workspace = await ctx.ds.azureLogAnalyticsDatasource.getFirstWorkspace();
expect(workspace).toEqual('foo');
});
});
});

View File

@ -39,7 +39,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
defaultSubscriptionId?: string;
azureMonitorPath: string;
defaultOrFirstWorkspace: string;
firstWorkspace?: string;
cache: Map<string, any>;
constructor(private instanceSettings: DataSourceInstanceSettings<AzureDataSourceJsonData>) {
@ -52,7 +52,6 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
this.azurePortalUrl = getAzurePortalUrl(cloud);
this.defaultSubscriptionId = this.instanceSettings.jsonData.subscriptionId || '';
this.defaultOrFirstWorkspace = this.instanceSettings.jsonData.logAnalyticsDefaultWorkspace || '';
}
isConfigured(): boolean {
@ -76,7 +75,10 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
return (
map(response.value, (val: any) => {
return { text: val.name, value: val.id };
return {
text: val.name,
value: val.id,
};
}) || []
);
}
@ -112,8 +114,8 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
const resource = templateSrv.replace(item.resource, scopedVars);
let workspace = templateSrv.replace(item.workspace, scopedVars);
if (!workspace && !resource && this.defaultOrFirstWorkspace) {
workspace = this.defaultOrFirstWorkspace;
if (!workspace && !resource && this.firstWorkspace) {
workspace = this.firstWorkspace;
}
const query = templateSrv.replace(item.query, scopedVars, this.interpolateVariable);
@ -238,7 +240,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
}
// Execute the query as KQL to the default or first workspace
return this.getDefaultOrFirstWorkspace().then((resourceURI) => {
return this.getFirstWorkspace().then((resourceURI) => {
if (!resourceURI) {
return [];
}
@ -322,9 +324,9 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
return subscriptions[0]?.value;
}
async getDefaultOrFirstWorkspace(): Promise<string | undefined> {
if (this.defaultOrFirstWorkspace) {
return this.defaultOrFirstWorkspace;
async getFirstWorkspace(): Promise<string | undefined> {
if (this.firstWorkspace) {
return this.firstWorkspace;
}
const subscriptionId = await this.getDefaultOrFirstSubscription();
@ -336,7 +338,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
const workspace = workspaces[0]?.value;
if (workspace) {
this.defaultOrFirstWorkspace = workspace;
this.firstWorkspace = workspace;
}
return workspace;
@ -384,7 +386,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
let resourceOrWorkspace: string;
try {
const result = await this.getDefaultOrFirstWorkspace();
const result = await this.getFirstWorkspace();
if (!result) {
return {
status: 'error',
@ -403,7 +405,7 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
try {
const path = isGUIDish(resourceOrWorkspace)
? `${this.resourcePath}/v1/workspaces/${resourceOrWorkspace}/metadata`
: `${this.resourcePath}/v1/${resourceOrWorkspace}/metadata`;
: `${this.resourcePath}/v1${resourceOrWorkspace}/metadata`;
return await this.getResource(path).then<DatasourceValidationResult>((response: any) => {
return {

View File

@ -27,14 +27,11 @@ const setup = (propsFunc?: (props: Props) => Props) => {
jsonData: {
cloudName: '',
subscriptionId: '',
logAnalyticsDefaultWorkspace: '',
},
version: 1,
readOnly: false,
},
updateOptions: jest.fn(),
getSubscriptions: jest.fn(),
getWorkspaces: jest.fn(),
};
if (propsFunc) {
@ -45,14 +42,8 @@ const setup = (propsFunc?: (props: Props) => Props) => {
};
describe('Render', () => {
it('should render component', () => {
const wrapper = setup();
expect(wrapper.baseElement).toMatchSnapshot();
});
it('should disable log analytics credentials form', () => {
const wrapper = setup((props) => ({
setup((props) => ({
...props,
options: {
...props.options,
@ -62,26 +53,7 @@ describe('Render', () => {
},
},
}));
expect(wrapper.baseElement).toMatchSnapshot();
});
it('should enable azure log analytics load workspaces button', () => {
const wrapper = setup((props) => ({
...props,
options: {
...props.options,
jsonData: {
...props.options.jsonData,
azureLogAnalyticsSameAs: false,
logAnalyticsDefaultWorkspace: '',
tenantId: 'e7f3f661-a933-4b3f-8176-51c4f982ec48',
clientId: '44693801-6ee6-49de-9b2d-9106972f9572',
subscriptionId: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
clientSecret: 'cddcc020-2c94-460a-a3d0-df3147ffa792',
},
},
}));
expect(wrapper.baseElement).toMatchSnapshot();
expect(screen.queryByText('Azure Monitor Logs')).not.toBeInTheDocument();
});
it('should not render the Switch to use different creds for log analytics by default', () => {
@ -123,15 +95,4 @@ describe('Render', () => {
const newOpts = onUpdate.mock.calls[0][0]({});
expect(newOpts).toEqual({ jsonData: { azureLogAnalyticsSameAs: true } });
});
it('should disable inputs', () => {
setup((props) => ({
...props,
options: {
...props.options,
readOnly: true,
},
}));
expect(screen.queryByText('Load Workspaces')?.closest('button')).toBeDisabled();
});
});

View File

@ -1,96 +1,24 @@
import React, { FunctionComponent, useEffect, useMemo, useReducer, useState } from 'react';
import { SelectableValue } from '@grafana/data';
import React, { FunctionComponent, useMemo } from 'react';
import { AzureCredentialsForm } from './AzureCredentialsForm';
import { InlineFormLabel, LegacyForms, Button, Alert } from '@grafana/ui';
const { Select } = LegacyForms;
import { Button, Alert } from '@grafana/ui';
import { AzureDataSourceSettings } from '../types';
import { getCredentials, isCredentialsComplete } from '../credentials';
import { getCredentials } from '../credentials';
export interface Props {
options: AzureDataSourceSettings;
updateOptions: (optionsFunc: (options: AzureDataSourceSettings) => AzureDataSourceSettings) => void;
getSubscriptions: () => Promise<Array<SelectableValue<string>>>;
getWorkspaces: (subscriptionId: string) => Promise<Array<SelectableValue<string>>>;
}
export const AnalyticsConfig: FunctionComponent<Props> = (props: Props) => {
const { updateOptions, getSubscriptions, getWorkspaces } = props;
const { updateOptions } = props;
const primaryCredentials = useMemo(() => getCredentials(props.options), [props.options]);
const subscriptionId = primaryCredentials.defaultSubscriptionId;
// Only show a section for setting LogAnalytics credentials if
// they were set from before with different values and the
// authType is supported
const logCredentialsEnabled =
primaryCredentials.authType === 'clientsecret' && props.options.jsonData.azureLogAnalyticsSameAs === false;
const hasRequiredFields = subscriptionId && isCredentialsComplete(primaryCredentials);
const defaultWorkspace = props.options.jsonData.logAnalyticsDefaultWorkspace;
const [workspaces, setWorkspaces] = useState<SelectableValue[]>([]);
const [loadWorkspaces, onLoadWorkspaces] = useReducer((val) => val + 1, 0);
useEffect(() => {
if (!hasRequiredFields || !subscriptionId) {
updateWorkspaces([]);
return;
}
let canceled = false;
getWorkspaces(subscriptionId).then((result) => {
if (!canceled) {
updateWorkspaces(result);
}
});
return () => {
canceled = true;
};
// This effect is intended to be called only once initially and on Load Workspaces click
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [loadWorkspaces, subscriptionId]);
const updateWorkspaces = (received: Array<SelectableValue<string>>) => {
setWorkspaces(received);
if (!defaultWorkspace && received.length > 0) {
// Setting the default workspace if workspaces received but no default workspace selected
updateOptions((options) => {
return {
...options,
jsonData: {
...options.jsonData,
logAnalyticsDefaultWorkspace: received[0].value,
},
};
});
} else if (defaultWorkspace) {
const found = received.find((opt) => opt.value === defaultWorkspace);
if (!found) {
// Unsetting the default workspace if it isn't found among the received workspaces
updateOptions((options) => {
return {
...options,
jsonData: {
...options.jsonData,
logAnalyticsDefaultWorkspace: undefined,
},
};
});
}
}
};
const onDefaultWorkspaceChange = (selected: SelectableValue<string>) => {
updateOptions((options) => {
return {
...options,
jsonData: {
...options.jsonData,
logAnalyticsDefaultWorkspace: selected.value || '',
},
};
});
};
const onClearAzLogsCreds = () => {
updateOptions((options) => {
return {
@ -103,70 +31,32 @@ export const AnalyticsConfig: FunctionComponent<Props> = (props: Props) => {
});
};
return (
return logCredentialsEnabled ? (
<>
<h3 className="page-heading">Azure Monitor Logs</h3>
{logCredentialsEnabled && (
<>
<Alert severity="error" title="Deprecated">
Using different credentials for Azure Monitor Logs is no longer supported. Authentication information above
will be used instead. Please create a new data source with the credentials below.
</Alert>
<>
<Alert severity="error" title="Deprecated">
Using different credentials for Azure Monitor Logs is no longer supported. Authentication information above
will be used instead. Please create a new data source with the credentials below.
</Alert>
<AzureCredentialsForm
managedIdentityEnabled={false}
credentials={{
...primaryCredentials,
authType: 'clientsecret',
// Use deprecated Log Analytics credentials read-only
// to help with a possible migration
tenantId: props.options.jsonData.logAnalyticsTenantId,
clientId: props.options.jsonData.logAnalyticsClientId,
}}
getSubscriptions={getSubscriptions}
disabled={true}
>
<Button onClick={onClearAzLogsCreds}>Clear Azure Monitor Logs Credentials</Button>
</AzureCredentialsForm>
</>
)}
<div className="gf-form-group">
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel
className="width-12"
tooltip="Choose the default/preferred Workspace for Azure Log Analytics queries."
>
Default Workspace
</InlineFormLabel>
<div className="width-25">
<Select
value={workspaces.find((opt) => opt.value === defaultWorkspace)}
options={workspaces}
onChange={onDefaultWorkspaceChange}
isDisabled={props.options.readOnly}
/>
</div>
</div>
</div>
<div className="gf-form-inline">
<div className="gf-form">
<div className="max-width-30 gf-form-inline">
<Button
variant="secondary"
size="sm"
type="button"
onClick={onLoadWorkspaces}
disabled={!hasRequiredFields || props.options.readOnly}
>
Load Workspaces
</Button>
</div>
</div>
</div>
</div>
<AzureCredentialsForm
managedIdentityEnabled={false}
credentials={{
...primaryCredentials,
authType: 'clientsecret',
// Use deprecated Log Analytics credentials read-only
// to help with a possible migration
tenantId: props.options.jsonData.logAnalyticsTenantId,
clientId: props.options.jsonData.logAnalyticsClientId,
}}
disabled={true}
>
<Button onClick={onClearAzLogsCreds}>Clear Azure Monitor Logs Credentials</Button>
</AzureCredentialsForm>
</>
</>
);
) : null;
};
export default AnalyticsConfig;

View File

@ -68,30 +68,6 @@ export class ConfigEditor extends PureComponent<Props, State> {
return ResponseParser.parseSubscriptionsForSelect(result);
};
private getLogAnalyticsSubscriptions = async (): Promise<Array<SelectableValue<string>>> => {
await this.saveOptions();
const query = `?api-version=2019-03-01`;
const result = await getBackendSrv().datasourceRequest({
url: this.baseURL + query,
method: 'GET',
});
return ResponseParser.parseSubscriptionsForSelect(result);
};
private getWorkspaces = async (subscriptionId: string): Promise<Array<SelectableValue<string>>> => {
await this.saveOptions();
const workspaceURL = `/${subscriptionId}/providers/Microsoft.OperationalInsights/workspaces?api-version=2017-04-26-preview`;
const result = await getBackendSrv().datasourceRequest({
url: this.baseURL + workspaceURL,
method: 'GET',
});
return ResponseParser.parseWorkspacesForSelect(result);
};
// TODO: Used only by InsightsConfig
private onUpdateJsonDataOption = (key: keyof AzureDataSourceJsonData) => (
event: React.SyntheticEvent<HTMLInputElement | HTMLSelectElement>
@ -117,14 +93,7 @@ export class ConfigEditor extends PureComponent<Props, State> {
return (
<>
<MonitorConfig options={options} updateOptions={this.updateOptions} getSubscriptions={this.getSubscriptions} />
<AnalyticsConfig
options={options}
updateOptions={this.updateOptions}
getSubscriptions={this.getLogAnalyticsSubscriptions}
getWorkspaces={this.getWorkspaces}
/>
<AnalyticsConfig options={options} updateOptions={this.updateOptions} />
{this.state.appInsightsInitiallyConfigured && (
<InsightsConfig
options={options}

View File

@ -1,525 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should disable log analytics credentials form 1`] = `
<body>
<div>
<h3
class="page-heading"
>
Azure Monitor Logs
</h3>
<div
class="gf-form-group"
>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Default Workspace
<div
class="gf-form-help-icon gf-form-help-icon--right-normal"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</label>
<div
class="width-25"
>
<div>
<div
class="gf-form-input gf-form-input--form-dropdown css-1daubv-SelectContainer"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="gf-form-select-box__control css-1g8ily9-Control"
>
<div
class="gf-form-select-box__value-container css-pilx6v-ValueContainer"
>
<div
class="gf-form-select-box__placeholder css-ovmm9z-Placeholder"
>
Choose
</div>
<div
class="css-17yls17-Input"
>
<div
class="gf-form-select-box__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-3-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="gf-form-select-box__indicators css-1pmvkci-IndicatorsContainer"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<div
class="max-width-30 gf-form-inline"
>
<button
class="css-191ipe8-button"
disabled=""
type="button"
>
<span
class="css-1mhnkuh"
>
Load Workspaces
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</body>
`;
exports[`Render should enable azure log analytics load workspaces button 1`] = `
<body>
<div>
<h3
class="page-heading"
>
Azure Monitor Logs
</h3>
<div
aria-label="Alert error"
class="css-7gef9a"
>
<div
class="css-a4coia"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
<div
class="css-zmuccj"
>
<div
class="css-hui7p1"
>
Deprecated
</div>
<div
class="css-1b0c7i6"
>
Using different credentials for Azure Monitor Logs is no longer supported. Authentication information above will be used instead. Please create a new data source with the credentials below.
</div>
</div>
</div>
<div
class="gf-form-group"
>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Directory (tenant) ID
</label>
<div
class="width-15"
>
<div
style="flex-grow: 1;"
>
<input
class="gf-form-input width-30"
disabled=""
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
value=""
/>
</div>
</div>
</div>
</div>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Application (client) ID
</label>
<div
class="width-15"
>
<div
style="flex-grow: 1;"
>
<input
class="gf-form-input width-30"
disabled=""
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
value=""
/>
</div>
</div>
</div>
</div>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Default Subscription
</label>
<div
class="width-25"
>
<div>
<div
class="gf-form-input gf-form-input--form-dropdown gf-form-select-box--is-disabled css-1daubv-SelectContainer"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="gf-form-select-box__control gf-form-select-box__control--is-disabled css-1g8ily9-Control"
>
<div
class="gf-form-select-box__value-container css-pilx6v-ValueContainer"
>
<div
class="gf-form-select-box__placeholder css-ovmm9z-Placeholder"
>
Choose
</div>
<div
class="css-17yls17-Input"
>
<div
class="gf-form-select-box__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
disabled=""
id="react-select-4-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="gf-form-select-box__indicators css-1pmvkci-IndicatorsContainer"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<button
class="css-5tn967-button"
>
<span
class="css-1mhnkuh"
>
Clear Azure Monitor Logs Credentials
</span>
</button>
</div>
<div
class="gf-form-group"
>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Default Workspace
<div
class="gf-form-help-icon gf-form-help-icon--right-normal"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</label>
<div
class="width-25"
>
<div>
<div
class="gf-form-input gf-form-input--form-dropdown css-1daubv-SelectContainer"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="gf-form-select-box__control css-1g8ily9-Control"
>
<div
class="gf-form-select-box__value-container css-pilx6v-ValueContainer"
>
<div
class="gf-form-select-box__placeholder css-ovmm9z-Placeholder"
>
Choose
</div>
<div
class="css-17yls17-Input"
>
<div
class="gf-form-select-box__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-5-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="gf-form-select-box__indicators css-1pmvkci-IndicatorsContainer"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<div
class="max-width-30 gf-form-inline"
>
<button
class="css-191ipe8-button"
disabled=""
type="button"
>
<span
class="css-1mhnkuh"
>
Load Workspaces
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</body>
`;
exports[`Render should render component 1`] = `
<body>
<div>
<h3
class="page-heading"
>
Azure Monitor Logs
</h3>
<div
class="gf-form-group"
>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<label
class="width-12 gf-form-label width-10"
>
Default Workspace
<div
class="gf-form-help-icon gf-form-help-icon--right-normal"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</label>
<div
class="width-25"
>
<div>
<div
class="gf-form-input gf-form-input--form-dropdown css-1daubv-SelectContainer"
>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="gf-form-select-box__control css-1g8ily9-Control"
>
<div
class="gf-form-select-box__value-container css-pilx6v-ValueContainer"
>
<div
class="gf-form-select-box__placeholder css-ovmm9z-Placeholder"
>
Choose
</div>
<div
class="css-17yls17-Input"
>
<div
class="gf-form-select-box__input"
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-2-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class="gf-form-select-box__indicators css-1pmvkci-IndicatorsContainer"
>
<div
class="css-1vzus6i-Icon"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="gf-form-inline"
>
<div
class="gf-form"
>
<div
class="max-width-30 gf-form-inline"
>
<button
class="css-191ipe8-button"
disabled=""
type="button"
>
<span
class="css-1mhnkuh"
>
Load Workspaces
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</body>
`;

View File

@ -58,7 +58,6 @@ export interface AzureDataSourceJsonData extends DataSourceJsonData {
subscriptionId?: string;
// logs
logAnalyticsDefaultWorkspace?: string;
/** @deprecated Azure Logs credentials */
azureLogAnalyticsSameAs?: boolean;
/** @deprecated Azure Logs credentials */