mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-16 03:48:09 +00:00
Removing Remaining App Function References from Deployment Code. (#2682)
* Removing Remaining App Function References from Deployment Code. * Update src/deployment/deploy.py Co-authored-by: Adam <103067949+AdamL-Microsoft@users.noreply.github.com> * Consolidating. * Updating function handles. * Removing copy. * Fixing. * Formatting. * Fixing array calls. * Adding json settings back. * Formatting. Co-authored-by: Adam <103067949+AdamL-Microsoft@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
0fb8bc4a86
commit
349604f03a
@ -117,19 +117,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
objectId: netFunction.outputs.principalId
|
||||
tenantId: tenantId
|
||||
permissions: {
|
||||
secrets: [
|
||||
'get'
|
||||
'list'
|
||||
'set'
|
||||
'delete'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
tenantId: tenantId
|
||||
}
|
||||
@ -192,21 +179,6 @@ resource roleAssignments 'Microsoft.Authorization/roleAssignments@2020-10-01-pre
|
||||
]
|
||||
}]
|
||||
|
||||
// try to make role assignments to deploy as late as possible in order to have principalId ready
|
||||
resource roleAssignmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
||||
name: guid('${resourceGroup().id}${r.suffix}-1f-net')
|
||||
properties: {
|
||||
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
|
||||
principalId: netFunction.outputs.principalId
|
||||
}
|
||||
dependsOn: [
|
||||
eventGrid
|
||||
keyVault
|
||||
serverFarm
|
||||
featureFlags
|
||||
]
|
||||
}]
|
||||
|
||||
// try to make role assignments to deploy as late as possible in order to have principalId ready
|
||||
resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
|
||||
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
|
||||
@ -250,27 +222,6 @@ module function 'bicep-templates/function.bicep' = {
|
||||
}
|
||||
}
|
||||
|
||||
module netFunction 'bicep-templates/function.bicep' = {
|
||||
name: 'netFunction'
|
||||
params: {
|
||||
linux_fx_version: 'DOTNET-ISOLATED|7.0'
|
||||
name: '${name}-net'
|
||||
|
||||
app_logs_sas_url: storage.outputs.FuncSasUrlBlobAppLogs
|
||||
app_func_audiences: app_func_audiences
|
||||
app_func_issuer: app_func_issuer
|
||||
client_id: clientId
|
||||
diagnostics_log_level: diagnosticsLogLevel
|
||||
location: location
|
||||
log_retention: log_retention
|
||||
owner: owner
|
||||
server_farm_id: serverFarm.outputs.id
|
||||
|
||||
use_windows: true
|
||||
enable_remote_debugging: enable_remote_debugging
|
||||
}
|
||||
}
|
||||
|
||||
module functionSettings 'bicep-templates/function-settings.bicep' = {
|
||||
name: 'functionSettings'
|
||||
params: {
|
||||
@ -291,118 +242,12 @@ module functionSettings 'bicep-templates/function-settings.bicep' = {
|
||||
multi_tenant_domain: multi_tenant_domain
|
||||
enable_profiler: enable_profiler
|
||||
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
|
||||
functions_disabled: '0'
|
||||
agent_function_names: [
|
||||
'AgentCanSchedule' //0
|
||||
'AgentCommands' //1
|
||||
'AgentEvents' //2
|
||||
'AgentRegistration' //3
|
||||
'Containers' //4
|
||||
'Download' //5
|
||||
'Info' //6
|
||||
'InstanceConfig' //7
|
||||
'Jobs' //8
|
||||
'JobTemplates' //9
|
||||
'JobTemplatesManage' //10
|
||||
'Negotiate' //11
|
||||
'Node' //12
|
||||
'NodeAddSshKey' //13
|
||||
'Notifications' //14
|
||||
'Pool' //15
|
||||
'Proxy' //16
|
||||
'QueueFileChanges' //17
|
||||
'QueueNodeHeartbeat' //18
|
||||
'QueueProxyUpdate' //19
|
||||
'QueueSignalrEvents' //20
|
||||
'QueueTaskHeartbeat' //21
|
||||
'QueueUpdates' //22
|
||||
'QueueWebhooks' //23
|
||||
'ReproVms' //24
|
||||
'Scaleset' //25
|
||||
'Tasks' //26
|
||||
'TimerDaily' //27
|
||||
'TimerProxy' //28
|
||||
'TimerRepro' //29
|
||||
'TimerRetention' //30
|
||||
'TimerTasks' //31
|
||||
'TimerWorkers' //32
|
||||
'Tools' //33
|
||||
'Webhooks' //34
|
||||
'WebhooksLogs' //35
|
||||
'WebhooksPing' //36
|
||||
]
|
||||
}
|
||||
dependsOn: [
|
||||
function
|
||||
]
|
||||
}
|
||||
|
||||
module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
|
||||
name: 'netFunctionSettings'
|
||||
params: {
|
||||
owner: owner
|
||||
name: '${name}-net'
|
||||
functions_worker_runtime: 'dotnet-isolated'
|
||||
functions_extension_version: '~4'
|
||||
instance_name: name
|
||||
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||
client_secret: clientSecret
|
||||
signal_r_connection_string: signalR.outputs.connectionString
|
||||
func_sas_url: storage.outputs.FuncSasUrl
|
||||
func_storage_resource_id: storage.outputs.FuncId
|
||||
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||
keyvault_name: keyVaultName
|
||||
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||
multi_tenant_domain: multi_tenant_domain
|
||||
enable_profiler: enable_profiler
|
||||
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
|
||||
functions_disabled: '1'
|
||||
agent_function_names: [
|
||||
'AgentCanSchedule' //0
|
||||
'AgentCommands' //1
|
||||
'AgentEvents' //2
|
||||
'AgentRegistration' //3
|
||||
'Containers' //4
|
||||
'Download' //5
|
||||
'Info' //6
|
||||
'InstanceConfig' //7
|
||||
'Jobs' //8
|
||||
'JobTemplates' //9
|
||||
'JobTemplatesManage' //10
|
||||
'Negotiate' //11
|
||||
'Node' //12
|
||||
'NodeAddSshKey' //13
|
||||
'Notifications' //14
|
||||
'Pool' //15
|
||||
'Proxy' //16
|
||||
'QueueFileChanges' //17
|
||||
'QueueNodeHeartbeat' //18
|
||||
'QueueProxyUpdate' //19
|
||||
'QueueSignalrEvents' //20
|
||||
'QueueTaskHeartbeat' //21
|
||||
'QueueUpdates' //22
|
||||
'QueueWebhooks' //23
|
||||
'ReproVms' //24
|
||||
'Scaleset' //25
|
||||
'Tasks' //26
|
||||
'TimerDaily' //27
|
||||
'TimerProxy' //28
|
||||
'TimerRepro' //29
|
||||
'TimerRetention' //30
|
||||
'TimerTasks' //31
|
||||
'TimerWorkers' //32
|
||||
'Tools' //33
|
||||
'Webhooks' //34
|
||||
'WebhookLogs' //35
|
||||
'WebhookPing' //36
|
||||
]
|
||||
}
|
||||
dependsOn: [
|
||||
netFunction
|
||||
]
|
||||
}
|
||||
|
||||
output fuzz_storage string = storage.outputs.FuzzId
|
||||
output fuzz_name string = storage.outputs.FuzzName
|
||||
output fuzz_key string = storage.outputs.FuzzKey
|
||||
|
@ -28,27 +28,14 @@ param monitor_account_name string
|
||||
param functions_worker_runtime string
|
||||
param functions_extension_version string
|
||||
|
||||
param agent_function_names array
|
||||
param functions_disabled string
|
||||
|
||||
param enable_profiler bool
|
||||
|
||||
var disabledFunctionName = 'disabledFunctions-${name}'
|
||||
|
||||
var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'
|
||||
|
||||
resource function 'Microsoft.Web/sites@2021-02-01' existing = {
|
||||
name: name
|
||||
}
|
||||
|
||||
module disabledFunctions 'function-settings-disabled-apps.bicep' = {
|
||||
name: disabledFunctionName
|
||||
params:{
|
||||
functions_disabled_setting: functions_disabled
|
||||
allFunctions: agent_function_names
|
||||
}
|
||||
}
|
||||
|
||||
var enable_profilers = enable_profiler ? {
|
||||
APPINSIGHTS_PROFILERFEATURE_VERSION : '1.0.0'
|
||||
DiagnosticServices_EXTENSION_VERSION: '~3'
|
||||
@ -79,5 +66,5 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||
ONEFUZZ_KEYVAULT: keyvault_name
|
||||
ONEFUZZ_OWNER: owner
|
||||
ONEFUZZ_CLIENT_SECRET: client_secret
|
||||
}, disabledFunctions.outputs.appSettings, enable_profilers)
|
||||
}, enable_profilers)
|
||||
}
|
||||
|
@ -99,8 +99,6 @@ UPPERCASE_NAME_ERROR = (
|
||||
"specifying for this argument and retry."
|
||||
)
|
||||
|
||||
DOTNET_APPLICATION_SUFFIX = "-net"
|
||||
|
||||
logger = logging.getLogger("deploy")
|
||||
|
||||
|
||||
@ -301,49 +299,25 @@ class Client:
|
||||
"cli_password", object_id, self.get_subscription_id()
|
||||
)
|
||||
|
||||
def get_instance_urls(self) -> List[str]:
|
||||
def get_instance_url(self) -> str:
|
||||
# The url to access the instance
|
||||
# This also represents the legacy identifier_uris of the application
|
||||
# registration
|
||||
if self.multi_tenant_domain:
|
||||
return [
|
||||
"https://%s/%s" % (self.multi_tenant_domain, name)
|
||||
for name in [
|
||||
self.application_name,
|
||||
self.application_name + DOTNET_APPLICATION_SUFFIX,
|
||||
]
|
||||
]
|
||||
return "https://%s/%s" % (self.multi_tenant_domain, self.application_name)
|
||||
else:
|
||||
return [
|
||||
"https://%s.azurewebsites.net" % name
|
||||
for name in [
|
||||
self.application_name,
|
||||
self.application_name + DOTNET_APPLICATION_SUFFIX,
|
||||
]
|
||||
]
|
||||
return "https://%s.azurewebsites.net" % self.application_name
|
||||
|
||||
def get_identifier_urls(self) -> List[str]:
|
||||
def get_identifier_url(self) -> str:
|
||||
# This is used to identify the application registration via the
|
||||
# identifier_uris field. Depending on the environment this value needs
|
||||
# to be from an approved domain The format of this value is derived
|
||||
# from the default value proposed by azure when creating an application
|
||||
# registration api://{guid}/...
|
||||
if self.multi_tenant_domain:
|
||||
return [
|
||||
"api://%s/%s" % (self.multi_tenant_domain, name)
|
||||
for name in [
|
||||
self.application_name,
|
||||
self.application_name + DOTNET_APPLICATION_SUFFIX,
|
||||
]
|
||||
]
|
||||
return "api://%s/%s" % (self.multi_tenant_domain, self.application_name)
|
||||
else:
|
||||
return [
|
||||
"api://%s.azurewebsites.net" % name
|
||||
for name in [
|
||||
self.application_name,
|
||||
self.application_name + DOTNET_APPLICATION_SUFFIX,
|
||||
]
|
||||
]
|
||||
return "api://%s.azurewebsites.net" % self.application_name
|
||||
|
||||
def get_signin_audience(self) -> str:
|
||||
# https://docs.microsoft.com/en-us/azure/active-directory/develop/supported-accounts-validation
|
||||
@ -514,7 +488,7 @@ class Client:
|
||||
# find any identifier URIs that need updating
|
||||
identifier_uris: List[str] = app["identifierUris"]
|
||||
updated_identifier_uris = list(
|
||||
set(identifier_uris) | set(self.get_identifier_urls())
|
||||
set(identifier_uris) | set([self.get_identifier_url()])
|
||||
)
|
||||
if len(updated_identifier_uris) > len(identifier_uris):
|
||||
update_properties["identifierUris"] = updated_identifier_uris
|
||||
@ -561,7 +535,7 @@ class Client:
|
||||
|
||||
params = {
|
||||
"displayName": self.application_name,
|
||||
"identifierUris": self.get_identifier_urls(),
|
||||
"identifierUris": [self.get_identifier_url()],
|
||||
"signInAudience": self.get_signin_audience(),
|
||||
"appRoles": app_roles,
|
||||
"api": {
|
||||
@ -583,10 +557,7 @@ class Client:
|
||||
"enableAccessTokenIssuance": False,
|
||||
"enableIdTokenIssuance": True,
|
||||
},
|
||||
"redirectUris": [
|
||||
f"{url}/.auth/login/aad/callback"
|
||||
for url in self.get_instance_urls()
|
||||
],
|
||||
"redirectUris": [f"{self.get_instance_url()}/.auth/login/aad/callback"],
|
||||
},
|
||||
"requiredResourceAccess": [
|
||||
{
|
||||
@ -662,8 +633,8 @@ class Client:
|
||||
"%Y-%m-%dT%H:%M:%SZ"
|
||||
)
|
||||
|
||||
app_func_audiences = self.get_identifier_urls().copy()
|
||||
app_func_audiences.extend(self.get_instance_urls())
|
||||
app_func_audiences = [self.get_identifier_url()]
|
||||
app_func_audiences.extend([self.get_instance_url()])
|
||||
|
||||
if self.multi_tenant_domain:
|
||||
# clear the value in the Issuer Url field:
|
||||
@ -1135,45 +1106,6 @@ class Client:
|
||||
if error is not None:
|
||||
raise error
|
||||
|
||||
def deploy_dotnet_app(self) -> None:
|
||||
logger.info("deploying function app %s ", self.app_zip)
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
with zipfile.ZipFile(self.app_zip, "r") as zip_ref:
|
||||
func = shutil.which("func")
|
||||
assert func is not None
|
||||
|
||||
zip_ref.extractall(tmpdirname)
|
||||
error: Optional[subprocess.CalledProcessError] = None
|
||||
max_tries = 5
|
||||
for i in range(max_tries):
|
||||
try:
|
||||
subprocess.check_output(
|
||||
[
|
||||
func,
|
||||
"azure",
|
||||
"functionapp",
|
||||
"publish",
|
||||
self.application_name + DOTNET_APPLICATION_SUFFIX,
|
||||
"--no-build",
|
||||
"--dotnet-version",
|
||||
"7.0",
|
||||
],
|
||||
env=dict(os.environ, CLI_DEBUG="1"),
|
||||
cwd=tmpdirname,
|
||||
)
|
||||
return
|
||||
except subprocess.CalledProcessError as err:
|
||||
error = err
|
||||
if i + 1 < max_tries:
|
||||
logger.debug("func failure error: %s", err)
|
||||
logger.warning(
|
||||
"function failed to deploy, waiting 60 "
|
||||
"seconds and trying again"
|
||||
)
|
||||
time.sleep(60)
|
||||
if error is not None:
|
||||
raise error
|
||||
|
||||
def update_registration(self) -> None:
|
||||
if not self.create_registration:
|
||||
return
|
||||
@ -1241,7 +1173,6 @@ def main() -> None:
|
||||
("instance-specific-setup", Client.upload_instance_setup),
|
||||
("third-party", Client.upload_third_party),
|
||||
("api", Client.deploy_app),
|
||||
("dotnet-api", Client.deploy_dotnet_app),
|
||||
("export_appinsights", Client.add_log_export),
|
||||
("update_registration", Client.update_registration),
|
||||
]
|
||||
|
Reference in New Issue
Block a user