Merge pull request #15884 from afscrome/extractdefaultransformers

Extract MS Graph Transformers to their own file
This commit is contained in:
Fredrik Adelöw
2023-01-23 17:12:01 +01:00
committed by GitHub
4 changed files with 171 additions and 139 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-msgraph': patch
---
Extract default transformers to their own file
@@ -0,0 +1,159 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
MICROSOFT_EMAIL_ANNOTATION,
MICROSOFT_GRAPH_GROUP_ID_ANNOTATION,
MICROSOFT_GRAPH_TENANT_ID_ANNOTATION,
MICROSOFT_GRAPH_USER_ID_ANNOTATION,
} from './constants';
import { normalizeEntityName } from './helper';
import { GroupEntity, UserEntity } from '@backstage/catalog-model';
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
/**
* The default implementation of the transformation from a graph organization
* entry to a Group entity.
*
* @public
*/
export async function defaultOrganizationTransformer(
organization: MicrosoftGraph.Organization,
): Promise<GroupEntity | undefined> {
if (!organization.id || !organization.displayName) {
return undefined;
}
const name = normalizeEntityName(organization.displayName!);
return {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: name,
description: organization.displayName!,
annotations: {
[MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]: organization.id!,
},
},
spec: {
type: 'root',
profile: {
displayName: organization.displayName!,
},
children: [],
},
};
}
function extractGroupName(group: MicrosoftGraph.Group): string {
if (group.securityEnabled) {
return group.displayName as string;
}
return (group.mailNickname || group.displayName) as string;
}
/**
* The default implementation of the transformation from a graph group entry to
* a Group entity.
*
* @public
*/
export async function defaultGroupTransformer(
group: MicrosoftGraph.Group,
groupPhoto?: string,
): Promise<GroupEntity | undefined> {
if (!group.id || !group.displayName) {
return undefined;
}
const name = normalizeEntityName(extractGroupName(group));
const entity: GroupEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: name,
annotations: {
[MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]: group.id,
},
},
spec: {
type: 'team',
profile: {},
children: [],
},
};
if (group.description) {
entity.metadata.description = group.description;
}
if (group.displayName) {
entity.spec.profile!.displayName = group.displayName;
}
if (group.mail) {
entity.spec.profile!.email = group.mail;
}
if (groupPhoto) {
entity.spec.profile!.picture = groupPhoto;
}
return entity;
}
/**
* The default implementation of the transformation from a graph user entry to
* a User entity.
*
* @public
*/
export async function defaultUserTransformer(
user: MicrosoftGraph.User,
userPhoto?: string,
): Promise<UserEntity | undefined> {
if (!user.id || !user.displayName || !user.mail) {
return undefined;
}
const name = normalizeEntityName(user.mail);
const entity: UserEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'User',
metadata: {
name,
annotations: {
[MICROSOFT_EMAIL_ANNOTATION]: user.mail!,
[MICROSOFT_GRAPH_USER_ID_ANNOTATION]: user.id!,
},
},
spec: {
profile: {
displayName: user.displayName!,
email: user.mail!,
// TODO: Additional fields?
// jobTitle: user.jobTitle || undefined,
// officeLocation: user.officeLocation || undefined,
// mobilePhone: user.mobilePhone || undefined,
},
memberOf: [],
},
};
if (userPhoto) {
entity.spec.profile!.picture = userPhoto;
}
return entity;
}
@@ -29,8 +29,8 @@ export {
defaultGroupTransformer,
defaultOrganizationTransformer,
defaultUserTransformer,
readMicrosoftGraphOrg,
} from './read';
} from './defaultTransformers';
export { readMicrosoftGraphOrg } from './read';
export type {
GroupTransformer,
OrganizationTransformer,
@@ -19,69 +19,25 @@ import {
stringifyEntityRef,
UserEntity,
} from '@backstage/catalog-model';
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
import limiterFactory from 'p-limit';
import { Logger } from 'winston';
import { MicrosoftGraphClient } from './client';
import {
MICROSOFT_EMAIL_ANNOTATION,
MICROSOFT_GRAPH_GROUP_ID_ANNOTATION,
MICROSOFT_GRAPH_TENANT_ID_ANNOTATION,
MICROSOFT_GRAPH_USER_ID_ANNOTATION,
} from './constants';
import { normalizeEntityName } from './helper';
import { buildMemberOf, buildOrgHierarchy } from './org';
import {
GroupTransformer,
OrganizationTransformer,
UserTransformer,
} from './types';
/**
* The default implementation of the transformation from a graph user entry to
* a User entity.
*
* @public
*/
export async function defaultUserTransformer(
user: MicrosoftGraph.User,
userPhoto?: string,
): Promise<UserEntity | undefined> {
if (!user.id || !user.displayName || !user.mail) {
return undefined;
}
const name = normalizeEntityName(user.mail);
const entity: UserEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'User',
metadata: {
name,
annotations: {
[MICROSOFT_EMAIL_ANNOTATION]: user.mail!,
[MICROSOFT_GRAPH_USER_ID_ANNOTATION]: user.id!,
},
},
spec: {
profile: {
displayName: user.displayName!,
email: user.mail!,
// TODO: Additional fields?
// jobTitle: user.jobTitle || undefined,
// officeLocation: user.officeLocation || undefined,
// mobilePhone: user.mobilePhone || undefined,
},
memberOf: [],
},
};
if (userPhoto) {
entity.spec.profile!.picture = userPhoto;
}
return entity;
}
import {
defaultGroupTransformer,
defaultOrganizationTransformer,
defaultUserTransformer,
} from './defaultTransformers';
export async function readMicrosoftGraphUsers(
client: MicrosoftGraphClient,
@@ -237,40 +193,6 @@ export async function readMicrosoftGraphUsersInGroups(
return { users };
}
/**
* The default implementation of the transformation from a graph organization
* entry to a Group entity.
*
* @public
*/
export async function defaultOrganizationTransformer(
organization: MicrosoftGraph.Organization,
): Promise<GroupEntity | undefined> {
if (!organization.id || !organization.displayName) {
return undefined;
}
const name = normalizeEntityName(organization.displayName!);
return {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: name,
description: organization.displayName!,
annotations: {
[MICROSOFT_GRAPH_TENANT_ID_ANNOTATION]: organization.id!,
},
},
spec: {
type: 'root',
profile: {
displayName: organization.displayName!,
},
children: [],
},
};
}
export async function readMicrosoftGraphOrganization(
client: MicrosoftGraphClient,
tenantId: string,
@@ -286,60 +208,6 @@ export async function readMicrosoftGraphOrganization(
return { rootGroup };
}
function extractGroupName(group: MicrosoftGraph.Group): string {
if (group.securityEnabled) {
return group.displayName as string;
}
return (group.mailNickname || group.displayName) as string;
}
/**
* The default implementation of the transformation from a graph group entry to
* a Group entity.
*
* @public
*/
export async function defaultGroupTransformer(
group: MicrosoftGraph.Group,
groupPhoto?: string,
): Promise<GroupEntity | undefined> {
if (!group.id || !group.displayName) {
return undefined;
}
const name = normalizeEntityName(extractGroupName(group));
const entity: GroupEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: name,
annotations: {
[MICROSOFT_GRAPH_GROUP_ID_ANNOTATION]: group.id,
},
},
spec: {
type: 'team',
profile: {},
children: [],
},
};
if (group.description) {
entity.metadata.description = group.description;
}
if (group.displayName) {
entity.spec.profile!.displayName = group.displayName;
}
if (group.mail) {
entity.spec.profile!.email = group.mail;
}
if (groupPhoto) {
entity.spec.profile!.picture = groupPhoto;
}
return entity;
}
export async function readMicrosoftGraphGroups(
client: MicrosoftGraphClient,
tenantId: string,