aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Azure/Tango.AzureUtils/FTP/FtpManager.cs
blob: 021426d12874d53f6e41f90d930db748c158e0f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Authentication;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using FluentFTP;
using Microsoft.Azure.Management.AppService.Fluent;
using Microsoft.Azure.Management.Fluent;

namespace Tango.AzureUtils.FTP
{
    public class FtpManager : AzureUtilsComponentBase
    {
        private IProgress<FtpProgress> _ftpDownloadProgress;
        private IProgress<FtpProgress> _ftpUploadProgress;
        private String _currentDownloadFile;

        public FtpManager(IAzure azure) : base(azure)
        {
            _ftpDownloadProgress = new Progress<FtpProgress>((p) =>
            {
                OnProgress(AzureUtilsStage.FtpDownload, $"Downloading {_currentDownloadFile}...", p.Progress, 100, false);
            });

            _ftpUploadProgress = new Progress<FtpProgress>((p) =>
            {
                OnProgress(AzureUtilsStage.FtpUpload, $"Uploading {_currentDownloadFile}...", p.Progress, 100, false);
            });
        }

        private FtpClient CreateFtpClient(String address, String userName, String password)
        {
            Uri uri = new Uri("ftp://" + address);
            string host = uri.Host;

            FtpClient client = new FtpClient(host, userName, password);
            //client.EncryptionMode = FtpEncryptionMode.Explicit;
            client.SslProtocols = SslProtocols.Tls;
            client.ValidateAnyCertificate = true;
            client.DataConnectionType = FtpDataConnectionType.PASV;
            client.DownloadDataType = FtpDataType.Binary;
            client.RetryAttempts = 5;
            client.SocketPollInterval = 1000;
            client.ConnectTimeout = 2000;
            client.ReadTimeout = 2000;
            client.DataConnectionConnectTimeout = 2000;
            client.DataConnectionReadTimeout = 2000;
            client.OnLogEvent = (ev, msg) => 
            {
                if (msg.Contains("DownloadFileAsync") || msg.Contains("UploadFileAsync"))
                {
                    var matches = Regex.Matches(msg, "(?<=\").+?(?=\")");
                    var match = matches.OfType<Match>().LastOrDefault();

                    if (match != null)
                    {
                        _currentDownloadFile = match.ToString();
                    }
                }
            };

            return client;
        }

        public async Task<List<FtpResult>> DownloadWebAppFiles(IWebAppBase app, String targetFolder)
        {
            OnProgress(AzureUtilsStage.FtpDownload, $"Downloading web app files for '{app.Name}'...");

            var profile = await app.GetPublishingProfileAsync();

            using (var ftp = CreateFtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword))
            {
                await ftp.ConnectAsync();
                var downloadResults = await ftp.DownloadDirectoryAsync(targetFolder, "/site/wwwroot", progress: _ftpDownloadProgress);

                foreach (var downloadResult in downloadResults)
                {
                    if (downloadResult.IsFailed)
                    {
                        throw downloadResult.Exception;
                    }
                }

                return downloadResults;
            }
        }

        public async Task<List<FtpResult>> UploadWebAppFiles(IWebAppBase app, String sourceFolder)
        {
            OnProgress(AzureUtilsStage.FtpUpload, $"Uploading web app files for '{app.Name}'...");

            var profile = await app.GetPublishingProfileAsync();

            using (var ftp = CreateFtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword))
            {
                var uploadResults = await ftp.UploadDirectoryAsync(sourceFolder, "/site/wwwroot", existsMode: FtpRemoteExists.Overwrite, progress: _ftpUploadProgress);

                foreach (var uploadResult in uploadResults)
                {
                    if (uploadResult.IsFailed)
                    {
                        throw uploadResult.Exception;
                    }
                }

                return uploadResults;
            }
        }

        public async Task CopyAppFiles(IWebAppBase sourceApp, IWebAppBase targetApp)
        {
            var webAppFilesTempFolder = TemporaryManager.CreateFolder();
            var downloadResults = await DownloadWebAppFiles(sourceApp, webAppFilesTempFolder);
            var uploadResults = await UploadWebAppFiles(targetApp, webAppFilesTempFolder);
        }

        public async Task<String> GetMachineServiceVersion(IWebAppBase app)
        {
            var exeTempFile = TemporaryManager.CreateImaginaryFile(".dll");

            var profile = await app.GetPublishingProfileAsync();

            using (var ftp = CreateFtpClient(profile.FtpUrl, profile.FtpUsername, profile.FtpPassword))
            {
                await ftp.ConnectAsync();
                await ftp.DownloadFileAsync(exeTempFile, "/site/wwwroot/bin/Tango.MachineService.dll");
                String version =  FileVersionInfo.GetVersionInfo(exeTempFile).ProductVersion;
                await exeTempFile.DeleteAsync();
                return version;
            }
        }
    }
}