-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
419 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
{} | ||
{ | ||
"lib.service.sku.eolWarning": "This SKU is scheduled for retirement on {eolDate}", | ||
"lib.service.sku.notFound": "SKU '{skuName}' not found" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
import { DependencyFactories } from "@azure/bonito-core/lib/environment"; | ||
import { NodeService } from "../node"; | ||
import { PoolService } from "../pool"; | ||
import { SkuService } from "../sku"; | ||
|
||
export enum BatchDependencyName { | ||
PoolService = "poolService", | ||
NodeService = "nodeService", | ||
SkuService = "skuService", | ||
} | ||
|
||
export interface BatchDependencyFactories extends DependencyFactories { | ||
[BatchDependencyName.PoolService]: () => PoolService; | ||
[BatchDependencyName.NodeService]: () => NodeService; | ||
[BatchDependencyName.SkuService]: () => SkuService; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
packages/service/src/sku/__tests__/fake-sku-service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { initMockBatchEnvironment } from "../../environment"; | ||
import { | ||
BasicBatchFakeSet, | ||
BatchFakeSet, | ||
FakeLocations, | ||
} from "../../test-util/fakes"; | ||
import { FakeSkuService } from "../fake-sku-service"; | ||
import { SupportedSkuType } from "../sku-models"; | ||
|
||
describe("FakeSkuService", () => { | ||
let fakeSet: BatchFakeSet; | ||
let service: FakeSkuService; | ||
|
||
beforeEach(() => { | ||
initMockBatchEnvironment(); | ||
fakeSet = new BasicBatchFakeSet(); | ||
service = new FakeSkuService(); | ||
service.setFakes(fakeSet); | ||
}); | ||
|
||
test("List by type", async () => { | ||
const skus = await service.list({ | ||
subscriptionId: "00000000-0000-0000-0000-000000000000", | ||
type: SupportedSkuType.CloudService, | ||
locationName: FakeLocations.Arrakis.name, | ||
}); | ||
expect(skus.length).toEqual(2); | ||
expect(skus[1].name).toEqual("A7"); | ||
expect(skus[1].batchSupportEndOfLife).toEqual("2024-08-31T00:00:00Z"); | ||
}); | ||
}); |
58 changes: 58 additions & 0 deletions
58
packages/service/src/sku/__tests__/live-sku-service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { MockHttpClient, MockHttpResponse } from "@azure/bonito-core/lib/http"; | ||
import { | ||
BasicBatchFakeSet, | ||
BatchFakeSet, | ||
FakeLocations, | ||
} from "../../test-util/fakes"; | ||
import { LiveSkuService } from "../live-sku-service"; | ||
import { initMockBatchEnvironment } from "../../environment"; | ||
import { getMockEnvironment } from "@azure/bonito-core/lib/environment"; | ||
import { getArmUrl } from "@azure/bonito-core"; | ||
import { BatchApiVersion } from "../../constants"; | ||
import { SupportedSkuType } from "../sku-models"; | ||
|
||
describe("LiveSkuService", () => { | ||
const arrakisLoc = | ||
"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Batch/locations/arrakis"; | ||
let service: LiveSkuService; | ||
let fakeSet: BatchFakeSet; | ||
|
||
let httpClient: MockHttpClient; | ||
|
||
beforeEach(() => { | ||
initMockBatchEnvironment(); | ||
httpClient = getMockEnvironment().getHttpClient(); | ||
service = new LiveSkuService(); | ||
fakeSet = new BasicBatchFakeSet(); | ||
}); | ||
|
||
test("List virtual machine SKUs", async () => { | ||
httpClient.addExpected( | ||
new MockHttpResponse( | ||
`${getArmUrl()}${arrakisLoc}/virtualMachineSkus?api-version=${ | ||
BatchApiVersion.arm | ||
}`, | ||
{ | ||
status: 200, | ||
body: JSON.stringify({ | ||
value: fakeSet.listSupportedSkus( | ||
SupportedSkuType.VirtualMachine, | ||
FakeLocations.Arrakis.name | ||
), | ||
}), | ||
} | ||
) | ||
); | ||
|
||
const skus = await service.list({ | ||
subscriptionId: "00000000-0000-0000-0000-000000000000", | ||
locationName: FakeLocations.Arrakis.name, | ||
}); | ||
expect(skus.length).toEqual(4); | ||
expect(skus[2]).toEqual({ | ||
name: "Standard_NC8as_T4_v3", | ||
familyName: "Standard NCASv3_T4 Family", | ||
batchSupportEndOfLife: "2024-08-31T00:00:00Z", | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { initMockBatchEnvironment } from "../../environment"; | ||
import { | ||
BasicBatchFakeSet, | ||
BatchFakeSet, | ||
FakeLocations, | ||
} from "../../test-util/fakes"; | ||
import { FakeSkuService } from "../fake-sku-service"; | ||
import { SupportedSkuType } from "../sku-models"; | ||
import { endOfLifeStatus } from "../sku-util"; | ||
|
||
describe("SKU Utilities", () => { | ||
let fakeSet: BatchFakeSet; | ||
let service: FakeSkuService; | ||
|
||
const options = { | ||
subscriptionId: "00000000-0000-0000-0000-000000000000", | ||
type: SupportedSkuType.VirtualMachine, | ||
locationName: FakeLocations.Arrakis.name, | ||
}; | ||
|
||
beforeEach(() => { | ||
initMockBatchEnvironment(); | ||
fakeSet = new BasicBatchFakeSet(); | ||
service = new FakeSkuService(); | ||
service.setFakes(fakeSet); | ||
}); | ||
|
||
test("returns an EOL date for a given SKU", async () => { | ||
const eolSku = "Standard_NC8as_T4_v3"; | ||
const nonEolSku = "Standard_NC64as_T4_v3"; | ||
const nonExistingSku = "non-SKU"; | ||
|
||
const eol = (skuName: string) => | ||
endOfLifeStatus({ ...options, skuName }); | ||
|
||
expect(await eol(eolSku)).toEqual({ | ||
eolDate: new Date("2024-08-31T00:00:00Z"), | ||
warning: "This SKU is scheduled for retirement on August 30, 2024", | ||
}); | ||
expect(await eol(nonEolSku)).toBeNull(); | ||
expect(eol(nonExistingSku)).rejects.toThrow(`SKU 'non-SKU' not found`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { BasicBatchFakeSet, BatchFakeSet } from "../test-util/fakes"; | ||
import { SupportedSku, SupportedSkuType } from "./sku-models"; | ||
import { ListSkusOptions, SkuService } from "./sku-service"; | ||
|
||
export class FakeSkuService implements SkuService { | ||
fakeSet: BatchFakeSet = new BasicBatchFakeSet(); | ||
|
||
setFakes(fakeSet: BatchFakeSet): void { | ||
this.fakeSet = fakeSet; | ||
} | ||
|
||
async list(options: ListSkusOptions): Promise<SupportedSku[]> { | ||
const { type = SupportedSkuType.VirtualMachine, locationName } = | ||
options; | ||
return this.fakeSet.listSupportedSkus(type, locationName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from "./fake-sku-service"; | ||
export * from "./live-sku-service"; | ||
export * from "./sku-service"; | ||
export * from "./sku-models"; | ||
export * from "./sku-util"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { AbstractHttpService, getArmUrl } from "@azure/bonito-core"; | ||
import { ListSkusOptions, SkuService } from "./sku-service"; | ||
import { SupportedSku, SupportedSkuType } from "./sku-models"; | ||
import { createARMBatchClient, isUnexpected } from "../internal/arm-batch-rest"; | ||
import { createArmUnexpectedStatusCodeError } from "../utils"; | ||
|
||
const VIRTUAL_MACHINE_SKU_PATH = | ||
"/subscriptions/{subscriptionId}/providers/Microsoft.Batch/locations/{locationName}/virtualMachineSkus"; | ||
const CLOUD_SERVICE_SKU_PATH = | ||
"/subscriptions/{subscriptionId}/providers/Microsoft.Batch/locations/{locationName}/cloudServiceSkus"; | ||
|
||
export class LiveSkuService extends AbstractHttpService implements SkuService { | ||
async list(options: ListSkusOptions): Promise<SupportedSku[]> { | ||
const { | ||
subscriptionId, | ||
locationName, | ||
type = SupportedSkuType.VirtualMachine, | ||
} = options; | ||
|
||
const armBatchClient = createARMBatchClient({ | ||
baseUrl: getArmUrl(), | ||
}); | ||
|
||
let res; | ||
if (type === SupportedSkuType.CloudService) { | ||
res = await armBatchClient | ||
.path(CLOUD_SERVICE_SKU_PATH, subscriptionId, locationName) | ||
.get(); | ||
} else { | ||
res = await armBatchClient | ||
.path(VIRTUAL_MACHINE_SKU_PATH, subscriptionId, locationName) | ||
.get(); | ||
} | ||
if (isUnexpected(res)) { | ||
throw createArmUnexpectedStatusCodeError(res); | ||
} | ||
return res.body.value ?? []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { SupportedSkuOutput as SupportedSku } from "../internal/arm-batch-rest"; | ||
|
||
export const enum SupportedSkuType { | ||
CloudService = "CloudService", | ||
VirtualMachine = "VirtualMachine", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { SupportedSku, SupportedSkuType } from "./sku-models"; | ||
|
||
export interface ListSkusOptions { | ||
subscriptionId: string; | ||
type?: SupportedSkuType; | ||
locationName: string; | ||
} | ||
|
||
export interface SkuService { | ||
list(options: ListSkusOptions): Promise<SupportedSku[]>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { getLocalizer, translate } from "@azure/bonito-core/lib/localization"; | ||
import { BatchDependencyName } from "../environment"; | ||
import { ListSkusOptions, SkuService } from "./sku-service"; | ||
import { inject } from "@azure/bonito-core/lib/environment"; | ||
|
||
export interface SkuEndOfLifeStatus { | ||
eolDate: Date; | ||
warning: string; | ||
} | ||
|
||
export interface EndOfLifeStatusQueryOptions extends ListSkusOptions { | ||
skuName: string; | ||
} | ||
|
||
/** | ||
* Get the end of life status for a SKU | ||
* | ||
* @param options - The options for the query | ||
* @returns The end of life status for the SKU | ||
* @throws If the SKU is not found | ||
*/ | ||
export async function endOfLifeStatus( | ||
options: EndOfLifeStatusQueryOptions | ||
): Promise<SkuEndOfLifeStatus | null> { | ||
const { skuName } = options; | ||
|
||
const skuService: SkuService = inject(BatchDependencyName.SkuService); | ||
const skus = await skuService.list(options); | ||
const sku = skus.find((s) => s.name === skuName); | ||
if (!sku) { | ||
throw new Error(translate("lib.service.sku.notFound", { skuName })); | ||
} | ||
if (sku.batchSupportEndOfLife) { | ||
const eolDate = new Date(sku.batchSupportEndOfLife); | ||
return { | ||
eolDate, | ||
warning: translate("lib.service.sku.eolWarning", { | ||
skuName, | ||
eolDate: eolDate.toLocaleDateString( | ||
getLocalizer().getLocale(), | ||
{ | ||
day: "numeric", | ||
month: "long", | ||
year: "numeric", | ||
} | ||
), | ||
}), | ||
}; | ||
} | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
sku: | ||
notFound: "SKU '{skuName}' not found" | ||
eolWarning: "This SKU is scheduled for retirement on {eolDate}" |
Oops, something went wrong.