fix cli client registration (#825)

- The CLIClient approle was not assigned to the cli registration created byt he registration.py script
This commit is contained in:
Cheick Keita
2021-04-26 13:35:34 -07:00
committed by GitHub
parent ced21b2ea3
commit 358d85ef82
3 changed files with 45 additions and 22 deletions

View File

@ -1572,10 +1572,14 @@ class Onefuzz:
client_secret: Optional[str] = None, client_secret: Optional[str] = None,
enable_feature: Optional[PreviewFeature] = None, enable_feature: Optional[PreviewFeature] = None,
tenant_domain: Optional[str] = None, tenant_domain: Optional[str] = None,
reset: Optional[bool] = None,
) -> BackendConfig: ) -> BackendConfig:
"""Configure onefuzz CLI""" """Configure onefuzz CLI"""
self.logger.debug("set config") self.logger.debug("set config")
if reset:
self._backend.config = BackendConfig(authority="", client_id="")
if endpoint is not None: if endpoint is not None:
# The normal path for calling the API always uses the oauth2 workflow, # The normal path for calling the API always uses the oauth2 workflow,
# which the devicelogin can take upwards of 15 minutes to fail in # which the devicelogin can take upwards of 15 minutes to fail in

View File

@ -65,7 +65,7 @@ from data_migration import migrate
from registration import ( from registration import (
OnefuzzAppRole, OnefuzzAppRole,
add_application_password, add_application_password,
assign_scaleset_role, assign_app_role,
authorize_application, authorize_application,
register_application, register_application,
set_app_audience, set_app_audience,
@ -525,10 +525,11 @@ class Client:
logger.info("Upgrading: skipping assignment of the managed identity role") logger.info("Upgrading: skipping assignment of the managed identity role")
return return
logger.info("assigning the user managed identity role") logger.info("assigning the user managed identity role")
assign_scaleset_role( assign_app_role(
self.application_name, self.application_name,
self.results["deploy"]["scaleset-identity"]["value"], self.results["deploy"]["scaleset-identity"]["value"],
self.get_subscription_id(), self.get_subscription_id(),
OnefuzzAppRole.ManagedNode,
) )
def apply_migrations(self) -> None: def apply_migrations(self) -> None:

View File

@ -26,6 +26,7 @@ from azure.graphrbac.models import (
RequiredResourceAccess, RequiredResourceAccess,
ResourceAccess, ResourceAccess,
ServicePrincipal, ServicePrincipal,
ServicePrincipalCreateParameters,
) )
from functional import seq from functional import seq
from msrest.serialization import TZ_UTC from msrest.serialization import TZ_UTC
@ -200,6 +201,16 @@ def create_application_registration(
registered_app: Application = client.applications.create(params) registered_app: Application = client.applications.create(params)
logger.info("creating service principal")
service_principal_params = ServicePrincipalCreateParameters(
account_enabled=True,
app_role_assignment_required=False,
service_principal_type="Application",
app_id=registered_app.app_id,
)
client.service_principals.create(service_principal_params)
atttempts = 5 atttempts = 5
while True: while True:
if atttempts < 0: if atttempts < 0:
@ -221,6 +232,9 @@ def create_application_registration(
continue continue
authorize_application(UUID(registered_app.app_id), UUID(app.app_id)) authorize_application(UUID(registered_app.app_id), UUID(app.app_id))
assign_app_role(
onefuzz_instance_name, name, subscription_id, OnefuzzAppRole.ManagedNode
)
return registered_app return registered_app
@ -395,8 +409,11 @@ def update_pool_registration(onefuzz_instance_name: str, subscription_id: str) -
) )
def assign_scaleset_role_manually( def assign_app_role_manually(
onefuzz_instance_name: str, scaleset_name: str, subscription_id: str onefuzz_instance_name: str,
application_name: str,
subscription_id: str,
app_role: OnefuzzAppRole,
) -> None: ) -> None:
client = get_graph_client(subscription_id) client = get_graph_client(subscription_id)
@ -419,7 +436,7 @@ def assign_scaleset_role_manually(
onefuzz_service_principal = onefuzz_service_principals[0] onefuzz_service_principal = onefuzz_service_principals[0]
scaleset_service_principals: List[ServicePrincipal] = list( scaleset_service_principals: List[ServicePrincipal] = list(
client.service_principals.list(filter="displayName eq '%s'" % scaleset_name) client.service_principals.list(filter="displayName eq '%s'" % application_name)
) )
if not scaleset_service_principals: if not scaleset_service_principals:
@ -428,7 +445,7 @@ def assign_scaleset_role_manually(
scaleset_service_principal.app_roles scaleset_service_principal.app_roles
app_roles: List[AppRole] = [ app_roles: List[AppRole] = [
role for role in app.app_roles if role.value == OnefuzzAppRole.ManagedNode.value role for role in app.app_roles if role.value == app_role.value
] ]
if not app_roles: if not app_roles:
@ -455,12 +472,15 @@ def assign_scaleset_role_manually(
) )
def assign_scaleset_role( def assign_app_role(
onefuzz_instance_name: str, scaleset_name: str, subscription_id: str onefuzz_instance_name: str,
application_name: str,
subscription_id: str,
app_role: OnefuzzAppRole,
) -> None: ) -> None:
""" """
Allows the nodes in the scaleset to access the service by assigning Allows the application to access the service by assigning
their managed identity to the ManagedNode Role their managed identity to the provided App Role
""" """
try: try:
onefuzz_service_appId = query_microsoft_graph( onefuzz_service_appId = query_microsoft_graph(
@ -471,11 +491,9 @@ def assign_scaleset_role(
"$select": "appId", "$select": "appId",
}, },
) )
if len(onefuzz_service_appId["value"]) == 0: if len(onefuzz_service_appId["value"]) == 0:
raise Exception("onefuzz app registration not found") raise Exception("onefuzz app registration not found")
appId = onefuzz_service_appId["value"][0]["appId"] appId = onefuzz_service_appId["value"][0]["appId"]
onefuzz_service_principals = query_microsoft_graph( onefuzz_service_principals = query_microsoft_graph(
method="GET", method="GET",
resource="servicePrincipals", resource="servicePrincipals",
@ -485,28 +503,25 @@ def assign_scaleset_role(
if len(onefuzz_service_principals["value"]) == 0: if len(onefuzz_service_principals["value"]) == 0:
raise Exception("onefuzz app service principal not found") raise Exception("onefuzz app service principal not found")
onefuzz_service_principal = onefuzz_service_principals["value"][0] onefuzz_service_principal = onefuzz_service_principals["value"][0]
scaleset_service_principals = query_microsoft_graph( scaleset_service_principals = query_microsoft_graph(
method="GET", method="GET",
resource="servicePrincipals", resource="servicePrincipals",
params={"$filter": "displayName eq '%s'" % scaleset_name}, params={"$filter": "displayName eq '%s'" % application_name},
) )
if len(scaleset_service_principals["value"]) == 0: if len(scaleset_service_principals["value"]) == 0:
raise Exception("scaleset service principal not found") raise Exception("scaleset service principal not found")
scaleset_service_principal = scaleset_service_principals["value"][0] scaleset_service_principal = scaleset_service_principals["value"][0]
managed_node_role = ( managed_node_role = (
seq(onefuzz_service_principal["appRoles"]) seq(onefuzz_service_principal["appRoles"])
.filter(lambda x: x["value"] == OnefuzzAppRole.ManagedNode.value) .filter(lambda x: x["value"] == app_role.value)
.head_option() .head_option()
) )
if not managed_node_role: if not managed_node_role:
raise Exception( raise Exception(
"ManagedNode role not found in the OneFuzz application " f"{app_role.value} role not found in the OneFuzz application "
"registration. Please redeploy the instance" "registration. Please redeploy the instance"
) )
assignments = query_microsoft_graph( assignments = query_microsoft_graph(
method="GET", method="GET",
resource="servicePrincipals/%s/appRoleAssignments" resource="servicePrincipals/%s/appRoleAssignments"
@ -529,8 +544,8 @@ def assign_scaleset_role(
}, },
) )
except adal.AdalError: except adal.AdalError:
assign_scaleset_role_manually( assign_app_role_manually(
onefuzz_instance_name, scaleset_name, subscription_id onefuzz_instance_name, application_name, subscription_id, app_role
) )
@ -622,8 +637,11 @@ def main() -> None:
args.subscription_id, args.subscription_id,
) )
elif args.command == "assign_scaleset_role": elif args.command == "assign_scaleset_role":
assign_scaleset_role( assign_app_role(
onefuzz_instance_name, args.scaleset_name, args.subscription_id onefuzz_instance_name,
args.scaleset_name,
args.subscription_id,
OnefuzzAppRole.ManagedNode,
) )
else: else:
raise Exception("invalid arguments") raise Exception("invalid arguments")