Example #1
0
        static async Task <int> Main(string[] args)
        {
            var watch = Stopwatch.StartNew();

            string[] parsedArgs = args.TakeWhile(a => a != "--").ToArray();
            string   usage      = @"Usage: rescaler [-simulate] [-verbose] <edition> <size> [+includedb1] [-excludedb1] [+includedb2] [-excludedb2] ...

simulate:      Dry run
verbose:       Verbose logging
edition:       Basic/Standard/Premium
size:          Basic/S0.../P1...
includedb...:  Substring to contain (name of: resource group, server, database)

Specify credentials using a service principal by setting the environment variables:
AzureTenantId
AzureClientId
AzureClientSecret

Multiple service principals can be specified by prefixing/postfixing the environment variables.";

            bool simulate = parsedArgs.Contains("-simulate");

            parsedArgs = parsedArgs.Where(a => a != "-simulate").ToArray();

            bool verbose = parsedArgs.Contains("-verbose");

            parsedArgs = parsedArgs.Where(a => a != "-verbose").ToArray();

            if (parsedArgs.Length < 2)
            {
                Log(usage);
                return(1);
            }

            string[] filterdbs = parsedArgs.Skip(2).ToArray();
            parsedArgs = parsedArgs.Take(2).ToArray();

            if (filterdbs.Length == 0)
            {
                Log($"At least 1 Include/Exclude filter must be specified.");
                Log(usage);
                return(1);
            }

            var invalidfilters = filterdbs.Where(db => !db.StartsWith('+') && !db.StartsWith('-')).ToArray();

            if (invalidfilters.Length > 0)
            {
                foreach (var filter in invalidfilters)
                {
                    Log($"Include/Exclude filters must be prefixed with + or -: '{filter}'");
                }
                Log(usage);
                return(1);
            }

            if (parsedArgs.Length != 2)
            {
                Log(usage);
                return(1);
            }

            string dbedition = parsedArgs[0];
            string dbsize    = parsedArgs[1];


            var servicePrincipals = GetServicePrincipals();

            if (servicePrincipals.Length == 0)
            {
                Log("Missing environment variables: AzureTenantId, AzureClientId, AzureClientSecret");
                return(1);
            }

            Log($"Got {servicePrincipals.Length} service principals: '{string.Join("', '", servicePrincipals.Select(sp => sp.FriendlyName))}'");

            await ServicePrincipal.GetAzureAccessTokensAsync(servicePrincipals);

            var accessTokens = servicePrincipals.Where(sp => sp.AccessToken != null).ToArray();

            Log($"Got {accessTokens.Length} access tokens.");
            if (accessTokens.Length == 0)
            {
                return(1);
            }


            var rescaler = new Rescaler();

            var tasks = accessTokens.Select(accessToken => rescaler.RescaleAsync(accessToken, dbedition, dbsize, filterdbs, simulate, verbose));
            await Task.WhenAll(tasks);

            Log($"Total done: {watch.Elapsed}");

            return(0);
        }