public async Task Configure()

in smoke/IotEdgeQuickstart/details/IotedgedLinux.cs [349:555]


        public async Task Configure(
            DeviceProvisioningMethod method,
            Option<string> agentImage,
            string hostname,
            Option<string> parentHostname,
            string deviceCaCert,
            string deviceCaPk,
            string deviceCaCerts,
            LogLevel runtimeLogLevel)
        {
            agentImage.ForEach(
                image =>
                {
                    Console.WriteLine($"Setting up aziot-edged with agent image {image}");
                },
                () =>
                {
                    Console.WriteLine("Setting up aziot-edged with agent image 1.0");
                });

            // Initialize each service's config file.
            Dictionary<string, Config> config = new Dictionary<string, Config>();
            config.Add(KEYD, await InitConfig(KEYD + ".default", "aziotks"));
            config.Add(CERTD, await InitConfig(CERTD + ".default", "aziotcs"));
            config.Add(IDENTITYD, await InitConfig(IDENTITYD + ".default", "aziotid"));
            config.Add(EDGED, await InitConfig(EDGED + ".default", "iotedge"));

            // Directory for storing keys; create it if it doesn't exist.
            string keyDir = "/var/secrets/aziot/keyd/";
            Directory.CreateDirectory(keyDir);
            SetOwner(keyDir, config[KEYD].Owner, "700");

            // Need to always reprovision so previous test runs don't affect this one.
            config[EDGED].Document.ReplaceOrAdd("auto_reprovisioning_mode", "AlwaysOnStartup");
            config[IDENTITYD].Document.RemoveIfExists("provisioning");
            parentHostname.ForEach(
                parent_hostame =>
                config[IDENTITYD].Document.ReplaceOrAdd("provisioning.local_gateway_hostname", parent_hostame));

            method.ManualConnectionString.Match(
                cs =>
                {
                    string keyPath = Path.Combine(keyDir, "device-id");
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.source", "manual");
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.authentication.method", "sas");
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.authentication.device_id_pk", "device-id");
                    config[KEYD].Document.ReplaceOrAdd("preloaded_keys.device-id", $"file://{keyPath}");

                    string[] segments = cs.Split(";");

                    foreach (string s in segments)
                    {
                        string[] param = s.Split("=", 2);

                        switch (param[0])
                        {
                            case "HostName":
                                // replace IoTHub hostname with parent hostname for nested edge
                                config[IDENTITYD].Document.ReplaceOrAdd("provisioning.iothub_hostname", param[1]);
                                break;
                            case "SharedAccessKey":
                                File.WriteAllBytes(keyPath, Convert.FromBase64String(param[1]));
                                SetOwner(keyPath, config[KEYD].Owner, "600");
                                break;
                            case "DeviceId":
                                config[IDENTITYD].Document.ReplaceOrAdd("provisioning.device_id", param[1]);
                                break;
                            default:
                                break;
                        }
                    }

                    this.SetAuth("device-id", config);

                    return string.Empty;
                },
                () =>
                {
                    config[IDENTITYD].Document.RemoveIfExists("provisioning");
                    return string.Empty;
                });

            method.Dps.ForEach(
                dps =>
                {
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.source", "dps");
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.global_endpoint", dps.EndPoint);
                    config[IDENTITYD].Document.ReplaceOrAdd("provisioning.scope_id", dps.ScopeId);
                    switch (dps.AttestationType)
                    {
                        case DPSAttestationType.SymmetricKey:
                            string dpsKeyPath = Path.Combine(keyDir, "device-id");
                            string dpsKey = dps.SymmetricKey.Expect(() => new ArgumentException("Expected symmetric key"));

                            File.WriteAllBytes(dpsKeyPath, Convert.FromBase64String(dpsKey));
                            SetOwner(dpsKeyPath, config[KEYD].Owner, "600");

                            config[KEYD].Document.ReplaceOrAdd("preloaded_keys.device-id", new Uri(dpsKeyPath).AbsoluteUri);
                            config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.method", "symmetric_key");
                            config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.symmetric_key", "device-id");

                            this.SetAuth("device-id", config);

                            break;
                        case DPSAttestationType.X509:
                            string certPath = dps.DeviceIdentityCertificate.Expect(() => new ArgumentException("Expected path to identity certificate"));
                            string keyPath = dps.DeviceIdentityPrivateKey.Expect(() => new ArgumentException("Expected path to identity private key"));

                            SetOwner(certPath, config[CERTD].Owner, "444");
                            SetOwner(keyPath, config[KEYD].Owner, "400");

                            config[CERTD].Document.ReplaceOrAdd("preloaded_certs.device-id", new Uri(certPath).AbsoluteUri);
                            config[KEYD].Document.ReplaceOrAdd("preloaded_keys.device-id", new Uri(keyPath).AbsoluteUri);

                            config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.method", "x509");
                            config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.identity_cert", "device-id");
                            config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.identity_pk", "device-id");

                            this.SetAuth("device-id", config);

                            break;
                        default:
                            break;
                    }

                    dps.RegistrationId.ForEach(id => { config[IDENTITYD].Document.ReplaceOrAdd("provisioning.attestation.registration_id", id); });
                });

            agentImage.ForEach(image =>
            {
                config[EDGED].Document.ReplaceOrAdd("agent.config.image", image);
            });

            config[EDGED].Document.ReplaceOrAdd("hostname", hostname);
            config[IDENTITYD].Document.ReplaceOrAdd("hostname", hostname);

            parentHostname.ForEach(v => config[EDGED].Document.ReplaceOrAdd("parent_hostname", v));

            foreach (RegistryCredentials c in this.credentials)
            {
                config[EDGED].Document.ReplaceOrAdd("agent.config.auth.serveraddress", c.Address);
                config[EDGED].Document.ReplaceOrAdd("agent.config.auth.username", c.User);
                config[EDGED].Document.ReplaceOrAdd("agent.config.auth.password", c.Password);
            }

            config[EDGED].Document.ReplaceOrAdd("agent.env.RuntimeLogLevel", runtimeLogLevel.ToString());

            if (this.httpUris.HasValue)
            {
                HttpUris uris = this.httpUris.OrDefault();
                config[EDGED].Document.ReplaceOrAdd("connect.management_uri", uris.ConnectManagement);
                config[EDGED].Document.ReplaceOrAdd("connect.workload_uri", uris.ConnectWorkload);
                config[EDGED].Document.ReplaceOrAdd("listen.management_uri", uris.ListenManagement);
                config[EDGED].Document.ReplaceOrAdd("listen.workload_uri", uris.ListenWorkload);
            }
            else
            {
                UriSocks socks = this.uriSocks;
                config[EDGED].Document.ReplaceOrAdd("connect.management_uri", socks.ConnectManagement);
                config[EDGED].Document.ReplaceOrAdd("connect.workload_uri", socks.ConnectWorkload);
                config[EDGED].Document.ReplaceOrAdd("listen.management_uri", socks.ListenManagement);
                config[EDGED].Document.ReplaceOrAdd("listen.workload_uri", socks.ListenWorkload);
            }

            foreach (string file in new string[] { deviceCaCert, deviceCaPk, deviceCaCerts })
            {
                if (string.IsNullOrEmpty(file))
                {
                    throw new ArgumentException("device_ca_cert, device_ca_pk, and trusted_ca_certs must all be provided.");
                }

                if (!File.Exists(file))
                {
                    throw new ArgumentException($"{file} does not exist.");
                }
            }

            // Files must be readable by KS and CS users.
            SetOwner(deviceCaCerts, config[CERTD].Owner, "444");
            SetOwner(deviceCaCert, config[CERTD].Owner, "444");
            SetOwner(deviceCaPk, config[KEYD].Owner, "400");

            config[CERTD].Document.ReplaceOrAdd("preloaded_certs.aziot-edged-trust-bundle", new Uri(deviceCaCerts).AbsoluteUri);
            config[CERTD].Document.ReplaceOrAdd("preloaded_certs.aziot-edged-ca", new Uri(deviceCaCert).AbsoluteUri);
            config[KEYD].Document.ReplaceOrAdd("preloaded_keys.aziot-edged-ca", new Uri(deviceCaPk).AbsoluteUri);

            this.proxy.ForEach(proxy => config[EDGED].Document.ReplaceOrAdd("agent.env.https_proxy", proxy));

            this.upstreamProtocol.ForEach(upstreamProtocol => config[EDGED].Document.ReplaceOrAdd("agent.env.UpstreamProtocol", upstreamProtocol.ToString()));

            foreach (KeyValuePair<string, Config> service in config)
            {
                string path = service.Key;
                string text = service.Value.Document.ToString();

                await File.WriteAllTextAsync(path, text);
                SetOwner(path, service.Value.Owner, "644");
                Console.WriteLine($"Created config {path}");
            }

            using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2)))
            {
                Console.WriteLine($"Calling iotedge system set-log-level {runtimeLogLevel.ToString().ToLower()}");
                string[] output = await Process.RunAsync("iotedge", $"system set-log-level {runtimeLogLevel.ToString().ToLower()}", cts.Token);
                Console.WriteLine($"{output.ToString()}");
            }
        }