Reset to safe template with azure deploy option

This commit is contained in:
benjaminramey
2019-11-03 00:45:25 +00:00
parent 27aab29965
commit ad2720fffb
11 changed files with 651 additions and 52 deletions

View File

@@ -21,6 +21,9 @@ fake build -t Run
```
You can use the included `arm-template.json` file and `build.fsx` script to deploy you application as an Azure Web App. Consult the [official template documentation](https://safe-stack.github.io/docs/template-appservice/) to learn more.
## SAFE Stack Documentation
You will find more documentation about the used F# components at the following places:

View File

@@ -1,2 +1,2 @@
### 0.0.1 - 2019-10-05
### 0.0.1 - 2019-11-02
* Initial release

117
arm-template.json Normal file
View File

@@ -0,0 +1,117 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string"
},
"location": {
"type": "string"
},
"pricingTier": {
"type": "string"
}
},
"variables": {
"environment": "[toLower(parameters('environment'))]",
"prefix": "[concat('safe-', variables('environment'))]",
"appServicePlan": "[concat(variables('prefix'), '-web-host')]",
"web": "[concat(variables('prefix'), '-web')]",
"storage": "[concat('safe', variables('environment'), 'storage')]",
"insights": "[concat(variables('prefix'), '-insights')]"
},
"resources": [
{
"type": "Microsoft.Insights/components",
"kind": "web",
"name": "[variables('insights')]",
"location": "[parameters('location')]",
"apiVersion": "2014-04-01",
"scale": null,
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('web'))]": "Resource",
"displayName": "AppInsightsComponent"
},
"properties": {
"name": "[variables('insights')]"
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "Storage",
"name": "[variables('storage')]",
"apiVersion": "2017-10-01",
"location": "[parameters('location')]",
"tags": {}
},
{
"type": "Microsoft.Web/serverfarms",
"sku": {
"name": "[parameters('pricingTier')]"
},
"name": "[variables('appServicePlan')]",
"apiVersion": "2016-09-01",
"location": "[parameters('location')]",
"properties": {
"name": "[variables('appserviceplan')]",
"perSiteScaling": false,
"reserved": false
}
},
{
"type": "Microsoft.Web/sites",
"name": "[variables('web')]",
"apiVersion": "2016-08-01",
"location": "[parameters('location')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlan'))]",
"siteConfig": {
"appSettings": [
{
"name": "public_path",
"value": "./public"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('Microsoft.Insights/components/', variables('insights'))).InstrumentationKey]"
},
{
"name": "STORAGE_CONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts/', variables('storage')), '2017-10-01').keys[0].value)]"
}
]
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlan'))]",
"[resourceId('Microsoft.Storage/storageAccounts/', variables('storage'))]",
"[resourceId('Microsoft.Insights/components/', variables('insights'))]"
],
"resources": [
{
"apiVersion": "2016-08-01",
"name": "Microsoft.ApplicationInsights.AzureWebSites",
"type": "siteextensions",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/', variables('web'))]"
],
"properties": {}
}
]
}
],
"outputs": {
"webAppName": {
"type": "string",
"value": "[variables('web')]"
},
"webAppPassword": {
"type": "string",
"value": "[list(resourceId('Microsoft.Web/sites/config', variables('web'), 'publishingcredentials'), '2014-06-01').properties.publishingPassword]"
}
}
}

View File

@@ -11,6 +11,10 @@ open System
open Fake.Core
open Fake.DotNet
open Fake.IO
#load @"paket-files/build/CompositionalIT/fshelpers/src/FsHelpers/ArmHelper/ArmHelper.fs"
open Cit.Helpers.Arm
open Cit.Helpers.Arm.Parameters
open Microsoft.Azure.Management.ResourceManager.Fluent.Core
Target.initEnvironment ()
@@ -110,6 +114,84 @@ Target.create "Run" (fun _ ->
Target.create "Bundle" (fun _ ->
let serverDir = deployDir
let publicDir = Path.combine deployDir "public"
let publishArgs = sprintf "publish -c Release -o \"%s\"" serverDir
runDotNet publishArgs serverPath
Shell.copyDir publicDir clientDeployPath FileFilter.allFiles
)
type ArmOutput =
{ WebAppName : ParameterValue<string>
WebAppPassword : ParameterValue<string> }
let mutable deploymentOutputs : ArmOutput option = None
Target.create "ArmTemplate" (fun _ ->
let environment = Environment.environVarOrDefault "environment" (Guid.NewGuid().ToString().ToLower().Split '-' |> Array.head)
let armTemplate = @"arm-template.json"
let resourceGroupName = "safe-" + environment
let authCtx =
// You can safely replace these with your own subscription and client IDs hard-coded into this script.
let subscriptionId = try Environment.environVar "subscriptionId" |> Guid.Parse with _ -> failwith "Invalid Subscription ID. This should be your Azure Subscription ID."
let clientId = try Environment.environVar "clientId" |> Guid.Parse with _ -> failwith "Invalid Client ID. This should be the Client ID of an application registered in Azure with permission to create resources in your subscription."
let tenantId =
try Environment.environVarOrNone "tenantId" |> Option.map Guid.Parse
with _ -> failwith "Invalid TenantId ID. This should be the Tenant ID of an application registered in Azure with permission to create resources in your subscription."
Trace.tracefn "Deploying template '%s' to resource group '%s' in subscription '%O'..." armTemplate resourceGroupName subscriptionId
subscriptionId
|> authenticateDevice Trace.trace { ClientId = clientId; TenantId = tenantId }
|> Async.RunSynchronously
let deployment =
let location = Environment.environVarOrDefault "location" Region.EuropeWest.Name
let pricingTier = Environment.environVarOrDefault "pricingTier" "F1"
{ DeploymentName = "SAFE-template-deploy"
ResourceGroup = New(resourceGroupName, Region.Create location)
ArmTemplate = IO.File.ReadAllText armTemplate
Parameters =
Simple
[ "environment", ArmString environment
"location", ArmString location
"pricingTier", ArmString pricingTier ]
DeploymentMode = Incremental }
deployment
|> deployWithProgress authCtx
|> Seq.iter(function
| DeploymentInProgress (state, operations) -> Trace.tracefn "State is %s, completed %d operations." state operations
| DeploymentError (statusCode, message) -> Trace.traceError <| sprintf "DEPLOYMENT ERROR: %s - '%s'" statusCode message
| DeploymentCompleted d -> deploymentOutputs <- d)
)
open Fake.IO.Globbing.Operators
open System.Net
// https://github.com/SAFE-Stack/SAFE-template/issues/120
// https://stackoverflow.com/a/6994391/3232646
type TimeoutWebClient() =
inherit WebClient()
override this.GetWebRequest uri =
let request = base.GetWebRequest uri
request.Timeout <- 30 * 60 * 1000
request
Target.create "AppService" (fun _ ->
let zipFile = "deploy.zip"
IO.File.Delete zipFile
Zip.zip deployDir zipFile !!(deployDir + @"\**\**")
let appName = deploymentOutputs.Value.WebAppName.value
let appPassword = deploymentOutputs.Value.WebAppPassword.value
let destinationUri = sprintf "https://%s.scm.azurewebsites.net/api/zipdeploy" appName
let client = new TimeoutWebClient(Credentials = NetworkCredential("$" + appName, appPassword))
Trace.tracefn "Uploading %s to %s" zipFile destinationUri
client.UploadData(destinationUri, IO.File.ReadAllBytes zipFile) |> ignore)
@@ -118,6 +200,9 @@ open Fake.Core.TargetOperators
"Clean"
==> "InstallClient"
==> "Build"
==> "Bundle"
==> "ArmTemplate"
==> "AppService"
"Clean"

View File

@@ -6,6 +6,8 @@ group Server
nuget FSharp.Core
nuget Saturn
nuget Thoth.Json.Giraffe
nuget Microsoft.ApplicationInsights.AspNetCore ~> 2.2
nuget WindowsAzure.Storage
group Client
source https://api.nuget.org/v3/index.json
@@ -32,4 +34,8 @@ group Build
nuget Fake.Core.Target
nuget Fake.DotNet.Cli
nuget Fake.IO.FileSystem
nuget Fake.Core.Environment
nuget Fake.Core.Trace
nuget Fake.IO.Zip
github CompositionalIT/fshelpers src/FsHelpers/ArmHelper/ArmHelper.fs

View File

@@ -96,6 +96,12 @@ NUGET
FSharp.Core (>= 4.3.4)
System.Diagnostics.FileVersionInfo (>= 4.3)
System.IO.FileSystem.Watcher (>= 4.3)
Fake.IO.Zip (5.15)
Fake.Core.String (>= 5.15)
Fake.IO.FileSystem (>= 5.15)
FSharp.Core (>= 4.3.4)
System.IO.Compression (>= 4.3)
System.IO.Compression.ZipFile (>= 4.3)
Fake.Net.Http (5.15)
Fake.Core.Trace (>= 5.15)
FSharp.Core (>= 4.3.4)
@@ -107,6 +113,12 @@ NUGET
FSharp.Core (>= 4.2.3)
System.Reactive (>= 4.0)
FSharp.Core (4.6.2)
Microsoft.Azure.Management.ResourceManager.Fluent (1.4.1)
Microsoft.Rest.ClientRuntime.Azure (>= 3.3.10)
Microsoft.Rest.ClientRuntime.Azure.Authentication (>= 2.3.1)
NETStandard.Library (>= 1.6.1)
System.Net.NetworkInformation (>= 4.3)
System.Reflection.TypeExtensions (>= 4.3)
Microsoft.Build (16.0.461)
Microsoft.Build.Framework (16.0.461)
System.Runtime.Serialization.Primitives (>= 4.1.1)
@@ -128,8 +140,28 @@ NUGET
Microsoft.Win32.Registry (>= 4.3)
System.Collections.Immutable (>= 1.5)
System.Text.Encoding.CodePages (>= 4.0.1)
Microsoft.IdentityModel.Clients.ActiveDirectory (3.19.8)
NETStandard.Library (>= 1.6)
System.Runtime.Serialization.Json (>= 4.3)
System.Runtime.Serialization.Primitives (>= 4.3)
Microsoft.IdentityModel.Logging (5.5)
Microsoft.IdentityModel.Tokens (5.5)
Microsoft.IdentityModel.Logging (>= 5.5)
Newtonsoft.Json (>= 10.0.1)
System.Security.Cryptography.Cng (>= 4.5)
Microsoft.NETCore.Platforms (2.2.1)
Microsoft.NETCore.Targets (2.1)
Microsoft.Rest.ClientRuntime (2.3.20)
Newtonsoft.Json (>= 10.0.3)
Microsoft.Rest.ClientRuntime.Azure (3.3.19)
Microsoft.Rest.ClientRuntime (>= 2.3.19 < 3.0)
Newtonsoft.Json (>= 10.0.3)
Microsoft.Rest.ClientRuntime.Azure.Authentication (2.3.2)
Microsoft.IdentityModel.Clients.ActiveDirectory (>= 3.13.9 < 4.0)
Microsoft.IdentityModel.Tokens (>= 5.1.2 < 6.0)
Microsoft.Rest.ClientRuntime (>= 2.3.9 < 3.0)
NETStandard.Library (>= 1.6.1)
Newtonsoft.Json (>= 9.0.1)
Microsoft.Win32.Primitives (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
@@ -173,6 +205,9 @@ NUGET
runtime.native.System (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
runtime.native.System.IO.Compression (4.3.2)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
runtime.native.System.Net.Http (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
@@ -304,6 +339,32 @@ NUGET
System.Runtime (>= 4.3)
System.Text.Encoding (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.IO.Compression (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
runtime.native.System (>= 4.3)
runtime.native.System.IO.Compression (>= 4.3)
System.Buffers (>= 4.3)
System.Collections (>= 4.3)
System.Diagnostics.Debug (>= 4.3)
System.IO (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Runtime.InteropServices (>= 4.3)
System.Text.Encoding (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.IO.Compression.ZipFile (4.3)
System.Buffers (>= 4.3)
System.IO (>= 4.3)
System.IO.Compression (>= 4.3)
System.IO.FileSystem (>= 4.3)
System.IO.FileSystem.Primitives (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Text.Encoding (>= 4.3)
System.IO.FileSystem (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
@@ -398,11 +459,42 @@ NUGET
System.Text.Encoding (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Net.NetworkInformation (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.Win32.Primitives (>= 4.3)
runtime.native.System (>= 4.3)
System.Collections (>= 4.3)
System.Diagnostics.Tracing (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.IO.FileSystem (>= 4.3)
System.IO.FileSystem.Primitives (>= 4.3)
System.Linq (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Net.Sockets (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Runtime.InteropServices (>= 4.3)
System.Security.Principal.Windows (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Overlapped (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Threading.Thread (>= 4.3)
System.Threading.ThreadPool (>= 4.3)
System.Net.Primitives (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
System.Runtime (>= 4.3.1)
System.Runtime.Handles (>= 4.3)
System.Net.Sockets (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.IO (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Runtime (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Numerics.Vectors (4.5)
System.ObjectModel (4.3)
System.Collections (>= 4.3)
@@ -410,6 +502,32 @@ NUGET
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Threading (>= 4.3)
System.Private.DataContractSerialization (4.3)
System.Collections (>= 4.3)
System.Collections.Concurrent (>= 4.3)
System.Diagnostics.Debug (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.Linq (>= 4.3)
System.Reflection (>= 4.3)
System.Reflection.Emit.ILGeneration (>= 4.3)
System.Reflection.Emit.Lightweight (>= 4.3)
System.Reflection.Extensions (>= 4.3)
System.Reflection.Primitives (>= 4.3)
System.Reflection.TypeExtensions (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Serialization.Primitives (>= 4.3)
System.Text.Encoding (>= 4.3)
System.Text.Encoding.Extensions (>= 4.3)
System.Text.RegularExpressions (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Xml.ReaderWriter (>= 4.3)
System.Xml.XDocument (>= 4.3)
System.Xml.XmlDocument (>= 4.3)
System.Xml.XmlSerializer (>= 4.3)
System.Reactive (4.1.5)
System.Runtime.InteropServices.WindowsRuntime (>= 4.3)
System.Threading.Tasks.Extensions (>= 4.5.2)
@@ -506,6 +624,10 @@ NUGET
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Serialization.Json (4.3)
System.IO (>= 4.3)
System.Private.DataContractSerialization (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Serialization.Primitives (4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
@@ -670,6 +792,24 @@ NUGET
System.Text.Encoding (>= 4.3)
System.Threading (>= 4.3)
System.Xml.ReaderWriter (>= 4.3)
System.Xml.XmlSerializer (4.3)
System.Collections (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.Linq (>= 4.3)
System.Reflection (>= 4.3)
System.Reflection.Emit (>= 4.3)
System.Reflection.Emit.ILGeneration (>= 4.3)
System.Reflection.Extensions (>= 4.3)
System.Reflection.Primitives (>= 4.3)
System.Reflection.TypeExtensions (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Text.RegularExpressions (>= 4.3)
System.Threading (>= 4.3)
System.Xml.ReaderWriter (>= 4.3)
System.Xml.XmlDocument (>= 4.3)
System.Xml.XPath (4.3)
System.Collections (>= 4.3)
System.Diagnostics.Debug (>= 4.3)
@@ -701,7 +841,11 @@ NUGET
System.Xml.ReaderWriter (>= 4.3)
System.Xml.XmlDocument (>= 4.3)
System.Xml.XPath (>= 4.3)
GITHUB
remote: CompositionalIT/fshelpers
src/FsHelpers/ArmHelper/ArmHelper.fs (2e1ba955ffcff32a3aa2638d3dcc4f4057cf7186)
Microsoft.Azure.Management.ResourceManager.Fluent (1.4.1)
Microsoft.Rest.ClientRuntime.Azure.Authentication (2.3.2)
GROUP Client
STORAGE: NONE
RESTRICTION: == netstandard2.0
@@ -799,6 +943,63 @@ NUGET
System.Xml.XmlSerializer (>= 4.3)
TaskBuilder.fs (>= 2.1)
Utf8Json (>= 1.3.7)
Microsoft.ApplicationInsights (2.9.1)
NETStandard.Library (>= 1.6.1)
System.Diagnostics.DiagnosticSource (>= 4.5)
System.Diagnostics.StackTrace (>= 4.3)
System.Net.Requests (>= 4.3)
System.Threading.Thread (>= 4.3)
Microsoft.ApplicationInsights.AspNetCore (2.6.1)
Microsoft.ApplicationInsights (>= 2.9.1)
Microsoft.ApplicationInsights.DependencyCollector (>= 2.9.1)
Microsoft.ApplicationInsights.PerfCounterCollector (>= 2.9.1)
Microsoft.ApplicationInsights.WindowsServer (>= 2.9.1)
Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel (>= 2.9.1)
Microsoft.AspNetCore.Hosting (>= 1.0.2)
Microsoft.Extensions.Configuration (>= 1.0.2)
Microsoft.Extensions.Configuration.Json (>= 1.0.2)
Microsoft.Extensions.DiagnosticAdapter (>= 1.1)
Microsoft.Extensions.Logging.Abstractions (>= 1.0.2)
NETStandard.Library (>= 1.6.1)
System.Diagnostics.DiagnosticSource (>= 4.5)
System.Net.NameResolution (>= 4.3)
System.Text.Encodings.Web (>= 4.3.1)
Microsoft.ApplicationInsights.DependencyCollector (2.9.1)
Microsoft.ApplicationInsights (>= 2.9.1)
Microsoft.Extensions.DiagnosticAdapter (>= 1.1)
Microsoft.Extensions.PlatformAbstractions (>= 1.1)
NETStandard.Library (>= 1.6.1)
System.Data.SqlClient (>= 4.3.1)
System.Diagnostics.DiagnosticSource (>= 4.5)
System.Diagnostics.StackTrace (>= 4.3)
Microsoft.ApplicationInsights.PerfCounterCollector (2.9.1)
Microsoft.ApplicationInsights (>= 2.9.1)
Microsoft.Extensions.Caching.Memory (>= 1.0)
Microsoft.Extensions.PlatformAbstractions (>= 1.1)
NETStandard.Library (>= 1.6.1)
System.Runtime.Serialization.Json (>= 4.3)
System.Runtime.Serialization.Primitives (>= 4.3)
System.Threading.Thread (>= 4.3)
Microsoft.ApplicationInsights.WindowsServer (2.9.1)
Microsoft.ApplicationInsights (>= 2.9.1)
Microsoft.ApplicationInsights.DependencyCollector (>= 2.9.1)
Microsoft.ApplicationInsights.PerfCounterCollector (>= 2.9.1)
Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel (>= 2.9.1)
NETStandard.Library (>= 1.6.1)
System.Diagnostics.DiagnosticSource (>= 4.5)
System.Runtime.Serialization.Json (>= 4.3)
System.Runtime.Serialization.Primitives (>= 4.3)
Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel (2.9.1)
Microsoft.ApplicationInsights (>= 2.9.1)
System.Diagnostics.Process (>= 4.3)
System.IO.FileSystem.AccessControl (>= 4.3)
System.Net.NetworkInformation (>= 4.3)
System.Net.Requests (>= 4.3)
System.Net.WebHeaderCollection (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Serialization.Primitives (>= 4.3)
System.Security.Cryptography.Algorithms (>= 4.3)
System.Threading.Thread (>= 4.3)
Microsoft.AspNetCore (2.2)
Microsoft.AspNetCore.Diagnostics (>= 2.2)
Microsoft.AspNetCore.HostFiltering (>= 2.2)
@@ -1047,6 +1248,8 @@ NUGET
Microsoft.Extensions.DependencyInjection (2.2)
Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.2)
Microsoft.Extensions.DependencyInjection.Abstractions (2.2)
Microsoft.Extensions.DiagnosticAdapter (2.2)
System.Diagnostics.DiagnosticSource (>= 4.5)
Microsoft.Extensions.FileProviders.Abstractions (2.2)
Microsoft.Extensions.Primitives (>= 2.2)
Microsoft.Extensions.FileProviders.Physical (2.2)
@@ -1086,6 +1289,9 @@ NUGET
Microsoft.Extensions.Configuration.Binder (>= 2.2)
Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.2)
Microsoft.Extensions.Options (>= 2.2)
Microsoft.Extensions.PlatformAbstractions (1.1)
NETStandard.Library (>= 1.6.1)
System.Reflection.TypeExtensions (>= 4.3)
Microsoft.Extensions.Primitives (2.2)
System.Memory (>= 4.5.1)
System.Runtime.CompilerServices.Unsafe (>= 4.5.1)
@@ -1133,6 +1339,10 @@ NUGET
System.Buffers (>= 4.5)
Microsoft.NETCore.Platforms (2.2.1)
Microsoft.NETCore.Targets (2.1)
Microsoft.Win32.Primitives (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
Microsoft.Win32.Registry (4.5)
System.Security.AccessControl (>= 4.5)
System.Security.Principal.Windows (>= 4.5)
@@ -1148,6 +1358,10 @@ NUGET
runtime.native.System (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
runtime.native.System.Data.SqlClient.sni (4.5)
runtime.win-arm64.runtime.native.System.Data.SqlClient.sni (>= 4.4)
runtime.win-x64.runtime.native.System.Data.SqlClient.sni (>= 4.4)
runtime.win-x86.runtime.native.System.Data.SqlClient.sni (>= 4.4)
runtime.native.System.Net.Http (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
@@ -1179,6 +1393,9 @@ NUGET
runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
runtime.win-arm64.runtime.native.System.Data.SqlClient.sni (4.4)
runtime.win-x64.runtime.native.System.Data.SqlClient.sni (4.4)
runtime.win-x86.runtime.native.System.Data.SqlClient.sni (4.4)
Saturn (0.8)
FSharp.Core (>= 4.2.3)
Giraffe (>= 3.4 < 4.0)
@@ -1226,6 +1443,11 @@ NUGET
System.Runtime.Extensions (>= 4.3)
System.Threading (>= 4.3)
System.ComponentModel.Annotations (4.5)
System.Data.SqlClient (4.6.1)
Microsoft.Win32.Registry (>= 4.5)
runtime.native.System.Data.SqlClient.sni (>= 4.5)
System.Security.Principal.Windows (>= 4.5)
System.Text.Encoding.CodePages (>= 4.5)
System.Diagnostics.Contracts (4.3)
System.Runtime (>= 4.3)
System.Diagnostics.Debug (4.3)
@@ -1233,6 +1455,33 @@ NUGET
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
System.Diagnostics.DiagnosticSource (4.5.1)
System.Diagnostics.Process (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.Win32.Primitives (>= 4.3)
Microsoft.Win32.Registry (>= 4.3)
runtime.native.System (>= 4.3)
System.Collections (>= 4.3)
System.Diagnostics.Debug (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.IO.FileSystem (>= 4.3)
System.IO.FileSystem.Primitives (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Runtime.InteropServices (>= 4.3)
System.Text.Encoding (>= 4.3)
System.Text.Encoding.Extensions (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Threading.Thread (>= 4.3)
System.Threading.ThreadPool (>= 4.3)
System.Diagnostics.StackTrace (4.3)
System.IO.FileSystem (>= 4.3)
System.Reflection (>= 4.3)
System.Reflection.Metadata (>= 1.4.1)
System.Runtime (>= 4.3)
System.Diagnostics.Tools (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
@@ -1291,6 +1540,9 @@ NUGET
System.Runtime.Handles (>= 4.3)
System.Text.Encoding (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.IO.FileSystem.AccessControl (4.5)
System.Security.AccessControl (>= 4.5)
System.Security.Principal.Windows (>= 4.5)
System.IO.FileSystem.Primitives (4.3)
System.Runtime (>= 4.3)
System.IO.Pipelines (4.5.3)
@@ -1346,11 +1598,76 @@ NUGET
System.Text.Encoding (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Net.NameResolution (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
runtime.native.System (>= 4.3)
System.Collections (>= 4.3)
System.Diagnostics.Tracing (>= 4.3)
System.Globalization (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Runtime.InteropServices (>= 4.3)
System.Security.Principal.Windows (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Net.NetworkInformation (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.Win32.Primitives (>= 4.3)
runtime.native.System (>= 4.3)
System.Collections (>= 4.3)
System.Diagnostics.Tracing (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.IO.FileSystem (>= 4.3)
System.IO.FileSystem.Primitives (>= 4.3)
System.Linq (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Net.Sockets (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Runtime.InteropServices (>= 4.3)
System.Security.Principal.Windows (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Overlapped (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Threading.Thread (>= 4.3)
System.Threading.ThreadPool (>= 4.3)
System.Net.Primitives (4.3.1)
Microsoft.NETCore.Platforms (>= 1.1.1)
Microsoft.NETCore.Targets (>= 1.1.3)
System.Runtime (>= 4.3.1)
System.Runtime.Handles (>= 4.3)
System.Net.Requests (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
System.Collections (>= 4.3)
System.Diagnostics.Debug (>= 4.3)
System.Diagnostics.Tracing (>= 4.3)
System.Globalization (>= 4.3)
System.IO (>= 4.3)
System.Net.Http (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Net.WebHeaderCollection (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Threading (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Net.Sockets (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.IO (>= 4.3)
System.Net.Primitives (>= 4.3)
System.Runtime (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Net.WebHeaderCollection (4.3)
System.Collections (>= 4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Numerics.Vectors (4.5)
System.ObjectModel (4.3)
System.Collections (>= 4.3)
@@ -1454,6 +1771,10 @@ NUGET
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Extensions (>= 4.3)
System.Runtime.Serialization.Json (4.3)
System.IO (>= 4.3)
System.Private.DataContractSerialization (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Serialization.Primitives (4.3)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
@@ -1568,6 +1889,9 @@ NUGET
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
System.Text.Encoding.CodePages (4.5.1)
Microsoft.NETCore.Platforms (>= 2.1.2)
System.Runtime.CompilerServices.Unsafe (>= 4.5.2)
System.Text.Encoding.Extensions (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
@@ -1579,11 +1903,21 @@ NUGET
System.Threading (4.3)
System.Runtime (>= 4.3)
System.Threading.Tasks (>= 4.3)
System.Threading.Overlapped (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
System.Resources.ResourceManager (>= 4.3)
System.Runtime (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.Threading.Tasks (4.3)
Microsoft.NETCore.Platforms (>= 1.1)
Microsoft.NETCore.Targets (>= 1.1)
System.Runtime (>= 4.3)
System.Threading.Tasks.Extensions (4.5.2)
System.Threading.Thread (4.3)
System.Runtime (>= 4.3)
System.Threading.ThreadPool (4.3)
System.Runtime (>= 4.3)
System.Runtime.Handles (>= 4.3)
System.ValueTuple (4.5)
System.Xml.ReaderWriter (4.3.1)
System.Collections (>= 4.3)
@@ -1659,3 +1993,6 @@ NUGET
System.Reflection.Emit.Lightweight (>= 4.3)
System.Threading.Tasks.Extensions (>= 4.4)
System.ValueTuple (>= 4.4)
WindowsAzure.Storage (9.3.3)
NETStandard.Library (>= 1.6.1)
Newtonsoft.Json (>= 10.0.2)

View File

@@ -8,58 +8,99 @@ open Fetch.Types
open Thoth.Fetch
open Fulma
open Thoth.Json
open Browser.Types
open Shared
let [<Literal>] ENTER_KEY = 13.
let onEnter msg dispatch =
OnKeyDown (fun ev ->
if ev.keyCode = ENTER_KEY then
dispatch msg)
let targetValue (ev: Event) =
(ev.target :?> HTMLInputElement).value
type Model = { Run: Run }
// The model holds data that you want to keep track of while the application is running
// in this case, we are keeping track of a counter
// we mark it as optional, because initially it will not be available from the client
// the initial value will be requested from server
type Model = { Counter: Counter option }
// The Msg type defines what events/actions can occur while the application is running
// the state of the application changes *only* in reaction to these events
type Msg =
| StartRun
| UpdateName of string
| Increment
| Decrement
| InitialCountLoaded of Counter
//let initialCounter () = Fetch.fetchAs<Counter> "/api/init"
let initialCounter () = Fetch.fetchAs<Counter> "/api/init"
// defines the initial state and initial command (= side-effect) of the application
let init () : Model * Cmd<Msg> =
let initialModel = { Run = { Name = "george" } }
initialModel, Cmd.none
let initialModel = { Counter = None }
let loadCountCmd =
Cmd.OfPromise.perform initialCounter () InitialCountLoaded
initialModel, loadCountCmd
// The update function computes the next state of the application based on the current state and the incoming events/messages
// It can also run side-effects (encoded as commands) like calling the server via Http.
// these commands in turn, can dispatch messages to which the update function will react.
let update (msg : Msg) (currentModel : Model) : Model * Cmd<Msg> =
match msg with
| StartRun ->
let nextModel = { currentModel with Run = { Name = currentModel.Run.Name + " saved" } }
match currentModel.Counter, msg with
| Some counter, Increment ->
let nextModel = { currentModel with Counter = Some { Value = counter.Value + 1 } }
nextModel, Cmd.none
| UpdateName newName ->
let nextModel = { currentModel with Run = { Name = newName }}
| Some counter, Decrement ->
let nextModel = { currentModel with Counter = Some { Value = counter.Value - 1 } }
nextModel, Cmd.none
| _, InitialCountLoaded initialCount->
let nextModel = { Counter = Some initialCount }
nextModel, Cmd.none
| _ -> currentModel, Cmd.none
let safeComponents =
let components =
span [ ]
[ a [ Href "https://github.com/SAFE-Stack/SAFE-template" ]
[ str "SAFE "
str Version.template ]
str ", "
a [ Href "https://saturnframework.github.io" ] [ str "Saturn" ]
str ", "
a [ Href "http://fable.io" ] [ str "Fable" ]
str ", "
a [ Href "https://elmish.github.io" ] [ str "Elmish" ]
str ", "
a [ Href "https://fulma.github.io/Fulma" ] [ str "Fulma" ]
]
span [ ]
[ str "Version "
strong [ ] [ str Version.app ]
str " powered by: "
components ]
let show = function
| { Counter = Some counter } -> string counter.Value
| { Counter = None } -> "Loading..."
let button txt onClick =
Button.button
[ Button.IsFullWidth
Button.Color IsPrimary
Button.OnClick onClick ]
[ str txt ]
let view (model : Model) (dispatch : Msg -> unit) =
Columns.columns []
[ Column.column [ Column.Offset (Screen.All, Column.Is3)
Column.Width (Screen.All, Column.Is6) ]
[ Box.box' []
[ Heading.h1 [] [ str "lunch run" ]
p [] [ str "Start a lunch run today!" ]
Field.div []
[ Control.div []
[ Input.text [ Input.Placeholder "lunch run name"
Input.Value model.Run.Name
Input.OnChange (fun ev -> targetValue ev |> UpdateName |> dispatch)
Input.Props [ onEnter StartRun dispatch ] ]
]
]
]
]
]
div []
[ Navbar.navbar [ Navbar.Color IsPrimary ]
[ Navbar.Item.div [ ]
[ Heading.h2 [ ]
[ str "SAFE Template" ] ] ]
Container.container []
[ Content.content [ Content.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ]
[ Heading.h3 [] [ str ("Press buttons to manipulate counter: " + show model) ] ]
Columns.columns []
[ Column.column [] [ button "-" (fun _ -> dispatch Decrement) ]
Column.column [] [ button "+" (fun _ -> dispatch Increment) ] ] ]
Footer.footer [ ]
[ Content.content [ Content.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ]
[ safeComponents ] ] ]
#if DEBUG
open Elmish.Debug

View File

@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<title>lunch run!</title>
<title>SAFE Template</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

View File

@@ -8,29 +8,37 @@ open Giraffe
open Saturn
open Shared
open Microsoft.WindowsAzure.Storage
let tryGetEnv = System.Environment.GetEnvironmentVariable >> function null | "" -> None | x -> Some x
let publicPath = Path.GetFullPath "../Client/public"
let publicPath = tryGetEnv "public_path" |> Option.defaultValue "../Client/public" |> Path.GetFullPath
let storageAccount = tryGetEnv "STORAGE_CONNECTIONSTRING" |> Option.defaultValue "UseDevelopmentStorage=true" |> CloudStorageAccount.Parse
let port =
"SERVER_PORT"
|> tryGetEnv |> Option.map uint16 |> Option.defaultValue 8085us
// let webApp = router {
// get "/api/init" (fun next ctx ->
// task {
// let counter = {Value = 7}
// return! json counter next ctx
// })
// }
let webApp = router {
get "/api/init" (fun next ctx ->
task {
let counter = {Value = 42}
return! json counter next ctx
})
}
let configureAzure (services:IServiceCollection) =
tryGetEnv "APPINSIGHTS_INSTRUMENTATIONKEY"
|> Option.map services.AddApplicationInsightsTelemetry
|> Option.defaultValue services
let app = application {
url ("http://0.0.0.0:" + port.ToString() + "/")
//use_router webApp
use_router webApp
memory_cache
use_static publicPath
use_json_serializer(Thoth.Json.Giraffe.ThothSerializer())
service_config configureAzure
use_gzip
}

View File

@@ -1,4 +1,6 @@
group Server
FSharp.Core
Saturn
Microsoft.ApplicationInsights.AspNetCore
WindowsAzure.Storage
Thoth.Json.Giraffe

View File

@@ -1,5 +1,5 @@
namespace Shared
type Run = { Name : string }
type Counter = { Value : int }