예제 #1
0
    def get_files_sas_url(self, production_name=None, path=None):
        from datetime import datetime, timedelta
        from azure.storage.blob import generate_container_sas
        from azure.storage.fileshare import ShareServiceClient, generate_account_sas, ResourceTypes, AccountSasPermissions

        sas_token = generate_account_sas(
            account_name=self.share_client.account_name,
            account_key=self.share_client.credential.account_key,
            resource_types=ResourceTypes(service=True,
                                         container=True,
                                         object=True),
            protocol='https',
            permission=AccountSasPermissions(read=True,
                                             write=True,
                                             delete=True,
                                             list=True,
                                             add=True,
                                             create=True,
                                             update=True,
                                             process=True,
                                             delete_previous_version=False),
            expiry=datetime.utcnow() + timedelta(hours=1))
        if production_name and path:
            return f"https://{self.share_client.account_name}.file.core.windows.net/{self.production_store_name}/{production_name}/{path}?{sas_token}"
        elif production_name and not path:
            return f"https://{self.share_client.account_name}.file.core.windows.net/{self.production_store_name}/{production_name}?{sas_token}"
        elif path and not production_name:
            logging.error(
                "must pass 'production name' parameter wwith 'path' parameter")
        else:
            return f"https://{self.share_client.account_name}.file.core.windows.net/{self.production_store_name}?{sas_token}"
 def create_resource(self, name, **kwargs):
     if self.is_live:
         storage_account = kwargs.pop("storage_account")
         storage_account_key = kwargs.pop("storage_account_key")
         sas_token = generate_account_sas(
             account_name=storage_account.name,
             account_key=storage_account_key,
             resource_types=ResourceTypes(container=True, object=True),
             permission=AccountSasPermissions(create=True,
                                              list=True,
                                              write=True,
                                              read=True,
                                              add=True,
                                              delete=True,
                                              delete_previous_version=True),
             expiry=datetime.utcnow() + timedelta(minutes=5),
         )
         blob_client = BlobServiceClient(
             storage_account.primary_endpoints.blob, sas_token)
         container = blob_client.create_container(name)
         container_uri = storage_account.primary_endpoints.blob + container.container_name
         self.test_class_instance.scrubber.register_name_pair(
             sas_token, "redacted")
         self.test_class_instance.scrubber.register_name_pair(
             container_uri, "https://storage/container")
     else:
         sas_token = "fake-sas"
         container_uri = "https://storage/container"
     return {"container_uri": container_uri, "sas_token": sas_token}
예제 #3
0
    def get_blob_sas_url(self, production_name=None, path=None):
        from datetime import datetime, timedelta
        from azure.storage.blob import generate_account_sas, generate_container_sas, ResourceTypes, AccountSasPermissions

        container_client = self.blob_service_client.get_container_client(
            self.production_store_id)

        sas_token = generate_account_sas(
            container_client.account_name,
            resource_types=ResourceTypes(service=True,
                                         object=True,
                                         container=True),
            permission=AccountSasPermissions(read=True,
                                             write=True,
                                             delete=True,
                                             list=True,
                                             add=True,
                                             create=True,
                                             update=True,
                                             process=True,
                                             delete_previous_version=False),
            expiry=datetime.utcnow() + timedelta(hours=24),
            account_key=self.blob_service_client.credential.account_key,
        )

        if path:
            return f"https://{container_client.account_name}.blob.core.windows.net/{self.production_store_id}/{production_name}/{path}?{sas_token}"
        else:
            return f"https://{container_client.account_name}.blob.core.windows.net/{self.production_store_id}/{production_name}?{sas_token}"
예제 #4
0
def generate_token():
    blob_service_client = BlobServiceClient(account_url=config.URL,
                                            credential=config.SHARED_KEY)

    try:
        for i in blob_service_client.list_containers():
            continue
    except:
        return 'cannot generate the sas token'
    container_client = blob_service_client.get_container_client("mycontainer")

    # container_token = generate_container_sas(
    #             container_client.account_name,
    #             container_client.container_name,
    #             account_key=container_client.credential.account_key,
    #             policy_id='my-access-policy-id'
    #         )

    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True,
                                         write=True,
                                         add=True,
                                         create=True),
        expiry=datetime.utcnow() + timedelta(hours=1))
    return sas_token
    def test_filter_blobs_using_account_sas(self, resource_group, location, storage_account, storage_account_key):
        token = generate_account_sas(
            storage_account.name,
            storage_account_key,
            ResourceTypes(service=True, container=True, object=True),
            AccountSasPermissions(write=True, list=True, read=True, delete_previous_version=True, tag=True,
                                  filter_by_tags=True),
            datetime.utcnow() + timedelta(hours=1),
        )
        self._setup(storage_account, token)

        tags = {"year": '1000', "tag2": "secondtag", "tag3": "thirdtag", "habitat_type": 'Shallow Lowland Billabongs'}
        blob_client, _ = self._create_block_blob(tags=tags, container_name=self.container_name)
        blob_client.set_blob_tags(tags=tags)
        tags_on_blob = blob_client.get_blob_tags()
        self.assertEqual(len(tags_on_blob), len(tags))

        if self.is_live:
            sleep(10)

        # To filter in a specific container use:
        # where = "@container='{}' and tag1='1000' and tag2 = 'secondtag'".format(container_name1)
        where = "\"year\"='1000' and tag2 = 'secondtag' and tag3='thirdtag'"

        blob_list = self.bsc.find_blobs_by_tags(filter_expression=where, results_per_page=2).by_page()
        first_page = next(blob_list)
        items_on_page1 = list(first_page)
        self.assertEqual(1, len(items_on_page1))
예제 #6
0
def generate_sas_token(storage_account, access_key):
    sas_token = generate_account_sas(
        storage_account,
        account_key=access_key,
        resource_types=ResourceTypes(service=True, container=True,
                                     object=True),
        permission=AccountSasPermissions(read=True, write=True),
        expiry=datetime.utcnow() + timedelta(hours=5))
    return sas_token
예제 #7
0
    def generate_sas_token(self):
        fake_key = 'a' * 30 + 'b' * 30

        return '?' + generate_account_sas(
            account_name='test',  # name of the storage account
            account_key=fake_key,  # key for the storage account
            resource_types=ResourceTypes(object=True),
            permission=AccountSasPermissions(read=True, list=True),
            start=datetime.now() - timedelta(hours=24),
            expiry=datetime.now() + timedelta(days=8))
예제 #8
0
    def _get_container_sas_token(self):


        sas_token = generate_account_sas(
            self.blob_service_client.account_name,
            account_key=self.blob_service_client.credential.account_key,
            resource_types=ResourceTypes(object=True),
            permission=AccountSasPermissions(write=True, delete=True, read=True),
            expiry=datetime.utcnow() + timedelta(hours=8)
        )
        return sas_token
예제 #9
0
def get_sas_token(connection_string):
    blob_service_client = BlobServiceClient.from_connection_string(
        connection_string)
    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1))
    print(sas_token)
    return sas_token
def getAzureStorageAccessSignature():
    blob_service_client = BlobServiceClient.from_connection_string(os.environ['aiengstorageaccntcode_STORAGE'])    
    
    sas_token = generate_account_sas(
       blob_service_client.account_name,
       account_key=blob_service_client.credential.account_key,
       resource_types=ResourceTypes(object=True),
       permission=AccountSasPermissions(read=True),
       expiry=datetime.utcnow() + timedelta(hours=1)
   )
    
    return sas_token
예제 #11
0
def generate_url_with_sas(blob_uri):
    # Generate SAS token to retrieve image content from blob storage
    blob_service_client = BlobServiceClient.from_connection_string(
        conn_str=connection_string)
    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1))
    image_url = blob_uri + '?' + sas_token
    return image_url
예제 #12
0
def GetSASToken():
    """Create a shared access token in order to read
        share access to the images.
       """
    sas_token = generate_account_sas(
        account_name,
        account_key=account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1))

    return sas_token
예제 #13
0
def generate_sas_key(connection_string):
    """Generate SAS key from connection string info."""
    account_name, account_key = get_account_info(connection_string)
    sas_token = generate_account_sas(
        account_name=account_name,
        account_key=account_key,
        resource_types=ResourceTypes(container=True, object=True),
        permission=AccountSasPermissions(read=True, write=True),
        expiry=datetime.utcnow() + timedelta(hours=1),
    )

    return sas_token
예제 #14
0
    def _create_sas_token(self):
        """Generate the shared access signature token using the storage account access key"""

        account_keys = self._getstorageaccountkey()
        # get one of the account keys
        account_keys = json.loads(account_keys)[0]['value']

        self.credential_token = generate_account_sas(
            account_name=self.storageaccount,
            account_key=account_keys,
            resource_types=ResourceTypes(service=True),
            permission=AccountSasPermissions(read=True),
            expiry=datetime.utcnow() + timedelta(hours=1))
예제 #15
0
def auth_shared_access_signature():
    from azure.storage.blob import BlobServiceClient
    # [START create_sas_token]
    # Create a SAS token to use to authenticate a new client
    from datetime import datetime, timedelta
    from azure.storage.blob import ResourceTypes, AccountSasPermissions, generate_account_sas

    return generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1))
예제 #16
0
 def azure_url_sas(self):
     from azure.storage.blob import ResourceTypes, AccountSasPermissions, generate_account_sas
     try:
        sas_token = generate_account_sas(self.blob_service_client.account_name, 
                    account_key=self.blob_service_client.credential.account_key, 
                    resource_types=ResourceTypes(object=True), permission=AccountSasPermissions(read=True), 
                    expiry=datetime.datetime.utcnow() + datetime.timedelta(minutes=5))
     except Exception as ex:
        tty.error("{}, Could not generate a sas token for Azure blob storage".format(ex))
     url_str = self.url.geturl()
     url_str = url_str.replace('azure', 'https', 1)
     url_sas_str = url_str + '?' + sas_token 
     return url_sas_str
예제 #17
0
def create_token_sas():
    """
    Cette fonction crée un token d'une durée de vie d'une heure
    elle renvoie et print le token
    """
    sas_token = generate_account_sas(
        account_name=(f"{config['storage']['account']}"),
        account_key=(f"{config['storage']['key']}"),
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    print(sas_token)
    return sas_token
예제 #18
0
def sas_account_token():
    """
    This function create a token with account and key
    the token sas, is a provisory key for share.
    
    """

    sas_token = generate_account_sas(
        account_name=(f"{config['storage']['account']}"),
        account_key=(f"{config['storage']['key']}"),
        resource_types=ResourceTypes(container=True, object=True),
        permission=AccountSasPermissions(read=True, list=True),
        expiry=datetime.utcnow() + timedelta(hours=1))
    return sas_token
    def create_connection(self, storage_account_name, storage_account_key,
                          container):
        try:
            dfs_url = "{}://{}.dfs.core.windows.net".format(
                "https", storage_account_name)
            blob_url = "{}://{}.blob.core.windows.net/".format(
                "https", storage_account_name)
            # print("ADLS URL:", dfs_url)
            # print("Blob URL:", blob_url)
            self.service_client = DataLakeServiceClient(
                account_url=dfs_url, credential=storage_account_key)
            # print("Getting file_system_client...")
            self.file_system_client = self.service_client.get_file_system_client(
                file_system=self.settings.storage_container)
            # print("Getting blob_service_client...")
            connect_string="DefaultEndpointsProtocol=https;AccountName=" + storage_account_name + ";AccountKey="\
                           + storage_account_key + ";EndpointSuffix=core.windows.net"
            self.blob_service_client = BlobServiceClient.from_connection_string(
                conn_str=connect_string)
            # Create sas token for blob

            self.sas_token = generate_account_sas(
                account_name=self.blob_service_client.account_name,
                account_key=storage_account_key,
                resource_types=ResourceTypes(service=True,
                                             object=True,
                                             container=True),
                permission=AccountSasPermissions(read=True,
                                                 write=True,
                                                 delete=True,
                                                 list=True,
                                                 add=True,
                                                 create=True),
                start=datetime.now() - timedelta(hours=1),
                expiry=datetime.utcnow() +
                timedelta(hours=4)  # Token valid for 4 hours
            )
            self.container_client = self.blob_service_client.get_container_client(
                container)
            # print("returning references.")
            return self.service_client\
                , self.file_system_client\
                , self.blob_service_client\
                , self.container_client\
                , self.sas_token

        except Exception as e:
            print(e)
            return None, None, None, None, None
    def setUp(self, *args, **kwargs):
        hsm_playback_url = "https://managedhsmname.managedhsm.azure.net"
        container_playback_uri = "https://storagename.blob.core.windows.net/container"
        playback_sas_token = "fake-sas"

        if self.is_live:
            self.managed_hsm_url = os.environ.get("AZURE_MANAGEDHSM_URL")
            if self.managed_hsm_url:
                self._scrub_url(real_url=self.managed_hsm_url,
                                playback_url=hsm_playback_url)

            storage_name = os.environ.get("BLOB_STORAGE_ACCOUNT_NAME")
            storage_endpoint_suffix = os.environ.get(
                "KEYVAULT_STORAGE_ENDPOINT_SUFFIX")
            container_name = os.environ.get("BLOB_CONTAINER_NAME")
            self.container_uri = "https://{}.blob.{}/{}".format(
                storage_name, storage_endpoint_suffix, container_name)
            self._scrub_url(real_url=self.container_uri,
                            playback_url=container_playback_uri)

            storage_account_key = os.environ.get(
                "BLOB_PRIMARY_STORAGE_ACCOUNT_KEY")
            if storage_account_key:
                self.sas_token = generate_account_sas(
                    account_name=storage_name,
                    account_key=storage_account_key,
                    resource_types=ResourceTypes(container=True, object=True),
                    permission=AccountSasPermissions(
                        create=True,
                        list=True,
                        write=True,
                        read=True,
                        add=True,
                        delete=True,
                        delete_previous_version=True,
                    ),
                    expiry=datetime.utcnow() + timedelta(minutes=30),
                )
                self.scrubber.register_name_pair(self.sas_token,
                                                 playback_sas_token)
        else:
            self.managed_hsm_url = hsm_playback_url
            self.container_uri = container_playback_uri
            self.sas_token = playback_sas_token

        self._set_mgmt_settings_real_values()
        super(AdministrationTestCase, self).setUp(*args, **kwargs)
    def auth_shared_access_signature(self):
        # Instantiate a BlobServiceClient using a connection string
        from azure.storage.blob import BlobServiceClient
        blob_service_client = BlobServiceClient.from_connection_string(self.connection_string)

        # [START create_sas_token]
        # Create a SAS token to use to authenticate a new client
        from datetime import datetime, timedelta
        from azure.storage.blob import ResourceTypes, AccountSasPermissions, generate_account_sas

        sas_token = generate_account_sas(
            blob_service_client.account_name,
            account_key=blob_service_client.credential.account_key,
            resource_types=ResourceTypes(object=True),
            permission=AccountSasPermissions(read=True),
            expiry=datetime.utcnow() + timedelta(hours=1)
        )
예제 #22
0
    async def auth_shared_access_signature_async(self):
        # SAS URL is calculated from storage key, so this test runs live only
        if TestMode.need_recording_file(self.test_mode):
            return

        # Instantiate a BlobServiceClient using a connection string
        from azure.storage.blob.aio import BlobServiceClient
        blob_service_client = BlobServiceClient.from_connection_string(
            self.connection_string)

        # [START create_sas_token]
        # Create a SAS token to use to authenticate a new client
        from datetime import datetime, timedelta
        from azure.storage.blob import ResourceTypes, AccountSasPermissions, generate_account_sas

        sas_token = generate_account_sas(
            blob_service_client.account_name,
            account_key=blob_service_client.credential.account_key,
            resource_types=ResourceTypes(object=True),
            permission=AccountSasPermissions(read=True),
            expiry=datetime.utcnow() + timedelta(hours=1))
예제 #23
0
def download_it():
    blob_list()
    # connect_str = os.getenv('AZURE_STORAGE_CONNECTION_STRING') --> Use in production

    # Temporary connection string format
    connect_str = storage_conn

    container_name = 'credentials'
    account_name = 'decentraliseduploads'

    blob_service_client = BlobServiceClient.from_connection_string(connect_str)

    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1))

    file_conn = 'https://' + account_name + '.blob.core.windows.net/' + container_name + '/' + blob_name[0] \
                + '?' + sas_token

    return file_conn
예제 #24
0
    def _get_blob_service_client(self):
        """Connect to Azure and return the blob service client

        The following environment variables must be set:
        * ``AZURE_STORAGE_CONNECTION_STRING``
        or
        * ``AZURE_STORAGE_ACCOUNT_NAME``
        * ``AZURE_STORAGE_ACCOUNT_URL``
        * ``AZURE_STORAGE_ACCOUNT_KEY``
        or if you want to use AAD (pod identity), set it to 1 or 0
        * ``AZURE_STORAGE_USE_AAD``

        """
        connect_str = os.environ.get("AZURE_STORAGE_CONNECTION_STRING")
        account_name = os.environ.get("AZURE_STORAGE_ACCOUNT_NAME")
        account_url = os.environ.get("AZURE_STORAGE_ACCOUNT_URL")
        account_key = os.environ.get("AZURE_STORAGE_ACCOUNT_KEY")
        account_use_aad = os.environ.get("AZURE_STORAGE_USE_AAD")
        if not (
            connect_str
            or (account_name and account_url and account_key)
            or account_use_aad
        ):
            msg = _(
                "If you want to read from the Azure container, you must provide the "
                "following environment variables:\n"
                "* AZURE_STORAGE_CONNECTION_STRING\n"
                "or\n"
                "* AZURE_STORAGE_ACCOUNT_NAME\n"
                "* AZURE_STORAGE_ACCOUNT_URL\n"
                "* AZURE_STORAGE_ACCOUNT_KEY\n"
                "or\n"
                "* AZURE_STORAGE_USE_AAD\n"
            )
            raise exceptions.UserError(msg)
        blob_service_client = None
        if account_use_aad:
            token_credential = DefaultAzureCredential()
            blob_service_client = BlobServiceClient(
                account_url=account_url, credential=token_credential
            )
        elif connect_str:
            try:
                blob_service_client = BlobServiceClient.from_connection_string(
                    connect_str
                )
            except HttpResponseError as error:
                _logger.exception(
                    "Error during the connection to Azure container using the "
                    "connection string."
                )
                raise exceptions.UserError(str(error))
        else:
            try:
                sas_token = generate_account_sas(
                    account_name=account_name,
                    account_key=account_key,
                    resource_types=ResourceTypes(container=True, object=True),
                    permission=AccountSasPermissions(read=True, write=True),
                    expiry=datetime.utcnow() + timedelta(hours=1),
                )
                blob_service_client = BlobServiceClient(
                    account_url=account_url,
                    credential=sas_token,
                )
            except HttpResponseError as error:
                _logger.exception(
                    "Error during the connection to Azure container using the Shared "
                    "Access Signature (SAS)"
                )
                raise exceptions.UserError(str(error))
        return blob_service_client
예제 #25
0
parser.add_argument('outputFilename')
args = parser.parse_args()


def convert_file(inputFile):
    output_path = ".\\output\\" + args.outputFilename
    stream = ffmpeg.input(args.inputFilename)
    stream = ffmpeg.output(stream, output_path)
    ffmpeg.run(stream)
    return output_path


sas_token = generate_account_sas(account_name=azure_acocunt_name,
                                 account_key=os.getenv("AZURE_ACCOUNT_KEY"),
                                 resource_types=ResourceTypes(service=True,
                                                              object=True),
                                 permission=AccountSasPermissions(read=True,
                                                                  write=True),
                                 expiry=datetime.utcnow() + timedelta(hours=1))

service = BlobServiceClient(account_url=account_url, credential=sas_token)

blob = service.get_blob_client(container=container_name,
                               blob=args.outputFilename)


def upload_blob(blobName):
    content_settings = ContentSettings(content_type='video/mp4')
    with open(blobName, "rb") as data:
        blob.upload_blob(data, content_settings=content_settings)
예제 #26
0
async def present(
    hub,
    ctx,
    name,
    resource_group,
    functions_file_path,
    os_type,
    runtime_stack,
    storage_account,
    storage_rg=None,
    app_service_plan=None,
    functions_version=2,
    enable_app_insights=None,
    app_insights=None,
    tags=None,
    connection_auth=None,
    **kwargs,
):
    """
    .. versionadded:: 3.0.0

    Ensure that a Function App exists.

    :param name: The name of the Function App.

    :param resource_group: The name of the resource group of the Function App.

    :param functions_file_path: The file path of the compressed (zip) file containing any Azure Functions that should
        be deployed to the Function App. The Azure Functions inside of this zip file should be using the same runtime
        stack or language that is specified within the runtime_stack parameter. This file will be uploaded every
        successfully run of this state. If there is a prior version of the zip file it will be overwritten. IMPORTANT:
        The code for all the functions in a specific function app should be located in a root project folder that
        contains a host configuration file and one or more subfolders. Each subfolder contains the code for a separate
        function. The folder structure is shown in the representation below::

        | functionapp.zip
        |   - host.json
        |   - MyFirstFunction/
        |     - function.json
        |     - ..
        |   - MySecondFunction/
        |     - function.json
        |     - ..
        |   - SharedCode/
        |   - bin/

    :param os_type: The operation system utilized by the Function App. This cannot be changed after the Function App
        has been created. Possible values are "linux" or "windows".

    :param runtime_stack: The language stack to be used for functions in this Function App. Possible values are
        "dotnet", "node", "java", "python", or "powershell".

    :param storage_account: The name of the storage account that will hold the Azure Functions used by the Function App.
        This storage account must be of the kind "Storage" or "StorageV2". If not already present, a container named
        "function-releases" will be created within this storage account to hold the zip file containing any Azure
        Functions.

    :param storage_rg: (Optional, used with storage_account) The resource group of the storage account passed. This
        parameter is only necessary if the storage account has a different resource group than the one specified for
        the Function App.

    :param app_service_plan: The name of the App Service (Consumption) Plan used by the Function App. If this
        parameter is not provided or the provided name is invalid/does not exist, then an App Service (Consumption)
        Plan will be built for the Function App with the name "plan-{name}". This plan should have the same OS as
        specified by the os_type parameter.

    :param functions_version: The version of Azure Functions to use. Additional information about Azure Functions
        versions can be found here: https://docs.microsoft.com/en-us/azure/azure-functions/functions-versions.
        Possible values include: 1, 2, and 3. Defaults to 2.

    :param enable_app_insights: Boolean flag for enabling Application Insights.

    :param app_insights: (Optional, used with enable_app_insights) The name of the Application Insights Component to
        use for the Function App. If the specified Application Insights Component does not exist, then it will be
        created. If this parameter is not specified, then an Application Insights Component named "app-insights-{name}"
        will be created and used.

    :param tags: A dictionary of strings representing tag metadata for the Function App.

    :param connection_auth: A dict with subscription and authentication parameters to be used in connecting to the
        Azure Resource Manager API.

    Example usage:

    .. code-block:: yaml

        Ensure function app exists:
            azurerm.web.function_app.present:
                - name: my_app
                - resource_group: my_group
                - functions_file_path: "/path/to/functions.zip"
                - os_type: "linux"
                - runtime_stack: "python"
                - storage_account: my_account
                - app_service_plan: my_plan
                - enable_app_insights: True
                - tags:
                    "Owner": "EITR Technologies"

    """
    ret = {"name": name, "result": False, "comment": "", "changes": {}}
    action = "create"
    app_settings = [
        {"name": "FUNCTIONS_WORKER_RUNTIME", "value": runtime_stack.lower()},
        {"name": "FUNCTIONS_EXTENSION_VERSION", "value": f"~{functions_version}",},
        {"name": "FUNCTION_APP_EDIT_MODE", "value": "readonly"},
        {"name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "false"},
    ]

    if not isinstance(connection_auth, dict):
        if ctx["acct"]:
            connection_auth = ctx["acct"]
        else:
            ret[
                "comment"
            ] = "Connection information must be specified via acct or connection_auth dictionary!"
            return ret

    # Ensures location is specified
    if "location" not in kwargs:
        rg_props = await hub.exec.azurerm.resource.group.get(
            ctx, resource_group, **kwargs
        )

        if "error" in rg_props:
            log.error("Unable to determine location from resource group specified.")
            return {
                "error": "Unable to determine location from resource group specified."
            }
        kwargs["location"] = rg_props["location"]

    # Handle storage account validation
    if not storage_rg:
        storage_rg = resource_group

    storage_acct = await hub.exec.azurerm.storage.account.get_properties(
        ctx, name=storage_account, resource_group=storage_rg
    )

    if "error" in storage_acct:
        log.error(
            f"The storage account {storage_account} does not exist within the given resource group {resource_group}."
        )
        ret[
            "comment"
        ] = f"The storage account {storage_account} does not exist within the given resource group {resource_group}."
        return ret

    # Ensure that the file path contains a zip file
    filename = os.path.basename(functions_file_path)
    if not filename.lower().endswith(".zip"):
        log.error(
            "The specified file in functions_file_path is not a compressed (zip) file."
        )
        ret[
            "comment"
        ] = "The specified file in functions_file_path is not a compressed (zip) file."
        return ret

    # Set reserved for the ASP and Function App based upon OS type
    if os_type.lower() == "windows":
        reserved = False
    else:  # linux
        reserved = True

    # Handle App Service Plan creation
    if not app_service_plan:
        app_service_plan = f"plan-{name}"

    plan = await hub.exec.azurerm.web.app_service_plan.get(
        ctx, name=app_service_plan, resource_group=resource_group
    )

    if "error" in plan:
        plan = await hub.exec.azurerm.web.app_service_plan.create_or_update(
            ctx,
            name=app_service_plan,
            resource_group=resource_group,
            kind="functionapp",
            reserved=reserved,
            sku="Y1",
            **connection_auth,
        )

        if "error" in plan:
            log.error(
                f"Unable to create the App Service Plan {app_service_plan} in the resource group {resource_group}."
            )
            ret[
                "comment"
            ] = f"Unable to create the App Service Plan {app_service_plan} in the resource group {resource_group}."
            return ret
    elif plan["reserved"] != reserved:
        log.error(
            f"The OS of the App Service Plan {app_service_plan} does not match the specified OS type for the Function App and thus cannot be used."
        )
        ret[
            "comment"
        ] = f"The OS of the App Service Plan {app_service_plan} does not match the specified OS type for the Function App and thus cannot be used."
        return ret

    # Gets the resource ID of the ASP
    server_farm_id = plan["id"]

    # Handle App Insights Validation and Creation
    if enable_app_insights:
        if not app_insights:
            app_insights = f"app-insights-{name}"

        component = await hub.exec.azurerm.application_insights.component.get(
            ctx, name=app_insights, resource_group=resource_group
        )

        if "error" in component:
            component = await hub.exec.azurerm.application_insights.component.create_or_update(
                ctx,
                name=app_insights,
                resource_group=resource_group,
                kind="web",
                application_type="web",
            )

            if "error" in component:
                log.error(
                    f"Unable to create the Application Insights Component {app_insights} within the resource group {resource_group}."
                )
                ret[
                    "comment"
                ] = f"Unable to create the Application Insights Component {app_insights} within the resource group {resource_group}."
                return ret

        instrumentation_key = component["instrumentation_key"]
        # Configures the application insights for the app settings
        app_settings.append(
            {"name": "APPINSIGHTS_INSTRUMENTATIONKEY", "value": instrumentation_key}
        )

    # Builds a storage container named "function-releases" within the specified storage account if not already present
    container = await hub.exec.azurerm.storage.container.get(
        ctx,
        name="function-releases",
        account=storage_account,
        resource_group=storage_rg,
    )

    if "error" in container:
        container = await hub.exec.azurerm.storage.container.create(
            ctx,
            name="function-releases",
            account=storage_account,
            resource_group=storage_rg,
            public_access="None",
        )

    # Upload the zip file containing the Azure Functions
    upload_zip = await hub.exec.azurerm.storage.container.upload_blob(
        ctx,
        name=filename,
        container="function-releases",
        account=storage_account,
        resource_group=storage_rg,
        file_path=functions_file_path,
        overwrite=True,
    )

    if "error" in upload_zip:
        log.error(
            f"Unable to upload {filename} to the function-releases container within the storage account {storage_account}."
        )
        ret[
            "comment"
        ] = f"Unable to upload {filename} to the function-releases container within the storage account {storage_account}."
        return ret

    # Retrieves the access keys for the storage account
    storage_acct_keys = await hub.exec.azurerm.storage.account.list_keys(
        ctx, name=storage_account, resource_group=storage_rg
    )
    if "error" not in storage_acct_keys:
        storage_acct_key = storage_acct_keys["keys"][0]["value"]
    else:
        log.error(
            f"Unable to get the account access key for the specified storage account {storage_account} within the given resource group {storage_rg}."
        )
        ret[
            "comment"
        ] = f"Unable to get the account access key for the specified storage account {storage_account} within the given resource group {storage_rg}."
        return ret

    # Generate the sas token used within app settings
    sas_token = generate_account_sas(
        account_name=storage_account,
        account_key=storage_acct_key,
        resource_types=ResourceTypes(object=True, container=True, service=True),
        permission=AccountSasPermissions(read=True, write=True, list=True, delete=True),
        expiry=datetime.utcnow() + timedelta(days=2),
    )

    # Update app settings information from the storage account
    app_settings.append(
        {
            "name": "AzureWebJobsStorage",
            "value": f"DefaultEndpointsProtocol=https;AccountName={storage_account};AccountKey={storage_acct_key}",
        }
    )
    app_settings.append(
        {
            "name": "WEBSITE_RUN_FROM_PACKAGE",
            "value": f"https://{storage_account}.blob.core.windows.net/function-releases/{filename}?{sas_token}",
        }
    )

    # Add any app settings related to a specific OSs
    if os_type.lower() == "windows":
        app_settings.append(
            {
                "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                "value": f"DefaultEndpointsProtocol=https;AccountName={storage_account};AccountKey={storage_acct_key}",
            }
        )
        app_settings.append({"name": "WEBSITE_CONTENTSHARE", "value": name.lower()})

    # Check for the existence of the Function App
    function_app = await hub.exec.azurerm.web.app.get(
        ctx, name, resource_group, azurerm_log_level="info", **connection_auth
    )

    if "error" not in function_app:
        action = "update"

        # tag changes
        tag_changes = differ.deep_diff(function_app.get("tags", {}), tags or {})
        if tag_changes:
            ret["changes"]["tags"] = tag_changes

        # app service plan changes
        if function_app.get("server_farm_id") != server_farm_id:
            ret["changes"]["server_farm_id"] = {
                "new": server_farm_id,
                "old": function_app.get("server_farm_id"),
            }

        # app setting changes
        existing_settings = await hub.exec.azurerm.web.app.list_application_settings(
            ctx, name=name, resource_group=resource_group
        )
        old_settings = existing_settings["properties"]
        new_settings = {}
        for setting in app_settings:
            new_settings.update({setting.get("name"): setting.get("value")})

        # Checks specifically for changes within the WEBSITE_RUN_FROM_PACKAGE app setting because the value of that
        # setting is changed every run.
        new_run_package_setting = new_settings.pop("WEBSITE_RUN_FROM_PACKAGE", "")
        old_run_package_setting = old_settings.pop("WEBSITE_RUN_FROM_PACKAGE", "")

        new_beginning = (new_run_package_setting.split("?"))[0]
        old_beginning = (old_run_package_setting.split("?"))[0]

        run_package_changes = False
        if old_beginning != new_beginning:
            run_package_changes = True

        # If there are changes within WEBSITE_RUN_FROM_PACKAGE, then that app setting should be readded to both settings
        # dictionaries to be recorded as app setting changes changes
        if run_package_changes:
            new_settings.update({"WEBSITE_RUN_FROM_PACKAGE": new_run_package_setting})
            old_settings.update({"WEBSITE_RUN_FROM_PACKAGE": old_run_package_setting})

        app_settings_changes = differ.deep_diff(old_settings, new_settings)
        if app_settings_changes:
            ret["changes"]["site_config"] = {"app_settings": app_settings_changes}

        if not ret["changes"]:
            ret["result"] = True
            ret["comment"] = "Function App {0} is already present.".format(name)
            return ret

        if ctx["test"]:
            ret["result"] = None
            ret["comment"] = "Function App {0} would be updated.".format(name)
            return ret

    else:
        ret["changes"] = {
            "old": {},
            "new": {
                "name": name,
                "resource_group": resource_group,
                "app_service_plan": app_service_plan,
                "os_type": os_type,
                "runtime_stack": runtime_stack,
                "site_config": {"app_settings": app_settings},
                "tags": tags,
            },
        }

        if enable_app_insights:
            ret["changes"]["new"]["application_insights"] = app_insights

    if ctx["test"]:
        ret["comment"] = "Function App {0} would be created.".format(name)
        ret["result"] = None
        return ret

    app_kwargs = kwargs.copy()
    app_kwargs.update(connection_auth)

    kind = "functionapp"
    if os_type.lower() == "linux":
        kind = kind + ",Linux"

    function_app = await hub.exec.azurerm.web.app.create_or_update(
        ctx=ctx,
        name=name,
        resource_group=resource_group,
        tags=tags,
        server_farm_id=server_farm_id,
        kind=kind,
        site_config={"app_settings": app_settings},
        **app_kwargs,
    )

    if "error" not in function_app:
        ret["result"] = True
        ret["comment"] = f"Function App {name} has been {action}d."
        return ret

    ret["comment"] = "Failed to {0} Function App {1}! ({2})".format(
        action, name, function_app.get("error")
    )
    if not ret["result"]:
        ret["changes"] = {}
    return ret
예제 #27
0
    def create_sas_uri(self, group_name, location, storage_account_name):
        if self.is_live:
            from azure.mgmt.storage.models import BlobContainer
            from azure.storage.blob import generate_account_sas, AccountSasPermissions, ContainerClient, ResourceTypes
            BODY = {
              "sku": {
                "name": "Standard_GRS"
              },
              "kind": "StorageV2",  # Storage v2 support policy
              "location": location,
              "encryption": {
                "services": {
                  "file": {
                    "key_type": "Account",
                    "enabled": True
                  },
                  "blob": {
                    "key_type": "Account",
                    "enabled": True
                  }
                },
                "key_source": "Microsoft.Storage"
              },

              "tags": {
                "key1": "value1",
                "key2": "value2"
              }
            }
            result = self.storage_client.storage_accounts.begin_create(
                group_name,
                storage_account_name,
                BODY
            )
            storage_account = result.result()

            # result = self.storage_client.blob_containers.create(
            #     group_name,
            #     storage_account_name,
            #     "foo",
            #     {}
            # )
            # result = result.result()

            keys = self.storage_client.storage_accounts.list_keys(
                group_name,
                storage_account_name
            ).keys

            sas_token = generate_account_sas(
                account_name=storage_account_name,
                account_key=keys[0].value,
                resource_types=ResourceTypes(object=True),
                permission=AccountSasPermissions(read=True, list=True),
                start=dt.datetime.now() - dt.timedelta(hours=24),
                expiry=dt.datetime.now() - dt.timedelta(days=8)
            )
            
            container_client = ContainerClient(
                storage_account.primary_endpoints.blob.rstrip("/"),
                credential="?" + sas_token,
                container_name="foo",
                blob_name="default"
            )
            return container_client.url
            # container_client.create_container()
            # return container_client.url + "?" + sas_token
        else:
            return "fakeuri"