diff --git a/.appveyor.yml b/.appveyor.yml index 2ebb6a7..313c5a4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,46 +1,47 @@ -version: '0.1.3-{build}' -init: -- git config --global core.autocrlf true -branches: - only: - - master - - /^v\d+\.\d+\.\d+.*$/ -build_script: -- cmd: .\package.cmd -- sh: ./package.sh -clone_depth: 1 -environment: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - AZBRIDGE_TEST_CXNSTRING: - secure: DLwQwbX0CCtVlezqK0rPcIgnxFofTos/c3UMLTGSIWdHFwO9YHIU8a6fbxVaH5sFP+MS/ELLP66C4KVY8KwAf2EkF5ZgNm8624d1ERwN6xNCQbIVprzXw0TfgWRdIp76/07R1BnGZ/+lawAieosU9v/r6L8ibaoWB3f+mfOAgAz+dkm+azytP9A3NgrbKhr6LiRirVTrzz4+JgVDrwTgKA== - DOCKER_USER: - secure: hNy9HBcjNhhWaM96cjKZYw== - DOCKER_PASS: - secure: gMshhMI/3eiFO2D7A59gpkzwpyuuyRG1lEga3a5p1xM= -test_script: - # - cmd: docker login -u=%DOCKER_USER% -p=%DOCKER_PASS% - - cmd: .\verify-build.cmd - - sh: docker login -u $DOCKER_USER -p $DOCKER_PASS - - sh: ./verify-build.sh -image: - - Visual Studio 2017 - - Ubuntu -artifacts: - - path: 'artifacts\build\**\*.tar.gz' - - path: 'artifacts\build\**\*.zip' - - path: 'artifacts\build\**\*.deb' - - path: 'artifacts\build\**\*.rpm' - - path: 'artifacts\build\**\*.msi' -deploy: - - provider: GitHub - tag: $(APPVEYOR_REPO_TAG_NAME) - release: Release $(APPVEYOR_REPO_TAG_NAME) - description: This is the release $(APPVEYOR_REPO_TAG_NAME) of $(APPVEYOR_REPO_NAME). - auth_token: - secure: y86dwXyXNSKbC78BtVOuwkdd3apz6wFaZvy42Sy56PtREJnLRV/KkBIkOK1iucSZ - artifact: /.*/ - draft: false - prerelease: true - on: +version: '0.1.3-{build}' +init: +- git config --global core.autocrlf true +matrix: + fast_finish: true + - image: Visual Studio 2017 + - image: Ubuntu +branches: + only: + - master + - /^v\d+\.\d+\.\d+.*$/ +build_script: +- cmd: .\package.cmd +- sh: ./package.sh +clone_depth: 1 +environment: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + AZBRIDGE_TEST_CXNSTRING: + secure: DLwQwbX0CCtVlezqK0rPcIgnxFofTos/c3UMLTGSIWdHFwO9YHIU8a6fbxVaH5sFP+MS/ELLP66C4KVY8KwAf2EkF5ZgNm8624d1ERwN6xNCQbIVprzXw0TfgWRdIp76/07R1BnGZ/+lawAieosU9v/r6L8ibaoWB3f+mfOAgAz+dkm+azytP9A3NgrbKhr6LiRirVTrzz4+JgVDrwTgKA== + DOCKER_USER: + secure: hNy9HBcjNhhWaM96cjKZYw== + DOCKER_PASS: + secure: gMshhMI/3eiFO2D7A59gpkzwpyuuyRG1lEga3a5p1xM= +test_script: + # - cmd: docker login -u=%DOCKER_USER% -p=%DOCKER_PASS% + - cmd: .\verify-build.cmd + - sh: docker login -u $DOCKER_USER -p $DOCKER_PASS + - sh: ./verify-build.sh +artifacts: + - path: 'artifacts\build\**\*.tar.gz' + - path: 'artifacts\build\**\*.zip' + - path: 'artifacts\build\**\*.deb' + - path: 'artifacts\build\**\*.rpm' + - path: 'artifacts\build\**\*.msi' +deploy: + - provider: GitHub + tag: $(APPVEYOR_REPO_TAG_NAME) + release: Release $(APPVEYOR_REPO_TAG_NAME) + description: This is the release $(APPVEYOR_REPO_TAG_NAME) of $(APPVEYOR_REPO_NAME). + auth_token: + secure: y86dwXyXNSKbC78BtVOuwkdd3apz6wFaZvy42Sy56PtREJnLRV/KkBIkOK1iucSZ + artifact: /.*/ + draft: false + prerelease: true + on: appveyor_repo_tag: true # deploy on tag push only \ No newline at end of file diff --git a/.dockerignore b/.dockerignore index 5d8355d..b3ca204 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,4 @@ -artifacts -test/ -**/bin/ +artifacts +test/ +**/bin/ **/obj/ \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 97b827b..4cbd21f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,51 +1,51 @@ -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain - -*.jpg binary -*.png binary -*.gif binary - -*.cs text=auto diff=csharp -*.vb text=auto -*.resx text=auto -*.c text=auto -*.cpp text=auto -*.cxx text=auto -*.h text=auto -*.hxx text=auto -*.py text=auto -*.rb text=auto -*.java text=auto -*.html text=auto -*.htm text=auto -*.css text=auto -*.scss text=auto -*.sass text=auto -*.less text=auto -*.js text=auto -*.lisp text=auto -*.clj text=auto -*.sql text=auto -*.php text=auto -*.lua text=auto -*.m text=auto -*.asm text=auto -*.erl text=auto -*.fs text=auto -*.fsx text=auto -*.hs text=auto - -*.csproj text=auto -*.vbproj text=auto -*.fsproj text=auto -*.dbproj text=auto -*.sln text=auto eol=crlf -*.sh eol=lf +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +*.jpg binary +*.png binary +*.gif binary + +*.cs text=auto diff=csharp +*.vb text=auto +*.resx text=auto +*.c text=auto +*.cpp text=auto +*.cxx text=auto +*.h text=auto +*.hxx text=auto +*.py text=auto +*.rb text=auto +*.java text=auto +*.html text=auto +*.htm text=auto +*.css text=auto +*.scss text=auto +*.sass text=auto +*.less text=auto +*.js text=auto +*.lisp text=auto +*.clj text=auto +*.sql text=auto +*.php text=auto +*.lua text=auto +*.m text=auto +*.asm text=auto +*.erl text=auto +*.fs text=auto +*.fsx text=auto +*.hs text=auto + +*.csproj text=auto +*.vbproj text=auto +*.fsproj text=auto +*.dbproj text=auto +*.sln text=auto eol=crlf +*.sh eol=lf diff --git a/.gitignore b/.gitignore index ef00e4e..104d221 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,34 @@ -[Oo]bj/ -[Bb]in/ -TestResults/ -.nuget/ -_ReSharper.*/ -packages/ -artifacts/ -PublishProfiles/ -*.user -*.suo -*.cache -*.docstates -_ReSharper.* -nuget.exe -*net45.csproj -*net451.csproj -*k10.csproj -*.psess -*.vsp -*.pidb -*.userprefs -*DS_Store -*.ncrunchsolution -*.*sdf -*.ipch -*.sln.ide -project.lock.json -/.vs -.vscode/ -.build/ -.testPublish/ -global.json -*.g.targets +[Oo]bj/ +[Bb]in/ +TestResults/ +.nuget/ +_ReSharper.*/ +packages/ +artifacts/ +PublishProfiles/ +*.user +*.suo +*.cache +*.docstates +_ReSharper.* +nuget.exe +*net45.csproj +*net451.csproj +*k10.csproj +*.psess +*.vsp +*.pidb +*.userprefs +*DS_Store +*.ncrunchsolution +*.*sdf +*.ipch +*.sln.ide +project.lock.json +/.vs +.vscode/ +.build/ +.testPublish/ +global.json +*.g.targets launchSettings.json \ No newline at end of file diff --git a/CONFIG.md b/CONFIG.md index 3d0f881..20a8a5c 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -1,479 +1,479 @@ -# Configuration and Command Line Options - -## Command Line Options - -'azbridge' can be run in a "local" or "remote" mode. The "local" mode binds a -local listener address or socket to a relay name. The "remote" mode binds a relay -name to a remote listener adress. - -Since azbridge helps with scenarios not dissimilar to SSH tunnels, albeit without -requiring peer-to-peer connectivity, the command line syntax of 'azbridge' uses -elements that resemble SSH's equivalent tunnel functionality, especially the -L -and -R arguments. The key difference to SSH is that azbridge always binds sockets -to an Azure Relay name, and that Azure Relay acts as the identifier for the -tunnel and as network rendezvous point. In other words, you **always** need to -pair an azbridge instance running as local forwarder with an azbridge running -as a remote forwarder on the other end. - -SSH's dynamic SOCKS proxy functionality (SSH's -D option) is not supported since -it puts clients in control of selecting remote hosts after they've been bridged -into a foreign network, and this may pose significant security risks and might -inadvertently enable undesired access to resources on that foreign network. - -`(C) -- 127.3.2.1:5000 -> (L) -- ['myname'] -> (R) -- 10.1.2.3:5000 -> (S)` - -* **(C)** Client -* **(L)** Local forwarder: `azbridge -L 127.3.2.1:5000:myname` -* **(R)** Remote forwarder: `azbridge -R myname:10.1.2.3:5000` -* **(S)** Server listening at `10.1.2.3:5000` - - -A single instance of azbridge can support multiple concurrent "local" listeners -and multiple "remote" forwarders concurrently, also in a mixed configuration. - -The required Azure Relay connection string can either be supplied on the command -line, can be picked from an environment variable, or from a configuration file. - -The connection string's embedded authentication/authorization information must -confer sufficient permissions for the desired operation(s) to be executed, e.g. -for the "local" mode, the connection string must enable the bridge to send to -the configured relay entity. - -Arguments: - -**-b bind_address** - -Use bind_address on the local machine as the source address of -forwarding connections. Only useful on systems with more than one -address. - -**-D** - -Reserved. Not presently supported - -**-E endpoint_uri** - -Azure Relay endpoint URI (see -x). - -**-F configfile** - -Specifies an alternative per-user configuration file. If a configuration -file is given on the command line, the system-wide configuration file -(Linux: /etc/azbridge/azbridge_config.machine.yml, -Windows: %ALLUSERSPROFILE%\Microsoft\AzureBridge\azbridge_config.machine.yml) will be -ignored. - -The default for the per-user configuration file is ~/.azurebridge/config -on Linux and %USERPROFILE%\.azurebridge\config on Windows. - -**-g** - -Allows remote hosts to connect to local forwarded ports. - -**-K policy_name** - -Azure Relay shared access policy name to use (see -x). - -**-k policy_key** - -Azure Relay shared access policy key to use (see -x). - -**-L [bind_address:]port[/port_name]{;...}:relay_name**
-**-L local_socket[/port_name]{;...}:relay_name**
- -Specifies that connections to the given TCP/UDP port(s) or Unix socket(s) -on the local (client) host are to be bound (forwarded) to the given -Azure Relay name. - -- `bind_address`: Optional local IP address to bind the - listener to. This may be a DNS name or a numerical IPv4 or - IPv6 address expression and must resolve to a network endpoint - on the local machine. When omitted, the listener is bound to - all addresses ("any"). -- `port`: TCP or UDP port number. TCP ports are the default. - UDP port numbers must be suffixed with `U`, - e.g. `-L 3434U:relay`. -- `local_socket`: Unix socket name. The expression will be - interpreted as a Unix socket name if it's not a valid `port` - expression (i.e. not a number, with optional protocol suffix). -- `port_name`: Optional logical name for the port. If a "local" - TCP port ought to be mapped to a different "remote" TCP port, - a logical name allows this clearly, e.g. `-L 13389/rdp:relay` - matches to `-R relay:rdp/3389` on the logical port name `rdp`, - which is bound to TCP port 13389 on the local side and TCP - port 3389 on the remote side. For TCP/UDP, the default value - for `port_name` is the `port` value itself, meaning - `-L 13389:relay` can also be matched with `-R relay:13389/3389`. - For Unix sockets, this logical mapping can also be used, and - the default value is the name of `local_socket`. It is - permitted for multiple local TCP ports and Unix sockets or - for multiple UDP ports to use the same logical port name. UDP - ports must always be matched to remote UDP forwarders. -- `relay_name`: Name of the relay to bind the port(s) to. - -There can be multiple local binding expressions given for a -`relay_name`, separated by semicolons. The expressions can -also mix protocols, e.g. `-L 7777;7777U:relay` binds the -TCP and UDP ports 7777 to one relay name. - -The bridge opens a listener on a TCP or UDP port or a Unix socket -"here". The TCP or UDP listener is optionally bound to the -specified `bind_address`. Whenever a connection -is made to the local port or socket, the connection is forwarded -to a connected remote bridge via the chosen Relay entity. - -Port forwardings can also be specified in the configuration file. -Only the superuser can forward privileged ports. IPv6 addresses -can be specified by enclosing the address in square brackets. - -By default, the local port is bound in accordance with the -*GatewayPorts* configuration setting. However, an explicit bind_address -may be used to bind the connection to a specific address. The -bind_address of ``localhost'' indicates that the listening port -be bound for local use only, while an empty address or '*' indi- -cates that the port should be available from all interfaces. - -The -L option can be used multiple times on a single command line, -but only once per `relay_name`. - -**-o option** - -Can be used to give options in the format used in the configura- -tion file. This is useful for specifying options for which there -is no separate command-line flag. - -**-q** - -Quiet mode. Causes most warning and diagnostic messages to be -suppressed. - -**-R relay_name:[port_name/]hostport{;...}**
-**-R relay_name:host:[port_name/]hostport{;...}**
-**-R relay_name:[port_name/]local_socket{;...}** - -Specifies that connections to the given Azure Relay name -and optional logical port name are to be forwarded to the -given host and port, or Unix socket*. -Whenever a connection is made to the Relay and logical port, -the connection is forwarded to this listener (or a concurrently -connected listener in a random load distribution fashion), and a -then a forwarding connection is made to either port, host:hostport, -or local_socket, from the local machine. - -- `relay_name`: Name of the relay to bind the forwarder to. -- `port_name`: Optional logical name for the port as defined by - the local forwarder bound to this relay (see -L). -- `host`: Host name or IP address to forward to. -- `port`: TCP or UDP port number. TCP ports are the default. - UDP port numbers must be suffixed with `U`, - e.g. `-R relay:3434U`. UDP forwarders can only be bound to - logcial UDP ports. -- `local_socket`: Unix socket name. The expression will be - interpreted as a Unix socket name if it's not a valid `port` - expression (i.e. not a number, with optional protocol suffix). - -There can be multiple local binding expressions given for a -`relay_name`, separated by semicolons. The expressions can -also mix protocols, e.g. `-R relay:7777;7777U` binds to -TCP and UDP port forwarders for 7777 on one relay name. - -Port forwardings can also be specified in the configuration file. -Privileged ports can be forwarded only when runing with elevated privileges. -IPv6 addresses can be specified by enclosing the address in square -brackets. - -The -R option can be used multiple times on a single command line, -but only once for each `relay_name`. - -**-S signature** - -Azure Relay shared access signature (previously issued access token) -to use (see -x) - -**-V** - -Display the version number and exit. - -**-v** - -Verbose mode. Causes ssh to print debugging messages about its -progress. This is helpful in debugging connection, authentica- -tion, and configuration problems. Multiple -v options increase -the verbosity. The maximum is 3. - -**-x connection_string** - -Connection String. Azure Relay connection string for the namespace -or for a specific Azure Relay. The Connection String properties -can be overriden by the -E (Endpoint), -K (SharedAccessKeyName), --k (SharedAccessKey), -S (SharedAccessSignature) arguments. - -If an EntityPath is specified in the connection string, that name -is the only valid option for the relay_name expressions in the --L and -R options or for expressions in the effective configuration -file. - -The connection string can be set via the AZURE_BRIDGE_CONNECTIONSTRING -environment variable. - -## Configuration File - -The configuration file is a YAML file that specifies options that apply -to the machine or user. The machine level options are always read and -then complemented by or overriden by the user-level options. - -The configuration file can exist in three locations: - -1. Machine configuration, always loaded if present. - Linux: /etc/azurebridge/azurebridge_config - Windows: %ALLUSERSPROFILE%\Microsoft\AzureBridge\azbridge_config -2. User configuration, overrides and complements machine config. - Linux: ~/.azurebridge/config - Windows: %USERPROFILE%\.azurebridge\config -3. Override user configuration location for current execution with - the -f option. - -The configuration file holds a range of configuration options that, just -like the command line options, partially lean on similar expressions -used in SSH, even though the configuration format differs from that of SSH. - -The "LocalForward" and "RemoteForward" sections define bindings as with -the -L and -R command line options above. - -* **AddressFamily** - Specifies which address family to use when connecting. Valid - arguments are "any", "inet" (use IPv4 only), or "inet6" - (use IPv6 only). The default is "any". -* **AzureRelayConnectionString** - Azure Relay connection string for a Relay - namespace. Only one namespace connection string can be specified per configuration - file. -* **AzureRelayEndpoint** - Azure Relay endpoint URI for a Relay namespace. Overrides - the 'Endpoint' property of the connection string, if present. -* **AzureRelaySharedAccessKeyName** - Azure Relay shared access policy name. Overrides - the 'SharedAccessKeyName' property of the connection string, if present. -* **AzureRelaySharedAccessKey** - Azure Relay shared access policy key. Overrides - the 'SharedAccessKey' property of the connection string, if present. -* **AzureRelaySharedAccessSignature** - Azure Relay shared access policy signature. Overrides - the 'SharedAccessSignature' property of the connection string, if present. -* **BindAddress** - Use the specified address on the local machine as the source - address of the connection. Only useful on systems with more than - one address. -* **ClearAllForwardings** - Specifies that all local, and remote port forwardings - specified in the configuration files or on the command line be - cleared. This option is primarily useful when used from the - command line to clear port forwardings set in configura- - tion files. The argument must be "true" or "false". The default is "false". -* **ConnectionAttempts** - Specifies the number of tries (one per second) to make - before exiting. The argument must be an integer. This may be useful in scripts - if the connection sometimes fails. The default is 1. -* **ConnectTimeout** - Specifies the timeout (in seconds) used when connecting to the - relay server, instead of using the default system TCP timeout. - This value is used only when the target is down or really - unreachable, not when it refuses the connection. -* **ExitOnForwardFailure** - Specifies whether azbridge(1) should terminate the - connection if it cannot set up all requested local, and remote port forwardings, - (e.g. if either end is unable to bind and listen on a specified port). - The argument must be "true" or "false". The default is "false". -* **GatewayPorts** - Specifies whether remote hosts are allowed to connect to local - forwarded ports. By default, azbridge(1) binds local port forwardings - to the loopback address. This prevents other remote hosts from - connecting to forwarded ports. GatewayPorts can be used to specify that azbridge - should bind local port forwardings to the wildcard address, thus allowing remote - hosts to connect to forwarded ports. The argument must be "true" or "false". - The default is "false". -* **LocalForward** - Specifies that a (set of) TCP ports on the local machine - shall be forwarded via the Azure Relay. Each entry can have four properties, - "BindAddress", "Port", "LocalSocket", and "RelayName". See [below](#localforward-properties) for - details. -* **LogLevel** - Gives the verbosity level that is used when logging messages - from azbridge(1). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, - DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. - DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify - higher levels of verbose output. -* **RemoteForward** - Specifies that a TCP port on the remote machine be bound to - a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", - "HostPort", and "LocalSocket". See [below](#remoteforward-properties) for details. - -### LocalForward properties - -The following properties are defined for LocalForward. LocalForward is a list -and multiple entries are permitted. - -* **RelayName** - name of the Azure Relay name to bind to -* **ConnectionString** - optional Azure Relay connection string to use just for this forwarder, overriding the global **AzureRelayConnectionString** property. - -For a single port binding on the Relay name, the following properties can be -used on the same entry. For multiple bindings they can be used to form a list. - -* **BindAddress** - network address to bind the socket to -* **PortName** - Logical port name -* **BindPort** - TCP port to bind the socket to -* **BindLocalSocket** - named UNIX socket to bind to -* **RemoteHostName** - optionally, remote host name represented by this entry (purely informational) - -Examples: - -- Single listener binding: - ``` YAML - - RelayName: myrelay - BindAddress: 127.0.8.1 - BindPort: 8888 - ``` -- Multiple listener binding: - ``` YAML - - RelayName: myrelay - Bindings: - - BindAddress: 127.0.8.1 - BindPort: 5671 - PortName: amqps - - BindAddress: 127.0.8.1 - BindPort: 5672 - PortName: amqp - ``` - - -Using `BindAddress` and `BindPort` is mutually exclusive with use of the -`BindLocalSocket` option. The bind_address argument is optional and when -omitted, the default is for the listener to bind to all interfaces. - -The `RelayName` option is always required. - -The `RemoteHostName` is property optional and used for documentation. Host -names that shall resolve to the -L local forwarder address need to -be added to the local hosts file. - -The `ConnectionString` property is optional and overrides the global settings -if supplied. - -### RemoteForward properties - -The following properties are defined for RemoteForward. RemoteForward is a list -and multiple entries are permitted. - -* **RelayName** - name of the Azure Relay name to bind to -* **ConnectionString** - Azure Relay connection string to use for this forwarder - -For a single port binding on the Relay name, the following properties can be -used on the same entry. For multiple bindings they can be used to form a list. - -* **Host** - network address to forward to -* **HostPort** - TCP port on the host to forward to -* **PortName** - Logical port name -* **LocalSocket** - named UNIX socket forward to - -Examples: - -- Single listener binding: - ``` YAML - - RelayName: myrelay - Host: localhost - HostPort: 8888 - ``` -- Multiple listener binding: - ``` YAML - - RelayName: myrelay - Bindings: - - Host: broker.corp.example.com - HostPort: 5671 - PortName: amqps - - Host: broker.corp.example.com - HostPort: 5672 - PortName: amqp - ``` - -Using `Host` and `HostPort` is mutually exclusive with use of the -`LocalSocket` option. The host argument is optional and when -omitted, the default is for the forwarder to connect to the local machine. - -The `RelayName` option is always required. - -The `ConnectionString` property is optional and overrides the global settings -if supplied. - -## Configuration examples - -### Example 1 - -This example shows a local configuration that enables local forwarders for -three remote computers on different intranets via RDP. - -``` yaml ---- -GatewayPorts : no -LocalForward: - - # RDP to remote machine abcxyz - - BindAddress: 127.0.10.1 - HostName: abcxyz.intra-de.example.com - BindPort: 3389 - RelayName: abcxyzrdp - -# SQL to remote machine abcxyz - - BindAddress: 127.0.10.1 - HostName: abcxyz.intra-de.example.com - BindPort: 1433 - RelayName: abcxyzsql - - # RDP to remote machine defijk - - BindAddress: 127.0.10.2 - HostName: defijk.intra-us.example.com - BindPort: 3389 - RelayName: defijkrdp - - # RDP to remote machine ghiuvw - - BindAddress: 127.0.10.3 - HostName: ghiuvw.intra-jp.example.com - BindPort: 3389 - RelayName: ghiuvwrdp -``` - -## Example 2 - -This example shows a local configuration that enables the remote -forwarder for RDP on the computer `abcxyz` from the prior example. - - -``` yaml ---- -GatewayPorts : no -RemoteForward: - - # RDP to this machine abcxyz - - RelayName: abcxyzrdp - HostPort: 3389 -``` - -## Example 3 - -This example shows a local configuration that enables the remote -forwarder for RDP to a computer `defijk` from the prior example -on the remote network, but from a different computer. - - -``` yaml ---- -GatewayPorts : no -RemoteForward: -# RDP to remote machine defijk - - RelayName: defijkrdp - Host: defijk.intra-us.example.com - HostPort: 3389 -``` - -## Example 4 - -This example shows a configuration that allows access -to a remote SQL server on a local network address of this computer. - -``` yaml ---- -GatewayPorts : true -LocalForward: - - # SQL to remote machine abcxyz - - BindAddress: 10.10.100.2 - HostName: abcxyz.intra-de.example.com - BindPort: 1433 - RelayName: abcxyzsql -``` - - +# Configuration and Command Line Options + +## Command Line Options + +'azbridge' can be run in a "local" or "remote" mode. The "local" mode binds a +local listener address or socket to a relay name. The "remote" mode binds a relay +name to a remote listener adress. + +Since azbridge helps with scenarios not dissimilar to SSH tunnels, albeit without +requiring peer-to-peer connectivity, the command line syntax of 'azbridge' uses +elements that resemble SSH's equivalent tunnel functionality, especially the -L +and -R arguments. The key difference to SSH is that azbridge always binds sockets +to an Azure Relay name, and that Azure Relay acts as the identifier for the +tunnel and as network rendezvous point. In other words, you **always** need to +pair an azbridge instance running as local forwarder with an azbridge running +as a remote forwarder on the other end. + +SSH's dynamic SOCKS proxy functionality (SSH's -D option) is not supported since +it puts clients in control of selecting remote hosts after they've been bridged +into a foreign network, and this may pose significant security risks and might +inadvertently enable undesired access to resources on that foreign network. + +`(C) -- 127.3.2.1:5000 -> (L) -- ['myname'] -> (R) -- 10.1.2.3:5000 -> (S)` + +* **(C)** Client +* **(L)** Local forwarder: `azbridge -L 127.3.2.1:5000:myname` +* **(R)** Remote forwarder: `azbridge -R myname:10.1.2.3:5000` +* **(S)** Server listening at `10.1.2.3:5000` + + +A single instance of azbridge can support multiple concurrent "local" listeners +and multiple "remote" forwarders concurrently, also in a mixed configuration. + +The required Azure Relay connection string can either be supplied on the command +line, can be picked from an environment variable, or from a configuration file. + +The connection string's embedded authentication/authorization information must +confer sufficient permissions for the desired operation(s) to be executed, e.g. +for the "local" mode, the connection string must enable the bridge to send to +the configured relay entity. + +Arguments: + +**-b bind_address** + +Use bind_address on the local machine as the source address of +forwarding connections. Only useful on systems with more than one +address. + +**-D** + +Reserved. Not presently supported + +**-E endpoint_uri** + +Azure Relay endpoint URI (see -x). + +**-F configfile** + +Specifies an alternative per-user configuration file. If a configuration +file is given on the command line, the system-wide configuration file +(Linux: /etc/azbridge/azbridge_config.machine.yml, +Windows: %ALLUSERSPROFILE%\Microsoft\AzureBridge\azbridge_config.machine.yml) will be +ignored. + +The default for the per-user configuration file is ~/.azurebridge/config +on Linux and %USERPROFILE%\.azurebridge\config on Windows. + +**-g** + +Allows remote hosts to connect to local forwarded ports. + +**-K policy_name** + +Azure Relay shared access policy name to use (see -x). + +**-k policy_key** + +Azure Relay shared access policy key to use (see -x). + +**-L [bind_address:]port[/port_name]{;...}:relay_name**
+**-L local_socket[/port_name]{;...}:relay_name**
+ +Specifies that connections to the given TCP/UDP port(s) or Unix socket(s) +on the local (client) host are to be bound (forwarded) to the given +Azure Relay name. + +- `bind_address`: Optional local IP address to bind the + listener to. This may be a DNS name or a numerical IPv4 or + IPv6 address expression and must resolve to a network endpoint + on the local machine. When omitted, the listener is bound to + all addresses ("any"). +- `port`: TCP or UDP port number. TCP ports are the default. + UDP port numbers must be suffixed with `U`, + e.g. `-L 3434U:relay`. +- `local_socket`: Unix socket name. The expression will be + interpreted as a Unix socket name if it's not a valid `port` + expression (i.e. not a number, with optional protocol suffix). +- `port_name`: Optional logical name for the port. If a "local" + TCP port ought to be mapped to a different "remote" TCP port, + a logical name allows this clearly, e.g. `-L 13389/rdp:relay` + matches to `-R relay:rdp/3389` on the logical port name `rdp`, + which is bound to TCP port 13389 on the local side and TCP + port 3389 on the remote side. For TCP/UDP, the default value + for `port_name` is the `port` value itself, meaning + `-L 13389:relay` can also be matched with `-R relay:13389/3389`. + For Unix sockets, this logical mapping can also be used, and + the default value is the name of `local_socket`. It is + permitted for multiple local TCP ports and Unix sockets or + for multiple UDP ports to use the same logical port name. UDP + ports must always be matched to remote UDP forwarders. +- `relay_name`: Name of the relay to bind the port(s) to. + +There can be multiple local binding expressions given for a +`relay_name`, separated by semicolons. The expressions can +also mix protocols, e.g. `-L 7777;7777U:relay` binds the +TCP and UDP ports 7777 to one relay name. + +The bridge opens a listener on a TCP or UDP port or a Unix socket +"here". The TCP or UDP listener is optionally bound to the +specified `bind_address`. Whenever a connection +is made to the local port or socket, the connection is forwarded +to a connected remote bridge via the chosen Relay entity. + +Port forwardings can also be specified in the configuration file. +Only the superuser can forward privileged ports. IPv6 addresses +can be specified by enclosing the address in square brackets. + +By default, the local port is bound in accordance with the +*GatewayPorts* configuration setting. However, an explicit bind_address +may be used to bind the connection to a specific address. The +bind_address of ``localhost'' indicates that the listening port +be bound for local use only, while an empty address or '*' indi- +cates that the port should be available from all interfaces. + +The -L option can be used multiple times on a single command line, +but only once per `relay_name`. + +**-o option** + +Can be used to give options in the format used in the configura- +tion file. This is useful for specifying options for which there +is no separate command-line flag. + +**-q** + +Quiet mode. Causes most warning and diagnostic messages to be +suppressed. + +**-R relay_name:[port_name/]hostport{;...}**
+**-R relay_name:host:[port_name/]hostport{;...}**
+**-R relay_name:[port_name/]local_socket{;...}** + +Specifies that connections to the given Azure Relay name +and optional logical port name are to be forwarded to the +given host and port, or Unix socket*. +Whenever a connection is made to the Relay and logical port, +the connection is forwarded to this listener (or a concurrently +connected listener in a random load distribution fashion), and a +then a forwarding connection is made to either port, host:hostport, +or local_socket, from the local machine. + +- `relay_name`: Name of the relay to bind the forwarder to. +- `port_name`: Optional logical name for the port as defined by + the local forwarder bound to this relay (see -L). +- `host`: Host name or IP address to forward to. +- `port`: TCP or UDP port number. TCP ports are the default. + UDP port numbers must be suffixed with `U`, + e.g. `-R relay:3434U`. UDP forwarders can only be bound to + logcial UDP ports. +- `local_socket`: Unix socket name. The expression will be + interpreted as a Unix socket name if it's not a valid `port` + expression (i.e. not a number, with optional protocol suffix). + +There can be multiple local binding expressions given for a +`relay_name`, separated by semicolons. The expressions can +also mix protocols, e.g. `-R relay:7777;7777U` binds to +TCP and UDP port forwarders for 7777 on one relay name. + +Port forwardings can also be specified in the configuration file. +Privileged ports can be forwarded only when runing with elevated privileges. +IPv6 addresses can be specified by enclosing the address in square +brackets. + +The -R option can be used multiple times on a single command line, +but only once for each `relay_name`. + +**-S signature** + +Azure Relay shared access signature (previously issued access token) +to use (see -x) + +**-V** + +Display the version number and exit. + +**-v** + +Verbose mode. Causes ssh to print debugging messages about its +progress. This is helpful in debugging connection, authentica- +tion, and configuration problems. Multiple -v options increase +the verbosity. The maximum is 3. + +**-x connection_string** + +Connection String. Azure Relay connection string for the namespace +or for a specific Azure Relay. The Connection String properties +can be overriden by the -E (Endpoint), -K (SharedAccessKeyName), +-k (SharedAccessKey), -S (SharedAccessSignature) arguments. + +If an EntityPath is specified in the connection string, that name +is the only valid option for the relay_name expressions in the +-L and -R options or for expressions in the effective configuration +file. + +The connection string can be set via the AZURE_BRIDGE_CONNECTIONSTRING +environment variable. + +## Configuration File + +The configuration file is a YAML file that specifies options that apply +to the machine or user. The machine level options are always read and +then complemented by or overriden by the user-level options. + +The configuration file can exist in three locations: + +1. Machine configuration, always loaded if present. + Linux: /etc/azurebridge/azurebridge_config + Windows: %ALLUSERSPROFILE%\Microsoft\AzureBridge\azbridge_config +2. User configuration, overrides and complements machine config. + Linux: ~/.azurebridge/config + Windows: %USERPROFILE%\.azurebridge\config +3. Override user configuration location for current execution with + the -f option. + +The configuration file holds a range of configuration options that, just +like the command line options, partially lean on similar expressions +used in SSH, even though the configuration format differs from that of SSH. + +The "LocalForward" and "RemoteForward" sections define bindings as with +the -L and -R command line options above. + +* **AddressFamily** - Specifies which address family to use when connecting. Valid + arguments are "any", "inet" (use IPv4 only), or "inet6" + (use IPv6 only). The default is "any". +* **AzureRelayConnectionString** - Azure Relay connection string for a Relay + namespace. Only one namespace connection string can be specified per configuration + file. +* **AzureRelayEndpoint** - Azure Relay endpoint URI for a Relay namespace. Overrides + the 'Endpoint' property of the connection string, if present. +* **AzureRelaySharedAccessKeyName** - Azure Relay shared access policy name. Overrides + the 'SharedAccessKeyName' property of the connection string, if present. +* **AzureRelaySharedAccessKey** - Azure Relay shared access policy key. Overrides + the 'SharedAccessKey' property of the connection string, if present. +* **AzureRelaySharedAccessSignature** - Azure Relay shared access policy signature. Overrides + the 'SharedAccessSignature' property of the connection string, if present. +* **BindAddress** - Use the specified address on the local machine as the source + address of the connection. Only useful on systems with more than + one address. +* **ClearAllForwardings** - Specifies that all local, and remote port forwardings + specified in the configuration files or on the command line be + cleared. This option is primarily useful when used from the + command line to clear port forwardings set in configura- + tion files. The argument must be "true" or "false". The default is "false". +* **ConnectionAttempts** - Specifies the number of tries (one per second) to make + before exiting. The argument must be an integer. This may be useful in scripts + if the connection sometimes fails. The default is 1. +* **ConnectTimeout** - Specifies the timeout (in seconds) used when connecting to the + relay server, instead of using the default system TCP timeout. + This value is used only when the target is down or really + unreachable, not when it refuses the connection. +* **ExitOnForwardFailure** - Specifies whether azbridge(1) should terminate the + connection if it cannot set up all requested local, and remote port forwardings, + (e.g. if either end is unable to bind and listen on a specified port). + The argument must be "true" or "false". The default is "false". +* **GatewayPorts** - Specifies whether remote hosts are allowed to connect to local + forwarded ports. By default, azbridge(1) binds local port forwardings + to the loopback address. This prevents other remote hosts from + connecting to forwarded ports. GatewayPorts can be used to specify that azbridge + should bind local port forwardings to the wildcard address, thus allowing remote + hosts to connect to forwarded ports. The argument must be "true" or "false". + The default is "false". +* **LocalForward** - Specifies that a (set of) TCP ports on the local machine + shall be forwarded via the Azure Relay. Each entry can have four properties, + "BindAddress", "Port", "LocalSocket", and "RelayName". See [below](#localforward-properties) for + details. +* **LogLevel** - Gives the verbosity level that is used when logging messages + from azbridge(1). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, + DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. + DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify + higher levels of verbose output. +* **RemoteForward** - Specifies that a TCP port on the remote machine be bound to + a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", + "HostPort", and "LocalSocket". See [below](#remoteforward-properties) for details. + +### LocalForward properties + +The following properties are defined for LocalForward. LocalForward is a list +and multiple entries are permitted. + +* **RelayName** - name of the Azure Relay name to bind to +* **ConnectionString** - optional Azure Relay connection string to use just for this forwarder, overriding the global **AzureRelayConnectionString** property. + +For a single port binding on the Relay name, the following properties can be +used on the same entry. For multiple bindings they can be used to form a list. + +* **BindAddress** - network address to bind the socket to +* **PortName** - Logical port name +* **BindPort** - TCP port to bind the socket to +* **BindLocalSocket** - named UNIX socket to bind to +* **RemoteHostName** - optionally, remote host name represented by this entry (purely informational) + +Examples: + +- Single listener binding: + ``` YAML + - RelayName: myrelay + BindAddress: 127.0.8.1 + BindPort: 8888 + ``` +- Multiple listener binding: + ``` YAML + - RelayName: myrelay + Bindings: + - BindAddress: 127.0.8.1 + BindPort: 5671 + PortName: amqps + - BindAddress: 127.0.8.1 + BindPort: 5672 + PortName: amqp + ``` + + +Using `BindAddress` and `BindPort` is mutually exclusive with use of the +`BindLocalSocket` option. The bind_address argument is optional and when +omitted, the default is for the listener to bind to all interfaces. + +The `RelayName` option is always required. + +The `RemoteHostName` is property optional and used for documentation. Host +names that shall resolve to the -L local forwarder address need to +be added to the local hosts file. + +The `ConnectionString` property is optional and overrides the global settings +if supplied. + +### RemoteForward properties + +The following properties are defined for RemoteForward. RemoteForward is a list +and multiple entries are permitted. + +* **RelayName** - name of the Azure Relay name to bind to +* **ConnectionString** - Azure Relay connection string to use for this forwarder + +For a single port binding on the Relay name, the following properties can be +used on the same entry. For multiple bindings they can be used to form a list. + +* **Host** - network address to forward to +* **HostPort** - TCP port on the host to forward to +* **PortName** - Logical port name +* **LocalSocket** - named UNIX socket forward to + +Examples: + +- Single listener binding: + ``` YAML + - RelayName: myrelay + Host: localhost + HostPort: 8888 + ``` +- Multiple listener binding: + ``` YAML + - RelayName: myrelay + Bindings: + - Host: broker.corp.example.com + HostPort: 5671 + PortName: amqps + - Host: broker.corp.example.com + HostPort: 5672 + PortName: amqp + ``` + +Using `Host` and `HostPort` is mutually exclusive with use of the +`LocalSocket` option. The host argument is optional and when +omitted, the default is for the forwarder to connect to the local machine. + +The `RelayName` option is always required. + +The `ConnectionString` property is optional and overrides the global settings +if supplied. + +## Configuration examples + +### Example 1 + +This example shows a local configuration that enables local forwarders for +three remote computers on different intranets via RDP. + +``` yaml +--- +GatewayPorts : no +LocalForward: + + # RDP to remote machine abcxyz + - BindAddress: 127.0.10.1 + HostName: abcxyz.intra-de.example.com + BindPort: 3389 + RelayName: abcxyzrdp + +# SQL to remote machine abcxyz + - BindAddress: 127.0.10.1 + HostName: abcxyz.intra-de.example.com + BindPort: 1433 + RelayName: abcxyzsql + + # RDP to remote machine defijk + - BindAddress: 127.0.10.2 + HostName: defijk.intra-us.example.com + BindPort: 3389 + RelayName: defijkrdp + + # RDP to remote machine ghiuvw + - BindAddress: 127.0.10.3 + HostName: ghiuvw.intra-jp.example.com + BindPort: 3389 + RelayName: ghiuvwrdp +``` + +## Example 2 + +This example shows a local configuration that enables the remote +forwarder for RDP on the computer `abcxyz` from the prior example. + + +``` yaml +--- +GatewayPorts : no +RemoteForward: + + # RDP to this machine abcxyz + - RelayName: abcxyzrdp + HostPort: 3389 +``` + +## Example 3 + +This example shows a local configuration that enables the remote +forwarder for RDP to a computer `defijk` from the prior example +on the remote network, but from a different computer. + + +``` yaml +--- +GatewayPorts : no +RemoteForward: +# RDP to remote machine defijk + - RelayName: defijkrdp + Host: defijk.intra-us.example.com + HostPort: 3389 +``` + +## Example 4 + +This example shows a configuration that allows access +to a remote SQL server on a local network address of this computer. + +``` yaml +--- +GatewayPorts : true +LocalForward: + + # SQL to remote machine abcxyz + - BindAddress: 10.10.100.2 + HostName: abcxyz.intra-de.example.com + BindPort: 1433 + RelayName: abcxyzsql +``` + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a35fc7..6977516 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,44 +1,44 @@ -# Contribute or Provide Feedback for Azure Relay - -## Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [Filing Issues](#filing-issues) -- [Pull Requests](#pull-requests) - - [General guidelines](#general-guidelines) - - [Testing guidelines](#testing-guidelines) - -## Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -## Language specific libraries - -If you have an issue for a specific client library, see the following: -* [.NET](https://github.com/clemensv/azure-relay-bridge-dotnet) -* [.Node](https://github.com/clemensv/azure-relay-bridge-node) - -## Filing Issues - -You can find all of the issues that have been filed in the [Issues](https://github.com/clemensv/azure-relay-bridge/issues) section of the repository. - -If you encounter any service side bugs, please file an issue [here](https://github.com/clemensv/azure-relay-bridge/issues/new) and make sure to fill out the provided template with the requested information. - -To suggest a new feature or changes that could be made, file an issue the same way you would for a bug, but remove the provided template and replace it with information about your suggestion. - -### Pull Requests - -You can find all of the pull requests that have been opened in the [Pull Request](https://github.com/clemensv/azure-relay-bridge/pulls) section of the repository. - -To open your own pull request, click [here](https://github.com/clemensv/azure-relay-bridge/compare). When creating a pull request, keep the following in mind: -- Make sure you are pointing to the fork and branch that your changes were made in -- The pull request template that is provided **should be filled out**; this is not something that should just be deleted or ignored when the pull request is created - - Deleting or ignoring this template will elongate the time it takes for your pull request to be reviewed - -#### General guidelines - -The following guidelines must be followed in **EVERY** pull request that is opened. - -- Title of the pull request is clear and informative -- There are a small number of commits that each have an informative message +# Contribute or Provide Feedback for Azure Relay + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Filing Issues](#filing-issues) +- [Pull Requests](#pull-requests) + - [General guidelines](#general-guidelines) + - [Testing guidelines](#testing-guidelines) + +## Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Language specific libraries + +If you have an issue for a specific client library, see the following: +* [.NET](https://github.com/clemensv/azure-relay-bridge-dotnet) +* [.Node](https://github.com/clemensv/azure-relay-bridge-node) + +## Filing Issues + +You can find all of the issues that have been filed in the [Issues](https://github.com/clemensv/azure-relay-bridge/issues) section of the repository. + +If you encounter any service side bugs, please file an issue [here](https://github.com/clemensv/azure-relay-bridge/issues/new) and make sure to fill out the provided template with the requested information. + +To suggest a new feature or changes that could be made, file an issue the same way you would for a bug, but remove the provided template and replace it with information about your suggestion. + +### Pull Requests + +You can find all of the pull requests that have been opened in the [Pull Request](https://github.com/clemensv/azure-relay-bridge/pulls) section of the repository. + +To open your own pull request, click [here](https://github.com/clemensv/azure-relay-bridge/compare). When creating a pull request, keep the following in mind: +- Make sure you are pointing to the fork and branch that your changes were made in +- The pull request template that is provided **should be filled out**; this is not something that should just be deleted or ignored when the pull request is created + - Deleting or ignoring this template will elongate the time it takes for your pull request to be reviewed + +#### General guidelines + +The following guidelines must be followed in **EVERY** pull request that is opened. + +- Title of the pull request is clear and informative +- There are a small number of commits that each have an informative message - A description of the changes the pull request makes is included, and a reference to the bug/issue the pull request fixes is included, if applicable \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index d1975f2..15d81ab 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,34 +1,34 @@ - - - - - - - - - false - net462; - netcoreapp2.1 - $(WindowsFrameworks)$(CoreFrameworks) - win7-x64;win7-x86;win10-x64;win10-x86; - osx-x64;debian.8-x64;ubuntu.16.10-x64;ubuntu.16.04-x64;opensuse-x64;ol-x64;rhel-x64;fedora-x64;centos-x64 - $(WindowsRuntimeIdentifiers)$(UnixRuntimeIdentifiers) - - - - Microsoft Azure Relay Bridge - https://github.com/Azure/azure-relay-bridge - git - $(MSBuildThisFileDirectory) - $(RepositoryRoot)/artifacts/build - $(MSBuildThisFileDirectory)build\Key.snk - true - true - true - false - Debug - + + + + + + + + + false + net462; + netcoreapp3.0 + $(WindowsFrameworks)$(CoreFrameworks) + win7-x64;win7-x86;win10-x64;win10-x86; + osx-x64;debian.8-x64;ubuntu.16.10-x64;ubuntu.16.04-x64;opensuse-x64;ol-x64;rhel-x64;fedora-x64;centos-x64 + $(WindowsRuntimeIdentifiers)$(UnixRuntimeIdentifiers) + + + + Microsoft Azure Relay Bridge + https://github.com/Azure/azure-relay-bridge + git + $(MSBuildThisFileDirectory) + $(RepositoryRoot)/artifacts/build + $(MSBuildThisFileDirectory)build\Key.snk + true + true + true + false + Debug + \ No newline at end of file diff --git a/Directory.Build.targets b/Directory.Build.targets index 8c0168c..911d4af 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,13 +1,11 @@ - - - $(MicrosoftNETCoreApp20PackageVersion) - $(MicrosoftNETCoreApp21PackageVersion) - $(MicrosoftNETCoreApp22PackageVersion) - $(NETStandardLibrary20PackageVersion) - - 99.9 - - - - - + + + $(MicrosoftNETCoreApp30PackageVersion) + $(NETStandardLibrary20PackageVersion) + + 99.9 + + + + + diff --git a/Dockerfile b/Dockerfile index e39fda9..7aae6e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,23 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as build - -WORKDIR /azure-relay-bridge/src - -COPY src/azbridge/azbridge.csproj /azure-relay-bridge/src/azbridge/ -COPY src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj /azure-relay-bridge/src/Microsoft.Azure.Relay.Bridge/ - -RUN dotnet restore /azure-relay-bridge/src/azbridge/azbridge.csproj - -COPY . /azure-relay-bridge/ - -WORKDIR /azure-relay-bridge/src/azbridge -RUN dotnet build azbridge.csproj - - -FROM build AS publish -WORKDIR /azure-relay-bridge/src/azbridge -RUN dotnet publish azbridge.csproj -c Release -f netcoreapp2.1 -o /app - - -FROM mcr.microsoft.com/dotnet/core/runtime:2.1 -WORKDIR /app -COPY --from=publish /app . +FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as build + +WORKDIR /azure-relay-bridge/src + +COPY src/azbridge/azbridge.csproj /azure-relay-bridge/src/azbridge/ +COPY src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj /azure-relay-bridge/src/Microsoft.Azure.Relay.Bridge/ + +RUN dotnet restore /azure-relay-bridge/src/azbridge/azbridge.csproj + +COPY . /azure-relay-bridge/ + +WORKDIR /azure-relay-bridge/src/azbridge +RUN dotnet build azbridge.csproj + + +FROM build AS publish +WORKDIR /azure-relay-bridge/src/azbridge +RUN dotnet publish azbridge.csproj -c Release -f netcoreapp3.0 -o /app + + +FROM mcr.microsoft.com/dotnet/core/runtime:2.1 +WORKDIR /app +COPY --from=publish /app . diff --git a/LICENSE.txt b/LICENSE.txt index 2e6aed8..82beab2 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,14 +1,14 @@ -Copyright (c) Microsoft Corporation - -All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. +Copyright (c) Microsoft Corporation + +All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index cb04f71..7337b94 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -1,18 +1,17 @@ -{ - - "Default": { - "packages" : { - "azbridge": { - "Exclusions": { - "DOC_MISSING": { - "lib/netcoreapp2.0/azbridge.dll": "no public API", - "lib/netcoreapp2.1/azbridge.dll": "no public API" - } - } - } - }, - "rules": [ - "DefaultCompositeRule" - ] - } +{ + + "Default": { + "packages" : { + "azbridge": { + "Exclusions": { + "DOC_MISSING": { + "lib/netcoreapp3.0/azbridge.dll": "no public API" + } + } + } + }, + "rules": [ + "DefaultCompositeRule" + ] + } } \ No newline at end of file diff --git a/README.md b/README.md index 312c9e4..4151f42 100644 --- a/README.md +++ b/README.md @@ -1,224 +1,224 @@ -# Azure Relay Bridge - -![img](https://ci.appveyor.com/api/projects/status/github/clemensv/azure-relay-bridge) - -The Azure Relay Bridge is a tool that allows creating TCP tunnels between any -pair of hosts, as log as those hosts each have outbound Internet connectivity on -port 443 (HTTPS) to the Azure Relay service. - -The Relay Bridge is designed for reaching networked assets in any environment -where it is impractical or impossible for those assets to be directly reachable -through a public IP address. - -For instance, if you need to reach an on-premises database or application from -a cloud-based solution, the on-premises assets are typically not accessible -from the public network. The Relay Bridge can help establishing a TCP tunnel -socket exclusive to a particular endpoint in such an on-premises environment, -and without the complexity of a VPN solution. - -Another example are on-premises applications that run behind network gateways -with dynamically assigned IP addresses, like in most residential and small-business -environments. An Azure Relay endpoint provides a stable network destination for -such application endpoints, without VPN, and without the complexity of a dynamic -DNS registration. - -Inside cloud and data-center environments, reaching into and bridging between -containerized workloads can also be tricky. The Relay Bridge can provide -every service inside a container instance with a stable and externally reachable -network address, and with the Relay's built-in load balancing support, you can -even bind multiple services inside separate container instances to the same name. -And you can do all that without configuring any kind of inbound network access -to the containers. - -Practically all TCP-based services, including HTTP(S), are compatible with -the Azure Relay Bridge. For services that require connections to be made from -both parties, the bridge can concurrently act as local and remote bridge. - -All Azure Relay endpoints are secure, requiring TLS 1.2+ (aka SSL) WebSocket -connections for all connections through the Relay, and both communicating -parties must provide an authorization token to establish a connection via the -Relay. - -The Azure Relay Bridge builds on this foundation and creates the illusion of a -local connection to the target service by ways of a *local forwarder* that listens -on a configured IP address and port, and that then forwards all incoming TCP -connections to a *remote forwarder* via the Azure Relay. The *remote forwarder* -connects each incoming connection to the target service. - - -## azbridge - -The Relay Bridge is a command line utility ("azbridge") with binary distributions -for Windows, macOS, and several Linux distributions. It can optionally also be -configured and run as a background service on Windows and Linux. - -Since the tool helps with scenarios not dissimilar to SSH tunnels (but without -requiring peer-to-peer connectivity) the command line syntax of *azbridge* uses -elements that resemble SSH's equivalent tunnel functionality, especially the -L -and -R arguments. The key difference to SSH is that *azbridge* always binds sockets -to an Azure Relay name, and that Azure Relay acts as the identifier for the -tunnel and as network rendezvous point. - -The bridge can either be used directly on the machines where a client or a server -resides, or it can be used as a gateway solution. When used as *local forwarder -gateway* (*-g* *-L*) and with externally resolvable listener addresses, the bridge -resides on a host in the network and allows connections from clients across the -network. The *remote forwarder* (*-R*) can always reach out to off-machine targets -within its network scope. - -When the bridge is used locally, the client can configure DNS names of the target -services in the local *hosts* file, picking a unique IP address out of the 127.x.x.x -range for each service, and then configuring a local forwarder for the respective -target address. Those addresses can only be reached on that local machine, shielding -the client from exposing TCP bridges to others. For instance, for reaching the remote -SQL Server "sql.corp.example.com", you would add an IP address like `127.1.2.3` to -the "hosts" file as `127.1.2.3 sql.corp.example.com`, and then use a local forwarder -configuration that refers to the `127.1.2.3` address, for example -`azbridge -L 127.1.2.3:1433:relay`. - -When used as a *local forwarder gateway*, you will need to use addresses that can be -reached by the clients in your network, and ideally have a multi-homed setup where -the gateway node has a network address, e.g. from the `10.x.x.x` range, per remote -target service host. For naming support, those network addresses should be registered -in a DNS service reachable and used by the clients in your network. A DNS service is -also required for resolving wildcard addresses, even for the local scenario. - -With a local configuration, when using *azbridge* to reach a Microsoft SQL Server -instance endpoint (port 1433) on a different network, you would use the following -constellation: - -* SQL Client connects to sql.corp.example.com:1433, whereby the local "hosts" file - re-maps the server name to a local address with the entry - `127.0.5.1 sql.corp.example.com` -* Local bridge on the same machine the client runs as - `azclient -L 127.0.5.1:1433:sql-corp-example-com -x {cxnstring}` -* Azure Relay has a configured endpoint - `wss://mynamespace.servicebus.windows.net/$hc/sql-corp-example-com` -* Remote Bridge on or near the server runs as - `azclient -R sql-corp-example-com:sql.corp.example.com:1433 -x {cxnstring}` -* SQL Server runs as `sql.corp.example.com:1433` - -The `{cxnstring}` represents the connection string for the configured -Azure Relay endpoint with appropriate send and/or listen permissions. - -The connection string can be obtained from the portal. - -Further details about how to use the tool and how to configure it can be found in -the [Configuration and Command Line Options](CONFIG.md) document. - -## Downloads - -This is an early preview. Unsigned (!) binaries are available for direct download -from the [Github Releases](../../releases) page for evaluation. Signed binaries will eventually -be available for download with common package managers. - -## Installation - -The tool has installation packages for a variety of platforms. All packages are -self-contained distributions, meaning they do not rely on a centrally installed -runtime. However, depending on the package type and platform, the installation -of some prerequisites may be required. - -### Windows - -The easiest way to install the bridge on Windows is by using the appropriate -*.msi package. The installer adds the tool to the PATH and also registers -the "azbridge" Windows service. The service is configured for on-demand -(manual) start at installation time. - -> **KNOWN ISSUE:** These early builds are not signed. Download the MSI file, -unblock it, and then install. Otherwise the application may not work as -expected. - -### Linux - -### Debian, Ubuntu, Linuxmint - -For Debian 8+ and all Debian-based distributions, like Ubuntu 16.04+ and Linuxmint 16+, -you can install the tool from the respective *.deb package with - -`sudo apt-get install ./{package-name}.deb` - -Using `apt-get` will automatically install the distribution prerequisites. The -.NET Core platform required by the tool is private and not installed machine-wide. - -The package install will put the tool into `/usr/share/azbridge`, place a machine-wide -configuration file into `/etc/azbridge`, add the tool to the PATH, and register two -BASH extensions for adding and removing entries from the `/etc/hosts` file: - -* `addhost {ipaddress} {name}` - adds an IP address with the given hostname to "hosts" -* `removehost {name}` - removes the entry for the given hostname - -### Fedora, CentOS, Red Hat Enterprise Linux - -For Fedora, CentOS, and Red Hat Enterprise Linux, you can install the tool from the -respective *.rpm package with - -`sudo yum install {package-name}.rpm` - -Using `yum` will automatically install the distribution prerequisites. The -.NET Core platform required by the tool is private and not installed machine-wide. - -The package install will put the tool into `/usr/share/azbridge`. - -> **KNOWN ISSUE 1:** The package will presently not install correctly if the install of -> documentation files is suppressed for `yum` and/or `dnf`. The is the case for many -> container base images. On CentOS, you should drop the respective configuration with -> `sed -i '/tsflags=nodocs/d' /etc/yum.conf` (RUN in a Dockerfile before installing -> the rpm) and on Fedora use `sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf`. -> **KNOWN ISSUE 2:** The package does not yet perform any of the post-install tasks that -> the Debian package performs, meaning the tool is not added to the PATH. - -### Other distributions and platforms - -You can also install the tool from respective platform *.tar.gz archive. For Linux, -you need to [explicitly install Linux prerequisites for .NET Core](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x) -for your respective distribution. For macOS, you need to [install prerequisites from -this list](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore2x). - -## Building the code - -The repo contains a complete build and verification structure for all platforms. - -The Windows version MUST be built on Windows because the service integration requires -the full .NET Framework and the installer can only be built on Windows. You will at least -need the "Build Tools for Visual Studio 2017", and ideally a local install of -Visual Studio 2017 with desktop C# support. - -All other versions are built with the .NET Core 2.0 or .NET Core 2.1 SDK. The DEB and -RPM packages are only created when building on a Unix (i.e. Linux or macOS) host. - -The ideal build environment is a Windows 10/Windows Server 2016 host with Docker for -Windows installed. The `package-all.cmd` script will first build and package all Windows -targets, and then launch a docker-based build with the official Microsoft .NET Core 2.1 -SDK image for the remaining targets. The `package.sh` script will only build and package -the Unix targets, the `package.cmd` script only Windows targets. - -The latter two scripts are used with the AppVeyor build as well. - -All build output is placed into `./artifacts/build` - -## Tests - -Running the Unit tests and the Integration tests both require an Azure Relay namespace -to be available for use and configured. Before running any of the test scenarios, the -environment variable `AZBRIDGE_TEST_CXNSTRING` must be set to the Relay namespace -connection string (enclosed in quotes) on the build platform. - -An [Azure Resource Manager template](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-deploy-cli) -to deploy a namespace with the definitions required for testing resides in -`./src/tools/azure/test-resource-template.json`. The template expects the name of a new namespace -and a region location as inputs. - -Once the template has been deployed using either Powershell or the Azure CLI, you can find -the "sendListenConnectionString" value (starts with "Endpoint...") in the returned output. -Copy and save that value for use in the `AZBRIDGE_TEST_CXNSTRING` environment variable. - -The Unit tests can be run from the command line with `dotnet test` with an .NET Core build. - -For integration testing that installs and executes the emitted packages, run `verify-build.cmd`/`verify-build.sh`. Expect for Windows, the integration tests depend on a -local Docker installation: The script cleans any existing images, builds CentOS, Debian, Fedora, and Ubuntu images with the newly built binaries, and then executes a series of tests on each image. - -## Contributions - -We're gladly accepting contributions. Please review the [contribution rules](CONTRIBUTING.md). +# Azure Relay Bridge + +![img](https://ci.appveyor.com/api/projects/status/github/clemensv/azure-relay-bridge) + +The Azure Relay Bridge is a tool that allows creating TCP tunnels between any +pair of hosts, as log as those hosts each have outbound Internet connectivity on +port 443 (HTTPS) to the Azure Relay service. + +The Relay Bridge is designed for reaching networked assets in any environment +where it is impractical or impossible for those assets to be directly reachable +through a public IP address. + +For instance, if you need to reach an on-premises database or application from +a cloud-based solution, the on-premises assets are typically not accessible +from the public network. The Relay Bridge can help establishing a TCP tunnel +socket exclusive to a particular endpoint in such an on-premises environment, +and without the complexity of a VPN solution. + +Another example are on-premises applications that run behind network gateways +with dynamically assigned IP addresses, like in most residential and small-business +environments. An Azure Relay endpoint provides a stable network destination for +such application endpoints, without VPN, and without the complexity of a dynamic +DNS registration. + +Inside cloud and data-center environments, reaching into and bridging between +containerized workloads can also be tricky. The Relay Bridge can provide +every service inside a container instance with a stable and externally reachable +network address, and with the Relay's built-in load balancing support, you can +even bind multiple services inside separate container instances to the same name. +And you can do all that without configuring any kind of inbound network access +to the containers. + +Practically all TCP-based services, including HTTP(S), are compatible with +the Azure Relay Bridge. For services that require connections to be made from +both parties, the bridge can concurrently act as local and remote bridge. + +All Azure Relay endpoints are secure, requiring TLS 1.2+ (aka SSL) WebSocket +connections for all connections through the Relay, and both communicating +parties must provide an authorization token to establish a connection via the +Relay. + +The Azure Relay Bridge builds on this foundation and creates the illusion of a +local connection to the target service by ways of a *local forwarder* that listens +on a configured IP address and port, and that then forwards all incoming TCP +connections to a *remote forwarder* via the Azure Relay. The *remote forwarder* +connects each incoming connection to the target service. + + +## azbridge + +The Relay Bridge is a command line utility ("azbridge") with binary distributions +for Windows, macOS, and several Linux distributions. It can optionally also be +configured and run as a background service on Windows and Linux. + +Since the tool helps with scenarios not dissimilar to SSH tunnels (but without +requiring peer-to-peer connectivity) the command line syntax of *azbridge* uses +elements that resemble SSH's equivalent tunnel functionality, especially the -L +and -R arguments. The key difference to SSH is that *azbridge* always binds sockets +to an Azure Relay name, and that Azure Relay acts as the identifier for the +tunnel and as network rendezvous point. + +The bridge can either be used directly on the machines where a client or a server +resides, or it can be used as a gateway solution. When used as *local forwarder +gateway* (*-g* *-L*) and with externally resolvable listener addresses, the bridge +resides on a host in the network and allows connections from clients across the +network. The *remote forwarder* (*-R*) can always reach out to off-machine targets +within its network scope. + +When the bridge is used locally, the client can configure DNS names of the target +services in the local *hosts* file, picking a unique IP address out of the 127.x.x.x +range for each service, and then configuring a local forwarder for the respective +target address. Those addresses can only be reached on that local machine, shielding +the client from exposing TCP bridges to others. For instance, for reaching the remote +SQL Server "sql.corp.example.com", you would add an IP address like `127.1.2.3` to +the "hosts" file as `127.1.2.3 sql.corp.example.com`, and then use a local forwarder +configuration that refers to the `127.1.2.3` address, for example +`azbridge -L 127.1.2.3:1433:relay`. + +When used as a *local forwarder gateway*, you will need to use addresses that can be +reached by the clients in your network, and ideally have a multi-homed setup where +the gateway node has a network address, e.g. from the `10.x.x.x` range, per remote +target service host. For naming support, those network addresses should be registered +in a DNS service reachable and used by the clients in your network. A DNS service is +also required for resolving wildcard addresses, even for the local scenario. + +With a local configuration, when using *azbridge* to reach a Microsoft SQL Server +instance endpoint (port 1433) on a different network, you would use the following +constellation: + +* SQL Client connects to sql.corp.example.com:1433, whereby the local "hosts" file + re-maps the server name to a local address with the entry + `127.0.5.1 sql.corp.example.com` +* Local bridge on the same machine the client runs as + `azclient -L 127.0.5.1:1433:sql-corp-example-com -x {cxnstring}` +* Azure Relay has a configured endpoint + `wss://mynamespace.servicebus.windows.net/$hc/sql-corp-example-com` +* Remote Bridge on or near the server runs as + `azclient -R sql-corp-example-com:sql.corp.example.com:1433 -x {cxnstring}` +* SQL Server runs as `sql.corp.example.com:1433` + +The `{cxnstring}` represents the connection string for the configured +Azure Relay endpoint with appropriate send and/or listen permissions. + +The connection string can be obtained from the portal. + +Further details about how to use the tool and how to configure it can be found in +the [Configuration and Command Line Options](CONFIG.md) document. + +## Downloads + +This is an early preview. Unsigned (!) binaries are available for direct download +from the [Github Releases](../../releases) page for evaluation. Signed binaries will eventually +be available for download with common package managers. + +## Installation + +The tool has installation packages for a variety of platforms. All packages are +self-contained distributions, meaning they do not rely on a centrally installed +runtime. However, depending on the package type and platform, the installation +of some prerequisites may be required. + +### Windows + +The easiest way to install the bridge on Windows is by using the appropriate +*.msi package. The installer adds the tool to the PATH and also registers +the "azbridge" Windows service. The service is configured for on-demand +(manual) start at installation time. + +> **KNOWN ISSUE:** These early builds are not signed. Download the MSI file, +unblock it, and then install. Otherwise the application may not work as +expected. + +### Linux + +### Debian, Ubuntu, Linuxmint + +For Debian 8+ and all Debian-based distributions, like Ubuntu 16.04+ and Linuxmint 16+, +you can install the tool from the respective *.deb package with + +`sudo apt-get install ./{package-name}.deb` + +Using `apt-get` will automatically install the distribution prerequisites. The +.NET Core platform required by the tool is private and not installed machine-wide. + +The package install will put the tool into `/usr/share/azbridge`, place a machine-wide +configuration file into `/etc/azbridge`, add the tool to the PATH, and register two +BASH extensions for adding and removing entries from the `/etc/hosts` file: + +* `addhost {ipaddress} {name}` - adds an IP address with the given hostname to "hosts" +* `removehost {name}` - removes the entry for the given hostname + +### Fedora, CentOS, Red Hat Enterprise Linux + +For Fedora, CentOS, and Red Hat Enterprise Linux, you can install the tool from the +respective *.rpm package with + +`sudo yum install {package-name}.rpm` + +Using `yum` will automatically install the distribution prerequisites. The +.NET Core platform required by the tool is private and not installed machine-wide. + +The package install will put the tool into `/usr/share/azbridge`. + +> **KNOWN ISSUE 1:** The package will presently not install correctly if the install of +> documentation files is suppressed for `yum` and/or `dnf`. The is the case for many +> container base images. On CentOS, you should drop the respective configuration with +> `sed -i '/tsflags=nodocs/d' /etc/yum.conf` (RUN in a Dockerfile before installing +> the rpm) and on Fedora use `sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf`. +> **KNOWN ISSUE 2:** The package does not yet perform any of the post-install tasks that +> the Debian package performs, meaning the tool is not added to the PATH. + +### Other distributions and platforms + +You can also install the tool from respective platform *.tar.gz archive. For Linux, +you need to [explicitly install Linux prerequisites for .NET Core](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x) +for your respective distribution. For macOS, you need to [install prerequisites from +this list](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore2x). + +## Building the code + +The repo contains a complete build and verification structure for all platforms. + +The Windows version MUST be built on Windows because the service integration requires +the full .NET Framework and the installer can only be built on Windows. You will at least +need the "Build Tools for Visual Studio 2017", and ideally a local install of +Visual Studio 2017 with desktop C# support. + +All other versions are built with the .NET Core 2.0 or .NET Core 2.1 SDK. The DEB and +RPM packages are only created when building on a Unix (i.e. Linux or macOS) host. + +The ideal build environment is a Windows 10/Windows Server 2016 host with Docker for +Windows installed. The `package-all.cmd` script will first build and package all Windows +targets, and then launch a docker-based build with the official Microsoft .NET Core 2.1 +SDK image for the remaining targets. The `package.sh` script will only build and package +the Unix targets, the `package.cmd` script only Windows targets. + +The latter two scripts are used with the AppVeyor build as well. + +All build output is placed into `./artifacts/build` + +## Tests + +Running the Unit tests and the Integration tests both require an Azure Relay namespace +to be available for use and configured. Before running any of the test scenarios, the +environment variable `AZBRIDGE_TEST_CXNSTRING` must be set to the Relay namespace +connection string (enclosed in quotes) on the build platform. + +An [Azure Resource Manager template](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-deploy-cli) +to deploy a namespace with the definitions required for testing resides in +`./src/tools/azure/test-resource-template.json`. The template expects the name of a new namespace +and a region location as inputs. + +Once the template has been deployed using either Powershell or the Azure CLI, you can find +the "sendListenConnectionString" value (starts with "Endpoint...") in the returned output. +Copy and save that value for use in the `AZBRIDGE_TEST_CXNSTRING` environment variable. + +The Unit tests can be run from the command line with `dotnet test` with an .NET Core build. + +For integration testing that installs and executes the emitted packages, run `verify-build.cmd`/`verify-build.sh`. Expect for Windows, the integration tests depend on a +local Docker installation: The script cleans any existing images, builds CentOS, Debian, Fedora, and Ubuntu images with the newly built binaries, and then executes a series of tests on each image. + +## Contributions + +We're gladly accepting contributions. Please review the [contribution rules](CONTRIBUTING.md). diff --git a/after.Microsoft.Azure.Relay.Bridge.sln.targets b/after.Microsoft.Azure.Relay.Bridge.sln.targets index cf28d82..0c0fbc6 100644 --- a/after.Microsoft.Azure.Relay.Bridge.sln.targets +++ b/after.Microsoft.Azure.Relay.Bridge.sln.targets @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/build.cmd b/build.cmd index d52d5c7..07cc86a 100644 --- a/build.cmd +++ b/build.cmd @@ -1,2 +1,2 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/build/dependencies.props b/build/dependencies.props index e88743e..f026cce 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,43 +1,42 @@ - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - 0.1.39 - 0.1.39 - 0.1.39 - 0.1.39 - 0.1.39 - 3.11.1 - 2.1.1 - 1.1.28 - 2.0.22 - 2.0.0 - 2.1.0 - 2.1.0 - 15.8.0 - 2.0.3 - 4.5.0-rtm-26502-02 - 4.3.0 - 4.8.0 - 4.3.1 - 4.3.0 - 4.3.0 - 4.3.0 - 4.5.0 - 4.3.3 - 4.3.0 - 5.0.1 - 2.1.1 - 2.1.1 - 2.4.0 - 2.3.1 - 2.4.0 - 2.4.0 - 11.0.2 - 2.0.0-preview1-20180523 - 2.2.5 - 1.1.0 - - - + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + 0.1.39 + 0.1.39 + 0.1.39 + 0.1.39 + 0.1.39 + 3.11.1 + 2.1.1 + 1.1.28 + 2.0.22 + 2.0.0 + 2.1.0 + 15.8.0 + 2.0.3 + 4.5.0-rtm-26502-02 + 4.3.0 + 4.8.0 + 4.3.1 + 4.3.0 + 4.3.0 + 4.3.0 + 4.5.0 + 4.3.3 + 4.3.0 + 5.0.1 + 2.1.1 + 2.1.1 + 2.4.0 + 2.3.1 + 2.4.0 + 2.4.0 + 11.0.2 + 2.0.0-preview1-20180523 + 2.2.5 + 1.1.0 + + + diff --git a/build/repo.props b/build/repo.props index ab1a2d4..11adb09 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,18 +1,16 @@ - - - - false - net462; - netcoreapp2.1 - $(WindowsFrameworks)$(CoreFrameworks) - win7-x64;win7-x86;win10-x64;win10-x86; - osx-x64;debian.8-x64;ubuntu.16.10-x64;ubuntu.16.04-x64;opensuse-x64;ol-x64;rhel-x64;fedora-x64;centos-x64 - $(WindowsRuntimeIdentifiers)$(UnixRuntimeIdentifiers) - - - - - - - - + + + + false + net462; + netcoreapp3.0 + $(WindowsFrameworks)$(CoreFrameworks) + win7-x64;win7-x86;win10-x64;win10-x86; + osx-x64;debian.8-x64;ubuntu.16.10-x64;ubuntu.16.04-x64;opensuse-x64;ol-x64;rhel-x64;fedora-x64;centos-x64 + $(WindowsRuntimeIdentifiers)$(UnixRuntimeIdentifiers) + + + + + + diff --git a/build/sources.props b/build/sources.props index d8fcf21..1c12e19 100644 --- a/build/sources.props +++ b/build/sources.props @@ -1,7 +1,7 @@ - - - - - $(DotNetRestoreSources) - - + + + + + $(DotNetRestoreSources) + + diff --git a/package-all.cmd b/package-all.cmd index 4fe7978..e7e149f 100644 --- a/package-all.cmd +++ b/package-all.cmd @@ -1,26 +1,26 @@ -@echo off -SET _DOCKER_BUILD="true" -docker -v > NUL -if not errorlevel 0 ( - echo Linux RPM and DEB packaging requires a docker install - SET _DOCKER_BUILD="false" -) -echo *** Sanity check Windows -dotnet restore -dotnet test %* -if not errorlevel 0 exit /b 1 -echo *** Building and packaging Windows Targets - -if %_DOCKER_BUILD% == "true" ( - echo *** Windows only - msbuild /t:clean,restore,package /p:WindowsOnly=true;Configuration=Release %* -) else ( - echo *** All platforms - msbuild /t:clean,restore,package /p:WindowsOnly=false;Configuration=Release %* -) - -if not errorlevel 0 exit /b 1 -if %_DOCKER_BUILD% == "true" ( - echo *** Building and packaging Unix/Linux Targets - docker run --rm -v %cd%:/build microsoft/dotnet:2.1-sdk /build/package.sh /p:TargetFramework=netcoreapp2.1 %* +@echo off +SET _DOCKER_BUILD="true" +docker -v > NUL +if not errorlevel 0 ( + echo Linux RPM and DEB packaging requires a docker install + SET _DOCKER_BUILD="false" +) +echo *** Sanity check Windows +dotnet restore +dotnet test %* +if not errorlevel 0 exit /b 1 +echo *** Building and packaging Windows Targets + +if %_DOCKER_BUILD% == "true" ( + echo *** Windows only + msbuild /t:clean,restore,package /p:WindowsOnly=true;Configuration=Release %* +) else ( + echo *** All platforms + msbuild /t:clean,restore,package /p:WindowsOnly=false;Configuration=Release %* +) + +if not errorlevel 0 exit /b 1 +if %_DOCKER_BUILD% == "true" ( + echo *** Building and packaging Unix/Linux Targets + docker run --rm -v %cd%:/build microsoft/dotnet:2.1-sdk /build/package.sh /p:TargetFramework=netcoreapp3.0 %* ) \ No newline at end of file diff --git a/package.cmd b/package.cmd index be9c1b4..9613e02 100644 --- a/package.cmd +++ b/package.cmd @@ -1,4 +1,4 @@ -if not "%APPVEYOR_BUILD_NUMBER%"=="" set _BuildProp="/p:BuildNumber=%APPVEYOR_BUILD_NUMBER%" -if not "%APPVEYOR_BUILD_VERSION%"=="" set _VersionProp="/p:VersionPrefix=%APPVEYOR_BUILD_VERSION%" -msbuild /t:clean,restore,build /p:WindowsOnly=true /p:Configuration=Debug %_BuildProp% %_VersionProp% %* +if not "%APPVEYOR_BUILD_NUMBER%"=="" set _BuildProp="/p:BuildNumber=%APPVEYOR_BUILD_NUMBER%" +if not "%APPVEYOR_BUILD_VERSION%"=="" set _VersionProp="/p:VersionPrefix=%APPVEYOR_BUILD_VERSION%" +msbuild /t:clean,restore,build /p:WindowsOnly=true /p:Configuration=Debug %_BuildProp% %_VersionProp% %* msbuild /t:clean,restore,build,package /p:WindowsOnly=true /p:Configuration=Release %_BuildProp% %_VersionProp% %* \ No newline at end of file diff --git a/package.sh b/package.sh index 94f290e..4511eb1 100755 --- a/package.sh +++ b/package.sh @@ -3,6 +3,6 @@ pushd "${0%/*}" > /dev/null if [ ! -z $APPVEYOR_BUILD_NUMBER ]; then _BuildProp="/p:BuildNumber=$APPVEYOR_BUILD_NUMBER"; fi if [ ! -z $APPVEYOR_BUILD_VERSION ]; then _VersionProp="/p:VersionPrefix=$APPVEYOR_BUILD_VERSION"; fi dotnet restore -dotnet msbuild /t:clean,restore,build /p:Configuration=Debug /p:TargetFramework=netcoreapp2.1 $_BuildProp $_VersionProp $@ -dotnet msbuild /t:clean,restore,build,package /p:Configuration=Release /p:TargetFramework=netcoreapp2.1 $_BuildProp $_VersionProp $@ +dotnet msbuild /t:clean,restore,build /p:Configuration=Debug /p:TargetFramework=netcoreapp3.0 $_BuildProp $_VersionProp $@ +dotnet msbuild /t:clean,restore,build,package /p:Configuration=Release /p:TargetFramework=netcoreapp3.0 $_BuildProp $_VersionProp $@ popd diff --git a/packages-microsoft-prod.deb b/packages-microsoft-prod.deb index 4f7f63d..97fffd3 100644 Binary files a/packages-microsoft-prod.deb and b/packages-microsoft-prod.deb differ diff --git a/run.cmd b/run.cmd index d52d5c7..07cc86a 100644 --- a/run.cmd +++ b/run.cmd @@ -1,2 +1,2 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 05002e1..75d4443 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,3 +1,3 @@ - - - + + + diff --git a/src/Microsoft.Azure.Relay.Bridge/.vs/config/applicationhost.config b/src/Microsoft.Azure.Relay.Bridge/.vs/config/applicationhost.config index 5441f24..f7669cc 100644 --- a/src/Microsoft.Azure.Relay.Bridge/.vs/config/applicationhost.config +++ b/src/Microsoft.Azure.Relay.Bridge/.vs/config/applicationhost.config @@ -1,1022 +1,1022 @@ - - - - - - - -
-
-
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
- -
-
- -
-
-
- - -
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.Azure.Relay.Bridge/Directory.Build.props b/src/Microsoft.Azure.Relay.Bridge/Directory.Build.props index 05002e1..75d4443 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Directory.Build.props +++ b/src/Microsoft.Azure.Relay.Bridge/Directory.Build.props @@ -1,3 +1,3 @@ - - - + + + diff --git a/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj b/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj index 03af932..eac90f1 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj +++ b/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.csproj @@ -3,7 +3,7 @@ false net462; - netcoreapp2.1 + netcoreapp3.0 $(WindowsFrameworks)$(CoreFrameworks) win7-x64;win7-x86;win10-x64;win10-x86; osx-x64;debian.8-x64;ubuntu.16.10-x64;ubuntu.16.04-x64;opensuse-x64;ol-x64;rhel-x64;fedora-x64;centos-x64 diff --git a/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.xml b/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.xml index ae5e9e5..eb1dc0b 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.xml +++ b/src/Microsoft.Azure.Relay.Bridge/Microsoft.Azure.Relay.Bridge.xml @@ -1,562 +1,562 @@ - - - - Microsoft.Azure.Relay.Bridge - - - - - - - - - - Specifies which address family to use when connecting.Valid - arguments are Unspecified ("any"), InterNetwork ("inet", IPv4 only), - or InterNetworkV6 ("inet6", IPv6 only). The default is Unspecified. - - - - - Azure Relay connection string for a Relay namespace. - - - - - Azure Relay endpoint URI for a Relay namespace. - - - - - Azure Relay shared access policy name. - - - - - Azure Relay shared access policy key. - - - - - Azure Relay shared access policy signature - - - - - Use the specified address on the local machine as the source - address of the connection. Only useful on systems with more than - one address. - - - - - Specifies that all local, and remote port forwardings - specified in the configuration files or on the command line be - cleared.This option is primarily useful when used from the - command line to clear port forwardings set in configura- - tion files. The default is false. - - - true to clear all forwardings; otherwise, false. - - - - - Gets or sets the connection attempts. - - - The connection attempts. - - - - - Specifies the timeout (in seconds) used when connecting to the - Relay server, instead of using the default system TCP timeout. - This value is used only when the target is down or really - unreachable, not when it refuses the connection. - - - - - Specifies whether the client should terminate the - connection if it cannot set up all requested local, and remote port forwardings, - (e.g. if either end is unable to bind and listen on a specified port). - The default is false. - - - - - Specifies whether remote hosts are allowed to connect to local - forwarded ports. By default, azbridge(1) binds local port - forwardings to the loopback address.This prevents other remote hosts - from connecting to forwarded ports.GatewayPorts can be used to - specify that azbridge should bind local port forwardings to the - wildcard address, thus allowing remote hosts to connect to forwarded - ports. The default is false. - - - - - Specifies that a (set of) TCP ports on the local machine - shall be forwarded via the Azure Relay. - - - - - Gives the verbosity level that is used when logging messages - from azbridge(1). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, - DEBUG, DEBUG1, DEBUG2, and DEBUG3.The default is INFO. - DEBUG and DEBUG1 are equivalent.DEBUG2 and DEBUG3 each specify - higher levels of verbose output. - - - - - Specifies that a TCP port on the remote machine be bound to - a name on the Azure Relay. - - - - - EventSource for the new Dynamic EventSource type of Microsoft-HybridConnectionManager traces. - - The default Level is Informational - - When defining Start/Stop tasks, the StopEvent.Id must be exactly StartEvent.Id + 1. - - Do not explicity include the Guid here, since EventSource has a mechanism to automatically - map to an EventSource Guid based on the Name (Microsoft-Azure-Relay). The Guid will - be consistent as long as the name stays Microsoft-Azure-Relay - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to The Listener's custom AcceptHandler threw an exception. See Listener logs for details. TrackingId: {0}.. - - - - - Looks up a localized string similar to Ensure either all or none of the following arguments are defined: '{0}'.. - - - - - Looks up a localized string similar to The argument is out of range. It should be between {0} and {1}.. - - - - - Looks up a localized string similar to The argument '{0}' cannot exceed {1} characters.. - - - - - Looks up a localized string similar to Buffer allocation failed. - - - - - Looks up a localized string similar to '{0}' contained character '{1}' which is not allowed because it is reserved in the Uri scheme.. - - - - - Looks up a localized string similar to Existing configuration {0} found.. - - - - - Looks up a localized string similar to {0} name should be specified as EntityPath in connectionString.. - - - - - Looks up a localized string similar to The connectionString must include either SharedAccessSignature or both SharedAccessKeyName and SharedAccessKey.. - - - - - Looks up a localized string similar to {0} name should not be specified as EntityPath in the connectionString while using this overload. Instead, use the 'path' parameter.. - - - - - Looks up a localized string similar to The value for the connection string parameter '{0}' is empty or missing.. - - - - - Looks up a localized string similar to The connection string contains unknown parameter '{0}'.. - - - - - Looks up a localized string similar to Duplicate connection ID.. - - - - - Looks up a localized string similar to The operation cannot be performed because the entity has been closed or aborted.. - - - - - Looks up a localized string similar to The entity path/name '{0}' exceeds the {1} character limit.. - - - - - Looks up a localized string similar to This '{0}' instance has already been started once. To start another instance, please create a new '{0}' object and start that.. - - - - - Looks up a localized string similar to The Uri address given contains a path which is not allowed. Remove the path from the supplied Uri '{0}'.. - - - - - Looks up a localized string similar to The specified Async result object is null or invalid.. - - - - - Looks up a localized string similar to Connection String is invalid {0}.. - - - - - Looks up a localized string similar to The string has an invalid encoding format.. - - - - - Looks up a localized string similar to The entity name or path cannot contain '/' as prefix or suffix. The supplied value is '{0}'.. - - - - - Looks up a localized string similar to The provided URI scheme '{0}' is invalid; expected '{1}'.. - - - - - Looks up a localized string similar to Management port matches the current one.. - - - - - Looks up a localized string similar to Management server is not running.. - - - - - Looks up a localized string similar to The status code must be between 100 and 999 inclusive.. - - - - - Looks up a localized string similar to Exception in {0}::{1} - {2}.. - - - - - Looks up a localized string similar to The requested security protocol is not supported.. - - - - - Looks up a localized string similar to This operation is not supported for a relative URI.. - - - - - Looks up a localized string similar to Specified value has invalid Control characters.. - - - - - Looks up a localized string similar to The WebSocket request or response operation was called with unsupported protocol(s).. - - - - - Looks up a localized string similar to There is already one outstanding '{0}' call for this WebSocket instance. ReceiveAsync and SendAsync can be called simultaneously, but at most one outstanding operation for each of them is allowed at the same time.. - - - - - Looks up a localized string similar to The WebSocket has already been started.. - - - - - Looks up a localized string similar to The message type '{0}' is not allowed for the '{1}' operation. Valid message types are: '{2}, {3}'. To close the WebSocket, use the '{4}' operation instead.. - - - - - Looks up a localized string similar to The byte array must have a length of at least '{0}' bytes.. - - - - - Looks up a localized string similar to The value of the '{0}' parameter ({1}) must be less than or equal to {2}.. - - - - - Looks up a localized string similar to The argument must be a value greater than {0}.. - - - - - Looks up a localized string similar to The server returned status code '{0}' when status code '101' was expected.. - - - - - Looks up a localized string similar to An internal WebSocket error occurred. Please see the innerException, if present, for more details.. - - - - - Looks up a localized string similar to The WebSocket protocol '{0}' is invalid because it contains the invalid character '{1}'.. - - - - - Looks up a localized string similar to The close status code '{0}' is reserved for system use only and cannot be specified when calling this method.. - - - - - Looks up a localized string similar to The close status description '{0}' is too long. The UTF8-representation of the status description must not be longer than {1} bytes.. - - - - - Looks up a localized string similar to Empty string is not a valid subprotocol value. Please use \"null\" to specify no value.. - - - - - Looks up a localized string similar to The WebSocket schemes must be registered with the HttpWebRequest class.. - - - - - Looks up a localized string similar to The '{0}' header value '{1}' is invalid.. - - - - - Looks up a localized string similar to The WebSocket is in an invalid state ('{0}') for this operation. Valid states are: '{1}'. - - - - - Looks up a localized string similar to The '{0}' instance cannot be used for communication because it has been transitioned into the '{1}' state.. - - - - - Looks up a localized string similar to Duplicate protocols are not allowed: '{0}'.. - - - - - Looks up a localized string similar to The WebSocket is not connected.. - - - - - Looks up a localized string similar to The close status description '{0}' is invalid. When using close status code '{1}' the description must be null.. - - - - - Looks up a localized string similar to Only Uris starting with 'ws://' or 'wss://' are supported.. - - - - - Looks up a localized string similar to The WebSocket protocol is not supported on this platform.. - - - - - Looks up a localized string similar to Unable to connect to the remote server. - - - - - Looks up a localized string similar to '{0}' is not a valid Absolute Uri.. - - - - - Looks up a localized string similar to '{0}' is not a valid TimeSpan.. - - - - - Looks up a localized string similar to The operation cannot be performed because the object has been closed or aborted.. - - - - - Looks up a localized string similar to This object is read-only and cannot be modified.. - - - - - Looks up a localized string similar to This object is not in an open state.. - - - - - Looks up a localized string similar to The request has timed out after {0} milliseconds. The successful completion of the request cannot be determined. Additional queries should be made to determine whether or not the operation has succeeded. For more information on exception types and proper exception handling, please refer to http://go.microsoft.com/fwlink/?LinkId=761101. - - - - - Looks up a localized string similar to {0} cannot be specified along with {1}. {0} alone should be sufficient to Authenticate the request.. - - - - - Looks up a localized string similar to Argument {0} must be a non-negative timeout value. The provided value was {1}.. - - - - - Looks up a localized string similar to Argument {0} must be a positive timeout value. The provided value was {1}.. - - - - - Looks up a localized string similar to The provided token does not specify the 'Audience' value.. - - - - - Looks up a localized string similar to The provided token does not specify the 'ExpiresOn' value.. - - - - - Looks up a localized string similar to A TokenProvider is required to perform management operations. If a connection string was provided it must include either SharedAccessSignature or both SharedAccessKeyName and SharedAccessKey.. - - - - - Looks up a localized string similar to Could not find configuration {0}.. - - - - - Looks up a localized string similar to Could not find Registry key {0}.. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - This parameter helps reduce allocations by passing state to the Funcs. e.g.: - await TaskEx.FromAsync( - (c, s) => ((Transaction)s).BeginCommit(c, s), - (a) => ((Transaction)a.AsyncState).EndCommit(a), - transaction); - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Create a Task based on Begin/End IAsyncResult pattern. - This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate - throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. - - - - - Creates a Task that has completed with a specified exception. - Once the code has moved to .NET 4.6 just use Task.FromException; - - - - - Creates a Task<TResult> that's completed with a specified exception. - Once the code has moved to .NET 4.6 just use Task.FromException<TResult> - - - - - Opens this PortBridgeServerProxy instance and listens for new connections coming through Service Bus. - - Throws a SecurityException if Group Policy prohibits Resource Publishing. - - - + + + + Microsoft.Azure.Relay.Bridge + + + + + + + + + + Specifies which address family to use when connecting.Valid + arguments are Unspecified ("any"), InterNetwork ("inet", IPv4 only), + or InterNetworkV6 ("inet6", IPv6 only). The default is Unspecified. + + + + + Azure Relay connection string for a Relay namespace. + + + + + Azure Relay endpoint URI for a Relay namespace. + + + + + Azure Relay shared access policy name. + + + + + Azure Relay shared access policy key. + + + + + Azure Relay shared access policy signature + + + + + Use the specified address on the local machine as the source + address of the connection. Only useful on systems with more than + one address. + + + + + Specifies that all local, and remote port forwardings + specified in the configuration files or on the command line be + cleared.This option is primarily useful when used from the + command line to clear port forwardings set in configura- + tion files. The default is false. + + + true to clear all forwardings; otherwise, false. + + + + + Gets or sets the connection attempts. + + + The connection attempts. + + + + + Specifies the timeout (in seconds) used when connecting to the + Relay server, instead of using the default system TCP timeout. + This value is used only when the target is down or really + unreachable, not when it refuses the connection. + + + + + Specifies whether the client should terminate the + connection if it cannot set up all requested local, and remote port forwardings, + (e.g. if either end is unable to bind and listen on a specified port). + The default is false. + + + + + Specifies whether remote hosts are allowed to connect to local + forwarded ports. By default, azbridge(1) binds local port + forwardings to the loopback address.This prevents other remote hosts + from connecting to forwarded ports.GatewayPorts can be used to + specify that azbridge should bind local port forwardings to the + wildcard address, thus allowing remote hosts to connect to forwarded + ports. The default is false. + + + + + Specifies that a (set of) TCP ports on the local machine + shall be forwarded via the Azure Relay. + + + + + Gives the verbosity level that is used when logging messages + from azbridge(1). The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, + DEBUG, DEBUG1, DEBUG2, and DEBUG3.The default is INFO. + DEBUG and DEBUG1 are equivalent.DEBUG2 and DEBUG3 each specify + higher levels of verbose output. + + + + + Specifies that a TCP port on the remote machine be bound to + a name on the Azure Relay. + + + + + EventSource for the new Dynamic EventSource type of Microsoft-HybridConnectionManager traces. + + The default Level is Informational + + When defining Start/Stop tasks, the StopEvent.Id must be exactly StartEvent.Id + 1. + + Do not explicity include the Guid here, since EventSource has a mechanism to automatically + map to an EventSource Guid based on the Name (Microsoft-Azure-Relay). The Guid will + be consistent as long as the name stays Microsoft-Azure-Relay + + + + + A strongly-typed resource class, for looking up localized strings, etc. + + + + + Returns the cached ResourceManager instance used by this class. + + + + + Overrides the current thread's CurrentUICulture property for all + resource lookups using this strongly typed resource class. + + + + + Looks up a localized string similar to The Listener's custom AcceptHandler threw an exception. See Listener logs for details. TrackingId: {0}.. + + + + + Looks up a localized string similar to Ensure either all or none of the following arguments are defined: '{0}'.. + + + + + Looks up a localized string similar to The argument is out of range. It should be between {0} and {1}.. + + + + + Looks up a localized string similar to The argument '{0}' cannot exceed {1} characters.. + + + + + Looks up a localized string similar to Buffer allocation failed. + + + + + Looks up a localized string similar to '{0}' contained character '{1}' which is not allowed because it is reserved in the Uri scheme.. + + + + + Looks up a localized string similar to Existing configuration {0} found.. + + + + + Looks up a localized string similar to {0} name should be specified as EntityPath in connectionString.. + + + + + Looks up a localized string similar to The connectionString must include either SharedAccessSignature or both SharedAccessKeyName and SharedAccessKey.. + + + + + Looks up a localized string similar to {0} name should not be specified as EntityPath in the connectionString while using this overload. Instead, use the 'path' parameter.. + + + + + Looks up a localized string similar to The value for the connection string parameter '{0}' is empty or missing.. + + + + + Looks up a localized string similar to The connection string contains unknown parameter '{0}'.. + + + + + Looks up a localized string similar to Duplicate connection ID.. + + + + + Looks up a localized string similar to The operation cannot be performed because the entity has been closed or aborted.. + + + + + Looks up a localized string similar to The entity path/name '{0}' exceeds the {1} character limit.. + + + + + Looks up a localized string similar to This '{0}' instance has already been started once. To start another instance, please create a new '{0}' object and start that.. + + + + + Looks up a localized string similar to The Uri address given contains a path which is not allowed. Remove the path from the supplied Uri '{0}'.. + + + + + Looks up a localized string similar to The specified Async result object is null or invalid.. + + + + + Looks up a localized string similar to Connection String is invalid {0}.. + + + + + Looks up a localized string similar to The string has an invalid encoding format.. + + + + + Looks up a localized string similar to The entity name or path cannot contain '/' as prefix or suffix. The supplied value is '{0}'.. + + + + + Looks up a localized string similar to The provided URI scheme '{0}' is invalid; expected '{1}'.. + + + + + Looks up a localized string similar to Management port matches the current one.. + + + + + Looks up a localized string similar to Management server is not running.. + + + + + Looks up a localized string similar to The status code must be between 100 and 999 inclusive.. + + + + + Looks up a localized string similar to Exception in {0}::{1} - {2}.. + + + + + Looks up a localized string similar to The requested security protocol is not supported.. + + + + + Looks up a localized string similar to This operation is not supported for a relative URI.. + + + + + Looks up a localized string similar to Specified value has invalid Control characters.. + + + + + Looks up a localized string similar to The WebSocket request or response operation was called with unsupported protocol(s).. + + + + + Looks up a localized string similar to There is already one outstanding '{0}' call for this WebSocket instance. ReceiveAsync and SendAsync can be called simultaneously, but at most one outstanding operation for each of them is allowed at the same time.. + + + + + Looks up a localized string similar to The WebSocket has already been started.. + + + + + Looks up a localized string similar to The message type '{0}' is not allowed for the '{1}' operation. Valid message types are: '{2}, {3}'. To close the WebSocket, use the '{4}' operation instead.. + + + + + Looks up a localized string similar to The byte array must have a length of at least '{0}' bytes.. + + + + + Looks up a localized string similar to The value of the '{0}' parameter ({1}) must be less than or equal to {2}.. + + + + + Looks up a localized string similar to The argument must be a value greater than {0}.. + + + + + Looks up a localized string similar to The server returned status code '{0}' when status code '101' was expected.. + + + + + Looks up a localized string similar to An internal WebSocket error occurred. Please see the innerException, if present, for more details.. + + + + + Looks up a localized string similar to The WebSocket protocol '{0}' is invalid because it contains the invalid character '{1}'.. + + + + + Looks up a localized string similar to The close status code '{0}' is reserved for system use only and cannot be specified when calling this method.. + + + + + Looks up a localized string similar to The close status description '{0}' is too long. The UTF8-representation of the status description must not be longer than {1} bytes.. + + + + + Looks up a localized string similar to Empty string is not a valid subprotocol value. Please use \"null\" to specify no value.. + + + + + Looks up a localized string similar to The WebSocket schemes must be registered with the HttpWebRequest class.. + + + + + Looks up a localized string similar to The '{0}' header value '{1}' is invalid.. + + + + + Looks up a localized string similar to The WebSocket is in an invalid state ('{0}') for this operation. Valid states are: '{1}'. + + + + + Looks up a localized string similar to The '{0}' instance cannot be used for communication because it has been transitioned into the '{1}' state.. + + + + + Looks up a localized string similar to Duplicate protocols are not allowed: '{0}'.. + + + + + Looks up a localized string similar to The WebSocket is not connected.. + + + + + Looks up a localized string similar to The close status description '{0}' is invalid. When using close status code '{1}' the description must be null.. + + + + + Looks up a localized string similar to Only Uris starting with 'ws://' or 'wss://' are supported.. + + + + + Looks up a localized string similar to The WebSocket protocol is not supported on this platform.. + + + + + Looks up a localized string similar to Unable to connect to the remote server. + + + + + Looks up a localized string similar to '{0}' is not a valid Absolute Uri.. + + + + + Looks up a localized string similar to '{0}' is not a valid TimeSpan.. + + + + + Looks up a localized string similar to The operation cannot be performed because the object has been closed or aborted.. + + + + + Looks up a localized string similar to This object is read-only and cannot be modified.. + + + + + Looks up a localized string similar to This object is not in an open state.. + + + + + Looks up a localized string similar to The request has timed out after {0} milliseconds. The successful completion of the request cannot be determined. Additional queries should be made to determine whether or not the operation has succeeded. For more information on exception types and proper exception handling, please refer to http://go.microsoft.com/fwlink/?LinkId=761101. + + + + + Looks up a localized string similar to {0} cannot be specified along with {1}. {0} alone should be sufficient to Authenticate the request.. + + + + + Looks up a localized string similar to Argument {0} must be a non-negative timeout value. The provided value was {1}.. + + + + + Looks up a localized string similar to Argument {0} must be a positive timeout value. The provided value was {1}.. + + + + + Looks up a localized string similar to The provided token does not specify the 'Audience' value.. + + + + + Looks up a localized string similar to The provided token does not specify the 'ExpiresOn' value.. + + + + + Looks up a localized string similar to A TokenProvider is required to perform management operations. If a connection string was provided it must include either SharedAccessSignature or both SharedAccessKeyName and SharedAccessKey.. + + + + + Looks up a localized string similar to Could not find configuration {0}.. + + + + + Looks up a localized string similar to Could not find Registry key {0}.. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + This parameter helps reduce allocations by passing state to the Funcs. e.g.: + await TaskEx.FromAsync( + (c, s) => ((Transaction)s).BeginCommit(c, s), + (a) => ((Transaction)a.AsyncState).EndCommit(a), + transaction); + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Create a Task based on Begin/End IAsyncResult pattern. + This is a wrapper around Task.Factory.FromAsync with the additional guarantee that if the begin delegate + throws an Exception it will result in a Task with that exception instead of the exception being thrown from this method. + + + + + Creates a Task that has completed with a specified exception. + Once the code has moved to .NET 4.6 just use Task.FromException; + + + + + Creates a Task<TResult> that's completed with a specified exception. + Once the code has moved to .NET 4.6 just use Task.FromException<TResult> + + + + + Opens this PortBridgeServerProxy instance and listens for new connections coming through Service Bus. + + Throws a SecurityException if Group Policy prohibits Resource Publishing. + + + diff --git a/src/Microsoft.Azure.Relay.Bridge/Settings.StyleCop b/src/Microsoft.Azure.Relay.Bridge/Settings.StyleCop index eba5966..d60e3bc 100644 --- a/src/Microsoft.Azure.Relay.Bridge/Settings.StyleCop +++ b/src/Microsoft.Azure.Relay.Bridge/Settings.StyleCop @@ -1,68 +1,68 @@ - - - - - - False - - - - - True - %REPOROOT%\src\Legacy.StyleCop - Linked - - - - - - - False - - - Action.lex.cs - Action.y.cs - EventSource.cs - Filter.lex.cs - Filter.y.cs - - - - - - - - - - - False - - - - - - - BasicHttpRelayMessageSecurity.cs - BrokeredMessage.cs - ByteArrayComparer.cs - ConfigurationHelpers.cs - DuplexMessageCorrelator.cs - EventData.cs - EventProvider.cs - IRelayedConnectionConnectionControl.cs - MessageCollection.cs - MessageSecurityOverRelayHttp.cs - MruCache.cs - RelayedHttpUtility.cs - SendAvailabilityMessagePump.cs - ServiceBusClientWebSocket.cs - ServiceBusInputChannel.cs - ServiceBusInputSessionChannelListener.cs - ServiceBusUriHelper.cs - SocketConnectionPoolSettingsElement.cs - TransportChannelFactory.cs - TransportChannelListener.cs - UriPrefixTable.cs - WSHttpRelayBindingBase.cs - + + + + + + False + + + + + True + %REPOROOT%\src\Legacy.StyleCop + Linked + + + + + + + False + + + Action.lex.cs + Action.y.cs + EventSource.cs + Filter.lex.cs + Filter.y.cs + + + + + + + + + + + False + + + + + + + BasicHttpRelayMessageSecurity.cs + BrokeredMessage.cs + ByteArrayComparer.cs + ConfigurationHelpers.cs + DuplexMessageCorrelator.cs + EventData.cs + EventProvider.cs + IRelayedConnectionConnectionControl.cs + MessageCollection.cs + MessageSecurityOverRelayHttp.cs + MruCache.cs + RelayedHttpUtility.cs + SendAvailabilityMessagePump.cs + ServiceBusClientWebSocket.cs + ServiceBusInputChannel.cs + ServiceBusInputSessionChannelListener.cs + ServiceBusUriHelper.cs + SocketConnectionPoolSettingsElement.cs + TransportChannelFactory.cs + TransportChannelListener.cs + UriPrefixTable.cs + WSHttpRelayBindingBase.cs + \ No newline at end of file diff --git a/src/azbridge-installer/Directory.Build.props b/src/azbridge-installer/Directory.Build.props index 05002e1..75d4443 100644 --- a/src/azbridge-installer/Directory.Build.props +++ b/src/azbridge-installer/Directory.Build.props @@ -1,3 +1,3 @@ - - - + + + diff --git a/src/azbridge-installer/Product.wxs b/src/azbridge-installer/Product.wxs index 8682d20..8207ea7 100644 --- a/src/azbridge-installer/Product.wxs +++ b/src/azbridge-installer/Product.wxs @@ -1,69 +1,69 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/azbridge-installer/azbridge-installer.wixproj b/src/azbridge-installer/azbridge-installer.wixproj index aa0b980..0f0582b 100644 --- a/src/azbridge-installer/azbridge-installer.wixproj +++ b/src/azbridge-installer/azbridge-installer.wixproj @@ -1,105 +1,105 @@ - - - - - Debug - 3.10 - {5496840b-ef30-44be-a316-0b69790ea9a3} - 2.0 - azbridge_installer - Package - false - false - false - ..\azbridge\bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish - ..\azbridge\azbridge.csproj - x64 - x86 - - - - - - obj\$(Configuration)\$(Platform)\ - Debug;ProcessorArchitecture=x86 - - - - obj\$(Configuration)\$(Platform)\ - ProcessorArchitecture=x86 - - - - obj\$(Configuration)\$(Platform)\ - Debug;ProcessorArchitecture=x64 - - - - obj\$(Configuration)\$(Platform)\ - ProcessorArchitecture=x64 - - - - - - - - WixUtilExtension - - - WixUIExtension - - - WixNetFxExtension - - - - - azbridge - {ac769774-b065-41e8-b0ab-d15ed6b8d6a8} - True - - - Binaries;Content;Satellites - INSTALLFOLDER - - - Microsoft.Azure.Relay.Bridge - {864ae8d8-f770-499b-a9e2-46e07c8fd3d2} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - - - - - - - - - - - - - - - $(BridgePublishPath) - BasePath=$(BridgePublishPath) - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - + + + + + Debug + 3.10 + {5496840b-ef30-44be-a316-0b69790ea9a3} + 2.0 + azbridge_installer + Package + false + false + false + ..\azbridge\bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish + ..\azbridge\azbridge.csproj + x64 + x86 + + + + + + obj\$(Configuration)\$(Platform)\ + Debug;ProcessorArchitecture=x86 + + + + obj\$(Configuration)\$(Platform)\ + ProcessorArchitecture=x86 + + + + obj\$(Configuration)\$(Platform)\ + Debug;ProcessorArchitecture=x64 + + + + obj\$(Configuration)\$(Platform)\ + ProcessorArchitecture=x64 + + + + + + + + WixUtilExtension + + + WixUIExtension + + + WixNetFxExtension + + + + + azbridge + {ac769774-b065-41e8-b0ab-d15ed6b8d6a8} + True + + + Binaries;Content;Satellites + INSTALLFOLDER + + + Microsoft.Azure.Relay.Bridge + {864ae8d8-f770-499b-a9e2-46e07c8fd3d2} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + + + + + + + + + + + + + + + $(BridgePublishPath) + BasePath=$(BridgePublishPath) + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + \ No newline at end of file diff --git a/src/azbridge-installer/installTransforms.xslt b/src/azbridge-installer/installTransforms.xslt index a114c6b..7a691df 100644 --- a/src/azbridge-installer/installTransforms.xslt +++ b/src/azbridge-installer/installTransforms.xslt @@ -1,80 +1,80 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/azbridge-installer/packages.config b/src/azbridge-installer/packages.config index 6425674..0cafd56 100644 --- a/src/azbridge-installer/packages.config +++ b/src/azbridge-installer/packages.config @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/src/azbridge-installer/restore.cmd b/src/azbridge-installer/restore.cmd index 44b5347..6a4e495 100644 --- a/src/azbridge-installer/restore.cmd +++ b/src/azbridge-installer/restore.cmd @@ -1,20 +1,20 @@ -REM -REM The WIX project MUST be built using the NETFX project format and -REM using the 32-bit runtime and we can't use the project-embedded -REM format. Therefore we do a nuget package restore -REM here. This is called from the build process in the package step. -REM - -@echo off -pushd "%~dp0" -if not exist ".\.nuget" mkdir ".\.nuget" -if not exist ".\.nuget\nuget.exe" powershell -Command "Invoke-WebRequest https://www.nuget.org/nuget.exe -OutFile .\.nuget\nuget.exe" -if not exist ".\.nuget\nuget.config" ( - echo ^ > .\.nuget\nuget.config - echo ^^ >> .\.nuget\nuget.config - echo ^ >> .\.nuget\nuget.config - echo ^^ >> .\.nuget\nuget.config -) - -".nuget\NuGet.exe" restore packages.config -PackagesDirectory packages -ConfigFile .nuget\nuget.config -Verbosity detailed +REM +REM The WIX project MUST be built using the NETFX project format and +REM using the 32-bit runtime and we can't use the project-embedded +REM format. Therefore we do a nuget package restore +REM here. This is called from the build process in the package step. +REM + +@echo off +pushd "%~dp0" +if not exist ".\.nuget" mkdir ".\.nuget" +if not exist ".\.nuget\nuget.exe" powershell -Command "Invoke-WebRequest https://www.nuget.org/nuget.exe -OutFile .\.nuget\nuget.exe" +if not exist ".\.nuget\nuget.config" ( + echo ^ > .\.nuget\nuget.config + echo ^^ >> .\.nuget\nuget.config + echo ^ >> .\.nuget\nuget.config + echo ^^ >> .\.nuget\nuget.config +) + +".nuget\NuGet.exe" restore packages.config -PackagesDirectory packages -ConfigFile .nuget\nuget.config -Verbosity detailed popd \ No newline at end of file diff --git a/src/azbridge/Directory.Build.props b/src/azbridge/Directory.Build.props index 05002e1..75d4443 100644 --- a/src/azbridge/Directory.Build.props +++ b/src/azbridge/Directory.Build.props @@ -1,3 +1,3 @@ - - - + + + diff --git a/src/azbridge/azbridge.csproj b/src/azbridge/azbridge.csproj index 66aafa9..fd40b70 100644 --- a/src/azbridge/azbridge.csproj +++ b/src/azbridge/azbridge.csproj @@ -3,7 +3,7 @@ false net462; - netcoreapp2.1 + netcoreapp3.0 $(WindowsFrameworks)$(CoreFrameworks) win7-x64;win7-x86;win10-x64;win10-x86; @@ -124,8 +124,6 @@ - - @@ -138,8 +136,6 @@ - - @@ -188,13 +184,13 @@ - + - + - + @@ -208,7 +204,7 @@ - + diff --git a/src/azbridge/azbridge.service b/src/azbridge/azbridge.service index e9dd310..4aaa81a 100644 --- a/src/azbridge/azbridge.service +++ b/src/azbridge/azbridge.service @@ -1,8 +1,8 @@ -[Unit] -Description=Azure Relay Bridge - -[Service] -ExecStart=/usr/shared/azbridge - -[Install] +[Unit] +Description=Azure Relay Bridge + +[Service] +ExecStart=/usr/shared/azbridge + +[Install] WantedBy=multi-user.target \ No newline at end of file diff --git a/src/azbridge/azbridge_config.machine.yml b/src/azbridge/azbridge_config.machine.yml index 66ff3b3..b6bd6ab 100644 --- a/src/azbridge/azbridge_config.machine.yml +++ b/src/azbridge/azbridge_config.machine.yml @@ -1,103 +1,103 @@ -# Azure Relay Bridge Configuration - -# Specifies which address family to use when connecting. Valid -# arguments are "any", "inet" (use IPv4 only), or "inet6" -# (use IPv6 only). The default is "any". - -AddressFamily : - -# Azure Relay connection string for a Relay namespace. Only one -# namespace connection string can be specified per configuration -# file. - -AzureRelayConnectionString : - -# Azure Relay endpoint URI for a Relay namespace. Overrides -# the 'Endpoint' property of the connection string, if present. - -AzureRelayEndpoint : - -# Azure Relay shared access policy name. Overrides the 'SharedAccessKeyName' -# property of the connection string, if present. - -AzureRelaySharedAccessKeyName : - -# Azure Relay shared access policy key. Overrides the 'SharedAccessKey' -# property of the connection string, if present. - -AzureRelaySharedAccessKey : - -# Azure Relay shared access policy signature. Overrides the 'SharedAccessSignature' -# property of the connection string, if present. - -AzureRelaySharedAccessSignature : - -# Use the specified address on the local machine as the source -# address of the connection. Only useful on systems with more than -# one address. - -BindAddress : - -# Specifies that all local, and remote port forwardings -# specified in the configuration files or on the command line be -# cleared. This option is primarily useful when used from the -# command line to clear port forwardings set in configura- -# tion files. The argument must be "true" or "false". The default is "false". - -ClearAllForwardings : - -# Specifies the number of tries (one per second) to make -# before exiting. The argument must be an integer. This may be useful in scripts -# if the connection sometimes fails. The default is 1. - -ConnectionAttempts : - -# Specifies the timeout (in seconds) used when connecting to the -# relay server, instead of using the default system TCP timeout. -# This value is used only when the target is down or really -# unreachable, not when it refuses the connection. - -ConnectTimeout : - -# Specifies whether azbridge(1) should terminate the -# connection if it cannot set up all requested local, and remote port forwardings, -# (e.g. if either end is unable to bind and listen on a specified port). -# The argument must be "true" or "false". The default is "false". - -ExitOnForwardFailure : - -# Specifies whether remote hosts are allowed to connect to local -# forwarded ports. By default, azbridge(1) binds local port forwardings -# to the loopback address. This prevents other remote hosts from -# connecting to forwarded ports. GatewayPorts can be used to specify that azbridge -# should bind local port forwardings to the wildcard address, thus allowing remote -# hosts to connect to forwarded ports. The argument must be "true" or "false". -# The default is "false". - -GatewayPorts : - -# Specifies that a (set of) TCP ports on the local machine -# shall be forwarded via the Azure Relay. Each entry can have four properties, -# "BindAddress", "BindPort", "LocalSocket", and "RelayName". - -LocalForward : -# - BindAddress: 127.0.8.1 -# BindPort: 443 -# RelayName: a1 - -# Gives the verbosity level that is used when logging messages -# from azbridge(1). The possible values are : QUIET, FATAL, ERROR, INFO, VERBOSE, -# DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. -# DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify -# higher levels of verbose output. - -LogLevel : ERROR - -# Specifies that a TCP port on the remote machine be bound to -# a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", -# "HostPort", and "LocalSocket". - -RemoteForward : -# - RelayName: a1 -# Host: localhost -# HostPort: 443 +# Azure Relay Bridge Configuration + +# Specifies which address family to use when connecting. Valid +# arguments are "any", "inet" (use IPv4 only), or "inet6" +# (use IPv6 only). The default is "any". + +AddressFamily : + +# Azure Relay connection string for a Relay namespace. Only one +# namespace connection string can be specified per configuration +# file. + +AzureRelayConnectionString : + +# Azure Relay endpoint URI for a Relay namespace. Overrides +# the 'Endpoint' property of the connection string, if present. + +AzureRelayEndpoint : + +# Azure Relay shared access policy name. Overrides the 'SharedAccessKeyName' +# property of the connection string, if present. + +AzureRelaySharedAccessKeyName : + +# Azure Relay shared access policy key. Overrides the 'SharedAccessKey' +# property of the connection string, if present. + +AzureRelaySharedAccessKey : + +# Azure Relay shared access policy signature. Overrides the 'SharedAccessSignature' +# property of the connection string, if present. + +AzureRelaySharedAccessSignature : + +# Use the specified address on the local machine as the source +# address of the connection. Only useful on systems with more than +# one address. + +BindAddress : + +# Specifies that all local, and remote port forwardings +# specified in the configuration files or on the command line be +# cleared. This option is primarily useful when used from the +# command line to clear port forwardings set in configura- +# tion files. The argument must be "true" or "false". The default is "false". + +ClearAllForwardings : + +# Specifies the number of tries (one per second) to make +# before exiting. The argument must be an integer. This may be useful in scripts +# if the connection sometimes fails. The default is 1. + +ConnectionAttempts : + +# Specifies the timeout (in seconds) used when connecting to the +# relay server, instead of using the default system TCP timeout. +# This value is used only when the target is down or really +# unreachable, not when it refuses the connection. + +ConnectTimeout : + +# Specifies whether azbridge(1) should terminate the +# connection if it cannot set up all requested local, and remote port forwardings, +# (e.g. if either end is unable to bind and listen on a specified port). +# The argument must be "true" or "false". The default is "false". + +ExitOnForwardFailure : + +# Specifies whether remote hosts are allowed to connect to local +# forwarded ports. By default, azbridge(1) binds local port forwardings +# to the loopback address. This prevents other remote hosts from +# connecting to forwarded ports. GatewayPorts can be used to specify that azbridge +# should bind local port forwardings to the wildcard address, thus allowing remote +# hosts to connect to forwarded ports. The argument must be "true" or "false". +# The default is "false". + +GatewayPorts : + +# Specifies that a (set of) TCP ports on the local machine +# shall be forwarded via the Azure Relay. Each entry can have four properties, +# "BindAddress", "BindPort", "LocalSocket", and "RelayName". + +LocalForward : +# - BindAddress: 127.0.8.1 +# BindPort: 443 +# RelayName: a1 + +# Gives the verbosity level that is used when logging messages +# from azbridge(1). The possible values are : QUIET, FATAL, ERROR, INFO, VERBOSE, +# DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. +# DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify +# higher levels of verbose output. + +LogLevel : ERROR + +# Specifies that a TCP port on the remote machine be bound to +# a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", +# "HostPort", and "LocalSocket". + +RemoteForward : +# - RelayName: a1 +# Host: localhost +# HostPort: 443 diff --git a/src/azbridge/azbridge_config.svc.yml b/src/azbridge/azbridge_config.svc.yml index 66ff3b3..b6bd6ab 100644 --- a/src/azbridge/azbridge_config.svc.yml +++ b/src/azbridge/azbridge_config.svc.yml @@ -1,103 +1,103 @@ -# Azure Relay Bridge Configuration - -# Specifies which address family to use when connecting. Valid -# arguments are "any", "inet" (use IPv4 only), or "inet6" -# (use IPv6 only). The default is "any". - -AddressFamily : - -# Azure Relay connection string for a Relay namespace. Only one -# namespace connection string can be specified per configuration -# file. - -AzureRelayConnectionString : - -# Azure Relay endpoint URI for a Relay namespace. Overrides -# the 'Endpoint' property of the connection string, if present. - -AzureRelayEndpoint : - -# Azure Relay shared access policy name. Overrides the 'SharedAccessKeyName' -# property of the connection string, if present. - -AzureRelaySharedAccessKeyName : - -# Azure Relay shared access policy key. Overrides the 'SharedAccessKey' -# property of the connection string, if present. - -AzureRelaySharedAccessKey : - -# Azure Relay shared access policy signature. Overrides the 'SharedAccessSignature' -# property of the connection string, if present. - -AzureRelaySharedAccessSignature : - -# Use the specified address on the local machine as the source -# address of the connection. Only useful on systems with more than -# one address. - -BindAddress : - -# Specifies that all local, and remote port forwardings -# specified in the configuration files or on the command line be -# cleared. This option is primarily useful when used from the -# command line to clear port forwardings set in configura- -# tion files. The argument must be "true" or "false". The default is "false". - -ClearAllForwardings : - -# Specifies the number of tries (one per second) to make -# before exiting. The argument must be an integer. This may be useful in scripts -# if the connection sometimes fails. The default is 1. - -ConnectionAttempts : - -# Specifies the timeout (in seconds) used when connecting to the -# relay server, instead of using the default system TCP timeout. -# This value is used only when the target is down or really -# unreachable, not when it refuses the connection. - -ConnectTimeout : - -# Specifies whether azbridge(1) should terminate the -# connection if it cannot set up all requested local, and remote port forwardings, -# (e.g. if either end is unable to bind and listen on a specified port). -# The argument must be "true" or "false". The default is "false". - -ExitOnForwardFailure : - -# Specifies whether remote hosts are allowed to connect to local -# forwarded ports. By default, azbridge(1) binds local port forwardings -# to the loopback address. This prevents other remote hosts from -# connecting to forwarded ports. GatewayPorts can be used to specify that azbridge -# should bind local port forwardings to the wildcard address, thus allowing remote -# hosts to connect to forwarded ports. The argument must be "true" or "false". -# The default is "false". - -GatewayPorts : - -# Specifies that a (set of) TCP ports on the local machine -# shall be forwarded via the Azure Relay. Each entry can have four properties, -# "BindAddress", "BindPort", "LocalSocket", and "RelayName". - -LocalForward : -# - BindAddress: 127.0.8.1 -# BindPort: 443 -# RelayName: a1 - -# Gives the verbosity level that is used when logging messages -# from azbridge(1). The possible values are : QUIET, FATAL, ERROR, INFO, VERBOSE, -# DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. -# DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify -# higher levels of verbose output. - -LogLevel : ERROR - -# Specifies that a TCP port on the remote machine be bound to -# a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", -# "HostPort", and "LocalSocket". - -RemoteForward : -# - RelayName: a1 -# Host: localhost -# HostPort: 443 +# Azure Relay Bridge Configuration + +# Specifies which address family to use when connecting. Valid +# arguments are "any", "inet" (use IPv4 only), or "inet6" +# (use IPv6 only). The default is "any". + +AddressFamily : + +# Azure Relay connection string for a Relay namespace. Only one +# namespace connection string can be specified per configuration +# file. + +AzureRelayConnectionString : + +# Azure Relay endpoint URI for a Relay namespace. Overrides +# the 'Endpoint' property of the connection string, if present. + +AzureRelayEndpoint : + +# Azure Relay shared access policy name. Overrides the 'SharedAccessKeyName' +# property of the connection string, if present. + +AzureRelaySharedAccessKeyName : + +# Azure Relay shared access policy key. Overrides the 'SharedAccessKey' +# property of the connection string, if present. + +AzureRelaySharedAccessKey : + +# Azure Relay shared access policy signature. Overrides the 'SharedAccessSignature' +# property of the connection string, if present. + +AzureRelaySharedAccessSignature : + +# Use the specified address on the local machine as the source +# address of the connection. Only useful on systems with more than +# one address. + +BindAddress : + +# Specifies that all local, and remote port forwardings +# specified in the configuration files or on the command line be +# cleared. This option is primarily useful when used from the +# command line to clear port forwardings set in configura- +# tion files. The argument must be "true" or "false". The default is "false". + +ClearAllForwardings : + +# Specifies the number of tries (one per second) to make +# before exiting. The argument must be an integer. This may be useful in scripts +# if the connection sometimes fails. The default is 1. + +ConnectionAttempts : + +# Specifies the timeout (in seconds) used when connecting to the +# relay server, instead of using the default system TCP timeout. +# This value is used only when the target is down or really +# unreachable, not when it refuses the connection. + +ConnectTimeout : + +# Specifies whether azbridge(1) should terminate the +# connection if it cannot set up all requested local, and remote port forwardings, +# (e.g. if either end is unable to bind and listen on a specified port). +# The argument must be "true" or "false". The default is "false". + +ExitOnForwardFailure : + +# Specifies whether remote hosts are allowed to connect to local +# forwarded ports. By default, azbridge(1) binds local port forwardings +# to the loopback address. This prevents other remote hosts from +# connecting to forwarded ports. GatewayPorts can be used to specify that azbridge +# should bind local port forwardings to the wildcard address, thus allowing remote +# hosts to connect to forwarded ports. The argument must be "true" or "false". +# The default is "false". + +GatewayPorts : + +# Specifies that a (set of) TCP ports on the local machine +# shall be forwarded via the Azure Relay. Each entry can have four properties, +# "BindAddress", "BindPort", "LocalSocket", and "RelayName". + +LocalForward : +# - BindAddress: 127.0.8.1 +# BindPort: 443 +# RelayName: a1 + +# Gives the verbosity level that is used when logging messages +# from azbridge(1). The possible values are : QUIET, FATAL, ERROR, INFO, VERBOSE, +# DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. +# DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify +# higher levels of verbose output. + +LogLevel : ERROR + +# Specifies that a TCP port on the remote machine be bound to +# a name on the Azure Relay. Each entry can have four properties, "RelayName", "Host", +# "HostPort", and "LocalSocket". + +RemoteForward : +# - RelayName: a1 +# Host: localhost +# HostPort: 443 diff --git a/src/tools/Powershell/add-hostname.ps1 b/src/tools/Powershell/add-hostname.ps1 index ba1a718..738ffbe 100644 --- a/src/tools/Powershell/add-hostname.ps1 +++ b/src/tools/Powershell/add-hostname.ps1 @@ -1,300 +1,300 @@ -<# -.DESCRIPTION -The hosts file is used to map hostnames to IP addresses. - -.PARAMETER IPAddress -The IP address to map the hostname(s) to. - -.PARAMETER Hostnames -One or more hostnames to map to the specified IP address. - -.PARAMETER Comment -Optional comment that is written above the new hosts entry. - -.EXAMPLE -.\Add-Hostnames.ps1 127.0.0.1 foobar - -Description ------------ -Adds the following line to the hosts file (assuming "foobar" does not already -exist in the hosts file): - -127.0.0.1 foobar - -A warning is displayed if "foobar" already exists in the hosts file and is -mapped to the specified IP address. An error occurs if "foobar" is already -mapped to a different IP address. - -.EXAMPLE -.\Add-Hostnames.ps1 127.0.0.1 foo, bar "This is a comment" - -Description ------------ -Adds the following lines to the hosts file (assuming "foo" and "bar" do not -already exist in the hosts file): - -# This is a comment -127.0.0.1 foo bar - -A warning is displayed if either "foo" or "bar" already exists in the hosts -file and is mapped to the specified IP address. An error occurs if "foo" or -"bar" is already mapped to a different IP address. - -.NOTES -This script must be run with administrator privileges. -#> -param( - [parameter(Mandatory = $true)] - [string] $IPAddress, - [parameter(Mandatory = $true, ValueFromPipeline = $true)] - [string[]] $Hostnames, - [string] $Comment -) - -begin -{ - Set-StrictMode -Version Latest - $ErrorActionPreference = "Stop" - - function CreateHostsEntryObject( - [string] $ipAddress, - [string[]] $hostnames, - <# [string] #> $comment) #HACK: never $null if type is specified - { - $hostsEntry = New-Object PSObject - $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` - -Value $ipAddress - - [System.Collections.ArrayList] $hostnamesList = - New-Object System.Collections.ArrayList - - $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` - -Value $hostnamesList - - If ($hostnames -ne $null) - { - $hostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment - - return $hostsEntry - } - - function ParseHostsEntry( - [string] $line) - { - $hostsEntry = CreateHostsEntryObject - - Write-Debug "Parsing hosts entry: $line" - - If ($line.Contains("#") -eq $true) - { - If ($line -eq "#") - { - $hostsEntry.Comment = [string]::Empty - } - Else - { - $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) - } - - $line = $line.Substring(0, $line.IndexOf("#")) - } - - $line = $line.Trim() - - If ($line.Length -gt 0) - { - $hostsEntry.IpAddress = ($line -Split "\s+")[0] - - Write-Debug "Parsed address: $($hostsEntry.IpAddress)" - - [string[]] $parsedHostnames = $line.Substring( - $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" - - Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` - + " $parsedHostnames") - - $parsedHostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - return $hostsEntry - } - - function ParseHostsFile - { - $hostsEntries = New-Object System.Collections.ArrayList - - [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" - - If ((Test-Path $hostsFile) -eq $false) - { - Write-Verbose "Hosts file does not exist." - } - Else - { - [string[]] $hostsContent = Get-Content $hostsFile - - $hostsContent | foreach { - $hostsEntry = ParseHostsEntry $_ - - $hostsEntries.Add($hostsEntry) | Out-Null - } - } - - # HACK: Return an array (containing the ArrayList) to avoid issue with - # PowerShell returning $null (when hosts file does not exist) - return ,$hostsEntries - } - - function UpdateHostsFile( - $hostsEntries = $(Throw "Value cannot be null: hostsEntries")) - { - Write-Verbose "Updatings hosts file..." - - [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" - - $buffer = New-Object System.Text.StringBuilder - - $hostsEntries | foreach { - - If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) - { - $buffer.Append($_.IpAddress) | Out-Null - $buffer.Append("`t") | Out-Null - } - - If ($_.Hostnames -ne $null) - { - [bool] $firstHostname = $true - - $_.Hostnames | foreach { - If ($firstHostname -eq $false) - { - $buffer.Append(" ") | Out-Null - } - Else - { - $firstHostname = $false - } - - $buffer.Append($_) | Out-Null - } - } - - If ($_.Comment -ne $null) - { - If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) - { - $buffer.Append(" ") | Out-Null - } - - $buffer.Append("#") | Out-Null - $buffer.Append($_.Comment) | Out-Null - } - - $buffer.Append([System.Environment]::NewLine) | Out-Null - } - - [string] $hostsContent = $buffer.ToString() - - $hostsContent = $hostsContent.Trim() - - Set-Content -Path $hostsFile -Value $hostsContent -Force -Encoding ASCII - - Write-Verbose "Successfully updated hosts file." - } - - [bool] $isInputFromPipeline = - ($PSBoundParameters.ContainsKey("Hostnames") -eq $false) - - [int] $pendingUpdates = 0 - - [Collections.ArrayList] $hostsEntries = ParseHostsFile -} - -process -{ - If ($isInputFromPipeline -eq $true) - { - $items = $_ - } - Else - { - $items = $Hostnames - } - - $newHostsEntry = CreateHostsEntryObject $IpAddress - $hostsEntries.Add($newHostsEntry) | Out-Null - - $items | foreach { - [string] $hostname = $_ - - [bool] $isHostnameInHostsEntries = $false - - for ([int] $i = 0; $i -lt $hostsEntries.Count; $i++) - { - $hostsEntry = $hostsEntries[$i] - - Write-Debug "Hosts entry: $hostsEntry" - - If ($hostsEntry.Hostnames.Count -eq 0) - { - continue - } - - for ([int] $j = 0; $j -lt $hostsEntry.Hostnames.Count; $j++) - { - [string] $parsedHostname = $hostsEntry.Hostnames[$j] - - Write-Debug ("Comparing specified hostname" ` - + " ($hostname) to existing hostname" ` - + " ($parsedHostname)...") - - If ([string]::Compare($hostname, $parsedHostname, $true) -eq 0) - { - $isHostnameInHostsEntries = $true - - If ($ipAddress -ne $hostsEntry.IpAddress) - { - Throw "The hosts file already contains the" ` - + " specified hostname ($parsedHostname) and it is" ` - + " mapped to a different address" ` - + " ($($hostsEntry.IpAddress))." - } - - Write-Verbose ("The hosts file already contains the" ` - + " specified hostname ($($hostsEntry.IpAddress) $parsedHostname).") - } - } - } - - If ($isHostnameInHostsEntries -eq $false) - { - Write-Debug ("Adding hostname ($hostname) to hosts entry...") - - $newHostsEntry.Hostnames.Add($hostname) | Out-Null - $pendingUpdates++ - } - } -} - -end -{ - If ($pendingUpdates -eq 0) - { - Write-Verbose "No changes to the hosts file are necessary." - - return - } - - Write-Verbose ("There are $pendingUpdates pending update(s) to the hosts" ` - + " file.") - - UpdateHostsFile $hostsEntries +<# +.DESCRIPTION +The hosts file is used to map hostnames to IP addresses. + +.PARAMETER IPAddress +The IP address to map the hostname(s) to. + +.PARAMETER Hostnames +One or more hostnames to map to the specified IP address. + +.PARAMETER Comment +Optional comment that is written above the new hosts entry. + +.EXAMPLE +.\Add-Hostnames.ps1 127.0.0.1 foobar + +Description +----------- +Adds the following line to the hosts file (assuming "foobar" does not already +exist in the hosts file): + +127.0.0.1 foobar + +A warning is displayed if "foobar" already exists in the hosts file and is +mapped to the specified IP address. An error occurs if "foobar" is already +mapped to a different IP address. + +.EXAMPLE +.\Add-Hostnames.ps1 127.0.0.1 foo, bar "This is a comment" + +Description +----------- +Adds the following lines to the hosts file (assuming "foo" and "bar" do not +already exist in the hosts file): + +# This is a comment +127.0.0.1 foo bar + +A warning is displayed if either "foo" or "bar" already exists in the hosts +file and is mapped to the specified IP address. An error occurs if "foo" or +"bar" is already mapped to a different IP address. + +.NOTES +This script must be run with administrator privileges. +#> +param( + [parameter(Mandatory = $true)] + [string] $IPAddress, + [parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string[]] $Hostnames, + [string] $Comment +) + +begin +{ + Set-StrictMode -Version Latest + $ErrorActionPreference = "Stop" + + function CreateHostsEntryObject( + [string] $ipAddress, + [string[]] $hostnames, + <# [string] #> $comment) #HACK: never $null if type is specified + { + $hostsEntry = New-Object PSObject + $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` + -Value $ipAddress + + [System.Collections.ArrayList] $hostnamesList = + New-Object System.Collections.ArrayList + + $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` + -Value $hostnamesList + + If ($hostnames -ne $null) + { + $hostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment + + return $hostsEntry + } + + function ParseHostsEntry( + [string] $line) + { + $hostsEntry = CreateHostsEntryObject + + Write-Debug "Parsing hosts entry: $line" + + If ($line.Contains("#") -eq $true) + { + If ($line -eq "#") + { + $hostsEntry.Comment = [string]::Empty + } + Else + { + $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) + } + + $line = $line.Substring(0, $line.IndexOf("#")) + } + + $line = $line.Trim() + + If ($line.Length -gt 0) + { + $hostsEntry.IpAddress = ($line -Split "\s+")[0] + + Write-Debug "Parsed address: $($hostsEntry.IpAddress)" + + [string[]] $parsedHostnames = $line.Substring( + $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" + + Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` + + " $parsedHostnames") + + $parsedHostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + return $hostsEntry + } + + function ParseHostsFile + { + $hostsEntries = New-Object System.Collections.ArrayList + + [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" + + If ((Test-Path $hostsFile) -eq $false) + { + Write-Verbose "Hosts file does not exist." + } + Else + { + [string[]] $hostsContent = Get-Content $hostsFile + + $hostsContent | foreach { + $hostsEntry = ParseHostsEntry $_ + + $hostsEntries.Add($hostsEntry) | Out-Null + } + } + + # HACK: Return an array (containing the ArrayList) to avoid issue with + # PowerShell returning $null (when hosts file does not exist) + return ,$hostsEntries + } + + function UpdateHostsFile( + $hostsEntries = $(Throw "Value cannot be null: hostsEntries")) + { + Write-Verbose "Updatings hosts file..." + + [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" + + $buffer = New-Object System.Text.StringBuilder + + $hostsEntries | foreach { + + If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) + { + $buffer.Append($_.IpAddress) | Out-Null + $buffer.Append("`t") | Out-Null + } + + If ($_.Hostnames -ne $null) + { + [bool] $firstHostname = $true + + $_.Hostnames | foreach { + If ($firstHostname -eq $false) + { + $buffer.Append(" ") | Out-Null + } + Else + { + $firstHostname = $false + } + + $buffer.Append($_) | Out-Null + } + } + + If ($_.Comment -ne $null) + { + If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) + { + $buffer.Append(" ") | Out-Null + } + + $buffer.Append("#") | Out-Null + $buffer.Append($_.Comment) | Out-Null + } + + $buffer.Append([System.Environment]::NewLine) | Out-Null + } + + [string] $hostsContent = $buffer.ToString() + + $hostsContent = $hostsContent.Trim() + + Set-Content -Path $hostsFile -Value $hostsContent -Force -Encoding ASCII + + Write-Verbose "Successfully updated hosts file." + } + + [bool] $isInputFromPipeline = + ($PSBoundParameters.ContainsKey("Hostnames") -eq $false) + + [int] $pendingUpdates = 0 + + [Collections.ArrayList] $hostsEntries = ParseHostsFile +} + +process +{ + If ($isInputFromPipeline -eq $true) + { + $items = $_ + } + Else + { + $items = $Hostnames + } + + $newHostsEntry = CreateHostsEntryObject $IpAddress + $hostsEntries.Add($newHostsEntry) | Out-Null + + $items | foreach { + [string] $hostname = $_ + + [bool] $isHostnameInHostsEntries = $false + + for ([int] $i = 0; $i -lt $hostsEntries.Count; $i++) + { + $hostsEntry = $hostsEntries[$i] + + Write-Debug "Hosts entry: $hostsEntry" + + If ($hostsEntry.Hostnames.Count -eq 0) + { + continue + } + + for ([int] $j = 0; $j -lt $hostsEntry.Hostnames.Count; $j++) + { + [string] $parsedHostname = $hostsEntry.Hostnames[$j] + + Write-Debug ("Comparing specified hostname" ` + + " ($hostname) to existing hostname" ` + + " ($parsedHostname)...") + + If ([string]::Compare($hostname, $parsedHostname, $true) -eq 0) + { + $isHostnameInHostsEntries = $true + + If ($ipAddress -ne $hostsEntry.IpAddress) + { + Throw "The hosts file already contains the" ` + + " specified hostname ($parsedHostname) and it is" ` + + " mapped to a different address" ` + + " ($($hostsEntry.IpAddress))." + } + + Write-Verbose ("The hosts file already contains the" ` + + " specified hostname ($($hostsEntry.IpAddress) $parsedHostname).") + } + } + } + + If ($isHostnameInHostsEntries -eq $false) + { + Write-Debug ("Adding hostname ($hostname) to hosts entry...") + + $newHostsEntry.Hostnames.Add($hostname) | Out-Null + $pendingUpdates++ + } + } +} + +end +{ + If ($pendingUpdates -eq 0) + { + Write-Verbose "No changes to the hosts file are necessary." + + return + } + + Write-Verbose ("There are $pendingUpdates pending update(s) to the hosts" ` + + " file.") + + UpdateHostsFile $hostsEntries } \ No newline at end of file diff --git a/src/tools/Powershell/get-hostname.ps1 b/src/tools/Powershell/get-hostname.ps1 index 85751a2..728b81e 100644 --- a/src/tools/Powershell/get-hostname.ps1 +++ b/src/tools/Powershell/get-hostname.ps1 @@ -1,136 +1,136 @@ -<# -.SYNOPSIS -Gets the hostnames (and corresponding IP addresses) specified in the hosts file. - -.DESCRIPTION -The hosts file is used to map hostnames to IP addresses. - -.EXAMPLE -.\Get-HostNames.ps1 - - IpAddress Hostname - --------- -------- - 127.0.0.1 localhost - 127.0.0.1 zurich-ac-portal-test.dnsdemo1.com # Added by HybridConnectionClient -#> - -begin -{ - Set-StrictMode -Version Latest - $ErrorActionPreference = "Stop" - - function CreateHostsEntryObject( - [string] $ipAddress, - [string[]] $hostnames, - <# [string] #> $comment) #HACK: never $null if type is specified - { - $hostsEntry = New-Object PSObject - $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` - -Value $ipAddress - - [System.Collections.ArrayList] $hostnamesList = - New-Object System.Collections.ArrayList - - $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` - -Value $hostnamesList - - If ($hostnames -ne $null) - { - $hostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment - - return $hostsEntry - } - - function ParseHostsEntry( - [string] $line) - { - $hostsEntry = CreateHostsEntryObject - - Write-Debug "Parsing hosts entry: $line" - - If ($line.Contains("#") -eq $true) - { - If ($line -eq "#") - { - $hostsEntry.Comment = [string]::Empty - } - Else - { - $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) - } - - $line = $line.Substring(0, $line.IndexOf("#")) - } - - $line = $line.Trim() - - If ($line.Length -gt 0) - { - $hostsEntry.IpAddress = ($line -Split "\s+")[0] - - Write-Debug "Parsed address: $($hostsEntry.IpAddress)" - - [string[]] $parsedHostnames = $line.Substring( - $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" - - Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` - + " $parsedHostnames") - - $parsedHostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - return $hostsEntry - } - - function ParseHostsFile - { - $hostsEntries = New-Object System.Collections.ArrayList - - [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" - - If ((Test-Path $hostsFile) -eq $false) - { - Write-Verbose "Hosts file does not exist." - } - Else - { - [string[]] $hostsContent = Get-Content $hostsFile - - $hostsContent | foreach { - $hostsEntry = ParseHostsEntry $_ - - $hostsEntries.Add($hostsEntry) | Out-Null - } - } - - # HACK: Return an array (containing the ArrayList) to avoid issue with - # PowerShell returning $null (when hosts file does not exist) - return ,$hostsEntries - } - - [Collections.ArrayList] $hostsEntries = ParseHostsFile -} - -process -{ - $hostsEntries | foreach { - $hostsEntry = $_ - - $hostsEntry.Hostnames | foreach { - $properties = @{ - Hostname = $_ - IpAddress = $hostsEntry.IpAddress - Comment = $hostsEntry.Comment - } - - New-Object PSObject -Property $properties - } - } +<# +.SYNOPSIS +Gets the hostnames (and corresponding IP addresses) specified in the hosts file. + +.DESCRIPTION +The hosts file is used to map hostnames to IP addresses. + +.EXAMPLE +.\Get-HostNames.ps1 + + IpAddress Hostname + --------- -------- + 127.0.0.1 localhost + 127.0.0.1 zurich-ac-portal-test.dnsdemo1.com # Added by HybridConnectionClient +#> + +begin +{ + Set-StrictMode -Version Latest + $ErrorActionPreference = "Stop" + + function CreateHostsEntryObject( + [string] $ipAddress, + [string[]] $hostnames, + <# [string] #> $comment) #HACK: never $null if type is specified + { + $hostsEntry = New-Object PSObject + $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` + -Value $ipAddress + + [System.Collections.ArrayList] $hostnamesList = + New-Object System.Collections.ArrayList + + $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` + -Value $hostnamesList + + If ($hostnames -ne $null) + { + $hostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment + + return $hostsEntry + } + + function ParseHostsEntry( + [string] $line) + { + $hostsEntry = CreateHostsEntryObject + + Write-Debug "Parsing hosts entry: $line" + + If ($line.Contains("#") -eq $true) + { + If ($line -eq "#") + { + $hostsEntry.Comment = [string]::Empty + } + Else + { + $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) + } + + $line = $line.Substring(0, $line.IndexOf("#")) + } + + $line = $line.Trim() + + If ($line.Length -gt 0) + { + $hostsEntry.IpAddress = ($line -Split "\s+")[0] + + Write-Debug "Parsed address: $($hostsEntry.IpAddress)" + + [string[]] $parsedHostnames = $line.Substring( + $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" + + Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` + + " $parsedHostnames") + + $parsedHostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + return $hostsEntry + } + + function ParseHostsFile + { + $hostsEntries = New-Object System.Collections.ArrayList + + [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" + + If ((Test-Path $hostsFile) -eq $false) + { + Write-Verbose "Hosts file does not exist." + } + Else + { + [string[]] $hostsContent = Get-Content $hostsFile + + $hostsContent | foreach { + $hostsEntry = ParseHostsEntry $_ + + $hostsEntries.Add($hostsEntry) | Out-Null + } + } + + # HACK: Return an array (containing the ArrayList) to avoid issue with + # PowerShell returning $null (when hosts file does not exist) + return ,$hostsEntries + } + + [Collections.ArrayList] $hostsEntries = ParseHostsFile +} + +process +{ + $hostsEntries | foreach { + $hostsEntry = $_ + + $hostsEntry.Hostnames | foreach { + $properties = @{ + Hostname = $_ + IpAddress = $hostsEntry.IpAddress + Comment = $hostsEntry.Comment + } + + New-Object PSObject -Property $properties + } + } } \ No newline at end of file diff --git a/src/tools/Powershell/remove-hostname.ps1 b/src/tools/Powershell/remove-hostname.ps1 index 58a46fe..790a466 100644 --- a/src/tools/Powershell/remove-hostname.ps1 +++ b/src/tools/Powershell/remove-hostname.ps1 @@ -1,295 +1,295 @@ -<# -.SYNOPSIS -Removes one or more hostnames from the hosts file. - -.DESCRIPTION -The hosts file is used to map hostnames to IP addresses. - -.PARAMETER Hostnames -One or more hostnames to remove from the hosts file. - -.EXAMPLE -.\Remove-Hostnames.ps1 foobar - -Description ------------ -Assume the following line was previously added to the hosts file: - -127.0.0.1 foobar - -After running "Remove-Hostnames.ps1 foobar" the hosts file no longer contains this -line. - -.EXAMPLE -.\Remove-Hostnames.ps1 foo - -Description ------------ -Assume the following line was previously added to the hosts file: - -127.0.0.1 foobar foo bar - -After running "Remove-Hostnames.ps1 foo" the line in the hosts file is updated -to remove the specified hostname ("foo"): - -127.0.0.1 foobar bar - -.EXAMPLE -.\Remove-Hostnames.ps1 foo, bar - -Description ------------ -Assume the following line was previously added to the hosts file: - -127.0.0.1 foobar foo bar - -After running "Remove-Hostnames.ps1 foo, bar" the line in the hosts file is updated to -remove the specified hostnames ("foo" and "bar"): - -127.0.0.1 foobar - -.NOTES -This script must be run with administrator privileges. -#> -param( - [parameter(Mandatory = $true, ValueFromPipeline = $true)] - [string[]] $Hostnames -) - -begin -{ - Set-StrictMode -Version Latest - $ErrorActionPreference = "Stop" - - function CreateHostsEntryObject( - [string] $ipAddress, - [string[]] $hostnames, - <# [string] #> $comment) #HACK: never $null if type is specified - { - $hostsEntry = New-Object PSObject - $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` - -Value $ipAddress - - [System.Collections.ArrayList] $hostnamesList = - New-Object System.Collections.ArrayList - - $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` - -Value $hostnamesList - - If ($hostnames -ne $null) - { - $hostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment - - return $hostsEntry - } - - function ParseHostsEntry( - [string] $line) - { - $hostsEntry = CreateHostsEntryObject - - Write-Debug "Parsing hosts entry: $line" - - If ($line.Contains("#") -eq $true) - { - If ($line -eq "#") - { - $hostsEntry.Comment = [string]::Empty - } - Else - { - $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) - } - - $line = $line.Substring(0, $line.IndexOf("#")) - } - - $line = $line.Trim() - - If ($line.Length -gt 0) - { - $hostsEntry.IpAddress = ($line -Split "\s+")[0] - - Write-Debug "Parsed address: $($hostsEntry.IpAddress)" - - [string[]] $parsedHostnames = $line.Substring( - $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" - - Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` - + " $parsedHostnames") - - $parsedHostnames | foreach { - $hostsEntry.Hostnames.Add($_) | Out-Null - } - } - - return $hostsEntry - } - - function ParseHostsFile - { - $hostsEntries = New-Object System.Collections.ArrayList - - [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" - - If ((Test-Path $hostsFile) -eq $false) - { - Write-Verbose "Hosts file does not exist." - } - Else - { - [string[]] $hostsContent = Get-Content $hostsFile - - $hostsContent | foreach { - $hostsEntry = ParseHostsEntry $_ - - $hostsEntries.Add($hostsEntry) | Out-Null - } - } - - # HACK: Return an array (containing the ArrayList) to avoid issue with - # PowerShell returning $null (when hosts file does not exist) - return ,$hostsEntries - } - - function UpdateHostsFile( - $hostsEntries = $(Throw "Value cannot be null: hostsEntries")) - { - Write-Verbose "Updatings hosts file..." - - [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" - - $buffer = New-Object System.Text.StringBuilder - - $hostsEntries | foreach { - - If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) - { - $buffer.Append($_.IpAddress) | Out-Null - $buffer.Append("`t") | Out-Null - } - - If ($_.Hostnames -ne $null) - { - [bool] $firstHostname = $true - - $_.Hostnames | foreach { - If ($firstHostname -eq $false) - { - $buffer.Append(" ") | Out-Null - } - Else - { - $firstHostname = $false - } - - $buffer.Append($_) | Out-Null - } - } - - If ($_.Comment -ne $null) - { - If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) - { - $buffer.Append(" ") | Out-Null - } - - $buffer.Append("#") | Out-Null - $buffer.Append($_.Comment) | Out-Null - } - - $buffer.Append([System.Environment]::NewLine) | Out-Null - } - - [string] $hostsContent = $buffer.ToString() - - $hostsContent = $hostsContent.Trim() - - Set-Content -Path $hostsFile -Value $hostsContent -Force -Encoding ASCII - - Write-Verbose "Successfully updated hosts file." - } - - [bool] $isInputFromPipeline = - ($PSBoundParameters.ContainsKey("Hostnames") -eq $false) - - [int] $pendingUpdates = 0 - - [Collections.ArrayList] $hostsEntries = ParseHostsFile -} - -process -{ - If ($isInputFromPipeline -eq $true) - { - $items = $_ - } - Else - { - $items = $Hostnames - } - - $items | foreach { - [string] $hostname = $_ - - for ([int] $i = 0; $i -lt $hostsEntries.Count; $i++) - { - $hostsEntry = $hostsEntries[$i] - - Write-Debug "Hosts entry: $hostsEntry" - - If ($hostsEntry.Hostnames.Count -eq 0) - { - continue - } - - for ([int] $j = 0; $j -lt $hostsEntry.Hostnames.Count; $j++) - { - [string] $parsedHostname = $hostsEntry.Hostnames[$j] - - Write-Debug ("Comparing specified hostname" ` - + " ($hostname) to existing hostname" ` - + " ($parsedHostname)...") - - If ([string]::Compare($hostname, $parsedHostname, $true) -eq 0) - { - Write-Debug "Removing hostname ($hostname) from host entry ($hostsEntry)..." - - $hostsEntry.Hostnames.RemoveAt($j) - $j-- - - $pendingUpdates++ - } - } - - If ($hostsEntry.Hostnames.Count -eq 0) - { - Write-Debug ("Removing host entry (because it no longer specifies" ` - + " any hostnames)...") - - $hostsEntries.RemoveAt($i) - $i-- - } - } - } -} - -end -{ - If ($pendingUpdates -eq 0) - { - Write-Verbose "No changes to the hosts file are necessary." - - return - } - - Write-Verbose ("There are $pendingUpdates pending update(s) to the hosts" ` - + " file.") - - UpdateHostsFile $hostsEntries +<# +.SYNOPSIS +Removes one or more hostnames from the hosts file. + +.DESCRIPTION +The hosts file is used to map hostnames to IP addresses. + +.PARAMETER Hostnames +One or more hostnames to remove from the hosts file. + +.EXAMPLE +.\Remove-Hostnames.ps1 foobar + +Description +----------- +Assume the following line was previously added to the hosts file: + +127.0.0.1 foobar + +After running "Remove-Hostnames.ps1 foobar" the hosts file no longer contains this +line. + +.EXAMPLE +.\Remove-Hostnames.ps1 foo + +Description +----------- +Assume the following line was previously added to the hosts file: + +127.0.0.1 foobar foo bar + +After running "Remove-Hostnames.ps1 foo" the line in the hosts file is updated +to remove the specified hostname ("foo"): + +127.0.0.1 foobar bar + +.EXAMPLE +.\Remove-Hostnames.ps1 foo, bar + +Description +----------- +Assume the following line was previously added to the hosts file: + +127.0.0.1 foobar foo bar + +After running "Remove-Hostnames.ps1 foo, bar" the line in the hosts file is updated to +remove the specified hostnames ("foo" and "bar"): + +127.0.0.1 foobar + +.NOTES +This script must be run with administrator privileges. +#> +param( + [parameter(Mandatory = $true, ValueFromPipeline = $true)] + [string[]] $Hostnames +) + +begin +{ + Set-StrictMode -Version Latest + $ErrorActionPreference = "Stop" + + function CreateHostsEntryObject( + [string] $ipAddress, + [string[]] $hostnames, + <# [string] #> $comment) #HACK: never $null if type is specified + { + $hostsEntry = New-Object PSObject + $hostsEntry | Add-Member NoteProperty -Name "IpAddress" ` + -Value $ipAddress + + [System.Collections.ArrayList] $hostnamesList = + New-Object System.Collections.ArrayList + + $hostsEntry | Add-Member NoteProperty -Name "Hostnames" ` + -Value $hostnamesList + + If ($hostnames -ne $null) + { + $hostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + $hostsEntry | Add-Member NoteProperty -Name "Comment" -Value $comment + + return $hostsEntry + } + + function ParseHostsEntry( + [string] $line) + { + $hostsEntry = CreateHostsEntryObject + + Write-Debug "Parsing hosts entry: $line" + + If ($line.Contains("#") -eq $true) + { + If ($line -eq "#") + { + $hostsEntry.Comment = [string]::Empty + } + Else + { + $hostsEntry.Comment = $line.Substring($line.IndexOf("#") + 1) + } + + $line = $line.Substring(0, $line.IndexOf("#")) + } + + $line = $line.Trim() + + If ($line.Length -gt 0) + { + $hostsEntry.IpAddress = ($line -Split "\s+")[0] + + Write-Debug "Parsed address: $($hostsEntry.IpAddress)" + + [string[]] $parsedHostnames = $line.Substring( + $hostsEntry.IpAddress.Length + 1).Trim() -Split "\s+" + + Write-Debug ("Parsed hostnames ($($parsedHostnames.Length)):" ` + + " $parsedHostnames") + + $parsedHostnames | foreach { + $hostsEntry.Hostnames.Add($_) | Out-Null + } + } + + return $hostsEntry + } + + function ParseHostsFile + { + $hostsEntries = New-Object System.Collections.ArrayList + + [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" + + If ((Test-Path $hostsFile) -eq $false) + { + Write-Verbose "Hosts file does not exist." + } + Else + { + [string[]] $hostsContent = Get-Content $hostsFile + + $hostsContent | foreach { + $hostsEntry = ParseHostsEntry $_ + + $hostsEntries.Add($hostsEntry) | Out-Null + } + } + + # HACK: Return an array (containing the ArrayList) to avoid issue with + # PowerShell returning $null (when hosts file does not exist) + return ,$hostsEntries + } + + function UpdateHostsFile( + $hostsEntries = $(Throw "Value cannot be null: hostsEntries")) + { + Write-Verbose "Updatings hosts file..." + + [string] $hostsFile = $env:WINDIR + "\System32\drivers\etc\hosts" + + $buffer = New-Object System.Text.StringBuilder + + $hostsEntries | foreach { + + If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) + { + $buffer.Append($_.IpAddress) | Out-Null + $buffer.Append("`t") | Out-Null + } + + If ($_.Hostnames -ne $null) + { + [bool] $firstHostname = $true + + $_.Hostnames | foreach { + If ($firstHostname -eq $false) + { + $buffer.Append(" ") | Out-Null + } + Else + { + $firstHostname = $false + } + + $buffer.Append($_) | Out-Null + } + } + + If ($_.Comment -ne $null) + { + If ([string]::IsNullOrEmpty($_.IpAddress) -eq $false) + { + $buffer.Append(" ") | Out-Null + } + + $buffer.Append("#") | Out-Null + $buffer.Append($_.Comment) | Out-Null + } + + $buffer.Append([System.Environment]::NewLine) | Out-Null + } + + [string] $hostsContent = $buffer.ToString() + + $hostsContent = $hostsContent.Trim() + + Set-Content -Path $hostsFile -Value $hostsContent -Force -Encoding ASCII + + Write-Verbose "Successfully updated hosts file." + } + + [bool] $isInputFromPipeline = + ($PSBoundParameters.ContainsKey("Hostnames") -eq $false) + + [int] $pendingUpdates = 0 + + [Collections.ArrayList] $hostsEntries = ParseHostsFile +} + +process +{ + If ($isInputFromPipeline -eq $true) + { + $items = $_ + } + Else + { + $items = $Hostnames + } + + $items | foreach { + [string] $hostname = $_ + + for ([int] $i = 0; $i -lt $hostsEntries.Count; $i++) + { + $hostsEntry = $hostsEntries[$i] + + Write-Debug "Hosts entry: $hostsEntry" + + If ($hostsEntry.Hostnames.Count -eq 0) + { + continue + } + + for ([int] $j = 0; $j -lt $hostsEntry.Hostnames.Count; $j++) + { + [string] $parsedHostname = $hostsEntry.Hostnames[$j] + + Write-Debug ("Comparing specified hostname" ` + + " ($hostname) to existing hostname" ` + + " ($parsedHostname)...") + + If ([string]::Compare($hostname, $parsedHostname, $true) -eq 0) + { + Write-Debug "Removing hostname ($hostname) from host entry ($hostsEntry)..." + + $hostsEntry.Hostnames.RemoveAt($j) + $j-- + + $pendingUpdates++ + } + } + + If ($hostsEntry.Hostnames.Count -eq 0) + { + Write-Debug ("Removing host entry (because it no longer specifies" ` + + " any hostnames)...") + + $hostsEntries.RemoveAt($i) + $i-- + } + } + } +} + +end +{ + If ($pendingUpdates -eq 0) + { + Write-Verbose "No changes to the hosts file are necessary." + + return + } + + Write-Verbose ("There are $pendingUpdates pending update(s) to the hosts" ` + + " file.") + + UpdateHostsFile $hostsEntries } \ No newline at end of file diff --git a/src/tools/azure/test-resource-template.json b/src/tools/azure/test-resource-template.json index 9d44642..0d96683 100644 --- a/src/tools/azure/test-resource-template.json +++ b/src/tools/azure/test-resource-template.json @@ -1,80 +1,80 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "relay_namespace": { - "type": "String" - }, - "location": { - "type": "String" - } - }, - "variables": { - "apiVersion": "2017-04-01" - }, - "resources": [{ - "type": "Microsoft.Relay/namespaces", - "name": "[parameters('relay_namespace')]", - "apiVersion": "[variables('apiVersion')]", - "location": "[parameters('location')]", - "dependsOn": [] - }, - { - "type": "Microsoft.Relay/namespaces/AuthorizationRules", - "name": "[concat(parameters('relay_namespace'), '/sendlisten')]", - "apiVersion": "[variables('apiVersion')]", - "properties": { - "rights": [ - "Send", - "Listen" - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" - ] - }, - { - "type": "Microsoft.Relay/namespaces/hybridConnections", - "name": "[concat(parameters('relay_namespace'), '/a1')]", - "apiVersion": "[variables('apiVersion')]", - "properties": { - "requiresClientAuthorization": true - }, - "dependsOn": [ - "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" - ] - }, - { - "type": "Microsoft.Relay/namespaces/hybridConnections", - "name": "[concat(parameters('relay_namespace'), '/a2')]", - "apiVersion": "[variables('apiVersion')]", - "properties": { - "requiresClientAuthorization": true - }, - "dependsOn": [ - "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" - ] - }, - { - "type": "Microsoft.Relay/namespaces/hybridConnections", - "name": "[concat(parameters('relay_namespace'), '/a3')]", - "apiVersion": "[variables('apiVersion')]", - "properties": { - "requiresClientAuthorization": true - }, - "dependsOn": [ - "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" - ] - } - ], - "outputs": { - "serviceBusNamespaceName": { - "type": "string", - "value": "[parameters('relay_namespace')]" - }, - "sendListenConnectionString": { - "type": "string", - "value": "[listkeys(resourceId('Microsoft.Relay/namespaces/AuthorizationRules', parameters('relay_namespace'), 'sendlisten'),variables('apiVersion')).primaryConnectionString]" - } - } +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "relay_namespace": { + "type": "String" + }, + "location": { + "type": "String" + } + }, + "variables": { + "apiVersion": "2017-04-01" + }, + "resources": [{ + "type": "Microsoft.Relay/namespaces", + "name": "[parameters('relay_namespace')]", + "apiVersion": "[variables('apiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [] + }, + { + "type": "Microsoft.Relay/namespaces/AuthorizationRules", + "name": "[concat(parameters('relay_namespace'), '/sendlisten')]", + "apiVersion": "[variables('apiVersion')]", + "properties": { + "rights": [ + "Send", + "Listen" + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" + ] + }, + { + "type": "Microsoft.Relay/namespaces/hybridConnections", + "name": "[concat(parameters('relay_namespace'), '/a1')]", + "apiVersion": "[variables('apiVersion')]", + "properties": { + "requiresClientAuthorization": true + }, + "dependsOn": [ + "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" + ] + }, + { + "type": "Microsoft.Relay/namespaces/hybridConnections", + "name": "[concat(parameters('relay_namespace'), '/a2')]", + "apiVersion": "[variables('apiVersion')]", + "properties": { + "requiresClientAuthorization": true + }, + "dependsOn": [ + "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" + ] + }, + { + "type": "Microsoft.Relay/namespaces/hybridConnections", + "name": "[concat(parameters('relay_namespace'), '/a3')]", + "apiVersion": "[variables('apiVersion')]", + "properties": { + "requiresClientAuthorization": true + }, + "dependsOn": [ + "[resourceId('Microsoft.Relay/namespaces', parameters('relay_namespace'))]" + ] + } + ], + "outputs": { + "serviceBusNamespaceName": { + "type": "string", + "value": "[parameters('relay_namespace')]" + }, + "sendListenConnectionString": { + "type": "string", + "value": "[listkeys(resourceId('Microsoft.Relay/namespaces/AuthorizationRules', parameters('relay_namespace'), 'sendlisten'),variables('apiVersion')).primaryConnectionString]" + } + } } \ No newline at end of file diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 3a0fbcd..48e19d1 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/test/docker/.dockerignore b/test/docker/.dockerignore index 6975847..85d6154 100644 --- a/test/docker/.dockerignore +++ b/test/docker/.dockerignore @@ -1,10 +1,10 @@ -node_modules -npm-debug.log -Dockerfile* -docker-compose* -.dockerignore -.git -.gitignore -README.md -LICENSE +node_modules +npm-debug.log +Dockerfile* +docker-compose* +.dockerignore +.git +.gitignore +README.md +LICENSE .vscode \ No newline at end of file diff --git a/test/docker/.gitattributes b/test/docker/.gitattributes index 27a248d..d767431 100644 --- a/test/docker/.gitattributes +++ b/test/docker/.gitattributes @@ -1 +1 @@ -*.txt eol=lf +*.txt eol=lf diff --git a/test/docker/Directory.Build.props b/test/docker/Directory.Build.props index 3a0fbcd..48e19d1 100644 --- a/test/docker/Directory.Build.props +++ b/test/docker/Directory.Build.props @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/test/docker/Test.proj b/test/docker/Test.proj index f29b6d0..33c4dbf 100644 --- a/test/docker/Test.proj +++ b/test/docker/Test.proj @@ -1,18 +1,18 @@ - - - None - - - - - - - - - - - - - - + + + None + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/docker/_scripts/imagetests.cmd b/test/docker/_scripts/imagetests.cmd index 69e75ec..0d6be2d 100644 --- a/test/docker/_scripts/imagetests.cmd +++ b/test/docker/_scripts/imagetests.cmd @@ -1,23 +1,23 @@ -@echo off - -SET _CXNSTRING= -FOR /F "delims=" %%i IN (%AZBRIDGE_TEST_CXNSTRING%) DO SET _CXNSTRING=%%i - -if "%_CXNSTRING%" == "" ( - echo AZBRIDGE_TEST_CXNSTRING environment variable must be set to valid relay connection string - exit /b -) - -set _IMAGE_ID= - -rem for /f %%i in ('docker images %IMAGE_NAME% -q') do set _IMAGE_ID=%%i -rem if "%_IMAGE_ID%"=="" call build.cmd - -FOR /F %%i IN ("%cd%\..") DO set _MOUNTPATH=%%~fi -set _TESTNAME=test_nc_ping_pong -call ../_scripts/runtest.cmd -if NOT "%_RESULT%"=="0" exit /b %_RESULT% - -set _TESTNAME=test_nc_config_ping_pong -call ../_scripts/runtest.cmd -exit /b %_RESULT% +@echo off + +SET _CXNSTRING= +FOR /F "delims=" %%i IN (%AZBRIDGE_TEST_CXNSTRING%) DO SET _CXNSTRING=%%i + +if "%_CXNSTRING%" == "" ( + echo AZBRIDGE_TEST_CXNSTRING environment variable must be set to valid relay connection string + exit /b +) + +set _IMAGE_ID= + +rem for /f %%i in ('docker images %IMAGE_NAME% -q') do set _IMAGE_ID=%%i +rem if "%_IMAGE_ID%"=="" call build.cmd + +FOR /F %%i IN ("%cd%\..") DO set _MOUNTPATH=%%~fi +set _TESTNAME=test_nc_ping_pong +call ../_scripts/runtest.cmd +if NOT "%_RESULT%"=="0" exit /b %_RESULT% + +set _TESTNAME=test_nc_config_ping_pong +call ../_scripts/runtest.cmd +exit /b %_RESULT% diff --git a/test/docker/_scripts/removeimage.cmd b/test/docker/_scripts/removeimage.cmd index 0a90454..70ae5c5 100644 --- a/test/docker/_scripts/removeimage.cmd +++ b/test/docker/_scripts/removeimage.cmd @@ -1,4 +1,4 @@ -set _IMAGE_ID= -for /f %%i in ('docker images %IMAGE_NAME% -q') do set _IMAGE_ID=%%i -if "%_IMAGE_ID%"=="" exit /b +set _IMAGE_ID= +for /f %%i in ('docker images %IMAGE_NAME% -q') do set _IMAGE_ID=%%i +if "%_IMAGE_ID%"=="" exit /b docker rmi -f %IMAGE_NAME%:latest \ No newline at end of file diff --git a/test/docker/_scripts/runtest.cmd b/test/docker/_scripts/runtest.cmd index d1847af..e4d41a0 100644 --- a/test/docker/_scripts/runtest.cmd +++ b/test/docker/_scripts/runtest.cmd @@ -1,21 +1,21 @@ -@echo off -echo Running %_TESTNAME% -set _OUTFILE=%temp%\azbridge-tests-%_TESTNAME%.output.txt -docker run -v %_MOUNTPATH%:/tests -e AZBRIDGE_TEST_CXNSTRING="%_CXNSTRING%" --rm %IMAGE_NAME%:latest bash /tests/%_TESTNAME%.sh > %_OUTFILE% -if exist %_MOUNTPATH%\%_TESTNAME%.reference.txt ( - fc /L %_MOUNTPATH%\%_TESTNAME%.reference.txt %_OUTFILE% > NUL - if ERRORLEVEL 1 ( - set _RESULT=%ERRORLEVEL% - type %_OUTFILE% - echo Error %_RESULT% - ) - if ERRORLEVEL 0 ( - set _RESULT=0 - echo OK - ) - del %_OUTFILE% -) else ( - copy /Y %_OUTFILE% %_MOUNTPATH%\%_TESTNAME%.reference.txt > NUL - set _RESULT=%ERRORLEVEL% -) +@echo off +echo Running %_TESTNAME% +set _OUTFILE=%temp%\azbridge-tests-%_TESTNAME%.output.txt +docker run -v %_MOUNTPATH%:/tests -e AZBRIDGE_TEST_CXNSTRING="%_CXNSTRING%" --rm %IMAGE_NAME%:latest bash /tests/%_TESTNAME%.sh > %_OUTFILE% +if exist %_MOUNTPATH%\%_TESTNAME%.reference.txt ( + fc /L %_MOUNTPATH%\%_TESTNAME%.reference.txt %_OUTFILE% > NUL + if ERRORLEVEL 1 ( + set _RESULT=%ERRORLEVEL% + type %_OUTFILE% + echo Error %_RESULT% + ) + if ERRORLEVEL 0 ( + set _RESULT=0 + echo OK + ) + del %_OUTFILE% +) else ( + copy /Y %_OUTFILE% %_MOUNTPATH%\%_TESTNAME%.reference.txt > NUL + set _RESULT=%ERRORLEVEL% +) exit /b %_RESULT% \ No newline at end of file diff --git a/test/docker/centos/Dockerfile b/test/docker/centos/Dockerfile index e750477..6b4554b 100644 --- a/test/docker/centos/Dockerfile +++ b/test/docker/centos/Dockerfile @@ -1,12 +1,12 @@ -FROM centos AS build -ARG rpm_package -WORKDIR /tmp -COPY ./tmp/$rpm_package . -USER root -# temporary workaround for RPM packaging issue -RUN sed -i '/tsflags=nodocs/d' /etc/yum.conf -RUN yum update -y -RUN useradd -ms /bin/bash azbridge -RUN yum install -y $rpm_package -RUN yum install -y nc findutils +FROM centos AS build +ARG rpm_package +WORKDIR /tmp +COPY ./tmp/$rpm_package . +USER root +# temporary workaround for RPM packaging issue +RUN sed -i '/tsflags=nodocs/d' /etc/yum.conf +RUN yum update -y +RUN useradd -ms /bin/bash azbridge +RUN yum install -y $rpm_package +RUN yum install -y nc findutils USER azbridge \ No newline at end of file diff --git a/test/docker/centos/Test.proj b/test/docker/centos/Test.proj index 4b2e9e7..a6824ba 100644 --- a/test/docker/centos/Test.proj +++ b/test/docker/centos/Test.proj @@ -1,19 +1,19 @@ - - - - None - - - - - - - - - - - - - - + + + + None + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/docker/centos/build.cmd b/test/docker/centos/build.cmd index f1ba12b..99715e7 100644 --- a/test/docker/centos/build.cmd +++ b/test/docker/centos/build.cmd @@ -1,19 +1,19 @@ -@echo off - -if not "%1" == "" set BuildNumber=%1 -if not "%2" == "" set VersionPrefix=%2 -if not "%3" == "" set VersionSuffix=%3 -if not "%4" == "" set TargetFramework=%4 - -if "%BuildNumber%"=="" set BuildNumber=0000 -if "%VersionSuffix%"=="" set VersionSuffix=preview -if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 -if "%TargetFramework%"=="" set TargetFramework=netcoreapp2.1 - -pushd "%~dp0" -if not exist "tmp" mkdir tmp -set RpmFile=azbridge.%VersionPrefix%-%VersionSuffix%.centos-x64.rpm -copy /y ..\..\..\artifacts\build\%TargetFramework%\%RpmFile% tmp > NUL -docker build -f Dockerfile . --tag azbridge_centos_test --build-arg rpm_package=%RpmFile% -rd /s /q tmp +@echo off + +if not "%1" == "" set BuildNumber=%1 +if not "%2" == "" set VersionPrefix=%2 +if not "%3" == "" set VersionSuffix=%3 +if not "%4" == "" set TargetFramework=%4 + +if "%BuildNumber%"=="" set BuildNumber=0000 +if "%VersionSuffix%"=="" set VersionSuffix=preview +if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 +if "%TargetFramework%"=="" set TargetFramework=netcoreapp3.0 + +pushd "%~dp0" +if not exist "tmp" mkdir tmp +set RpmFile=azbridge.%VersionPrefix%-%VersionSuffix%.centos-x64.rpm +copy /y ..\..\..\artifacts\build\%TargetFramework%\%RpmFile% tmp > NUL +docker build -f Dockerfile . --tag azbridge_centos_test --build-arg rpm_package=%RpmFile% +rd /s /q tmp popd \ No newline at end of file diff --git a/test/docker/centos/build.sh b/test/docker/centos/build.sh index 63fa205..f0c2a11 100755 --- a/test/docker/centos/build.sh +++ b/test/docker/centos/build.sh @@ -9,7 +9,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null if [ ! -d "tmp" ]; then mkdir tmp; fi diff --git a/test/docker/centos/clean.cmd b/test/docker/centos/clean.cmd index d583923..17eb601 100644 --- a/test/docker/centos/clean.cmd +++ b/test/docker/centos/clean.cmd @@ -1,3 +1,3 @@ -@echo off -set IMAGE_NAME=azbridge_centos_test +@echo off +set IMAGE_NAME=azbridge_centos_test call ../_scripts/removeimage.cmd \ No newline at end of file diff --git a/test/docker/centos/test.cmd b/test/docker/centos/test.cmd index 4703a8e..a4fa844 100644 --- a/test/docker/centos/test.cmd +++ b/test/docker/centos/test.cmd @@ -1,7 +1,7 @@ -@echo off - -pushd "%~dp0" -SET IMAGE_NAME=azbridge_centos_test -call ../_scripts/imagetests.cmd %* -popd -exit /b %ERRORLEVEL% +@echo off + +pushd "%~dp0" +SET IMAGE_NAME=azbridge_centos_test +call ../_scripts/imagetests.cmd %* +popd +exit /b %ERRORLEVEL% diff --git a/test/docker/centos/test.sh b/test/docker/centos/test.sh index 37db6a8..312b1be 100755 --- a/test/docker/centos/test.sh +++ b/test/docker/centos/test.sh @@ -9,7 +9,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null IMAGE_NAME=azbridge_centos_test diff --git a/test/docker/debian/Dockerfile b/test/docker/debian/Dockerfile index 6ebc702..fb0d060 100644 --- a/test/docker/debian/Dockerfile +++ b/test/docker/debian/Dockerfile @@ -1,14 +1,14 @@ -FROM debian:jessie AS build -ARG deb_package -WORKDIR /tmp -COPY ./tmp/$deb_package . -USER root -# temporary workaround for RPM packaging issue -# RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf -RUN apt-get update -y -#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 -RUN useradd -ms /bin/bash azbridge -#RUN rpm -i $deb_package -RUN apt-get install -y netcat-openbsd findutils gdebi-core -RUN gdebi -n $deb_package +FROM debian:jessie AS build +ARG deb_package +WORKDIR /tmp +COPY ./tmp/$deb_package . +USER root +# temporary workaround for RPM packaging issue +# RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf +RUN apt-get update -y +#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 +RUN useradd -ms /bin/bash azbridge +#RUN rpm -i $deb_package +RUN apt-get install -y netcat-openbsd findutils gdebi-core +RUN gdebi -n $deb_package USER azbridge \ No newline at end of file diff --git a/test/docker/debian/Test.proj b/test/docker/debian/Test.proj index 66f983d..3536317 100644 --- a/test/docker/debian/Test.proj +++ b/test/docker/debian/Test.proj @@ -1,19 +1,19 @@ - - - - None - - - - - - - - - - - - - - + + + + None + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/docker/debian/build.cmd b/test/docker/debian/build.cmd index 643de13..0185c54 100644 --- a/test/docker/debian/build.cmd +++ b/test/docker/debian/build.cmd @@ -1,20 +1,20 @@ -@echo off - -if not "%1" == "" set BuildNumber=%1 -if not "%2" == "" set VersionPrefix=%2 -if not "%3" == "" set VersionSuffix=%3 -if not "%4" == "" set TargetFramework=%4 - -if "%BuildNumber%"=="" set BuildNumber=0000 -if "%VersionSuffix%"=="" set VersionSuffix=preview -if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 -if "%TargetFramework%"=="" set TargetFramework="netcoreapp2.1" - -pushd "%~dp0" -if not exist "tmp" mkdir tmp -set DebFile=azbridge.%VersionPrefix%-%VersionSuffix%.debian.8-x64.deb -copy /y ..\..\..\artifacts\build\%TargetFramework%\%DebFile% tmp > NUL -docker build -f Dockerfile . --tag azbridge_debian8_test --build-arg deb_package=%DebFile% -rd /s /q tmp - +@echo off + +if not "%1" == "" set BuildNumber=%1 +if not "%2" == "" set VersionPrefix=%2 +if not "%3" == "" set VersionSuffix=%3 +if not "%4" == "" set TargetFramework=%4 + +if "%BuildNumber%"=="" set BuildNumber=0000 +if "%VersionSuffix%"=="" set VersionSuffix=preview +if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 +if "%TargetFramework%"=="" set TargetFramework="netcoreapp3.0" + +pushd "%~dp0" +if not exist "tmp" mkdir tmp +set DebFile=azbridge.%VersionPrefix%-%VersionSuffix%.debian.8-x64.deb +copy /y ..\..\..\artifacts\build\%TargetFramework%\%DebFile% tmp > NUL +docker build -f Dockerfile . --tag azbridge_debian8_test --build-arg deb_package=%DebFile% +rd /s /q tmp + popd \ No newline at end of file diff --git a/test/docker/debian/build.sh b/test/docker/debian/build.sh index 23242fa..1e74896 100755 --- a/test/docker/debian/build.sh +++ b/test/docker/debian/build.sh @@ -8,7 +8,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null if [ ! -d "tmp" ]; then mkdir tmp; fi diff --git a/test/docker/debian/clean.cmd b/test/docker/debian/clean.cmd index 73e464b..36bbf2f 100644 --- a/test/docker/debian/clean.cmd +++ b/test/docker/debian/clean.cmd @@ -1,3 +1,3 @@ -@echo off -set IMAGE_NAME=azbridge_debian8_test +@echo off +set IMAGE_NAME=azbridge_debian8_test call ../_scripts/removeimage.cmd \ No newline at end of file diff --git a/test/docker/debian/test.cmd b/test/docker/debian/test.cmd index 1104a13..19ef05c 100644 --- a/test/docker/debian/test.cmd +++ b/test/docker/debian/test.cmd @@ -1,7 +1,7 @@ -@echo off - -pushd "%~dp0" -SET IMAGE_NAME=azbridge_debian8_test -call ../_scripts/imagetests.cmd %* -popd -exit /b %ERRORLEVEL% +@echo off + +pushd "%~dp0" +SET IMAGE_NAME=azbridge_debian8_test +call ../_scripts/imagetests.cmd %* +popd +exit /b %ERRORLEVEL% diff --git a/test/docker/debian/test.sh b/test/docker/debian/test.sh index 62ca725..b5497f7 100755 --- a/test/docker/debian/test.sh +++ b/test/docker/debian/test.sh @@ -9,7 +9,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null IMAGE_NAME=azbridge_debian8_test diff --git a/test/docker/fedora/Dockerfile b/test/docker/fedora/Dockerfile index 9c1de56..44e1f00 100644 --- a/test/docker/fedora/Dockerfile +++ b/test/docker/fedora/Dockerfile @@ -1,14 +1,14 @@ -FROM fedora AS build -ARG rpm_package -WORKDIR /tmp -COPY ./tmp/$rpm_package . -USER root -# temporary workaround for RPM packaging issue -RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf -RUN yum update -y -#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 -RUN useradd -ms /bin/bash azbridge -#RUN rpm -i $rpm_package -RUN yum install -y $rpm_package -RUN yum install -y nc findutils +FROM fedora AS build +ARG rpm_package +WORKDIR /tmp +COPY ./tmp/$rpm_package . +USER root +# temporary workaround for RPM packaging issue +RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf +RUN yum update -y +#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 +RUN useradd -ms /bin/bash azbridge +#RUN rpm -i $rpm_package +RUN yum install -y $rpm_package +RUN yum install -y nc findutils USER azbridge \ No newline at end of file diff --git a/test/docker/fedora/Test.proj b/test/docker/fedora/Test.proj index 4b2e9e7..a6824ba 100644 --- a/test/docker/fedora/Test.proj +++ b/test/docker/fedora/Test.proj @@ -1,19 +1,19 @@ - - - - None - - - - - - - - - - - - - - + + + + None + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/docker/fedora/build.cmd b/test/docker/fedora/build.cmd index 0caac6d..4e9b834 100644 --- a/test/docker/fedora/build.cmd +++ b/test/docker/fedora/build.cmd @@ -1,19 +1,19 @@ -@echo off - -if not "%1" == "" set BuildNumber=%1 -if not "%2" == "" set VersionPrefix=%2 -if not "%3" == "" set VersionSuffix=%3 -if not "%4" == "" set TargetFramework=%4 - -if "%BuildNumber%"=="" set BuildNumber=0000 -if "%VersionSuffix%"=="" set VersionSuffix=preview -if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 -if "%TargetFramework%"=="" set TargetFramework="netcoreapp2.1" - -pushd "%~dp0" -if not exist "tmp" mkdir tmp -set RpmFile=azbridge.%VersionPrefix%-%VersionSuffix%.fedora-x64.rpm -copy /y ..\..\..\artifacts\build\%TargetFramework%\%RpmFile% tmp > NUL -docker build -f Dockerfile . --tag azbridge_fedora_test --build-arg rpm_package=%RpmFile% -rd /s /q tmp +@echo off + +if not "%1" == "" set BuildNumber=%1 +if not "%2" == "" set VersionPrefix=%2 +if not "%3" == "" set VersionSuffix=%3 +if not "%4" == "" set TargetFramework=%4 + +if "%BuildNumber%"=="" set BuildNumber=0000 +if "%VersionSuffix%"=="" set VersionSuffix=preview +if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 +if "%TargetFramework%"=="" set TargetFramework="netcoreapp3.0" + +pushd "%~dp0" +if not exist "tmp" mkdir tmp +set RpmFile=azbridge.%VersionPrefix%-%VersionSuffix%.fedora-x64.rpm +copy /y ..\..\..\artifacts\build\%TargetFramework%\%RpmFile% tmp > NUL +docker build -f Dockerfile . --tag azbridge_fedora_test --build-arg rpm_package=%RpmFile% +rd /s /q tmp popd \ No newline at end of file diff --git a/test/docker/fedora/build.sh b/test/docker/fedora/build.sh index 4c7d7dc..1955ada 100755 --- a/test/docker/fedora/build.sh +++ b/test/docker/fedora/build.sh @@ -8,7 +8,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null if [ ! -d "tmp" ]; then mkdir tmp; fi diff --git a/test/docker/fedora/clean.cmd b/test/docker/fedora/clean.cmd index 227ac22..3b3e959 100644 --- a/test/docker/fedora/clean.cmd +++ b/test/docker/fedora/clean.cmd @@ -1,3 +1,3 @@ -@echo off -set IMAGE_NAME=azbridge_fedora_test +@echo off +set IMAGE_NAME=azbridge_fedora_test call ../_scripts/removeimage.cmd \ No newline at end of file diff --git a/test/docker/fedora/test.cmd b/test/docker/fedora/test.cmd index ce4cc96..9979465 100644 --- a/test/docker/fedora/test.cmd +++ b/test/docker/fedora/test.cmd @@ -1,7 +1,7 @@ -@echo off - -pushd "%~dp0" -SET IMAGE_NAME=azbridge_fedora_test -call ../_scripts/imagetests.cmd %* -popd -exit /b %ERRORLEVEL% +@echo off + +pushd "%~dp0" +SET IMAGE_NAME=azbridge_fedora_test +call ../_scripts/imagetests.cmd %* +popd +exit /b %ERRORLEVEL% diff --git a/test/docker/fedora/test.sh b/test/docker/fedora/test.sh index 58a7d6e..c006d54 100755 --- a/test/docker/fedora/test.sh +++ b/test/docker/fedora/test.sh @@ -9,7 +9,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null diff --git a/test/docker/test_nc_config_ping_pong.local.yml b/test/docker/test_nc_config_ping_pong.local.yml index a0ce6a6..d09a141 100644 --- a/test/docker/test_nc_config_ping_pong.local.yml +++ b/test/docker/test_nc_config_ping_pong.local.yml @@ -1,6 +1,6 @@ -LocalForward: - - RelayName: a1 - BindAddress: 127.0.8.1 - BindPort: 8888 - PortName: test - +LocalForward: + - RelayName: a1 + BindAddress: 127.0.8.1 + BindPort: 8888 + PortName: test + diff --git a/test/docker/test_nc_config_ping_pong.remote.yml b/test/docker/test_nc_config_ping_pong.remote.yml index f013fce..c376d95 100644 --- a/test/docker/test_nc_config_ping_pong.remote.yml +++ b/test/docker/test_nc_config_ping_pong.remote.yml @@ -1,5 +1,5 @@ -RemoteForward: - - RelayName: a1 - HostPort: 9999 - Host: localhost - PortName: test +RemoteForward: + - RelayName: a1 + HostPort: 9999 + Host: localhost + PortName: test diff --git a/test/docker/ubuntu/Dockerfile b/test/docker/ubuntu/Dockerfile index 700a615..8e884bb 100644 --- a/test/docker/ubuntu/Dockerfile +++ b/test/docker/ubuntu/Dockerfile @@ -1,14 +1,14 @@ -FROM ubuntu:xenial AS build -ARG deb_package -WORKDIR /tmp -COPY ./tmp/$deb_package . -USER root -# temporary workaround for RPM packaging issue -# RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf -RUN apt-get update -y -#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 -RUN useradd -ms /bin/bash azbridge -#RUN rpm -i $deb_package -RUN apt-get install -y netcat-openbsd findutils gdebi-core -RUN gdebi -n $deb_package +FROM ubuntu:xenial AS build +ARG deb_package +WORKDIR /tmp +COPY ./tmp/$deb_package . +USER root +# temporary workaround for RPM packaging issue +# RUN sed -i '/tsflags=nodocs/d' /etc/dnf/dnf.conf +RUN apt-get update -y +#RUN yum install -y nc libstdc++ libunwind libicu compat-openssl10 +RUN useradd -ms /bin/bash azbridge +#RUN rpm -i $deb_package +RUN apt-get install -y netcat-openbsd findutils gdebi-core +RUN gdebi -n $deb_package USER azbridge \ No newline at end of file diff --git a/test/docker/ubuntu/Test.proj b/test/docker/ubuntu/Test.proj index 66f983d..3536317 100644 --- a/test/docker/ubuntu/Test.proj +++ b/test/docker/ubuntu/Test.proj @@ -1,19 +1,19 @@ - - - - None - - - - - - - - - - - - - - + + + + None + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/docker/ubuntu/build.cmd b/test/docker/ubuntu/build.cmd index 526e177..c6d6eb6 100644 --- a/test/docker/ubuntu/build.cmd +++ b/test/docker/ubuntu/build.cmd @@ -1,20 +1,20 @@ -@echo off - -if not "%1" == "" set BuildNumber=%1 -if not "%2" == "" set VersionPrefix=%2 -if not "%3" == "" set VersionSuffix=%3 -if not "%4" == "" set TargetFramework=%4 - -if "%BuildNumber%"=="" set BuildNumber=0000 -if "%VersionSuffix%"=="" set VersionSuffix=preview -if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 -if "%TargetFramework%"=="" set TargetFramework="netcoreapp2.1" - -pushd "%~dp0" -if not exist "tmp" mkdir tmp -set DebFile=azbridge.%VersionPrefix%-%VersionSuffix%.ubuntu.16.04-x64.deb -copy /y ..\..\..\artifacts\build\%TargetFramework%\%DebFile% tmp > NUL -docker build -f Dockerfile . --tag azbridge_ubuntu1604_test --build-arg deb_package=%DebFile% -rd /s /q tmp - +@echo off + +if not "%1" == "" set BuildNumber=%1 +if not "%2" == "" set VersionPrefix=%2 +if not "%3" == "" set VersionSuffix=%3 +if not "%4" == "" set TargetFramework=%4 + +if "%BuildNumber%"=="" set BuildNumber=0000 +if "%VersionSuffix%"=="" set VersionSuffix=preview +if "%VersionPrefix%"=="" set VersionPrefix=1.0.0 +if "%TargetFramework%"=="" set TargetFramework="netcoreapp3.0" + +pushd "%~dp0" +if not exist "tmp" mkdir tmp +set DebFile=azbridge.%VersionPrefix%-%VersionSuffix%.ubuntu.16.04-x64.deb +copy /y ..\..\..\artifacts\build\%TargetFramework%\%DebFile% tmp > NUL +docker build -f Dockerfile . --tag azbridge_ubuntu1604_test --build-arg deb_package=%DebFile% +rd /s /q tmp + popd \ No newline at end of file diff --git a/test/docker/ubuntu/build.sh b/test/docker/ubuntu/build.sh index 3d9e8b2..552e54b 100755 --- a/test/docker/ubuntu/build.sh +++ b/test/docker/ubuntu/build.sh @@ -8,7 +8,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null if [ ! -d "tmp" ]; then mkdir tmp; fi diff --git a/test/docker/ubuntu/clean.cmd b/test/docker/ubuntu/clean.cmd index cef0709..d8476bf 100644 --- a/test/docker/ubuntu/clean.cmd +++ b/test/docker/ubuntu/clean.cmd @@ -1,3 +1,3 @@ -@echo off -set IMAGE_NAME=azbridge_ubuntu1604_test +@echo off +set IMAGE_NAME=azbridge_ubuntu1604_test call ../_scripts/removeimage.cmd \ No newline at end of file diff --git a/test/docker/ubuntu/test.cmd b/test/docker/ubuntu/test.cmd index 0244e8f..fae0520 100644 --- a/test/docker/ubuntu/test.cmd +++ b/test/docker/ubuntu/test.cmd @@ -1,7 +1,7 @@ -@echo off - -pushd "%~dp0" -SET IMAGE_NAME=azbridge_ubuntu1604_test -call ../_scripts/imagetests.cmd %* -popd -exit /b %ERRORLEVEL% +@echo off + +pushd "%~dp0" +SET IMAGE_NAME=azbridge_ubuntu1604_test +call ../_scripts/imagetests.cmd %* +popd +exit /b %ERRORLEVEL% diff --git a/test/docker/ubuntu/test.sh b/test/docker/ubuntu/test.sh index ba68cb7..1c27136 100755 --- a/test/docker/ubuntu/test.sh +++ b/test/docker/ubuntu/test.sh @@ -9,7 +9,7 @@ if [ ! -z $4 ]; then TargetFramework=$4; fi if [ -z ${BuildNumber+x} ]; then BuildNumber='0000'; fi if [ -z ${VersionSuffix+x} ]; then VersionSuffix='preview'; fi if [ -z ${VersionPrefix+x} ]; then VersionPrefix='1.0.0'; fi -if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp2.1'; fi +if [ -z ${TargetFramework+x} ]; then TargetFramework='netcoreapp3.0'; fi pushd "${0%/*}" > /dev/null diff --git a/test/unit/Directory.Build.props b/test/unit/Directory.Build.props index da1c4b4..405c163 100644 --- a/test/unit/Directory.Build.props +++ b/test/unit/Directory.Build.props @@ -1,16 +1,16 @@ - - - - - netcoreapp2.1 - $(DeveloperBuildTestTfms) - $(StandardTestTfms) - $(StandardTestTfms);net461 - - - - - - - - + + + + + netcoreapp3.0 + $(DeveloperBuildTestTfms) + $(StandardTestTfms) + $(StandardTestTfms);net461 + + + + + + + + diff --git a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Directory.Build.props b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Directory.Build.props index 05002e1..75d4443 100644 --- a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Directory.Build.props +++ b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Directory.Build.props @@ -1,3 +1,3 @@ - - - + + + diff --git a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Microsoft.Azure.Relay.Bridge.Tests.csproj b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Microsoft.Azure.Relay.Bridge.Tests.csproj index 7230161..1ca6ad2 100644 --- a/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Microsoft.Azure.Relay.Bridge.Tests.csproj +++ b/test/unit/Microsoft.Azure.Relay.Bridge.Tests/Microsoft.Azure.Relay.Bridge.Tests.csproj @@ -3,7 +3,7 @@ false net462; - netcoreapp2.1 + netcoreapp3.0 $(WindowsFrameworks)$(CoreFrameworks) win7-x64;win7-x86;win10-x64;win10-x86; diff --git a/test/unit/Test.proj b/test/unit/Test.proj index 6aaf451..eb2e6b7 100644 --- a/test/unit/Test.proj +++ b/test/unit/Test.proj @@ -1,12 +1,12 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/verify-build.cmd b/verify-build.cmd index 969dda9..049b725 100644 --- a/verify-build.cmd +++ b/verify-build.cmd @@ -1,10 +1,10 @@ -pushd "%~dp0" - -set xunitrunner=%userprofile%\.nuget\packages\dotnet-xunit\2.3.1\tools\net452\xunit.console.exe -%xunitrunner% -? 2>&1 > NUL -if ERRORLEVEL 1 set xunitrunner=C:\Tools\xUnit20\xunit.console.exe -"%xunitrunner%" "test\unit\Microsoft.Azure.Relay.Bridge.Tests\bin\Debug\net462\Microsoft.Azure.Relay.Bridge.Tests.dll" -appveyor - -rem cd test\docker -rem msbuild /t:clean,build,vstest -popd +pushd "%~dp0" + +set xunitrunner=%userprofile%\.nuget\packages\dotnet-xunit\2.3.1\tools\net452\xunit.console.exe +%xunitrunner% -? 2>&1 > NUL +if ERRORLEVEL 1 set xunitrunner=C:\Tools\xUnit20\xunit.console.exe +"%xunitrunner%" "test\unit\Microsoft.Azure.Relay.Bridge.Tests\bin\Debug\net462\Microsoft.Azure.Relay.Bridge.Tests.dll" -appveyor + +rem cd test\docker +rem msbuild /t:clean,build,vstest +popd diff --git a/verify-build.sh b/verify-build.sh index 6216dc0..0055190 100755 --- a/verify-build.sh +++ b/verify-build.sh @@ -5,6 +5,6 @@ if [ ! -z $APPVEYOR_BUILD_VERSION ]; then _VersionProp="/p:VersionPrefix=$APPVEY dotnet test --verbosity=normal cd test/docker -dotnet clean --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp2.1 $_BuildProp $_VersionProp $@ -dotnet build --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp2.1 $_BuildProp $_VersionProp $@ -dotnet test --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp2.1 $_BuildProp $_VersionProp $@ +dotnet clean --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp3.0 $_BuildProp $_VersionProp $@ +dotnet build --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp3.0 $_BuildProp $_VersionProp $@ +dotnet test --verbosity=normal /p:Configuration=Debug /p:TargetFramework=netcoreapp3.0 $_BuildProp $_VersionProp $@ diff --git a/version.props b/version.props index d152bb7..aeb1ae7 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - - - 0.1.1 - - preview - - + + + 0.1.1 + + preview + +