Skip to content
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

support cluster credentials api #360

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export declare function AksServiceTests(): void;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import assert = require("assert");
import * as ttm from 'azure-pipelines-task-lib/mock-test';
import tl = require('azure-pipelines-task-lib');
import * as path from 'path';

export function AksServiceTests() {
it('azure-arm-aks-service AksService', (done: Mocha.Done) => {
let tp = path.join(__dirname, 'azure-arm-aks-service-tests.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
let passed: boolean = true;

try {
tr.run();
assert(tr.stdOutContained("Aks Cluster Credential Found: clusterAdmin"), "Should have printed: Aks Cluster Credential Found: clusterAdmin");
assert(tr.stdOutContained("Aks Cluster Credential Found: clusterUser"), "Should have printed: Aks Cluster Credential Found: clusterUser");
assert(tr.stdOutContained("Aks Cluster Credential Found: customUser"), "Should have printed: Aks Cluster Credential Found: customUser");
}
catch(error) {
passed = false;
console.log(tr.stdout);
console.log(tr.stderr);
done(error);
}

if(passed) {
done();
}
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export declare class AksServiceTests {
static credentialsByClusterAdmin(): Promise<void>;
static credentialsByClusterUser(): Promise<void>;
static credentialsByCustomClusterUser(): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { getMockEndpoint, nock, mockAzureAksServiceTests } from './mock_utils';
import tl = require('azure-pipelines-task-lib');
import { AzureAksService } from '../azure-arm-aks-service';

var endpoint = getMockEndpoint();

// Mock all calls for Azure AKS Service
mockAzureAksServiceTests();

export class AksServiceTests {
public static async credentialsByClusterAdmin() {
let aksService: AzureAksService = new AzureAksService(endpoint);
try {
let result = await aksService.getClusterCredential("MOCK_RESOURCE_GROUP_NAME", "MOCK_CLUSTER", true);
console.log(`Aks Cluster Credential Found: ${result.name}`);
}
catch(error) {
console.log(error);
tl.setResult(tl.TaskResult.Failed, 'AksServiceTests.credentialsByClusterAdmin() should have passed but failed');
}
}

public static async credentialsByClusterUser() {
let aksService: AzureAksService = new AzureAksService(endpoint);
try {
let result = await aksService.getClusterCredential("MOCK_RESOURCE_GROUP_NAME", "MOCK_CLUSTER", false);
console.log(`Aks Cluster Credential Found: ${result.name}`);
}
catch(error) {
console.log(error);
tl.setResult(tl.TaskResult.Failed, 'AksServiceTests.credentialsByClusterUser() should have passed but failed');
}
}

public static async credentialsByCustomClusterUser() {
let aksService: AzureAksService = new AzureAksService(endpoint);
try {
let result = await aksService.getClusterCredential("MOCK_RESOURCE_GROUP_NAME", "MOCK_CLUSTER", false, 'customUser');
console.log(`Aks Cluster Credential Found: ${result.name}`);
}
catch(error) {
console.log(error);
tl.setResult(tl.TaskResult.Failed, 'AksServiceTests.credentialsByCustomClusterUser() should have passed but failed');
}
}
}

async function RUNTESTS() {
await AksServiceTests.credentialsByClusterAdmin();
await AksServiceTests.credentialsByClusterUser();
await AksServiceTests.credentialsByCustomClusterUser();
}

RUNTESTS();
46 changes: 45 additions & 1 deletion common-npm-packages/azure-arm-rest/Tests/mock_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ export function mockAzureARMResourcesTests() {
"authorization": "Bearer DUMMY_ACCESS_TOKEN",
"content-type": "application/json; charset=utf-8"
}
}).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resources?$filter=resourceType%20EQ%20%27Microsoft.Web%2Fsites%27%20AND%20name%20EQ%20%27g%C3%B6m-mig-fr%C3%A5n-omv%C3%A4rlden%27&api-version=2016-07-01")
}).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resources?&api-version=2016-07-01")
.reply(200, {
value: [{
id: "subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.web/sites/göm-mig-från-omvär",
Expand All @@ -718,4 +718,48 @@ export function mockAzureARMResourcesTests() {
properties: {}
}]
}).persist();


}

export function mockAzureAksServiceTests() {
nock('https://management.azure.com', {
reqheaders: {
"authorization": "Bearer DUMMY_ACCESS_TOKEN",
"content-type": "application/json; charset=utf-8"
}
}).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.ContainerService/managedClusters/MOCK_CLUSTER/listClusterUserCredential?api-version=2024-05-01")
.reply(200, {
kubeconfigs: [{
name: "clusterUser",
value: "base46kubeconfig"
}]
}).persist();

nock('https://management.azure.com', {
reqheaders: {
"authorization": "Bearer DUMMY_ACCESS_TOKEN",
"content-type": "application/json; charset=utf-8"
}
}).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.ContainerService/managedClusters/MOCK_CLUSTER/listClusterAdminCredential?api-version=2024-05-01")
.reply(200, {
kubeconfigs: [{
name: "clusterAdmin",
value: "base46kubeconfig"
}]
}).persist();

nock('https://management.azure.com', {
reqheaders: {
"authorization": "Bearer DUMMY_ACCESS_TOKEN",
"content-type": "application/json; charset=utf-8"
}
}).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.ContainerService/managedClusters/MOCK_CLUSTER/listClusterUserCredential?api-version=2024-05-01")
.reply(200, {
kubeconfigs: [{
name: "customUser",
value: "base46kubeconfig"
}]
}).persist();

}
34 changes: 30 additions & 4 deletions common-npm-packages/azure-arm-rest/azure-arm-aks-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export class AzureAksService {
this._client = new ServiceClient(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30);
}

public beginRequest(uri: string, parameters: {}) : Promise<webClient.WebResponse> {
public beginRequest(uri: string, parameters: {}, apiVersion: string) : Promise<webClient.WebResponse> {
var webRequest = new webClient.WebRequest();
webRequest.method = 'GET';
webRequest.uri = this._client.getRequestUri(uri, parameters, null,'2017-08-31');
webRequest.uri = this._client.getRequestUri(uri, parameters, null, apiVersion);
return this._client.beginRequestExpBackoff(webRequest, 3).then((response)=>{
if(response.statusCode >= 200 && response.statusCode < 300) {
return response;
Expand All @@ -48,10 +48,36 @@ export class AzureAksService {
'{ResourceGroupName}': resourceGroup,
'{ClusterName}': clusterName,
'{AccessProfileName}': accessProfileName
}).then((response) => {
}, '2017-08-31').then((response) => {
return response.body;
}, (reason) => {
throw Error(tl.loc('CantDownloadAccessProfile',clusterName, this._client.getFormattedError(reason)));
});
}
}

public getClusterCredentials(resourceGroup : string , clusterName : string, useClusterAdmin?: boolean): Promise<Model.AKSCredentialResults> {
var credentialAction = !!useClusterAdmin ? 'listClusterAdminCredential' : 'listClusterUserCredential';
return this.beginRequest(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.ContainerService/managedClusters/{ClusterName}/{CredentialAction}`,
{
'{ResourceGroupName}': resourceGroup,
'{ClusterName}': clusterName,
'{CredentialAction}': credentialAction
}, '2024-05-01').then((response) => {
return response.body;
}, (reason) => {
throw Error(tl.loc('CantDownloadClusterCredentials',clusterName, this._client.getFormattedError(reason)));
});
}

public getClusterCredential(resourceGroup : string , clusterName : string, useClusterAdmin?: boolean, credentialName?: string): Promise<Model.AKSCredentialResult> {
var credentialName = !!credentialName ? credentialName : !!useClusterAdmin ? 'clusterAdmin' : 'clusterUser';
var clusterCredentials = this.getClusterCredentials(resourceGroup, clusterName, useClusterAdmin)
return clusterCredentials.then((credentials) => {
var credential = credentials.kubeconfigs.find(credential => credential.name == credentialName)
if (credential === undefined) {
throw Error(tl.loc('CantDownloadClusterCredentials', clusterName, `${credentialName} not found in the list of cluster credentials.`));
}
return credential;
})
}
}
9 changes: 9 additions & 0 deletions common-npm-packages/azure-arm-rest/azureModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ export interface AKSClusterAccessProfile extends AzureBaseObject {
properties: AKSClusterAccessProfileProperties
}

export interface AKSCredentialResult {
name: string;
value: string;
}

export interface AKSCredentialResults extends AzureBaseObject {
kubeconfigs: Array<AKSCredentialResult>
}

export interface IThresholdRuleConditionDataSource {
"odata.type": string;
resourceUri: string;
Expand Down