예제 #1
0
    def get_public_key(self):
        public_key_config = self.get_config_or_default(
            self.docs, 'infrastructure/public-key')
        public_key_config.specification.name = self.cluster_model.specification.admin_user.name

        # To avoid key-pair collisions on AWS we generate a randomized key to store it. In order to successfully
        # re-run TF we need to re-use the randomized key which we extract from the terraform.tfstate from the previous
        # run.
        tfstate_path = get_terraform_path(
            self.cluster_model.specification.name) + '/terraform.tfstate'
        if os.path.isfile(tfstate_path):
            tfstate = load_json_obj(tfstate_path)
            key_pair = select_first(tfstate['resources'],
                                    lambda x: x['type'] == 'aws_key_pair')
            public_key_config.specification.key_name = key_pair['instances'][
                0]['attributes']['id']
        else:
            public_key_config.specification.key_name = self.cluster_model.specification.admin_user.name + '-' \
                                                       + str(uuid.uuid4())
        pub_key_path = self.cluster_model.specification.admin_user.key_path + '.pub'
        if os.path.isfile(pub_key_path):
            with open(pub_key_path, 'r') as stream:
                public_key_config.specification.public_key = stream.read(
                ).rstrip()
        else:
            raise Exception(
                f'SSH key path "{pub_key_path}" is not valid. Ansible run will fail.'
            )
        return public_key_config
예제 #2
0
 def __init__(self, cluster_model, config_docs):
     super().__init__(__name__)
     self.cluster_model = cluster_model
     self.config_docs = config_docs
     self.terraform = TerraformCommand(
         get_terraform_path(self.cluster_model.specification.name))
     self.new_env = os.environ.copy()
     self.terraform.init(env=self.new_env)
     if self.cluster_model.provider == 'azure':
         self.azure_login()
예제 #3
0
    def azure_login(self):
        # From the 4 methods terraform provides to login to
        # Azure we support (https://www.terraform.io/docs/providers/azurerm/auth/azure_cli.html):
        # - Authenticating to Azure using the Azure CLI
        # - Authenticating to Azure using a Service Principal and a Client Secret
        apiproxy = APIProxy(self.cluster_model, self.config_docs)
        if not self.cluster_model.specification.cloud.use_service_principal:
            # Account
            subscription = apiproxy.login_account()
            apiproxy.set_active_subscribtion(subscription['id'])
        else:
            # Service principal
            sp_file = os.path.join(
                get_terraform_path(self.cluster_model.specification.name),
                SP_FILE_NAME)
            if not os.path.exists(sp_file):
                # If no service principal exists or is defined we created one and for that we need to login using an account
                subscription = apiproxy.login_account()
                apiproxy.set_active_subscribtion(subscription['id'])

                # Create the service principal, for now we use the default subscription
                self.logger.info('Creating service principal')
                cluster_name = self.cluster_model.specification.name.lower()
                cluster_prefix = self.cluster_model.specification.prefix.lower(
                )
                resource_group_name = resource_name(cluster_prefix,
                                                    cluster_name, 'rg')
                sp = apiproxy.create_sp(resource_group_name,
                                        subscription['id'])
                sp['subscriptionId'] = subscription['id']
                save_sp(sp, self.cluster_model.specification.name)
            else:
                self.logger.info('Using service principal from file')
                sp = load_yaml_file(sp_file)

            # Login as SP and get the default subscription.
            subscription = apiproxy.login_sp(sp)

            if 'subscriptionId' in sp:
                # Set active subscription if sp contains it.
                apiproxy.set_active_subscribtion(sp['subscriptionId'])
                self.new_env['ARM_SUBSCRIPTION_ID'] = sp['subscriptionId']
            else:
                # No subscriptionId in sp.yml so use the default one from Azure SP login.
                self.new_env['ARM_SUBSCRIPTION_ID'] = subscription[0]['id']

            # Set other environment variables for Terraform when working with Azure and service principal.
            self.new_env['ARM_TENANT_ID'] = sp['tenant']
            self.new_env['ARM_CLIENT_ID'] = sp['appId']
            self.new_env['ARM_CLIENT_SECRET'] = sp['password']
예제 #4
0
 def __init__(self, cluster_name):
     super().__init__(__name__)
     self.terraform = TerraformCommand(get_terraform_path(cluster_name))