Skip to content

Commit

Permalink
Add Azure AD authentication (#14)
Browse files Browse the repository at this point in the history
* Update NuGet packages

* Dump version to 1.2.0

* Add authentication with Azure AD

* Update tests

* Improve docs

* Add observability docker files

* Add OpenTelemetry in .net projects

* Add OpenTelemetry service config value

* Add additional demo services for observability

* Update line ending

* Add tags to activity

* Fix unit test

* Remove IIS parameters in launch settings

* Rollback OpenTelemetry packages to RC8 (Issue with Metrics with RC9)

* Add first metrics and validate correct forwarding to exporter

* Update pipeline for manual execution
  • Loading branch information
devpro authored Mar 23, 2022
1 parent 7feac36 commit 3aa541d
Show file tree
Hide file tree
Showing 56 changed files with 896 additions and 205 deletions.
39 changes: 39 additions & 0 deletions .docker/grafana-datasources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
orgId: 1
url: http://prometheus:9090
basicAuth: false
isDefault: false
version: 1
editable: false
- name: Tempo
type: tempo
access: proxy
orgId: 1
url: http://tempo:3200
basicAuth: false
isDefault: false
version: 1
editable: false
apiVersion: 1
uid: tempo
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: true
version: 1
editable: false
apiVersion: 1
jsonData:
derivedFields:
- datasourceUid: tempo
matcherRegex: (?:"traceid"):"(\w+)"
name: TraceID
url: $${__value.raw}
42 changes: 42 additions & 0 deletions .docker/opentelemetry-collector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
receivers:
otlp:
protocols:
grpc:

exporters:
prometheus:
endpoint: "0.0.0.0:8889"
logging:
zipkin:
endpoint: "http://zipkin:9411/api/v2/spans"
format: proto
file:
path: /etc/output/logs.json
otlp:
endpoint: tempo:4317
tls:
insecure: true
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
format: json
labels:
resource:
service.name: "service_name"
service.instance.id: "service_instance_id"

processors:
batch:

service:
pipelines:
logs:
receivers: [otlp]
exporters: [logging, file, loki]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [logging, prometheus]
traces:
receivers: [otlp]
processors: [batch]
exporters: [logging, zipkin, otlp]
6 changes: 6 additions & 0 deletions .docker/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['otel-collector:8889']
- targets: ['otel-collector:8888']
15 changes: 15 additions & 0 deletions .docker/tempo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
server:
http_listen_port: 3200

distributor:
receivers:
otlp:
protocols:
http:
grpc:

storage:
trace:
backend: local
local:
path: /tmp/tempo/blocks
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,6 @@ Local.md
# GitLab runner files
/builds/
/.gitlab/runner/local/

# Local build and log files
/output/*
16 changes: 11 additions & 5 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "external_pull_request_event"'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "web"'

#.dotnet_build:
build:
Expand All @@ -48,16 +49,20 @@ build:
test:
stage: test
variables:
ServiceNow__RestApi__BaseUrl: http://localhost:3000/api/now
ServiceNow__RestApi__Username: dummy
ServiceNow__RestApi__Password: dummy
COBERTURA_REPORT_FILEPATH: ./test/*/TestResults/*/coverage.cobertura.xml
REPORTGENERATOR_OPTIONS: -targetdir:sonarqubecoverage -reporttypes:SonarQube
SONAR_EXTRA_PARAMETERS: /d:sonar.cpd.exclusions=**/*Generated*.cs /d:sonar.coverageReportPaths=./sonarqubecoverage/SonarQube.xml
Application__IsSecuredByAzureAd: "false"
OpenTelemetry__Service: SampleServiceNowRestClient
OpenTelemetry__Metrics__Meter: SampleServiceNowRestClientMetrics
OpenTelemetry__Tracing__Source: SampleServiceNowRestClientTracing
ServiceNow__RestApi__BaseUrl: "http://localhost:3000/api/now"
ServiceNow__RestApi__Password: dummy
ServiceNow__RestApi__Username: dummy
ServiceNow__SqlServer__DataSource: mssql
ServiceNow__SqlServer__UserId: SA
ServiceNow__SqlServer__Password: $SA_PASSWORD
ServiceNow__SqlServer__InitialCatalog: TestDB
ServiceNow__SqlServer__Password: $SA_PASSWORD
ServiceNow__SqlServer__UserId: SA
before_script:
# updates system
- apt-get update
Expand Down Expand Up @@ -105,6 +110,7 @@ test:
only:
- external_pull_requests
- main
- web

# ref. https://docs.microsoft.com/en-us/nuget/nuget-org/publish-a-package
#.dotnet_pack:
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<PropertyGroup>
<!-- edit this value to change the current MAJOR.MINOR.PATCH version -->
<VersionPrefix>1.1.0</VersionPrefix>
<VersionPrefix>1.2.0</VersionPrefix>
</PropertyGroup>

<Choose>
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=rabbids-incubator_servicenow-dotnet-client&metric=coverage)](https://sonarcloud.io/summary/new_code?id=rabbids-incubator_servicenow-dotnet-client)
[![Nuget](https://img.shields.io/nuget/v/RabbidsIncubator.ServiceNowClient.Application.svg)](https://www.nuget.org/packages/RabbidsIncubator.ServiceNowClient.Application)

This is the codebase of .NET components (API & libraries) to simplify the integration with [ServiceNow](https://www.servicenow.com/),
from any system (Linux, MacOS, Windows).
.NET components (API & libraries) to simplify the integration with [ServiceNow](https://www.servicenow.com/), from any system (Linux, MacOS, Windows).

## Quick start
## Getting started

* [Getting Started](./docs/getting-started.md) page to learn about how to use the components
* [Quickstart](./docs/quickstart.md) to get an application running in 5 minutes

* [Contribute](./docs/contribute.md) page to work locally with the sources and improve them
* [Contribution](./docs/contribution.md) to run locally the solution and push code changes

## Going further

* [GitLab](./docs/gitlab.md) page to understand the automation done on this codebase
* [Authentication](./docs/authentication.md) to secure the application

* [ServiceNow](./docs/servicenow.md) page for resources on the SaaS solution
* [Automation](./docs/automation.md) to know about the Continuous Integration and Delivery pipeline

* [Dependencies](./docs/dependencies.md) to view the dependencies (in particular the link with ServiceNow)

* [Design](./docs/design.md) to understand the software design of the solution

* [Observability](./docs/automation.md) to monitor and measure the application
21 changes: 17 additions & 4 deletions RabbidsIncubator.ServiceNowClient.sln
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Application", "src\Applicat
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{D314857E-9EE4-4947-AD1A-0949B04E28CA}"
ProjectSection(SolutionItems) = preProject
docs\contribute.md = docs\contribute.md
docs\getting-started.md = docs\getting-started.md
docs\gitlab.md = docs\gitlab.md
docs\servicenow.md = docs\servicenow.md
docs\authentication.md = docs\authentication.md
docs\automation.md = docs\automation.md
docs\contribution.md = docs\contribution.md
docs\dependencies.md = docs\dependencies.md
docs\design.md = docs\design.md
docs\observability.md = docs\observability.md
docs\quickstart.md = docs\quickstart.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Infrastructure.InMemory", "src\Infrastructure.InMemory\Infrastructure.InMemory.csproj", "{A01619B4-8F70-417D-B4BD-1651D627770E}"
Expand All @@ -62,6 +65,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mocks", "mocks", "{B338D8C5
mocks\servicenow.json = mocks\servicenow.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{8B94AA54-5F8B-463E-9CA0-D7E75B6F60AE}"
ProjectSection(SolutionItems) = preProject
docker-compose.yml = docker-compose.yml
.docker\grafana-datasources.yaml = .docker\grafana-datasources.yaml
.docker\opentelemetry-collector.yml = .docker\opentelemetry-collector.yml
.docker\prometheus.yml = .docker\prometheus.yml
.docker\tempo.yaml = .docker\tempo.yaml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -136,6 +148,7 @@ Global
{84A01CD5-1282-4114-A519-6F4C3625CE60} = {B952F0A1-0DB3-4D9F-BD49-C3DB6389FCB4}
{EA2379E0-3613-4EED-9238-92E6D48C5A62} = {03243F43-0975-4776-A5D3-9BA7141293DA}
{B338D8C5-A1F8-4EAD-97D4-8E23624372BB} = {03243F43-0975-4776-A5D3-9BA7141293DA}
{8B94AA54-5F8B-463E-9CA0-D7E75B6F60AE} = {03243F43-0975-4776-A5D3-9BA7141293DA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CF38BCED-2352-4EDA-A4D5-1462CCD9C659}
Expand Down
62 changes: 62 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
version: "3.9"
services:
zipkin:
image: openzipkin/zipkin:latest
container_name: zipkin
ports:
- "9411:9411"

otel-collector:
image: otel/opentelemetry-collector-contrib:latest
container_name: otel-collector
command: ["--config=/etc/otel-collector.yml"]
volumes:
- ./.docker/opentelemetry-collector.yml:/etc/otel-collector.yml
- ./output:/etc/output:rw
ports:
- "8888:8888" # prometheus metrics
- "8889:8889" # prometheus exporter
- "4317:4317" # oltp grpc receiver
depends_on:
- zipkin
- grafana

prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./.docker/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"

tempo:
image: grafana/tempo:latest
container_name: tempo
command: [ "-config.file=/etc/tempo.yaml" ]
volumes:
- ./.docker/tempo.yaml:/etc/tempo.yaml
ports:
- "3200:3200"

loki:
image: grafana/loki:2.4.2
container_name: loki
command: [ "-config.file=/etc/loki/local-config.yaml" ]
ports:
- "3100:3100"

grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- ./.docker/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_AUTH_DISABLE_LOGIN_FORM=true
depends_on:
- prometheus
- loki
- tempo
26 changes: 26 additions & 0 deletions docs/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Authentication

## How to secure an ASP.NET application with Azure AD

* In [Azure Portal](https://portal.azure.com/), in "Azure Active Directory > Application registrations",
select "New registration"
* Only the same is mandatory
* Once created, the application is displayed
* Save the values of "Application (client) ID", "Directory (tenant) ID"
* Update the application
* "Manifest": manually edit the content (`accessTokenAcceptedVersion` and `allowPublicClient` are null by default)

```json
{
"accessTokenAcceptedVersion": 2,
"allowPublicClient": true,
}
```

* "Certificates & secrets": in "Client Secrets", add a new secret and save the secret value
* "Api permissions": do "Grant admin consent for Default Directory" (Microsoft Graph > User.Read has been added by default)
* "Expose an API": set the application ID URI, "api://<client_id>" is the default and correct choice
* "Expose an API": add a scope, for example "access_as_user" with "Admins and users" for the consent option

* References:
* [Scenario: Protected web API](https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-overview)
2 changes: 1 addition & 1 deletion docs/gitlab.md → docs/automation.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# GitLab configuration guide
# Automation

[GitLab](https://gitlab.com/) is used to run the CI (Continuous Integration) pipeline, which is defined in `.gitlab-ci.yml` file.

Expand Down
35 changes: 32 additions & 3 deletions docs/contribute.md → docs/contribution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contribution guide
# Contribution

## Requirements

Expand Down Expand Up @@ -55,6 +55,12 @@ dotnet build
"IsSwaggerEnabled": true,
"IsHttpsEnforced": false
},
"AzureAd": {
"Domain": "xxx.onmicrosoft.com",
"TenantId": "xxx",
"ClientId": "xxx",
"ClientSecret": "xxx"
},
"Logging": {
"LogLevel": {
"RabbidsIncubator": "Debug",
Expand Down Expand Up @@ -188,7 +194,7 @@ SA_PASSWORD='s0m3Str0ng!P@ssw0rd'

# runs SQL Server in a container (can be accessed with localhost or 127.0.0.1 as Data Source)
docker pull mcr.microsoft.com/mssql/server:2019-latest
docker run --rm --name mssql --hostname $MSSQL_HOST \
docker run --name mssql --hostname $MSSQL_HOST \
-e "ACCEPT_EULA=Y" -e "SA_PASSWORD=$SA_PASSWORD" -p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2019-latest

Expand All @@ -198,6 +204,29 @@ docker exec -it mssql bash

# initializes database with data
docker cp $PWD/scripts/mssql/db-init.sql mssql:/home/db-init.sql
docker exec mssql ls "/home"
#docker exec mssql ls "/home"
docker exec mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA_PASSWORD -i /home/db-init.sql
```

### Observability

* Start containers (Prometheus, Zipkin and OpenTelemetry collector)

```bash
docker-compose up
```

* Open web UIs:
* [Zipkin](http://localhost:9411/zipkin/)
* [Prometheus](http://localhost:9090/graph)
* [Grafana](http://localhost:3000/)

* Remove containers

```bash
docker-compose up
```

* Warnings:
* If you are running the containers on WSL, when the Linux VM memory is full you will face strange behaviors.
Do not hesitate to restart regularly WSL: `wsl --shutdown`.
4 changes: 3 additions & 1 deletion docs/servicenow.md → docs/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# ServiceNow resources
# Dependencies resources

### ServiceNow

## General

Expand Down
Loading

0 comments on commit 3aa541d

Please sign in to comment.