Skip to content

Commit 8ab3d5f

Browse files
chore: Refactor dynatrace client into its own authentication sub-folder (#58)
1 parent 33ba8ee commit 8ab3d5f

File tree

8 files changed

+64
-48
lines changed

8 files changed

+64
-48
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
.env
22
dist/*
33
node_modules/
4-
.vscode/
4+
/.vscode/*
5+
!/.vscode/mcp.json
6+
7+
tsconfig.tsbuildinfo

.vscode/mcp.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"servers": {
3+
"my-dynatrace-mcp-server": {
4+
"command": "node",
5+
"cwd": "${workspaceFolder}",
6+
"args": ["${workspaceFolder}/dist/index.js"],
7+
"envFile": "${workspaceFolder}/.env"
8+
}
9+
}
10+
}

src/dynatrace-clients.ts renamed to src/authentication/dynatrace-clients.ts

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,24 @@ import {
55
RequestBodyTypes,
66
} from '@dynatrace-sdk/http-client';
77
import { getSSOUrl } from 'dt-app';
8-
import { version as VERSION } from '../package.json';
9-
10-
// Define the OAuthTokenResponse interface to match the expected structure of the response
11-
export interface OAuthTokenResponse {
12-
scope?: string;
13-
token_type?: string;
14-
expires_in?: number;
15-
access_token?: string;
16-
errorCode?: number;
17-
message?: string;
18-
issueId?: string;
19-
error?: string;
20-
error_description?: string;
21-
}
8+
import { version as VERSION } from '../../package.json';
9+
import { OAuthTokenResponse } from './types';
2210

2311
/**
24-
* Uses the provided oauth Client ID and Secret and requests a token
12+
* Uses the provided oauth Client ID and Secret and requests a token via client-credentials flow
2513
* @param clientId - OAuth Client ID for Dynatrace
2614
* @param clientSecret - Oauth Client Secret for Dynatrace
27-
* @param authUrl - SSO Authentication URL
15+
* @param ssoAuthUrl - SSO Authentication URL
2816
* @param scopes - List of requested scopes
2917
* @returns
3018
*/
3119
const requestToken = async (
3220
clientId: string,
3321
clientSecret: string,
34-
authUrl: string,
22+
ssoAuthUrl: string,
3523
scopes: string[],
3624
): Promise<OAuthTokenResponse> => {
37-
const res = await fetch(authUrl, {
25+
const res = await fetch(ssoAuthUrl, {
3826
method: 'POST',
3927
headers: {
4028
'Content-Type': 'application/x-www-form-urlencoded',
@@ -83,7 +71,9 @@ export class ExtendedOauthClient extends _OAuthHttpClient {
8371
}
8472
}
8573

86-
/** Create an Oauth Client based on clientId, clientSecret, environmentUrl and scopes */
74+
/** Create an Oauth Client based on clientId, clientSecret, environmentUrl and scopes
75+
* This uses a client-credentials flow to request a token from the SSO endpoint.
76+
*/
8777
export const createOAuthClient = async (
8878
clientId: string,
8979
clientSecret: string,
@@ -130,28 +120,3 @@ export const createOAuthClient = async (
130120
userAgent,
131121
);
132122
};
133-
134-
/** Helper function to call an app-function via platform-api */
135-
export const callAppFunction = async (
136-
dtClient: _OAuthHttpClient,
137-
appId: string,
138-
functionName: string,
139-
payload: any,
140-
) => {
141-
console.error(`Sending payload ${JSON.stringify(payload)}`);
142-
143-
const response = await dtClient.send({
144-
url: `/platform/app-engine/app-functions/v1/apps/${appId}/api/${functionName}`,
145-
method: 'POST',
146-
headers: {
147-
'Accept': 'application/json',
148-
'Content-Type': 'application/json',
149-
},
150-
body: payload,
151-
statusValidator: (status: number) => {
152-
return [200].includes(status);
153-
},
154-
});
155-
156-
return await response.body('json');
157-
};

src/authentication/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Define the OAuthTokenResponse interface to match the expected structure of the response
2+
export interface OAuthTokenResponse {
3+
scope?: string;
4+
token_type?: string;
5+
expires_in?: number;
6+
access_token?: string;
7+
errorCode?: number;
8+
message?: string;
9+
issueId?: string;
10+
error?: string;
11+
error_description?: string;
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { _OAuthHttpClient } from '@dynatrace-sdk/http-client';
2+
3+
/** Helper function to call an app-function via platform-api */
4+
export const callAppFunction = async (
5+
dtClient: _OAuthHttpClient,
6+
appId: string,
7+
functionName: string,
8+
payload: any,
9+
) => {
10+
console.error(`Sending payload ${JSON.stringify(payload)}`);
11+
12+
const response = await dtClient.send({
13+
url: `/platform/app-engine/app-functions/v1/apps/${appId}/api/${functionName}`,
14+
method: 'POST',
15+
headers: {
16+
'Accept': 'application/json',
17+
'Content-Type': 'application/json',
18+
},
19+
body: payload,
20+
statusValidator: (status: number) => {
21+
return [200].includes(status);
22+
},
23+
});
24+
25+
return await response.body('json');
26+
};

src/capabilities/get-ownership-information.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { _OAuthHttpClient } from '@dynatrace-sdk/http-client';
2-
import { callAppFunction } from '../dynatrace-clients';
2+
import { callAppFunction } from './call-app-function';
33

44
export const getOwnershipInformation = async (dtClient: _OAuthHttpClient, entityIds: string) => {
55
const ownershipResponse = await callAppFunction(dtClient, 'dynatrace.ownership', 'get-ownership-from-entity', {

src/capabilities/send-slack-message.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { _OAuthHttpClient } from '@dynatrace-sdk/http-client';
2-
import { callAppFunction } from '../dynatrace-clients';
2+
import { callAppFunction } from './call-app-function';
33

44
export const sendSlackMessage = async (
55
dtClient: _OAuthHttpClient,

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { config } from 'dotenv';
2020
import { z, ZodRawShape, ZodTypeAny } from 'zod';
2121

2222
import { version as VERSION } from '../package.json';
23-
import { createOAuthClient } from './dynatrace-clients';
23+
import { createOAuthClient } from './authentication/dynatrace-clients';
2424
import { listVulnerabilities } from './capabilities/list-vulnerabilities';
2525
import { listProblems } from './capabilities/list-problems';
2626
import { getProblemDetails } from './capabilities/get-problem-details';

0 commit comments

Comments
 (0)