예제 #1
0
    def deploy(self, deployment_tpl_path, conf_file_path, bucket_name):
        """Deploy Forseti using the deployment template

        Args:
            deployment_tpl_path (str): Deployment template path
            conf_file_path (str): Configuration file path
            bucket_name (str): Name of the GCS bucket

        Returns:
            bool: Whether or not the deployment was successful
            str: Deployment name
        """
        deployment_name = gcloud.create_deployment(
            self.project_id, self.organization_id, deployment_tpl_path,
            self.config.installation_type, self.config.identifier)

        status_checker = (lambda: gcloud.check_deployment_status(
            deployment_name, constants.DeploymentStatus.DONE))
        loading_message = 'Waiting for deployment to be completed...'
        deployment_completed = utils.start_loading(
            max_loading_time=900,
            exit_condition_checker=status_checker,
            message=loading_message)

        if not deployment_completed:
            # If after 15 mins and the deployment is still not completed, there
            # is something wrong with the deployment.
            print('Deployment failed.')
            sys.exit(1)

        if deployment_completed:
            # If deployed successfully, make sure the VM has been initialized,
            # copy configuration file, deployment template file and
            # rule files to the GCS bucket

            utils.print_banner('Backing Up Important Files To GCS')

            conf_output_path = constants.FORSETI_CONF_PATH.format(
                bucket_name=bucket_name,
                installation_type=self.config.installation_type)

            print('Copying the Forseti {} configuration file to:\n\t{}'.format(
                self.config.installation_type, conf_output_path))

            files.copy_file_to_destination(conf_file_path,
                                           conf_output_path,
                                           is_directory=False)

            deployment_tpl_output_path = (
                constants.DEPLOYMENT_TEMPLATE_OUTPUT_PATH.format(bucket_name))

            print(
                'Copying the Forseti {} deployment template to:\n\t{}'.format(
                    self.config.installation_type, deployment_tpl_output_path))

            files.copy_file_to_destination(deployment_tpl_path,
                                           deployment_tpl_output_path,
                                           is_directory=False)

        return deployment_completed, deployment_name
예제 #2
0
    def wait_until_vm_initialized(self, vm_name):
        """Check vm init status.

        Args:
            vm_name (str): Name of the VM instance.
        """

        installation_type = self.config.installation_type
        utils.print_banner('Forseti {} VM Initialization'.format(
            installation_type.capitalize()))
        _, zone, name = gcloud.get_vm_instance_info(vm_name)

        status_checker = (lambda: gcloud.check_vm_init_status(name, zone))

        loading_message = ('Waiting for Forseti {} to be initialized...'.
                           format(installation_type))

        try:
            _ = utils.start_loading(
                max_loading_time=constants.MAXIMUM_LOADING_TIME_IN_SECONDS,
                exit_condition_checker=status_checker,
                message=loading_message)
        except installer_errors.SSHError:
            # There is problem when SSHing to the VM, maybe there is a
            # firewall rule setting that is blocking the SSH from the
            # cloud shell. We will skip waiting for the VM to be initialized.
            pass
    def get_email_settings(self):
        """Ask user for specific install values."""
        utils.print_banner('Configuring GSuite Admin Information')
        if not self.config.gsuite_superadmin_email:
            # Ask for GSuite Superadmin email.
            print(constants.MESSAGE_ASK_GSUITE_SUPERADMIN_EMAIL)
            self.config.gsuite_superadmin_email = raw_input(
                constants.QUESTION_GSUITE_SUPERADMIN_EMAIL).strip()

        if self.config.skip_sendgrid_config:
            print(constants.MESSAGE_SKIP_SENDGRID_API_KEY)
            return

        utils.print_banner('Configuring Forseti Email Settings')
        if not self.config.sendgrid_api_key:
            # Ask for SendGrid API Key.
            print(constants.MESSAGE_ASK_SENDGRID_API_KEY)
            self.config.sendgrid_api_key = raw_input(
                constants.QUESTION_SENDGRID_API_KEY).strip()
        if self.config.sendgrid_api_key:
            if not self.config.notification_sender_email:
                self.config.notification_sender_email = (
                    constants.NOTIFICATION_SENDER_EMAIL)

            # Ask for notification recipient email.
            if not self.config.notification_recipient_email:
                self.config.notification_recipient_email = raw_input(
                    constants.QUESTION_NOTIFICATION_RECIPIENT_EMAIL).strip()
예제 #4
0
 def create_or_reuse_service_accts(self):
     """Create or reuse service accounts."""
     utils.print_banner('Creating/Reusing Service Account(s)')
     gcp_service_acct_email, gcp_service_acct_name = (
         self.format_gcp_service_acct_id())
     self.gcp_service_acct_email = gcloud.create_or_reuse_service_acct(
         'GCP Service Account', gcp_service_acct_name,
         gcp_service_acct_email)
예제 #5
0
    def run_setup(self,
                  setup_continuation=False,
                  final_setup=True,
                  previous_instructions=None):
        """Run the setup steps.

        If setup_continuation is True, we don't need to run the pre-flight
        checks any more because it has been done in the previous installation.

        Args:
            setup_continuation (bool): If this is a continuation of the
                previous setup.
            final_setup (bool): The final setup.
            previous_instructions (ForsetiInstructions): Post installation
                instructions from previous installation.

        Returns:
            ForsetiInstructions: Forseti instructions.
        """
        utils.print_installation_header('Installing Forseti {}'.format(
            self.config.installation_type.capitalize()))

        if not setup_continuation:
            self.preflight_checks()

        # Create/Reuse service account(s).
        self.create_or_reuse_service_accts()

        # Create configuration file and deployment template.
        (conf_file_path, deployment_tpl_path) = self.create_resource_files()

        # Deployment.
        bucket_name = self.generate_bucket_name()
        deploy_success, _ = self.deploy(deployment_tpl_path, conf_file_path,
                                        bucket_name)

        # After deployment.
        instructions = self.post_install_instructions(deploy_success,
                                                      bucket_name)

        if previous_instructions is not None:
            instructions.merge_head(previous_instructions)

        if final_setup:
            utils.print_banner('Forseti Post-Setup Instructions')
            print(instructions)

        return instructions
    def determine_access_target(self):
        """Determine where to enable Forseti access.

        Allow only org level access since IAM explain
        requires org level access.
        """
        utils.print_banner('Forseti Installation Configuration')

        if self.composite_root_resources:
            # split element 0 into type and id
            rtype, rid = self.composite_root_resources[0].split('/')
            self.access_target = rtype
            self.target_id = rid
        else:
            self.access_target = constants.RESOURCE_TYPES[0]
            self.target_id = self.organization_id

        while not self.target_id:
            if self.setup_explain:
                # If user wants to setup Explain, they must setup
                # access on an organization.
                choice_index = 1
            else:
                try:
                    print(constants.MESSAGE_FORSETI_CONFIGURATION_ACCESS_LEVEL)
                    for (i, choice) in enumerate(constants.RESOURCE_TYPES):
                        print('[%s] %s' % (i+1, choice))
                    choice_input = raw_input(
                        constants.QUESTION_FORSETI_CONFIGURATION_ACCESS_LEVEL
                    ).strip()
                    choice_index = int(choice_input)
                except ValueError:
                    print('Invalid choice, try again.')
                    continue

            if choice_index and choice_index <= len(constants.RESOURCE_TYPES):
                self.access_target = constants.RESOURCE_TYPES[choice_index-1]
                if self.access_target == 'organizations':
                    self.target_id = gcloud.choose_organization()
                elif self.access_target == 'folders':
                    self.target_id = gcloud.choose_folder(self.organization_id)
                else:
                    self.target_id = gcloud.choose_project()

        self.resource_root_id = utils.format_resource_id(
            self.access_target, self.target_id)
예제 #7
0
    def preflight_checks(self):
        """Pre-flight checks"""
        utils.print_banner('Pre-installation checks')
        self.version = utils.infer_version()
        self.composite_root_resources = self.config.composite_root_resources
        service_account_key_file = self.config.service_account_key_file
        if self.config.project_id:
            gcloud.set_project_id(self.config.project_id)

        self.project_id, authed_user, is_cloudshell = gcloud.get_gcloud_info()
        gcloud.verify_gcloud_information(self.project_id, authed_user,
                                         self.config.force_no_cloudshell,
                                         is_cloudshell)
        self.organization_id = gcloud.lookup_organization(self.project_id)
        self.config.generate_identifier(self.organization_id)

        if not service_account_key_file:
            self.check_if_authed_user_in_domain(self.organization_id,
                                                authed_user)
        else:
            gcloud.activate_service_account(service_account_key_file)

        gcloud.check_billing_enabled(self.project_id, self.organization_id)