Azure / azure-iot-remote-monitoring

Azure IoT Remote Monitoring preconfigured solution
Other
249 stars 221 forks source link

Local deployment failing due to DNS bug with storage account hostname #406

Closed mark-read-coriel closed 3 years ago

mark-read-coriel commented 7 years ago

I am trying to do a local deployment for debug as discussed in the readme file:

https://github.com/Azure/azure-iot-remote-monitoring/blob/master/Docs/local-deployment.md

However, the "build.cmd local debug" fails with the following error:

Unable to create unique name for resource localrm for url blob.core.windows.net At C:\sw\Microsoft-Examples\azure-iot-remote-monitoring\Common\Deployment\DeploymentLib.ps1:288 char:13

Upon investigation it appears the issue relates to the function HostEntryExists() in common/Deployment/DeploymentLib.ps1.

If you test line "if ([Net.Dns]::GetHostEntry($hostName) -ne $null)" it never returns null, even if the storageaccount name does not exist, i.e. it is in effect always resolving "*.blob.core.windows.net" regardless of whether the storage account exists or not.

You can test this manually from a powershell. e.g:

$hostname = "localrm2e8be.blob.core.windows.net"

The hostname is always resolved, so the storage account never gets created. Example-run-build.cmd.txt

I have attached a verbose run of the command "build.cmd local debug" for investigation.

mark-read-coriel commented 7 years ago

Is it possible to get somebody assigned to help resolve this please?

corywink commented 7 years ago

Thanks for reporting the issue, we are investigating.

joyhui commented 7 years ago

Here is what I tried just now. If the storage account does not exist, GetHostEntry will fail.

capture

It seems Host resolve has problem in your machine. Did you modify your local host file? All lines should begin with "#" (means this line is commented out.) "C:\Windows\System32\drivers\etc\hosts"

mark-read-coriel commented 7 years ago

I have not modified the host file, every line is still commented out.

What is interesting is that if I do exactly the same thing as above in PowerShell it behaves differently and returns and address list:-

PS C:\Users\Mark> $hostname = "notexistforsure12341.blob.core.windows.net" PS C:\Users\Mark> [Net.Dns]::GetHostEntry($hostname)

HostName Aliases AddressList


notexistforsure12341.blob.core.windows.net {} {81.200.64.50}

Could it be the version of power shell of the azure cmdlets module I am using, since I am probably using the latest versions. Version details are shown below:-

PS C:\Users\Mark> $PSVersionTable.PSVersion

Major Minor Build Revision


5 1 14393 576

PS C:\Users\Mark> (Get-Module -ListAvailable | Where-Object{ $_.Name -eq 'Azure' }) ` | Select Version, Name, Author, PowerShellVersion  | Format-List;

Version : 3.3.0 Name : Azure Author : Microsoft Corporation PowerShellVersion : 3.0

joyhui commented 7 years ago

Here is mine (same with you). I asked my coworkers to try the same commands and they all have same result as me. Can you find another machine and give a try? let's try to isolate the problem.

PS C:\Source\azure-iot-remote-monitoring> $PSVersionTable.PSVersion

Major Minor Build Revision


5 1 14393 576

mark-read-coriel commented 7 years ago

An interesting development. My network provider is Virgin media in the UK. If I connect to that network it resolves the DNS entry as discussed above. e.g. PS C:\Users\Mark> $hostname = "notexistforsure12341.blob.core.windows.net" PS C:\Users\Mark> [Net.Dns]::GetHostEntry($hostname) HostName Aliases AddressList

notexistforsure12341.blob.core.windows.net {} {81.200.64.50}

However if I switch to using my phone (EE network in the UK) as a hostspot I get different behaviour:-

PS C:\Users\Mark> $hostname = "notexistforsure12341.blob.core.windows.net" PS C:\Users\Mark> [Net.Dns]::GetHostEntry($hostname) Exception calling "GetHostEntry" with "1" argument(s): "No such host is known" At line:1 char:1

It appears the DNS entries on being cached on certain networks or something. I asked a colleague to try at different locations. He working from home was that worked as expected (e.g. didn't resolve the address). However as a second test he VPN'd into our office network (on the university of Nottingham site) and it resolved the address.

joyhui commented 7 years ago

hum.. You can also try the following to check dns: https://mxtoolbox.com/

It is every more strange: 81.200.64.50 does exist!

I think the DNS server did some magic things which it should not be. It always resolve as a fixed IP if the DNS does not exist.

For a workaround, you can check the result, if it contains this fixed IP, you can assume this resource exist.

mark-read-coriel commented 7 years ago

If you look up the IP address of when it resolves the DNS it appears that certain ISP's redirect you if a address does not exist. e.g. the use of barefruit for advertising (see http://barefruit.co.uk/). I think the solution needs to be modified such that the function HostEntryExists() in common/Deployment/DeploymentLib.ps1 only returns true if a DNS entry is returned and it is a Microsoft azure network IP address..

These are the addresses returned in the DNS entries when the script fails:

http://whatismyipaddress.com/ip/81.200.64.50 http://whatismyipaddress.com/ip/92.242.132.15

joyhui commented 7 years ago

There is a PS command to check Azure resource: (Need to login and select subscription) Test-AzureName -Storage "huidemodmdev"

We will change to use this command to test it.

mark-read-coriel commented 7 years ago

Ok that's great. I think the problem exists for all resources that are created, not just the storage so a similar solution could be used when creating these also.

joyhui commented 7 years ago

Yes. Please use this fix in your local for now. We will revisit this and provide necessary fix together.

Thanks!

mark-read-coriel commented 7 years ago

Hi Joyhui, I have fixed the problem with testing the blob but now running onto the same issue with "LocalRM42fbb.azure-devices.net". Modified code as follows so far:

function HostEntryExists() { Param( [Parameter(Mandatory=$true,Position=0)] $hostName ) try {

Fix for github issue https://github.com/Azure/azure-iot-remote-monitoring/issues/406

    $splitHostName = $hostName.Split('.')
    if($splitHostName[1].Equals("blob"))
    {
        $blobExists = Test-AzureName -Storage $splitHostName[0]
        return $blobExists
    }
    elseif ([Net.Dns]::GetHostEntry($hostName) -ne $null)
    {
        Write-Verbose ("Found hostname: {0}" -f $hostName)
        return $true
    }
}
catch {}
Write-Verbose ("Did not find hostname: {0}" -f $hostName)
return $false

}

What check can I do for this next problem?

mark-read-coriel commented 7 years ago

I have modified the HostEntryExists function as shown below and local deploy now works. It doesn't feel the most elegant solution but appears to work. Maybe you can review and suggest any improvements.

function HostEntryExists() { Param( [Parameter(Mandatory=$true,Position=0)] $hostName ) try {

Fix for github issue https://github.com/Azure/azure-iot-remote-monitoring/issues/406

    $splitHostName = $hostName.Split('.')
    if ( $splitHostName[1].Equals("blob"))
    {
        if (Test-AzureName -Storage $splitHostName[0])
        {
            Write-Verbose ("Found hostname (blob): {0}" -f $hostName)
            return $true
        }
    }
    elseif ($splitHostName[1].Equals("azure-devices") -or $splitHostName[1].Equals("documents"))
    {
        if (Test-AzureName -Service $splitHostName[0])
        {
            Write-Verbose ("Found hostname (service): {0}" -f $hostName)
            return $true
        }
    }
    elseif ($splitHostName[1].Equals("servicebus") )
    {
        if (Test-AzureName -ServiceBusNameSpace $splitHostName[0])
        {
            Write-Verbose ("Found hostname (servicebus): {0}" -f $hostName)
            return $true
        }
    }
    elseif ([Net.Dns]::GetHostEntry($hostName) -ne $null)
    {
        Write-Verbose ("Found hostname (DNS): {0}" -f $hostName)
        return $true
    }
}
catch {}
Write-Verbose ("Did not find hostname: {0}" -f $hostName)
return $false

}

ankitscribbles commented 3 years ago

Note: As of December 10th 2020, Remote Monitoring solution accelerator is no longer supported. All supporting repositories have been archived.