Skip to content

Commit

Permalink
Merge pull request #1174 from CompositionalIT/vm_features
Browse files Browse the repository at this point in the history
VM support for Azure Linux 3.0, Standard SKU Public IP, Gallery Apps
  • Loading branch information
ninjarobot authored Dec 31, 2024
2 parents 2b168ce + 541450e commit 0936a50
Show file tree
Hide file tree
Showing 13 changed files with 1,769 additions and 849 deletions.
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

## 1.9.9
* Virtual Machines: support for Azure Linux 3.0
* Virtual Machines: support for Standard SKU Public IP Address
* Galleries: support for Gallery Applications to distribute applications for Virtual Machines and Virtual Machine Scale Sets

## 1.9.8
* AKS Cluster: support for node pool availability zones

Expand Down
136 changes: 105 additions & 31 deletions docs/content/api-overview/resources/gallery.md

Large diffs are not rendered by default.

113 changes: 57 additions & 56 deletions docs/content/api-overview/resources/virtual-machine.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Farmer/Arm/AutoscaleSettings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let autoscaleSettings =

// Have avoided SRTPs in the past but end up with a lot of repetitive code, so trying them.

module private Option =
module internal Option =
let defaultUnchecked<'t> = Option.defaultValue Unchecked.defaultof<'t>

let inline toArmJson resourceOpt =
Expand Down
229 changes: 224 additions & 5 deletions src/Farmer/Arm/Gallery.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ open Farmer
open Farmer.Image
open Farmer.GalleryValidation

let galleries = ResourceType("Microsoft.Compute/galleries", "2022-03-03")
let galleryImages = ResourceType("Microsoft.Compute/galleries/images", "2022-03-03")
let galleries = ResourceType("Microsoft.Compute/galleries", "2023-07-03")
let galleryImages = ResourceType("Microsoft.Compute/galleries/images", "2023-07-03")

let imageVersions =
ResourceType("Microsoft.Compute/galleries/images/versions", "2022-03-03")
ResourceType("Microsoft.Compute/galleries/images/versions", "2023-07-03")

let galleryApplications =
ResourceType("Microsoft.Compute/galleries/applications", "2022-03-03")
ResourceType("Microsoft.Compute/galleries/applications", "2023-07-03")

let galleryApplicationVersions =
ResourceType("Microsoft.Compute/galleries/applications/versions", "2022-03-03")
ResourceType("Microsoft.Compute/galleries/applications/versions", "2023-07-03")

type CommunityGalleryInfo = {
Eula: string
Expand Down Expand Up @@ -172,4 +172,223 @@ type GalleryImage = {
|}
releaseNoteUri = this.ReleaseNoteUri |> Option.map (fun uri -> uri.AbsoluteUri) |> Option.toObj
|}
|}

[<RequireQualifiedAccess>]
type ParameterType =
| ConfigurationDataBlob
| LogOutputBlob
| String of DefaultValue: string option

member internal this.ToArmJson =
match this with
| ConfigurationDataBlob -> "ConfigurationDataBlob"
| LogOutputBlob -> "LogOutputBlob"
| String _ -> "String"

type CustomActionParameter = {
Description: string option
Name: string
Required: bool option
ParameterType: ParameterType
} with

member internal this.ToArmJson = {|
defaultValue =
match this.ParameterType with
| ParameterType.String(Some defaultVal) -> defaultVal
| _ -> null
description = this.Description |> Option.toObj
name = this.Name
required = this.Required |> Option.toNullable
``type`` = this.ParameterType.ToArmJson
|}

type CustomAction = {
Description: string option
Name: string
Parameters: CustomActionParameter list
Script: string
} with

member internal this.ToArmJson = {|
description = this.Description |> Option.toObj
name = this.Name
parameters = this.Parameters |> List.map _.ToArmJson
script = this.Script
|}

type GalleryApplication = {
Name: GalleryApplicationName
GalleryName: GalleryName
Location: Location
CustomActions: CustomAction list
Description: string option
EndOfLifeDate: DateTimeOffset option
Eula: string option
OsType: OS
PrivacyStatementUri: Uri option
ReleaseNoteUri: Uri option
Tags: Map<string, string>
Dependencies: Set<ResourceId>
} with

interface IArmResource with
member this.ResourceId =
galleryApplications.resourceId (this.GalleryName.ResourceName, this.Name.ResourceName)

member this.JsonModel = {|
galleryApplications.Create(
this.GalleryName.ResourceName / this.Name.ResourceName,
this.Location,
dependsOn = this.Dependencies,
tags = this.Tags
) with
properties = {|
customActions = this.CustomActions |> List.map _.ToArmJson
description = this.Description |> Option.toObj
endOfLifeDate = this.EndOfLifeDate |> Option.map (_.ToString("yyyy-MM-dd")) |> Option.toObj
eula = this.Eula |> Option.toObj
supportedOSType = string<OS> this.OsType
privacyStatementUri =
this.PrivacyStatementUri
|> Option.map (fun uri -> uri.AbsoluteUri)
|> Option.toObj
releaseNoteUri = this.ReleaseNoteUri |> Option.map (fun uri -> uri.AbsoluteUri) |> Option.toObj
|}
|}

type ManageActions = {
Install: string
Remove: string
Update: string option
} with

static member Empty = {
Install = ""
Remove = ""
Update = None
}

member internal this.ToArmJson = {|
install = this.Install
remove = this.Remove
update = this.Update |> Option.toObj
|}

type ReplicationMode =
| Full
| Shallow

member this.ArmValue =
match this with
| Full -> "Full"
| Shallow -> "Shallow"

type UserArtifactSettings = {
ConfigFileName: string option
PackageFileName: string option
} with

member internal this.ToArmJson = {|
configFileName = this.ConfigFileName |> Option.toObj
packageFileName = this.PackageFileName |> Option.toObj
|}

type UserArtifactSource = {
DefaultConfigurationLink: Uri option
MediaLink: Uri
} with

static member Empty = {
DefaultConfigurationLink = None
MediaLink = null
}

member internal this.ToArmJson = {|
defaultConfigurationLink = this.DefaultConfigurationLink |> Option.toObj
mediaLink = this.MediaLink
|}

[<RequireQualifiedAccess>]
type StorageAccountType =
| Premium_LRS
| Standard_LRS
| Standard_ZRS

member internal this.ArmValue =
match this with
| Premium_LRS -> "Premium_LRS"
| Standard_LRS -> "Standard_LRS"
| Standard_ZRS -> "Standard_ZRS"

type TargetRegion = {
ExcludeFromLatest: bool option
Name: Location
RegionalReplicaCount: int option
StorageAccountType: StorageAccountType option
} with

member internal this.ToArmJson = {|
excludeFromLatest = this.ExcludeFromLatest |> Option.toNullable
name = this.Name.ArmValue
regionalReplicaCount = this.RegionalReplicaCount |> Option.toNullable
storageAccountType = this.StorageAccountType |> Option.map _.ArmValue |> Option.toObj
|}

type GalleryApplicationVersion = {
Name: GalleryApplicationVersionName
GalleryApplicationName: GalleryApplicationName
GalleryName: GalleryName
Location: Location
CustomActions: CustomAction list
EnableHealthCheck: bool option
EndOfLifeDate: DateTimeOffset option
ExcludeFromLatest: bool option
ManageActions: ManageActions
ReplicaCount: int option
ReplicationMode: ReplicationMode option
Settings: UserArtifactSettings option
Source: UserArtifactSource
StorageAccountType: StorageAccountType option
TargetRegions: TargetRegion list
Tags: Map<string, string>
Dependencies: Set<ResourceId>
} with

interface IArmResource with
member this.ResourceId =
galleryApplicationVersions.resourceId (
this.GalleryName.ResourceName
/ this.GalleryApplicationName.ResourceName
/ this.Name.ResourceName
)

member this.JsonModel = {|
galleryApplicationVersions.Create(
this.GalleryName.ResourceName
/ this.GalleryApplicationName.ResourceName
/ this.Name.ResourceName,
this.Location,
dependsOn = this.Dependencies,
tags = this.Tags
) with
properties = {|
publishingProfile = {|
customActions = this.CustomActions |> List.map _.ToArmJson
enableHealthCheck = this.EnableHealthCheck |> Option.toNullable
endOfLifeDate = this.EndOfLifeDate |> Option.map (_.ToString("yyyy-MM-dd")) |> Option.toObj
excludeFromLatest = this.ExcludeFromLatest |> Option.toNullable
manageActions = this.ManageActions.ToArmJson
replicaCount = this.ReplicaCount |> Option.toNullable
replicationMode = this.ReplicationMode |> Option.map _.ArmValue |> Option.toObj
settings =
this.Settings
|> Option.map _.ToArmJson
|> Option.defaultValue Unchecked.defaultof<_>
source = this.Source.ToArmJson
storageAccountType = this.StorageAccountType |> Option.map _.ArmValue |> Option.toObj
targetRegions = this.TargetRegions |> List.map _.ToArmJson
|}
|}
|}
2 changes: 1 addition & 1 deletion src/Farmer/Builders/Builders.AutoscaleSettings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ type AutoscaleSettingsBuilder() =

member _.Yield _ = {
AutoscaleSettings.Name = ResourceName.Empty
Location = Location.Location "[resourceGroup().Location]"
Location = Location.ResourceGroup
Dependencies = Set.empty
Tags = Map.empty
Properties = AutoscaleSettingsPropertiesBuilder().Yield()
Expand Down
Loading

0 comments on commit 0936a50

Please sign in to comment.