Skip to content

Commit

Permalink
add major and minor SLAs for sofa
Browse files Browse the repository at this point in the history
  • Loading branch information
erikng committed Jul 10, 2024
1 parent 16f4090 commit 93ce34a
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 40 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ Requires macOS 12.0 and higher. Further releases and feature requests may make t
- `latest-minor`: stay in the current major release and get the latest minor updates available
- This requires utilizing the SOFA feed features to properly work, which is opt-out by default
- Nudge will then utilize two date integers to automatically calculate the `requiredInstallationDate`
- `activelyExploitedCVEsInstallationSLA` under the `osVersionRequirement` key will default to 14 days
- `nonActivelyExploitedCVEsSLA` under the `osVersionRequirement` key will default to 21 days
- `standardInstallationSLA` under the `osVersionRequirement` key will default to 28 days
- `activelyExploitedCVEsMajorUpgradeSLA` under the `osVersionRequirement` key will default to 14 days
- `activelyExploitedCVEsMinorUpdateSLA` under the `osVersionRequirement` key will default to 14 days
- `nonActivelyExploitedCVEsMajorUpgradeSLA` under the `osVersionRequirement` key will default to 21 days
- `nonActivelyExploitedCVEsMinorUpdateSLA` under the `osVersionRequirement` key will default to 21 days
- `standardMajorUpgradeSLA` under the `osVersionRequirement` key will default to 28 days
- `standardMinorUpdateSLA` under the `osVersionRequirement` key will default to 28 days
- These dates are calculated against the `ReleaseDate` key in the SOFA feed, which is UTC formatted. Local timezones will **not be supported** with the automatic sofa feed unless you use a custom feed and change this value yourself, following ISO-8601 date formats
- To artificially delay the SOFA nudge events, see the details below for `nudgeEventLaunchDelay`
- If you'd like to not have nudge events for releases without any known CVEs, please configure the `disableNudgeForStandardInstalls` key under `optionalFeatures` to true
Expand Down
36 changes: 27 additions & 9 deletions Nudge/Preferences/DefaultPreferencesNudge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,15 @@ struct OSVersionRequirementVariables {
""
}

static var activelyExploitedCVEsInstallationSLA: Int {
osVersionRequirementsProfile?.activelyExploitedCVEsInstallationSLA ??
osVersionRequirementsJSON?.activelyExploitedCVEsInstallationSLA ??
static var activelyExploitedCVEsMajorUpgradeSLA: Int {
osVersionRequirementsProfile?.activelyExploitedCVEsMajorUpgradeSLA ??
osVersionRequirementsJSON?.activelyExploitedCVEsMajorUpgradeSLA ??
14
}

static var activelyExploitedCVEsMinorUpdateSLA: Int {
osVersionRequirementsProfile?.activelyExploitedCVEsMinorUpdateSLA ??
osVersionRequirementsJSON?.activelyExploitedCVEsMinorUpdateSLA ??
14
}

Expand All @@ -219,9 +225,15 @@ struct OSVersionRequirementVariables {
""
}

static var nonActivelyExploitedCVEsSLA: Int {
osVersionRequirementsProfile?.nonActivelyExploitedCVEsSLA ??
osVersionRequirementsJSON?.nonActivelyExploitedCVEsSLA ??
static var nonActivelyExploitedCVEsMajorUpgradeSLA: Int {
osVersionRequirementsProfile?.nonActivelyExploitedCVEsMajorUpgradeSLA ??
osVersionRequirementsJSON?.nonActivelyExploitedCVEsMajorUpgradeSLA ??
21
}

static var nonActivelyExploitedCVEsMinorUpdateSLA: Int {
osVersionRequirementsProfile?.nonActivelyExploitedCVEsMinorUpdateSLA ??
osVersionRequirementsJSON?.nonActivelyExploitedCVEsMinorUpdateSLA ??
21
}

Expand All @@ -233,9 +245,15 @@ struct OSVersionRequirementVariables {
}
}

static var standardInstallationSLA: Int {
osVersionRequirementsProfile?.standardInstallationSLA ??
osVersionRequirementsJSON?.standardInstallationSLA ??
static var standardMajorUpgradeSLA: Int {
osVersionRequirementsProfile?.standardMajorUpgradeSLA ??
osVersionRequirementsJSON?.standardMajorUpgradeSLA ??
28
}

static var standardMinorUpdateSLA: Int {
osVersionRequirementsProfile?.standardMinorUpdateSLA ??
osVersionRequirementsJSON?.standardMinorUpdateSLA ??
28
}

Expand Down
36 changes: 24 additions & 12 deletions Nudge/Preferences/PreferencesStructure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,15 @@ struct OSVersionRequirement: Codable {
var aboutUpdateURL: String?
var aboutUpdateURLs: [AboutUpdateURL]?
var actionButtonPath: String?
var activelyExploitedCVEsInstallationSLA: Int?
var activelyExploitedCVEsMajorUpgradeSLA: Int?
var activelyExploitedCVEsMinorUpdateSLA: Int?
var majorUpgradeAppPath: String?
var nonActivelyExploitedCVEsSLA: Int?
var nonActivelyExploitedCVEsMajorUpgradeSLA: Int?
var nonActivelyExploitedCVEsMinorUpdateSLA: Int?
var requiredInstallationDate: Date?
var requiredMinimumOSVersion: String?
var standardInstallationSLA: Int?
var standardMajorUpgradeSLA: Int?
var standardMinorUpdateSLA: Int?
var targetedOSVersionsRule: String?
var unsupportedURL: String?
var unsupportedURLs: [UnsupportedURL]?
Expand All @@ -164,11 +167,14 @@ extension OSVersionRequirement {
init(fromDictionary: [String: AnyObject]) {
self.aboutUpdateURL = fromDictionary["aboutUpdateURL"] as? String
self.actionButtonPath = fromDictionary["actionButtonPath"] as? String
self.activelyExploitedCVEsInstallationSLA = fromDictionary["activelyExploitedCVEsInstallationSLA"] as? Int
self.activelyExploitedCVEsMajorUpgradeSLA = fromDictionary["activelyExploitedCVEsMajorUpgradeSLA"] as? Int
self.activelyExploitedCVEsMinorUpdateSLA = fromDictionary["activelyExploitedCVEsMinorUpdateSLA"] as? Int
self.majorUpgradeAppPath = fromDictionary["majorUpgradeAppPath"] as? String
self.nonActivelyExploitedCVEsSLA = fromDictionary["nonActivelyExploitedCVEsSLA"] as? Int
self.nonActivelyExploitedCVEsMajorUpgradeSLA = fromDictionary["nonActivelyExploitedCVEsMajorUpgradeSLA"] as? Int
self.nonActivelyExploitedCVEsMinorUpdateSLA = fromDictionary["nonActivelyExploitedCVEsMinorUpdateSLA"] as? Int
self.requiredMinimumOSVersion = fromDictionary["requiredMinimumOSVersion"] as? String
self.standardInstallationSLA = fromDictionary["standardInstallationSLA"] as? Int
self.standardMajorUpgradeSLA = fromDictionary["standardMajorUpgradeSLA"] as? Int
self.standardMinorUpdateSLA = fromDictionary["standardMinorUpdateSLA"] as? Int
self.targetedOSVersionsRule = fromDictionary["targetedOSVersionsRule"] as? String
self.unsupportedURL = fromDictionary["unsupportedURL"] as? String

Expand Down Expand Up @@ -239,12 +245,15 @@ extension OSVersionRequirement {
aboutUpdateURL: String? = nil,
aboutUpdateURLs: [AboutUpdateURL]? = nil,
actionButtonPath: String? = nil,
activelyExploitedCVEsInstallationSLA: Int? = nil,
activelyExploitedCVEsMajorUpgradeSLA: Int? = nil,
activelyExploitedCVEsMinorUpdateSLA: Int? = nil,
majorUpgradeAppPath: String? = nil,
nonActivelyExploitedCVEsSLA: Int? = nil,
nonActivelyExploitedCVEsMajorUpgradeSLA: Int? = nil,
nonActivelyExploitedCVEsMinorUpdateSLA: Int? = nil,
requiredInstallationDate: Date? = nil,
requiredMinimumOSVersion: String? = nil,
standardInstallationSLA: Int? = nil,
standardMajorUpgradeSLA: Int? = nil,
standardMinorUpdateSLA: Int? = nil,
targetedOSVersionsRule: String? = nil,
unsupportedURL: String? = nil,
unsupportedURLs: [UnsupportedURL]? = nil
Expand All @@ -253,12 +262,15 @@ extension OSVersionRequirement {
aboutUpdateURL: aboutUpdateURL ?? self.aboutUpdateURL,
aboutUpdateURLs: aboutUpdateURLs ?? self.aboutUpdateURLs,
actionButtonPath: actionButtonPath ?? self.actionButtonPath,
activelyExploitedCVEsInstallationSLA: activelyExploitedCVEsInstallationSLA ?? self.activelyExploitedCVEsInstallationSLA,
activelyExploitedCVEsMajorUpgradeSLA: activelyExploitedCVEsMajorUpgradeSLA ?? self.activelyExploitedCVEsMajorUpgradeSLA,
activelyExploitedCVEsMinorUpdateSLA: activelyExploitedCVEsMinorUpdateSLA ?? self.activelyExploitedCVEsMinorUpdateSLA,
majorUpgradeAppPath: majorUpgradeAppPath ?? self.majorUpgradeAppPath,
nonActivelyExploitedCVEsSLA: nonActivelyExploitedCVEsSLA ?? self.nonActivelyExploitedCVEsSLA,
nonActivelyExploitedCVEsMajorUpgradeSLA: nonActivelyExploitedCVEsMajorUpgradeSLA ?? self.nonActivelyExploitedCVEsMajorUpgradeSLA,
nonActivelyExploitedCVEsMinorUpdateSLA: nonActivelyExploitedCVEsMinorUpdateSLA ?? self.nonActivelyExploitedCVEsMinorUpdateSLA,
requiredInstallationDate: requiredInstallationDate ?? self.requiredInstallationDate,
requiredMinimumOSVersion: requiredMinimumOSVersion ?? self.requiredMinimumOSVersion,
standardInstallationSLA: standardInstallationSLA ?? self.standardInstallationSLA,
standardMajorUpgradeSLA: standardMajorUpgradeSLA ?? self.standardMajorUpgradeSLA,
standardMinorUpdateSLA: standardMinorUpdateSLA ?? self.standardMinorUpdateSLA,
targetedOSVersionsRule: targetedOSVersionsRule ?? self.targetedOSVersionsRule,
unsupportedURL: unsupportedURL ?? self.unsupportedURL,
unsupportedURLs: unsupportedURLs ?? self.unsupportedURLs
Expand Down
26 changes: 16 additions & 10 deletions Nudge/UI/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,21 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let activelyExploitedCVEs = selectedOS!.activelyExploitedCVEs.count > 0
let presentCVEs = selectedOS!.cves.count > 0
let slaExtension: TimeInterval
switch (activelyExploitedCVEs, presentCVEs) {
case (false, true):
slaExtension = TimeInterval(OSVersionRequirementVariables.nonActivelyExploitedCVEsSLA * 86400)
case (true, true):
slaExtension = TimeInterval(OSVersionRequirementVariables.activelyExploitedCVEsInstallationSLA * 86400)
case (false, false):
slaExtension = TimeInterval(OSVersionRequirementVariables.standardInstallationSLA * 86400)
default:
slaExtension = TimeInterval(OSVersionRequirementVariables.standardInstallationSLA * 86400)
switch (activelyExploitedCVEs, presentCVEs, AppStateManager().requireMajorUpgrade()) {
case (false, true, true):
slaExtension = TimeInterval(OSVersionRequirementVariables.nonActivelyExploitedCVEsMajorUpgradeSLA * 86400)
case (false, true, false):
slaExtension = TimeInterval(OSVersionRequirementVariables.nonActivelyExploitedCVEsMinorUpdateSLA * 86400)
case (true, true, true):
slaExtension = TimeInterval(OSVersionRequirementVariables.activelyExploitedCVEsMajorUpgradeSLA * 86400)
case (true, true, false):
slaExtension = TimeInterval(OSVersionRequirementVariables.activelyExploitedCVEsMinorUpdateSLA * 86400)
case (false, false, true):
slaExtension = TimeInterval(OSVersionRequirementVariables.standardMajorUpgradeSLA * 86400)
case (false, false, false):
slaExtension = TimeInterval(OSVersionRequirementVariables.standardMinorUpdateSLA * 86400)
default: // If we get here, something is wrong, use 90 days as a safety
slaExtension = TimeInterval(90 * 86400)
}

if OptionalFeatureVariables.disableNudgeForStandardInstalls && !presentCVEs {
Expand All @@ -228,7 +234,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
nudgePrimaryState.requiredMinimumOSVersion = osVersion.latest.productVersion
nudgePrimaryState.activelyExploitedCVEs = activelyExploitedCVEs
releaseDate = selectedOS!.releaseDate ?? Date()
requiredInstallationDate = selectedOS!.releaseDate?.addingTimeInterval(slaExtension) ?? DateManager().getCurrentDate().addingTimeInterval(TimeInterval(OSVersionRequirementVariables.standardInstallationSLA * 86400))
requiredInstallationDate = selectedOS!.releaseDate?.addingTimeInterval(slaExtension) ?? DateManager().getCurrentDate().addingTimeInterval(TimeInterval(90 * 86400))

LogManager.notice("Extending requiredInstallationDate to \(requiredInstallationDate)", logger: sofaLog)
LogManager.notice("SOFA Matched OS Version: \(selectedOS!.productVersion)", logger: sofaLog)
Expand Down
69 changes: 63 additions & 6 deletions Schema/jamf/com.github.macadmins.Nudge.json
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,27 @@
}
]
},
"activelyExploitedCVEsInstallationSLA": {
"description": "When an update is under active exploit, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"activelyExploitedCVEsMajorUpgradeSLA": {
"description": "When a major upgrade is under active exploit, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
"type": "null"
},
{
"title": "Configured",
"default": 14,
"type": "integer",
"options": {
"inputAttributes": {
"placeholder": "14"
}
}
}
]
},
"activelyExploitedCVEsMinorUpdateSLA": {
"description": "When a minor update is under active exploit, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
Expand Down Expand Up @@ -489,8 +508,27 @@
}
]
},
"nonActivelyExploitedCVEsSLA": {
"description": "When an update is not under active exploit but contains CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"nonActivelyExploitedCVEsMajorUpgradeSLA": {
"description": "When a major upgrade is not under active exploit but contains CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
"type": "null"
},
{
"title": "Configured",
"default": 21,
"type": "integer",
"options": {
"inputAttributes": {
"placeholder": "21"
}
}
}
]
},
"nonActivelyExploitedCVEsMinorUpdateSLA": {
"description": "When a minor update is not under active exploit but contains CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
Expand Down Expand Up @@ -544,8 +582,27 @@
}
]
},
"standardInstallationSLA": {
"description": "When an update has no known CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"standardMajorUpgradeSLA": {
"description": "When a major upgrade has no known CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
"type": "null"
},
{
"title": "Configured",
"default": 28,
"type": "integer",
"options": {
"inputAttributes": {
"placeholder": "28"
}
}
}
]
},
"standardMinorupdateSLA": {
"description": "When a minor update has no known CVEs, this is the amount of days a user has to install the update. (Note: This key is only used with Nudge v2.0 and higher)",
"anyOf": [
{
"title": "Not Configured",
Expand Down

0 comments on commit 93ce34a

Please sign in to comment.