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

[ADMINAPI-645] - DRAFT - Adding script for Bulk vendor-application creation #152

Merged
merged 1 commit into from
Sep 18, 2024
Merged
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
52 changes: 51 additions & 1 deletion docs/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- [Application Architecture](#application-architecture)
- [Database Layer](#database-layer)
- [Validation](#validation)
- [Bulk Application Creation](#bulk-application-creation)

## Development Pre-Requisites

Expand Down Expand Up @@ -198,4 +199,53 @@ credentials.
### Validation

Validation of API requests is configured via
[FluentValidation](https://docs.fluentvalidation.net/en/latest/).
[FluentValidation](https://docs.fluentvalidation.net/en/latest/).

### Bulk Application Creation

This PowerShell script creates multiple vendors and applications upon execution and stores the generated keys/secrets in a file.
The script utilizes a CSV file as input to specify the vendors and applications to be created.
The script prevents duplicate creation of vendors and applications by skipping existing combinations.
Remember to store keys/secrets securely.

## Instructions
1. Download the code: `[email protected]:Ed-Fi-Alliance-OSS/AdminAPI-1.x.git`
2. Open a PowerShell window in Administrator mode and navigate to the /eng/bulk-key-creation folder.
3. Populate the sample CSV with the required vendor and application information.
4. Run the following PowerShell command to load modules for Applications creation:
```
Import-Module .\Bulk-EdFiOdsApplications.psm1
```
5. The Bulk Register Applications can take a number of parameters, copy and modify the following parameter code to fit your needs:

```
$parameters = @{
CSVFilePath = "District details.csv"
BaseApiUrl = "https://localhost/AdminApi"
NamespacePrefixes = "uri://ed-fi.org/"
Key = "YourAdminApiUser"
Secret = "yourAdminApiPassword"
ClaimsetName = "District Hosted SIS Vendor"
logRootPath = "Logs"
}
```

6. Run the following command in the PowerShell window:
```
Bulk-EdFiOdsApplications $parameters
```

7. A new file will be create with the Key and Secrets
###### Parameters definition
* ` CSVFilePath `The csv file to be processed
* ` BaseApiUrl `The Admin Api url, Example: https://localhost/AdminApi1x
* ` namespacePrefixes `The namespace for the vendor, Example: uri://ed-fi.org/
* ` Key `The Key to authenticate with the API
* ` Secret `The Secret to authenticate with the API
* ` ClaimsetName `The claim name that will be assigned to the application, Ex: "District Hosted SIS Vendor"
* ` logRootPath `The Path where you could find the log file


### Logs

By default, the script creates log files, to review them go to the root directory and find the Logs folder.
270 changes: 270 additions & 0 deletions eng/bulk-key-creation/Bulk-EdFiOdsApplications.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
# SPDX-License-Identifier: Apache-2.0
# Licensed to the Ed-Fi Alliance under one or more agreements.
# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
# See the LICENSE and NOTICES files in the project root for more information.

#requires -version 5
$ErrorActionPreference = "Stop"

## CONSTANTS
$ADMINAPI_ENDPOINT_VENDOR = "/v1/vendors"
$ADMINAPI_ENDPOINT_APPLICATION = "/v1/applications"
$ADMINAPI_ENDPOINT_OAUTH_URL = "/connect/token"

function Bulk-EdFiOdsApplications
{
<#
.SYNOPSIS
EdFi Bulk Application generator.

.DESCRIPTION
This PowerShell script creates multiple vendors and applications upon execution and stores the generated keys and secrets in a file.
Please remember to securely store keys and secrets. The script utilizes a CSV file as input to specify the vendors and applications to be created.
The script prevents duplicate creation of vendors and applications by skipping existing combinations.
This Script only works for AdminAPI-1.x

.EXAMPLE
PS c:/> $parameters = @{
CSVFilePath = "District details.csv"
BaseApiUrl = 'https://localhost/AdminApi'
namespacePrefixes = "uri://ed-fi.org/"
Key = "Your_Admin_Api_User"
Secret = "Your_Admin_Api_Password"
ClaimsetName = "District Hosted SIS Vendor"
LogRootPath = "Logs"
}
PS c:/> Bulk-EdFiOdsApplications @parameters

Set your apropiate values .
#>
[CmdletBinding()]
param (
[hashtable]
[Parameter(Mandatory = $true)]
$Config
)

Write-Host "BaseApiUrl $($config.BaseApiUrl)"
# Execute\Init task
Init -Config $config
}

Function Init
{
[CmdletBinding()]
param (
[hashtable]
[Parameter(Mandatory = $true)]
$Config
)
$error.clear()
# Enable Logging
New-Item -ItemType Directory -Force -Path $Config.logRootPath
$date = Get-Date -Format "yyyy-MM-dd-H-m-s"
$logPath = Join-Path -Path $Config.logRootPath -ChildPath "Applications_Log_$date.log"
Start-Transcript -Path $logPath

Write-Host "*** Initializing Ed-Fi > CSV Processing. ***"
Write-Host $Config.BaseApiUrl
Get-Token $Config
Write-Host "Creating a Json Object and Post Applications"
Create-Applications $Config
Stop-Transcript
}
<#
.SYNOPSIS
function that generates a token
#>
Function Get-Token
{
[CmdletBinding()]
param (
[hashtable]
$Config
)
# extract the requiered parameters from the config file.
$baseApiUrl = $Config.BaseApiUrl
$oAuthUrl = "$baseApiUrl" + $ADMINAPI_ENDPOINT_OAUTH_URL
Write-Host " *** Getting Token ******** "
$formData = @{
client_id = $Config.Key
client_secret = $Config.Secret
grant_type = 'client_credentials'
scope = 'edfi_admin_api/full_access'
}
Write-Host "token url $oAuthUrl"
$oAuthResponse = Invoke-RestMethod -Uri "$oAuthUrl" -Method Post -Body $formData
$Config.Token = $OAuthResponse.access_token
}

Function Set-Headers
{
[CmdletBinding()]
param (
[hashtable]
[Parameter(Mandatory = $true)]
$Config
)
$token = $Config.Token
$headers = @{
"Accept" = "application/json"
"Authorization" = "Bearer $token"
"Content-Type" = "application/json"
}
return $headers
}
<#
.SYNOPSIS
function that extract the Vendor Id from the Header
#>
Function Extract-VendorId($Result)
{
try {
$location = $Result.Headers.Location | ConvertTo-Json
return ($location.split("/")[-1]) -replace '\"', ''
}
catch {
Write-Host " An error occurred: $_"
Write-Host $_
}
}

Function Get-Resource
{
[CmdletBinding()]
Param(
[hashtable]
[Parameter(Mandatory = $true)]
$Config,
[string]
[Parameter(Mandatory = $true)]
$EndPoint
)

$token = $Config.Token
$headers = Set-Headers $Config
$baseApiUrl = $Config.BaseApiUrl
$uri = "$baseApiUrl" + "$EndPoint" + "?offset=0&limit=1000"
try {
$result = Invoke-WebRequest -Method Get -Uri $uri -Headers $headers
return $result
}
catch {
Write-Host "An error occurred: $uri"
Write-Host $_
}
}

<#
.SYNOPSIS
function that allows us to post a payload
#>
Function Post-Data
{
[CmdletBinding()]
Param(
[hashtable]
[Parameter(Mandatory = $true)]
$Config,
[PSCustomObject]
[Parameter(Mandatory = $true)]
$PostPayloadJSON,
[string]
[Parameter(Mandatory = $true)]
$EndPoint
)

$headers = Set-Headers $Config
$baseApiUrl = $Config.BaseApiUrl
$uri = "$baseApiUrl" + "$EndPoint"
Write-Host "Uri ***********$uri"
$requestSchema = ConvertTo-Json $PostPayloadJSON
try {
$result = Invoke-WebRequest -Uri $uri -Method Post -Headers $headers -Body $requestSchema
return $result
}
catch {
Write-Host "An error occurred: $uri"
Write-Host "$requestSchema"
Write-Host $_
}
}
<#
.SYNOPSIS
function that allows us to create and Post payloads for vendors and applications
#>
Function Create-Applications
{
[CmdletBinding()]
Param(
[hashtable]
[Parameter(Mandatory = $true)]
$Config
)
Write-Host "Working file '" $Config.CSVFilePath "'"
$vendorsFromOds = @()
$newApplications = @()
$vendorId = 0
$applicationsCount = 0
$csv = import-csv -path $Config.CSVFilePath
$Config.CSVResultFile = ($Config.CSVFilePath -replace '.csv', "$(Get-Date -Format "yyyy-MM-dd-H-m") _key_Secret.csv")
$namesPace = $Config.NamesPace

$vendorsFromOds = ((Get-Resource $Config $ADMINAPI_ENDPOINT_VENDOR).Content | ConvertFrom-Json)."result"
$applicationsFromOds = ((Get-Resource $Config $ADMINAPI_ENDPOINT_APPLICATION).Content | ConvertFrom-Json)."result"

Import-Csv $Config.CSVFilePath -delimiter "," -Header EducationOrganiztionId,VendorName,ApplicationName,ContactName,ContactEmail,key,secret|Select-Object -Skip 1|
ForEach-Object {
$vendor = $_.Vendorname
$applicationName = $_.ApplicationName
$vendorId = ($vendorsFromOds | Where-object {$_.company -eq $vendor }).vendorId | Select-Object -First 1
if ($null -eq $vendorId)
{
$objVendors = [PSCustomObject]@{
company = [System.Security.SecurityElement]::Escape($_.Vendorname)
namespacePrefixes = [System.Security.SecurityElement]::Escape($Config.namespacePrefixes)
contactName = [System.Security.SecurityElement]::Escape($_.contactName)
contactEmailAddress = [System.Security.SecurityElement]::Escape($_.ContactEmail)
}
$vendorResult = Post-Data $Config $objVendors $ADMINAPI_ENDPOINT_VENDOR
$vendorId = Extract-VendorId $vendorResult
Write-Host "A new Vendor was created $vendorId"
}
$applicationId = ($applicationsFromOds | Where-object {$_.applicationName -eq $applicationName -and $_.vendorId -eq $vendorId }).applicationId | Select-Object -First 1
if ($null -eq $applicationId)
{
$objApplications = [PSCustomObject]@{
applicationName = [System.Security.SecurityElement]::Escape($applicationName)
vendorId = $vendorId
claimSetName = [System.Security.SecurityElement]::Escape($Config.ClaimsetName)
educationOrganizationIds = @([System.Security.SecurityElement]::Escape($_.EducationOrganiztionId))
}

$application = (Post-Data $Config $ObjApplications $ADMINAPI_ENDPOINT_APPLICATION).Content | ConvertFrom-Json
$applicationResult = $Application."result"
Write-Host "The application $applicationName was created"
$newApplications += [PSCustomObject]@{
ApplicationName = $_.ApplicationName
key = $applicationResult.key
secret = $applicationResult.secret
}
$applicationsCount ++
}else
{
Write-Host "The application already exist. Skipped Vendor : $vendor, Application : $applicationName"
}
}
if ($applicationsCount -gt 0)
{
$newApplications | Export-Csv -Path $Config.CSVResultFile -NoTypeInformation
Write-Host "*********************************************************************************************************"
Write-Host "*** Find the keys and secrets in the '$($Config.CSVResultFile)' file "
Write-Host "*********************************************************************************************************"
}else
{
Write-Host "*********************************************************************************************************"
Write-Host "*** No applications were created "
Write-Host "*********************************************************************************************************"
}

}
1 change: 1 addition & 0 deletions eng/bulk-key-creation/District details.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EducationOrganiztionId,VendorName,ApplicationName,ContactName,ContactEmail