Skip to content

Commit

Permalink
Add PlaybackService code
Browse files Browse the repository at this point in the history
  • Loading branch information
xieyubo committed Aug 10, 2023
1 parent b9815c6 commit 41ca835
Show file tree
Hide file tree
Showing 36 changed files with 3,076 additions and 0 deletions.
6 changes: 6 additions & 0 deletions AMSMigrate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<RepositoryUrl>https://github.com/Azure/azure-media-migration</RepositoryUrl>
</PropertyGroup>

<ItemGroup>
<Compile Remove="tools\**" />
<EmbeddedResource Remove="tools\**" />
<None Remove="tools\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.9.0" />
<PackageReference Include="Azure.Monitor.Query" Version="1.2.0" />
Expand Down
28 changes: 28 additions & 0 deletions tools/PlaybackService/.github/ISSUE_TEMPLATE/JitAccess.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Temporary administrator access request
description: Request for temporary repository administrator access to this repository, a.k.a Just-in-Time (JIT) access.
title: "JIT Request"
labels: ["jit"]
assignees:
- gimsvc_microsoft
-
body:
- type: markdown
attributes:
value: |
:closed_lock_with_key: Permanent repository administrator access is not allowed as per Microsoft security policy. You can use this form to request for temporary administrator access to this repository.
- type: textarea
id: justification
attributes:
label: Justification
description: Describe the actions that you will perform with your temporary administrator access.
placeholder: I need to create secrets.
validations:
required: true
- type: dropdown
id: duration
attributes:
label: Duration (hours)
description: How long do you need access for? The duration you select is in hours.
options:
- 1
- 2
14 changes: 14 additions & 0 deletions tools/PlaybackService/.github/acl/access.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Documentation for ACL policy: https://aka.ms/gim/docs/policy/acl

name: Access control list
description: List of teams and their permission levels
resource: repository
where:
configuration:
manageAccess:
- team: AMS-OK
role: Write
- member: yuboxie
role: Maintain
- member: pohhsu
role: Maintain
6 changes: 6 additions & 0 deletions tools/PlaybackService/.github/compliance/inventory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
inventory:
- source: DirectOwners
items:
- id: yuboxie@microsoft.com
- id: pohhsu@microsoft.com
isProduction: false
15 changes: 15 additions & 0 deletions tools/PlaybackService/.github/policies/branch-protection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Documentation for branch policy: https://aka.ms/gim/docs/policy/branch-protection

name: Default branch protection policy
description: Requires build & test pass before merging into master branch
resource: repository
where:
configuration:
branchProtectionRules:
- branchNamePattern: "master"
requiredApprovingReviewsCount: 0
requiresPullRequestBeforeMerging: true
dismissStaleReviews: true
requiresStrictStatusChecks: true
requiredStatusChecks: ["build_and_test"]
requiresLinearHistory: true
19 changes: 19 additions & 0 deletions tools/PlaybackService/.github/policies/jit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Documentation for JIT policy: https://aka.ms/gim/docs/policy/jit

# metadata
id: id
name: JIT_Access
description: Policy for admin JIT for repos in this org

# filters
resource: repository

# primitive configuration
configuration:
jitAccess:
enabled: true
maxHours: 2
approvers:
role: Maintain
requestors:
role: Write
86 changes: 86 additions & 0 deletions tools/PlaybackService/.github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Master CI

on:
pull_request:
branches:
- master

push:
branches:
- master

workflow_dispatch:

schedule:
- cron: "0 0 * * 1"

jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup DotNet Environment
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x

- name: Build and publish
run: |
dotnet publish -c Release
- name: Test
run: |
dotnet test -c Release
- name: Login Container Repository
uses: docker/login-action@v2
with:
registry: amstest.azurecr.io
username: amstest
password: ${{ secrets.AMSTEST_REPOSITORY_PASSWORD }}

- name: Build Container Image
uses: docker/build-push-action@v4
with:
context: src
tags: amstest.azurecr.io/ams-ok/playbackservice:${{ github.sha }},amstest.azurecr.io/ams-ok/playbackservice:latest

- name: Push Container Image
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event == 'schedule' }}
run: |
docker push amstest.azurecr.io/ams-ok/playbackservice:${{ github.sha }}
docker push amstest.azurecr.io/ams-ok/playbackservice:latest
- name: Upload Deployment Files
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event == 'schedule' }}
uses: actions/upload-artifact@v3
with:
name: deployment-files
path: deployment/

deploy:
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event == 'schedule' }}
runs-on: ubuntu-latest
needs: [build_and_test]
steps:
- name: Download Deployment Files
uses: actions/download-artifact@v3
with:
name: deployment-files
path: deployment/

- name: Login Kubernets
uses: azure/k8s-set-context@v1
with:
kubeconfig: '${{ secrets.AMSTEST_EASTUS_KUBECONFIG }}'

- name: Deploy
uses: Azure/k8s-deploy@v4
with:
namespace: ams-ok
manifests: |
deployment/playbackservice.yaml
images: |
amstest.azurecr.io/ams-ok/playbackservice:${{ github.sha }}
3 changes: 3 additions & 0 deletions tools/PlaybackService/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vs/
bin/
obj/
31 changes: 31 additions & 0 deletions tools/PlaybackService/PlaybackService.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlaybackService", "src\PlaybackService.csproj", "{A084A6AB-1CCC-42AA-B16B-FD78BF9BA1C5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlaybackService.Test", "test\PlaybackService.Test.csproj", "{913B6876-C2CF-4545-A3E3-1F1918510508}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A084A6AB-1CCC-42AA-B16B-FD78BF9BA1C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A084A6AB-1CCC-42AA-B16B-FD78BF9BA1C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A084A6AB-1CCC-42AA-B16B-FD78BF9BA1C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A084A6AB-1CCC-42AA-B16B-FD78BF9BA1C5}.Release|Any CPU.Build.0 = Release|Any CPU
{913B6876-C2CF-4545-A3E3-1F1918510508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{913B6876-C2CF-4545-A3E3-1F1918510508}.Debug|Any CPU.Build.0 = Debug|Any CPU
{913B6876-C2CF-4545-A3E3-1F1918510508}.Release|Any CPU.ActiveCfg = Release|Any CPU
{913B6876-C2CF-4545-A3E3-1F1918510508}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D1C9648F-3171-462F-91D9-859731437864}
EndGlobalSection
EndGlobal
66 changes: 66 additions & 0 deletions tools/PlaybackService/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Azure Media Services Playback Proxy & ClearKey Delivery Server
==

## Overview

This server is an addon service to [Azure Media Services Migration Tool](https://github.com/Azure/azure-media-migration). Azure Media Services Migration tool supports statically encrypting (ClearKey DRM) the content while packaging and upload to an azure blob storage container that has no public access permissions by default. In order for user to be able to view the encrypted content, we provide this sample server that demonstrates the following tasks needed for playback:
- Authorize the request for media fragments from players.
- Read the encrypted media fragments out from the private storage account, and return back to players.
- Respond to the DRM key requests from players.

## Features

* Supports ClearKey DRM for both DASH and HLS format.
* Supports token based customized authorization.
* Supports Azure keyVault service (for ClearKey DRM storage).
* Supports Azure storage service (for DASH/HLS manifests and encrypted media fragments).

## Identity and Permissions

The tool uses Azure Identity library for authentication. See [here](https://learn.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme?view=azure-dotnet) for various ways to authenticate and the settings needed.

You'll need to have the following permissions:

* The identity must have ['Storage Blob Data Reader'](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-blob-data-reader) role for the azure storage account where the media data stored by the [Azure Media Services Migration Tool](https://github.com/Azure/azure-media-migration).
* The identity must have ['Key Vault Secrets User'](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-secrets-user) role for the azure key vault account where the ClearKeys stored by the [Azure Media Services Migration Tool](https://github.com/Azure/azure-media-migration).

_NOTE: If the storage account or key vault account doesn't use Azure RBAC, then you will have to create access policies and grant the read permissions on them._

## Quick Start

### Customize the authorization

To customize the authorization, you can modify the file `src/Middlewares/CustomAuthenticationHandler.cs` and add your own token validation logic inside.

**NOTE: You must add a `token` claim in the final `ClaimsIdentity`. This token will be injected into the DASH/HLS manifests returned to the player. It will be used to authorize the key requests sent by client later.**

### Build project

To build the project, you can run the following command:

dotnet build -c Release
dotnet publish -c Release

You can deploy the binaries in your publish folder (e.g. src\bin\Release\net7.0\publish) by yourself or build a docker image:

docker build -t ams-migration-tool-playback-service:latest src/

### Deploy and run

If you deploy the binaries by yourself, you might need modify some settings in `appsettings.json` file. The most important settings is `AzureKeyVaultAccountName` which is the key vault account name used by [Azure Media Services Migration Tool](https://github.com/Azure/azure-media-migration) to store the ClearKeys.

If you build a docker image, you can set `AzureKeyVaultAccountName` from the environment variable, e.g:

docker run -e PlaybackService__AzureKeyVaultAccountName=<your_azure_key_vault_account_name> -p 80:80 ams-migration-tool-playback-service:latest

If you want to deploy the service in your kubernetes cluster, you can take a look at the configuration file `deployment/playbackservices.yaml` as an example.

## Request URI pattern

This service uses the following URI pattern to retrieve DASH/HLS manifests and media fragments from azure storage account:

https://xxx.xxx.xxxx/<azure-storage-account-name>/<path-to-manifests-or-media-fragments-file>

For example, if you have a dash manifest in an azure storage account called `'amsmigrate'`, and its path is `'ams-migration-output/encrypted/dash.mpd'`, then the URI used for this proxy service will be: `'https://xxx.xxx.xxxx/amsmigrate/ams-migration-output/encrypted/dash.mpd'`.

If you use custom domain for your azure storage account, the `'<azure-storage-account-name>'` can be your custom domain also, e.g: `'https://xxx.xxx.xxxx/amsmigrate.storage.custom.domain/ams-migration-output/encrypted/dash.mpd'`.
77 changes: 77 additions & 0 deletions tools/PlaybackService/deployment/playbackservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: playbackservice
spec:
replicas: 2
selector:
matchLabels:
app: playbackservice
template:
metadata:
labels:
app: playbackservice
spec:
imagePullSecrets:
- name: amtestcr-secret
containers:
- name: playbackservice
image: amstest.azurecr.io/ams-ok/playbackservice:latest
ports:
- containerPort: 80
env:
- name: PlaybackService__AzureKeyVaultAccountName
value: amsmigrationtooltest
- name: PlaybackService__EnableDebugUI
value: "true"
- name: AZURE_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-app-credentials
key: AZURE_TENANT_ID
- name: AZURE_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-app-credentials
key: AZURE_CLIENT_ID
- name: AZURE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-app-credentials
key: AZURE_CLIENT_SECRET
nodeSelector:
kubernetes.io/os: linux
---
apiVersion: v1
kind: Service
metadata:
name: playbackservice
spec:
ports:
- port: 80
selector:
app: playbackservice
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: playbackservice
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- playback.ams-ok.net
secretName: playbackservice-https-cert
rules:
- host: playback.ams-ok.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: playbackservice
port:
number: 80
Loading

0 comments on commit 41ca835

Please sign in to comment.