def op_load_system_policies(cls, calling_process): """ Create the initial set of policy rules for the system. To establish clear rule precedence, denying all anonymous access to Org services first and then add rules which Permit access to specific operations based on conditions. """ orgms_client = OrgManagementServiceProcessClient(process=calling_process) policyms_client = PolicyManagementServiceProcessClient(process=calling_process) ion_org = orgms_client.find_org() system_actor = get_system_actor() log.info('System actor: %s', system_actor._id) sa_user_header = get_system_actor_header(system_actor) policy_rules_filename = calling_process.CFG.get_safe("bootstrap.initial_policy_rules") if not policy_rules_filename: raise ContainerConfigError("Policy rules file not configured") if not os.path.exists(policy_rules_filename): raise ContainerConfigError("Policy rules file does not exist") with open(policy_rules_filename, "r") as f: policy_rules_yml = f.read() policy_rules_cfg = yaml.safe_load(policy_rules_yml) if "type" not in policy_rules_cfg or policy_rules_cfg["type"] != "scioncc_policy_rules": raise ContainerConfigError("Invalid policy rules file content") log.info("Loading %s policy rules", len(policy_rules_cfg["rules"])) for rule_cfg in policy_rules_cfg["rules"]: rule_name, policy_type, rule_desc = rule_cfg["name"], rule_cfg["policy_type"], rule_cfg.get("description", "") if rule_cfg.get("enable") is False: log.info("Policy rule %s disabled", rule_name) continue log.info("Loading policy rule %s (%s)", rule_name, policy_type) rule_filename = rule_cfg["rule_def"] if not os.path.isabs(rule_filename): rule_filename = os.path.join(os.path.dirname(policy_rules_filename), rule_filename) with open(rule_filename, "r") as f: rule_def = f.read() ordinal = rule_cfg.get("ordinal", 0) # Create the policy if policy_type == "common_service_access": policyms_client.create_common_service_access_policy(rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) elif policy_type == "service_access": service_name = rule_cfg["service_name"] policyms_client.create_service_access_policy(service_name, rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) elif policy_type == "resource_access": resource_type, resource_name = rule_cfg["resource_type"], rule_cfg["resource_name"] res_ids, _ = calling_process.container.resource_registry.find_resources( restype=resource_type, name=resource_name, id_only=True) if res_ids: resource_id = res_ids[0] policyms_client.create_resource_access_policy(resource_id, rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) else: raise ContainerConfigError("Rule %s has invalid policy type: %s" % (rule_name, policy_type))
class ScionLoader(ImmediateProcess, Preloader): def on_init(self): self.process = getattr(self, "process", None) or self self.rr = self.container.resource_registry self.idm_client = IdentityManagementServiceProcessClient(process=self.process) self.org_client = OrgManagementServiceProcessClient(process=self.process) self.scion_client = ScionManagementProcessClient(process=self.process) self.op = self.CFG.get("op", "load") if self.op == "auto": self.do_auto_preload() elif self.op == "init": pass # Initialization only for explicit call elif self.op == "load": preload_master = CFG.get_safe("scion.preload.default_master") if preload_master: self.do_preload_master(preload_master) else: raise BadRequest("Unknown command") def do_preload_core(self): client_obj = IonObject(RT.ActorIdentity, name="SciON UI Client", details=IonObject(OT.OAuthClientIdentityDetails, default_scopes="scion")) client_actor_id = self.idm_client.create_actor_identity(client_obj) client_id = "client:scion_ui" self.idm_client.set_actor_credentials(client_actor_id, client_id, "client_secret") return True def do_auto_preload(self): """ Load configured preload scenarios and remembers in directory which ones have been loaded. """ log.info("Executing auto preload") preload_entries = self.process.container.directory.lookup("/System/Preload") preload_changed = False if preload_entries is None: preload_entries = dict(scenarios={}) preload_changed = True # "HACK" Preload core to get app specifics in if "core" not in preload_entries["scenarios"]: preload_entries["scenarios"]["core"] = self._get_dir_entry("core") self.do_preload_core() preload_changed = True preload_scenarios = CFG.get_safe("scion.preload.scenarios") or [] preload_scope = CFG.get_safe("scion.preload.scope") for scenario_info in preload_scenarios: scope, scenario = scenario_info if scope == "all" or scope == preload_scope: if scenario not in preload_entries["scenarios"]: preload_entries["scenarios"][scenario] = self._get_dir_entry(scenario) changed = self.do_preload_master(scenario) preload_changed = preload_changed or changed if preload_changed: self.process.container.directory.register("/System", "Preload", scenarios=preload_entries["scenarios"]) def _get_dir_entry(self, scenario): return dict(ts=get_ion_ts(), name=scenario, sys_name=get_sys_name()) def do_preload_master(self, master): if CFG.get_safe("scion.preload.enabled", False) is not True: return False log.info("############## PRELOAD SCION RESOURCES (%s) ##############", master) skip_steps = CFG.get_safe("skipsteps") if skip_steps: skip_steps = skip_steps.split(",") self.initialize_preloader(self.process, {}) if os.path.isdir("res/preload/{}".format(master)): self.preload_master("res/preload/{}/actions.yml".format(master), skip_steps=skip_steps) elif os.path.exists("res/preload/{}".format(master)): self.preload_master("res/preload/{}".format(master), skip_steps=skip_steps) else: raise BadRequest("Cannot find preload master") log.info("############## END PRELOAD ##############") return True # ------------------------------------------------------------------------- # Action callbacks def _load_preload_CommitBulk(self, action_cfg): self.commit_bulk() def _load_resource_CORE_CreateRole(self, action_cfg): org_name = action_cfg["org"] role_name = action_cfg["role"] org_obj = self.org_client.find_org(org_name) role_obj = IonObject(RT.UserRole, name=role_name, governance_name=role_name, description="Role %s.%s" % (org_name, role_name)) self.org_client.add_org_role(org_obj._id, role_obj, headers=self._get_system_actor_headers()) def _load_resource_APP_ScionUser(self, action_cfg): actor_obj = self.create_object_from_cfg(action_cfg, RT.ActorIdentity) username, password = action_cfg["username"], action_cfg.get("password", None) user_alias = action_cfg[KEY_ID] if user_alias in self.resource_ids: log.info("Skipping existing user '%s', alias=%s", username, user_alias) return log.debug("Preload user '%s', alias=%s", username, user_alias) actor_id = self.scion_client.define_user( first_name=actor_obj.details.contact.individual_names_given, last_name=actor_obj.details.contact.individual_name_family, username=username, password=password, email=actor_obj.details.contact.email, attributes=actor_obj.details.profile) self.scion_client.update_user_contact(actor_id, actor_obj.details.contact) res_obj = self.container.resource_registry.read(actor_id) res_obj.alt_ids += ['PRE:'+action_cfg[KEY_ID]] self.container.resource_registry.update(res_obj) self._register_id(action_cfg[KEY_ID], actor_id, res_obj) # Roles roles = action_cfg.get("roles", []) for role in roles: org_name, role_name = role.split(".", 1) org_obj = self.org_client.find_org(org_name) self.org_client.grant_role(org_obj._id, actor_id, role_name, headers=self._get_system_actor_headers()) def _load_resource_Instrument(self, action_cfg): if action_cfg[KEY_ID] in self.resource_ids: return res_id = self.basic_resource_create(action_cfg, RT.Instrument, "resource_registry", "create", support_bulk=True) self.basic_associations_create(action_cfg, action_cfg[KEY_ID], support_bulk=True) def _load_resource_Dataset(self, action_cfg): if action_cfg[KEY_ID] in self.resource_ids: return schema_def = {} if "schema_def" in action_cfg: schema_def = DataSchemaParser.parse_schema_ref(action_cfg["schema_def"]) if "schema_override" in action_cfg: dict_merge(schema_def, action_cfg["schema_override"], inplace=True) res_id = self.basic_resource_create(action_cfg, RT.Dataset, "resource_registry", "create", support_bulk=True, set_attributes=dict(schema_definition=schema_def)) self.basic_associations_create(action_cfg, action_cfg[KEY_ID], support_bulk=True) def _load_action_StartAgent(self, action_cfg): asset_id = action_cfg["asset_id"] agent_res_id = self.resource_ids[asset_id] self.scion_client.start_agent(agent_res_id) def _load_action_StopAgent(self, action_cfg): asset_id = action_cfg["asset_id"] agent_res_id = self.resource_ids[asset_id] self.scion_client.stop_agent(agent_res_id)
def op_load_system_policies(cls, calling_process): """ Create the initial set of policy rules for the system. To establish clear rule precedence, denying all anonymous access to Org services first and then add rules which Permit access to specific operations based on conditions. """ orgms_client = OrgManagementServiceProcessClient( process=calling_process) policyms_client = PolicyManagementServiceProcessClient( process=calling_process) ion_org = orgms_client.find_org() system_actor = get_system_actor() log.info('System actor: %s', system_actor._id) sa_user_header = get_system_actor_header(system_actor) policy_rules_filename = calling_process.CFG.get_safe( "bootstrap.initial_policy_rules") if not policy_rules_filename: raise ContainerConfigError("Policy rules file not configured") if not os.path.exists(policy_rules_filename): raise ContainerConfigError("Policy rules file does not exist") with open(policy_rules_filename, "r") as f: policy_rules_yml = f.read() policy_rules_cfg = yaml.safe_load(policy_rules_yml) if "type" not in policy_rules_cfg or policy_rules_cfg[ "type"] != "scioncc_policy_rules": raise ContainerConfigError("Invalid policy rules file content") log.info("Loading %s policy rules", len(policy_rules_cfg["rules"])) for rule_cfg in policy_rules_cfg["rules"]: rule_name, policy_type, rule_desc = rule_cfg["name"], rule_cfg[ "policy_type"], rule_cfg.get("description", "") if rule_cfg.get("enable") is False: log.info("Policy rule %s disabled", rule_name) continue log.info("Loading policy rule %s (%s)", rule_name, policy_type) rule_filename = rule_cfg["rule_def"] if not os.path.isabs(rule_filename): rule_filename = os.path.join( os.path.dirname(policy_rules_filename), rule_filename) with open(rule_filename, "r") as f: rule_def = f.read() ordinal = rule_cfg.get("ordinal", 0) # Create the policy if policy_type == "common_service_access": policyms_client.create_common_service_access_policy( rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) elif policy_type == "service_access": service_name = rule_cfg["service_name"] policyms_client.create_service_access_policy( service_name, rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) elif policy_type == "resource_access": resource_type, resource_name = rule_cfg[ "resource_type"], rule_cfg["resource_name"] res_ids, _ = calling_process.container.resource_registry.find_resources( restype=resource_type, name=resource_name, id_only=True) if res_ids: resource_id = res_ids[0] policyms_client.create_resource_access_policy( resource_id, rule_name, rule_desc, rule_def, ordinal=ordinal, headers=sa_user_header) else: raise ContainerConfigError( "Rule %s has invalid policy type: %s" % (rule_name, policy_type))