Exemplo n.º 1
0
        public void BasicTest()
        {
            var edgeAgentModule = Mock.Of <IEdgeAgentModule>(m => m.Name == "edgeAgent");
            var edgeHubModule   = Mock.Of <IEdgeHubModule>(m => m.Name == "edgeHub");
            var systemModules   = new SystemModules(edgeAgentModule, edgeHubModule);

            var mod1 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod1"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultPriority, new ConfigurationInfo(), null);
            var mod2 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod2"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultPriority, new ConfigurationInfo(), null);

            var modules = new Dictionary <string, IModule>
            {
                ["mod1"] = mod1,
                ["mod2"] = mod2
            };

            var deploymentConfig = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules);

            Assert.Equal("mod1", deploymentConfig.Modules["mod1"].Name);
            Assert.Equal("mod2", deploymentConfig.Modules["mod2"].Name);

            ModuleSet moduleSet = deploymentConfig.GetModuleSet();

            Assert.NotNull(moduleSet);
            Assert.Equal(4, moduleSet.Modules.Count);
            Assert.Equal(edgeHubModule.Name, moduleSet.Modules["edgeHub"].Name);
            Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["edgeAgent"].Name);
            Assert.Equal(modules["mod1"].Name, moduleSet.Modules["mod1"].Name);
            Assert.Equal(modules["mod2"].Name, moduleSet.Modules["mod2"].Name);
        }
Exemplo n.º 2
0
        public async Task TestEnvVars()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = "test-env";
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("deviceKey"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(Timeout))
                {
                    await Client.CleanupContainerAsync(Name, Image);

                    string createOptions = @"{""Env"": [ ""k1=v1"", ""k2=v2""]}";
                    var    config        = new DockerConfig(Image, createOptions);
                    var    loggingConfig = new DockerLoggingConfig("json-file");
                    var    module        = new DockerModule(Name, "1.0", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy, config, null, null);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                        new Dictionary <string, string>
                    {
                        { "EdgeDeviceConnectionString", fakeConnectionString }
                    }).Build();

                    var deploymentConfigModules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, deploymentConfigModules));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    var credential = new ConnectionStringCredentials("fake");
                    var identity   = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(credential);

                    ICommand create = await CreateCommand.BuildAsync(Client, module, identity.Object, loggingConfig, configSource.Object, false);

                    await Client.PullImageAsync(Image, cts.Token);

                    // create module using command
                    await create.ExecuteAsync(cts.Token);

                    // check that the environment variables are being returned
                    RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client);

                    IEnumerable <ModuleRuntimeInfo> modules = await runtimeInfoProvider.GetModules(cts.Token);

                    var returnedModule = modules.First(m => m.Name == Name) as ModuleRuntimeInfo <DockerReportedConfig>;
                    Assert.NotNull(returnedModule);
                }
            }
            finally
            {
                await Client.CleanupContainerAsync(Name, Image);

                await Client.CleanupContainerAsync("test-filters-external", Image);
            }
        }
Exemplo n.º 3
0
        public void BasicTest(string[] signercert, string[] intermediatecacert, string signature, string algo)
        {
            var edgeAgentModule = Mock.Of <IEdgeAgentModule>(m => m.Name == "edgeAgent");
            var edgeHubModule   = Mock.Of <IEdgeHubModule>(m => m.Name == "edgeHub");
            var systemModules   = new SystemModules(edgeAgentModule, edgeHubModule);

            var mod1 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod1"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, new ConfigurationInfo(), null);
            var mod2 = new TestModule(null, string.Empty, "test", ModuleStatus.Running, new TestConfig("mod2"), RestartPolicy.Always, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, new ConfigurationInfo(), null);

            var modules = new Dictionary <string, IModule>
            {
                ["mod1"] = mod1,
                ["mod2"] = mod2
            };
            var deploymentConfig                  = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules, null);
            ManifestIntegrity integrity           = new ManifestIntegrity(new TwinHeader(signercert, intermediatecacert), new TwinSignature(signature, algo));
            var deploymentConfigWithTwinIntegrity = new DeploymentConfig("1.0", Mock.Of <IRuntimeInfo>(), systemModules, modules, integrity);

            Assert.Equal("mod1", deploymentConfig.Modules["mod1"].Name);
            Assert.Equal("mod2", deploymentConfig.Modules["mod2"].Name);

            ModuleSet moduleSet = deploymentConfig.GetModuleSet();

            Assert.NotNull(moduleSet);
            Assert.Equal(4, moduleSet.Modules.Count);
            Assert.Equal(edgeHubModule.Name, moduleSet.Modules["edgeHub"].Name);
            Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["edgeAgent"].Name);
            Assert.Equal(modules["mod1"].Name, moduleSet.Modules["mod1"].Name);
            Assert.Equal(modules["mod2"].Name, moduleSet.Modules["mod2"].Name);
            Assert.Equal(deploymentConfigWithTwinIntegrity.Integrity, Option.Some(integrity));
        }
Exemplo n.º 4
0
        private void GetProcessModules()
        {
            var modules = ProcessModel.Process.Modules;

            for (var i = 0; i < modules.Count; i++)
            {
                var module = modules[i];
                SystemModules.Add(module);
            }
        }
Exemplo n.º 5
0
        public static DeploymentConfigInfo SetupNonEmptyDeployment(string moduleName = "m1")
        {
            var runtime = Mock.Of <IRuntimeInfo>();
            var m1      = Mock.Of <IModule>();
            var modules = new Dictionary <string, IModule> {
                [moduleName] = m1
            };
            SystemModules systemMods = new SystemModules(Option.None <IEdgeAgentModule>(), Option.None <IEdgeHubModule>());

            return(new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtime, systemMods, modules)));
        }
Exemplo n.º 6
0
        public static DeploymentConfigInfo SetupNonEmptyDeployment(string moduleName = "m1")
        {
            var runtime = Mock.Of <IRuntimeInfo>();
            var m1      = Mock.Of <IModule>();
            var modules = new Dictionary <string, IModule> {
                [moduleName] = m1
            };
            SystemModules systemMods = new SystemModules(Option.None <IEdgeAgentModule>(), Option.None <IEdgeHubModule>());
            var           integrity  = new ManifestIntegrity(new TwinHeader(new string[] { "signercert1", "signercert2" }, new string[] { "intermediatecacert1", "intermediatecacert2" }), new TwinSignature("bytes", "algo"));

            return(new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtime, systemMods, modules, integrity)));
        }
Exemplo n.º 7
0
        public async void GetDeploymentConfigTest2()
        {
            // Arrange
            var    runtimeInfo       = Mock.Of <IRuntimeInfo>();
            var    edgeHubModule     = Mock.Of <IEdgeHubModule>(m => m.Name == "$edgeHub");
            var    edgeAgentModule   = Mock.Of <IEdgeAgentModule>(m => m.Name == "$edgeAgent");
            var    systemModules     = new SystemModules(edgeAgentModule, edgeHubModule);
            string customModule1Name = null;
            string customModule2Name = null;
            var    customModule1     = Mock.Of <IModule>();
            var    customModule2     = Mock.Of <IModule>();

            Mock.Get(customModule1).SetupSet(n => n.Name = It.IsAny <string>()).Callback <string>(n => customModule1Name = n);
            Mock.Get(customModule2).SetupSet(n => n.Name = It.IsAny <string>()).Callback <string>(n => customModule2Name = n);
            IDictionary <string, IModule> modules = new Dictionary <string, IModule>
            {
                ["module1"] = customModule1,
                ["module2"] = customModule2
            };
            var deploymentConfig     = new DeploymentConfig("1.0", runtimeInfo, systemModules, modules);
            var deploymentConfigInfo = new DeploymentConfigInfo(5, deploymentConfig);

            var edgeAgentConnection = new Mock <IEdgeAgentConnection>();

            edgeAgentConnection.Setup(e => e.GetDeploymentConfigInfoAsync()).ReturnsAsync(Option.Some(deploymentConfigInfo));
            var configuration    = Mock.Of <IConfiguration>();
            var twinConfigSource = new TwinConfigSource(edgeAgentConnection.Object, configuration);

            // Act
            DeploymentConfigInfo receivedDeploymentConfigInfo = await twinConfigSource.GetDeploymentConfigInfoAsync();

            // Assert
            Assert.NotNull(receivedDeploymentConfigInfo);
            Assert.NotNull(receivedDeploymentConfigInfo.DeploymentConfig);
            Assert.Equal(5, receivedDeploymentConfigInfo.Version);

            DeploymentConfig returnedDeploymentConfig = receivedDeploymentConfigInfo.DeploymentConfig;

            Assert.Equal(Option.Some(edgeAgentModule), returnedDeploymentConfig.SystemModules.EdgeAgent);
            Assert.Equal(Option.Some(edgeHubModule), returnedDeploymentConfig.SystemModules.EdgeHub);
            ModuleSet moduleSet = returnedDeploymentConfig.GetModuleSet();

            Assert.Equal(4, returnedDeploymentConfig.GetModuleSet().Modules.Count);
            Assert.Equal(customModule1.Name, moduleSet.Modules["module1"].Name);
            Assert.Equal(customModule2.Name, moduleSet.Modules["module2"].Name);
            Assert.Equal(edgeHubModule.Name, moduleSet.Modules["$edgeHub"].Name);
            Assert.Equal(edgeAgentModule.Name, moduleSet.Modules["$edgeAgent"].Name);
            Assert.Equal("module1", customModule1Name);
            Assert.Equal("module2", customModule2Name);
        }
Exemplo n.º 8
0
 public AgentState(
     long lastDesiredVersion               = 0,
     DeploymentStatus lastDesiredStatus    = null,
     IRuntimeInfo runtimeInfo              = null,
     SystemModules systemModules           = null,
     IDictionary <string, IModule> modules = null,
     string schemaVersion = "",
     VersionInfo version  = null)
 {
     this.SchemaVersion      = schemaVersion ?? string.Empty;
     this.Version            = version ?? VersionInfo.Empty;
     this.LastDesiredVersion = lastDesiredVersion;
     this.LastDesiredStatus  = lastDesiredStatus ?? DeploymentStatus.Unknown;
     this.RuntimeInfo        = runtimeInfo;
     this.SystemModules      = systemModules ?? new SystemModules(UnknownEdgeAgentModule.Instance, UnknownEdgeHubModule.Instance);
     this.Modules            = modules?.ToImmutableDictionary() ?? ImmutableDictionary <string, IModule> .Empty;
 }
Exemplo n.º 9
0
        public void SetProcess(ProcessModel processModel, string gameLanguage = "English", string patchVersion = "latest", bool useLocalCache = true, bool scanAllMemoryRegions = false)
        {
            ProcessModel  = processModel;
            GameLanguage  = gameLanguage;
            UseLocalCache = useLocalCache;

            UnsetProcess();

            try
            {
                ProcessHandle = UnsafeNativeMethods.OpenProcess(UnsafeNativeMethods.ProcessAccessFlags.PROCESS_VM_ALL, false, (uint)ProcessModel.ProcessID);
            }
            catch (Exception)
            {
                ProcessHandle = processModel.Process.Handle;
            }
            finally
            {
                Constants.ProcessHandle = ProcessHandle;
                IsAttached = true;
            }

            if (IsNewInstance)
            {
                IsNewInstance = false;

                ActionHelper.Resolve();
                StatusEffectHelper.Resolve();
                ZoneHelper.Resolve();

                ResolveMemoryStructures(processModel, patchVersion);
            }

            AttachmentWorker = new AttachmentWorker();
            AttachmentWorker.StartScanning(processModel);

            SystemModules.Clear();
            GetProcessModules();

            Scanner.Instance.Locations.Clear();
            Scanner.Instance.LoadOffsets(Signatures.Resolve(processModel, patchVersion), scanAllMemoryRegions);
        }
Exemplo n.º 10
0
        public async Task UpstreamProtocolTest()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = "test-helloworld";
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15)))
                {
                    // Arrange
                    await DockerHelper.Client.CleanupContainerAsync(Name, Image);

                    // ensure image has been pulled
                    await DockerHelper.Client.PullImageAsync(Image, cts.Token);

                    var dockerLoggingOptions = new Dictionary <string, string>
                    {
                        { "max-size", "1m" },
                        { "max-file", "1" }
                    };
                    // Logging options will be derived from these default logging options
                    var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions);
                    var config        = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""], ""HostConfig"": {""PortBindings"": {""8080/tcp"": [{""HostPort"": ""80""}]}}}");
                    var module        = new DockerModule(Name, "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy, config, null, EnvVars);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                        new Dictionary <string, string>
                    {
                        { "EdgeHubConnectionString", fakeConnectionString },
                        { Constants.EdgeModuleCaCertificateFileKey, "/module.ca.cert" },
                        { "UpstreamProtocol", "AmqpWs" }
                    }).Build();

                    var modules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", "")), systemModules, modules));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    var identity = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString));

                    ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, false);

                    // Act
                    // run the command
                    await command.ExecuteAsync(cts.Token);

                    // Assert
                    // verify container is created and has correct settings
                    ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name);

                    Assert.Equal(Name, container.Name.Substring(1));  // for whatever reason the container name is returned with a starting "/"
                    Assert.Equal("1.0", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing"));
                    // port mapping
                    Assert.Equal("8080/tcp", container.HostConfig.PortBindings.First().Key);
                    // logging
                    Assert.Equal("json-file", container.HostConfig.LogConfig.Type);
                    Assert.True(container.HostConfig.LogConfig.Config.Count == 2);
                    Assert.Equal("1m", container.HostConfig.LogConfig.Config.GetOrElse("max-size", "missing"));
                    Assert.Equal("1", container.HostConfig.LogConfig.Config.GetOrElse("max-file", "missing"));
                    // environment variables
                    IDictionary <string, string> envMap = container.Config.Env.ToDictionary('=');
                    Assert.Equal("v1", envMap["k1"]);
                    Assert.Equal("v2", envMap["k2"]);
                    Assert.Equal("AmqpWs", envMap["UpstreamProtocol"]);
                    Assert.Equal(fakeConnectionString, envMap["EdgeHubConnectionString"]);
                    // certificates env variables
                    Assert.Equal("/module.ca.cert", envMap[Constants.EdgeModuleCaCertificateFileKey]);
                }
            }
            finally
            {
                await DockerHelper.Client.CleanupContainerAsync(Name, Image);
            }
        }
Exemplo n.º 11
0
        public async Task TestMountModuleVolume()
        {
            // Arrange
            const string VolumeName = "vol1";
            const string VolumePath = "/azure-edge/vol1";

            CreateContainerParameters createContainerParameters = null;
            var containerOperations = new Mock <IContainerOperations>();

            containerOperations.Setup(co => co.CreateContainerAsync(It.IsAny <CreateContainerParameters>(), It.IsAny <CancellationToken>()))
            .Callback((CreateContainerParameters ccp, CancellationToken tok) => createContainerParameters = ccp)
            .ReturnsAsync(new CreateContainerResponse());

            var dockerClient = new Mock <IDockerClient>();

            dockerClient.SetupGet(c => c.Containers)
            .Returns(containerOperations.Object);

            var moduleIdentity = new Mock <IModuleIdentity>();

            moduleIdentity.SetupGet(i => i.Credentials)
            .Returns(new ConnectionStringCredentials(string.Empty));

            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(r => r.Config)
            .Returns(new DockerRuntimeConfig("1.25", string.Empty));

            var systemModules = new SystemModules(
                this.CreateMockEdgeAgentModule(),
                this.CreateMockEdgeHubModule()
                );

            IConfigurationRoot configuration = new ConfigurationBuilder().AddInMemoryCollection(
                new Dictionary <string, string>
            {
                { Constants.EdgeModuleVolumeNameKey, VolumeName },
                { Constants.EdgeModuleVolumePathKey, VolumePath }
            }
                ).Build();

            var configSource     = new Mock <IConfigSource>();
            var deploymentConfig = new DeploymentConfig(
                "1.0", runtimeInfo.Object, systemModules,
                ImmutableDictionary <string, IModule> .Empty
                );
            var deploymentConfigInfo = new DeploymentConfigInfo(10, deploymentConfig);

            configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync())
            .ReturnsAsync(deploymentConfigInfo);
            configSource.SetupGet(cs => cs.Configuration)
            .Returns(configuration);

            // Act
            ICommand createCommand = await CreateCommand.BuildAsync(
                dockerClient.Object,
                new DockerModule(
                    "mod1", "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy,
                    new DockerConfig("image1"), new ConfigurationInfo("1234"), EnvVars
                    ),
                moduleIdentity.Object,
                new DockerLoggingConfig("json"),
                configSource.Object,
                false);

            await createCommand.ExecuteAsync(CancellationToken.None);

            // Assert
            Assert.NotNull(createContainerParameters);
            Assert.Contains($"{VolumeName}:{VolumePath}:ro", createContainerParameters.HostConfig.Binds);
        }
Exemplo n.º 12
0
        public async Task EdgeHubLaunchWithBadLogOptions()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = Constants.EdgeHubModuleName;
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15)))
                {
                    await DockerHelper.Client.CleanupContainerAsync(Name, Image);

                    // ensure image has been pulled
                    await DockerHelper.Client.PullImageAsync(Image, cts.Token);

                    var dockerLoggingOptions = new Dictionary <string, string>
                    {
                        { "max-size", "1m" },
                        { "max-file", "1" }
                    };
                    var loggingConfig     = new DockerLoggingConfig("json-file", dockerLoggingOptions);
                    var config            = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""]}");
                    var configurationInfo = new ConfigurationInfo("43");
                    var module            = new EdgeHubDockerModule("docker", ModuleStatus.Running, Core.RestartPolicy.Always, config, configurationInfo, EnvVars);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                        new Dictionary <string, string>
                    {
                        { "EdgeHubConnectionString", fakeConnectionString }
                    }).Build();
                    var modules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", "Not a valid JSON")), systemModules, modules));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    var identity = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString));

                    ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, true);

                    // run the command
                    await command.ExecuteAsync(cts.Token);

                    // verify container is created with correct settings
                    ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name);

                    Assert.Equal(Name, container.Name.Substring(1));  // for whatever reason the container name is returned with a starting "/"
                    // labels - edgeHub doesn's have a version
                    Assert.Equal("missing", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing"));
                    Assert.Equal("43", container.Config.Labels.GetOrElse(Constants.Labels.ConfigurationId, "missing"));
                    // port bindings - check that we added default bindings for hub
                    Assert.True(container.HostConfig.PortBindings.ContainsKey("8883/tcp"));
                    Assert.True(container.HostConfig.PortBindings["8883/tcp"].Count == 1);
                    Assert.Equal("8883", container.HostConfig.PortBindings["8883/tcp"].First().HostPort);
                    Assert.True(container.HostConfig.PortBindings.ContainsKey("443/tcp"));
                    Assert.True(container.HostConfig.PortBindings["443/tcp"].Count == 1);
                    Assert.Equal("443", container.HostConfig.PortBindings["443/tcp"][0].HostPort);
                    // logging
                    Assert.Equal("json-file", container.HostConfig.LogConfig.Type);
                    Assert.True(container.HostConfig.LogConfig.Config.Count == 2);
                    Assert.Equal("1m", container.HostConfig.LogConfig.Config.GetOrElse("max-size", "missing"));
                    Assert.Equal("1", container.HostConfig.LogConfig.Config.GetOrElse("max-file", "missing"));
                    // environment variables
                    IDictionary <string, string> envMap = container.Config.Env.ToDictionary('=');
                    Assert.Equal("v1", envMap["k1"]);
                    Assert.Equal("v2", envMap["k2"]);
                    Assert.Equal(fakeConnectionString, envMap[Constants.IotHubConnectionStringKey]);
                }
            }
            finally
            {
                await DockerHelper.Client.CleanupContainerAsync(Name, Image);
            }
        }
Exemplo n.º 13
0
        public async Task TestUdpModuleConfig()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = "test-helloworld";
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15)))
                {
                    await DockerHelper.Client.CleanupContainerAsync(Name, Image);

                    // ensure image has been pulled
                    await DockerHelper.Client.PullImageAsync(Image, cts.Token);

                    var loggingConfig = new DockerLoggingConfig("json-file");
                    var config        = new DockerConfig(Image, @"{""HostConfig"": {""PortBindings"": {""42/udp"": [{""HostPort"": ""42""}]}}}");
                    var module        = new DockerModule(Name, "1.0", ModuleStatus.Running, Core.RestartPolicy.OnUnhealthy, config, null, EnvVars);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary <string, string>
                    {
                        { "EdgeHubConnectionString", fakeConnectionString }
                    }).Build();

                    // Logging options will be derived from application level configuration
                    var modules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", @"{""Type"":""json-file"",""Config"":{""max-size"":""100M""}}")), systemModules, modules));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    string credential = "fake";
                    var    identity   = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(credential));

                    ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, false);

                    // run the command
                    await command.ExecuteAsync(cts.Token);

                    // verify container is created with correct settings.
                    ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name);

                    Assert.Equal(Name, container.Name.Substring(1));  // for whatever reason the container name is returned with a starting "/"
                    Assert.Equal("1.0", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing"));
                    // port bindings
                    Assert.Equal(1, container.HostConfig.PortBindings.Count);
                    Assert.False(container.HostConfig.PortBindings.ContainsKey("8883/tcp"));
                    Assert.False(container.HostConfig.PortBindings.ContainsKey("443/tcp"));
                    // logging
                    Assert.Equal("json-file", container.HostConfig.LogConfig.Type);
                    Assert.True(container.HostConfig.LogConfig.Config.Count == 1);
                    Assert.Equal("100M", container.HostConfig.LogConfig.Config["max-size"]);
                }
            }
            finally
            {
                await DockerHelper.Client.CleanupContainerAsync(Name, Image);
            }
        }
Exemplo n.º 14
0
        public async Task TestFilters()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = "test-filters";
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(Timeout))
                {
                    await Client.CleanupContainerAsync(Name, Image);

                    await Client.CleanupContainerAsync("test-filters-external", Image);

                    var loggingConfig = new DockerLoggingConfig("json-file");
                    var config        = new DockerConfig(Image);
                    var module        = new DockerModule(Name, "1.0", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy, config, ImagePullPolicy.OnCreate, Constants.DefaultStartupOrder, null, null);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                        new Dictionary <string, string>
                    {
                        { "EdgeDeviceConnectionString", fakeConnectionString }
                    }).Build();

                    var deploymentConfigModules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, deploymentConfigModules, null));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    var credential = new ConnectionStringCredentials("fake");
                    var identity   = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(credential);

                    ICommand create = await CreateCommand.BuildAsync(Client, module, identity.Object, loggingConfig, configSource.Object, false);

                    // pull the image for both containers
                    await Client.PullImageAsync(Image, cts.Token);

                    // pull and create module using commands
                    await create.ExecuteAsync(cts.Token);

                    var createParams = new CreateContainerParameters
                    {
                        Name  = "test-filters-external",
                        Image = Image,
                    };
                    await Client.Containers.CreateContainerAsync(createParams);

                    // Check that only containers created via command are listed in the environment
                    RuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(Client);

                    IEnumerable <ModuleRuntimeInfo> modules = await runtimeInfoProvider.GetModules(cts.Token);

                    Assert.Single(modules);
                    Assert.Equal(module.Name, modules.First().Name);
                }
            }
            finally
            {
                await Client.CleanupContainerAsync(Name, Image);

                await Client.CleanupContainerAsync("test-filters-external", Image);
            }
        }
Exemplo n.º 15
0
        public async Task EdgeHubLaunch()
        {
            const string Image                = "hello-world:latest";
            const string Name                 = Constants.EdgeHubModuleName;
            string       sharedAccessKey      = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
            string       fakeConnectionString = $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}";

            try
            {
                using (var cts = new CancellationTokenSource(this.defaultTimeout))
                {
                    var mountMap = new Dictionary <string, string>()
                    {
                        { Constants.EdgeModuleCaCertificateFileKey, "/module.ca.cert" },
                        { Constants.EdgeModuleHubServerCaChainCertificateFileKey, "/module.ca.chain.cert" },
                        { Constants.EdgeModuleHubServerCertificateFileKey, "/module.server.cert" }
                    };
                    await DockerHelper.Client.CleanupContainerAsync(Name, Image);

                    // ensure image has been pulled
                    await DockerHelper.Client.PullImageAsync(Image, cts.Token);

                    var dockerLoggingOptions = new Dictionary <string, string>
                    {
                        { "max-size", "1m" },
                        { "max-file", "1" }
                    };
                    var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions);
                    // Logging options will be derived from module options.
                    var config            = new DockerConfig(Image, @"{""Env"": [""k1=v1"", ""k2=v2""], ""HostConfig"": {""LogConfig"": {""Type"":""none""}, ""PortBindings"": {""8080/tcp"": [{""HostPort"": ""80""}],""443/tcp"": [{""HostPort"": ""11443""}]}}}", Option.None <string>());
                    var configurationInfo = new ConfigurationInfo();
                    var module            = new EdgeHubDockerModule("docker", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, config, ImagePullPolicy.Never, Constants.HighestPriority, configurationInfo, EnvVars);

                    IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                        new Dictionary <string, string>
                    {
                        { "EdgeHubConnectionString", fakeConnectionString },
                        { Constants.NetworkIdKey, "testnetwork" },
                        { Constants.EdgeDeviceHostNameKey, "testdevice" },
                        { Constants.EdgeModuleHubServerCaChainCertificateFileKey, mountMap[Constants.EdgeModuleHubServerCaChainCertificateFileKey] },
                        { Constants.EdgeModuleHubServerCertificateFileKey, mountMap[Constants.EdgeModuleHubServerCertificateFileKey] },
                    }).Build();
                    var modules = new Dictionary <string, IModule> {
                        [Name] = module
                    };
                    var systemModules        = new SystemModules(null, null);
                    var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", new DockerRuntimeInfo("docker", new DockerRuntimeConfig("1.25", string.Empty)), systemModules, modules, null));
                    var configSource         = new Mock <IConfigSource>();
                    configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                    configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                    var identity = new Mock <IModuleIdentity>();
                    identity.Setup(id => id.Credentials).Returns(new ConnectionStringCredentials(fakeConnectionString));

                    ICommand command = await CreateCommand.BuildAsync(DockerHelper.Client, module, identity.Object, loggingConfig, configSource.Object, true);

                    // run the command
                    await command.ExecuteAsync(cts.Token);

                    // verify container is created with correct settings
                    ContainerInspectResponse container = await DockerHelper.Client.Containers.InspectContainerAsync(Name);

                    Assert.Equal(Name, container.Name.Substring(1)); // for whatever reason the container name is returned with a starting "/"
                    // edgeHub doesn't have a version
                    Assert.Equal("missing", container.Config.Labels.GetOrElse(Constants.Labels.Version, "missing"));
                    // port bindings - added default bindings for edgeHub
                    Assert.True(container.HostConfig.PortBindings.ContainsKey("8080/tcp"));
                    Assert.True(container.HostConfig.PortBindings.ContainsKey("8883/tcp"));
                    Assert.Equal("8883", container.HostConfig.PortBindings["8883/tcp"].First().HostPort);
                    Assert.True(container.HostConfig.PortBindings.ContainsKey("443/tcp"));
                    Assert.True(container.HostConfig.PortBindings["443/tcp"].Count == 2);
                    Assert.Equal("11443", container.HostConfig.PortBindings["443/tcp"][0].HostPort);
                    Assert.Equal("443", container.HostConfig.PortBindings["443/tcp"][1].HostPort);
                    // logging
                    Assert.Equal("none", container.HostConfig.LogConfig.Type);
                    Assert.True(container.HostConfig.LogConfig.Config.Count == 0);
                    // network settings
                    Assert.Equal("testdevice", container.NetworkSettings.Networks.GetOrElse("testnetwork", new EndpointSettings()).Aliases.FirstOrDefault());

                    Assert.Equal("testdevice", container.NetworkSettings.Networks.GetOrElse("testnetwork", new EndpointSettings()).Aliases.FirstOrDefault());
                    // environment variables
                    IDictionary <string, string> envMap = container.Config.Env.ToDictionary('=');
                    Assert.Equal("v1", envMap["k1"]);
                    Assert.Equal("v2", envMap["k2"]);
                    Assert.Equal(fakeConnectionString, envMap[Constants.IotHubConnectionStringKey]);
                    // certificates env variables
                    Assert.Equal("/module.ca.chain.cert", envMap[Constants.EdgeModuleHubServerCaChainCertificateFileKey]);
                    Assert.Equal("/module.server.cert", envMap[Constants.EdgeModuleHubServerCertificateFileKey]);
                }
            }
            finally
            {
                await DockerHelper.Client.CleanupContainerAsync(Name, Image);
            }
        }
Exemplo n.º 16
0
        public async Task AgentStartsUpModules(TestConfig testConfig)
        {
            // Build the docker host URL.
            string       dockerHostUrl = ConfigHelper.TestConfig["dockerHostUrl"];
            DockerClient client        = new DockerClientConfiguration(new Uri(dockerHostUrl)).CreateClient();

            try
            {
                // Remove any running containers with the same name that may be a left-over
                // from previous test runs.
                await RemoveContainer(client, testConfig);

                // Initialize docker configuration for this module.
                DockerConfig dockerConfig = testConfig.ImageCreateOptions != null
                    ? new DockerConfig(testConfig.Image, testConfig.ImageCreateOptions)
                    : new DockerConfig(testConfig.Image);

                // Initialize an Edge Agent module object.
                var dockerModule = new DockerModule(
                    testConfig.Name,
                    testConfig.Version,
                    ModuleStatus.Running,
                    global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.OnUnhealthy,
                    dockerConfig,
                    null,
                    null);
                var modules = new Dictionary <string, IModule> {
                    [testConfig.Name] = dockerModule
                };
                var systemModules = new SystemModules(null, null);

                // Start up the agent and run a "reconcile".
                var dockerLoggingOptions = new Dictionary <string, string>
                {
                    { "max-size", "1m" },
                    { "max-file", "1" }
                };
                var loggingConfig = new DockerLoggingConfig("json-file", dockerLoggingOptions);

                string             sharedAccessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("test"));
                IConfigurationRoot configRoot      = new ConfigurationBuilder().AddInMemoryCollection(
                    new Dictionary <string, string>
                {
                    { "DeviceConnectionString", $"Hostname=fakeiothub;Deviceid=test;SharedAccessKey={sharedAccessKey}" }
                }).Build();

                var runtimeConfig        = new DockerRuntimeConfig("1.24.0", "{}");
                var runtimeInfo          = new DockerRuntimeInfo("docker", runtimeConfig);
                var deploymentConfigInfo = new DeploymentConfigInfo(1, new DeploymentConfig("1.0", runtimeInfo, systemModules, modules));

                var configSource = new Mock <IConfigSource>();
                configSource.Setup(cs => cs.Configuration).Returns(configRoot);
                configSource.Setup(cs => cs.GetDeploymentConfigInfoAsync()).ReturnsAsync(deploymentConfigInfo);

                // TODO: Fix this up with a real reporter. But before we can do that we need to use
                // the real configuration source that talks to IoT Hub above.
                NullReporter reporter = NullReporter.Instance;

                var restartStateStore                = Mock.Of <IEntityStore <string, ModuleState> >();
                var configStore                      = Mock.Of <IEntityStore <string, string> >();
                var deploymentConfigInfoSerde        = Mock.Of <ISerde <DeploymentConfigInfo> >();
                IRestartPolicyManager restartManager = new Mock <IRestartPolicyManager>().Object;

                var dockerCommandFactory = new DockerCommandFactory(client, loggingConfig, configSource.Object, new CombinedDockerConfigProvider(Enumerable.Empty <AuthConfig>()));
                IRuntimeInfoProvider runtimeInfoProvider = await RuntimeInfoProvider.CreateAsync(client);

                IEnvironmentProvider environmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, restartStateStore, restartManager);

                var logFactoryMock = new Mock <ILoggerFactory>();
                var logMock        = new Mock <ILogger <LoggingCommandFactory> >();
                logFactoryMock.Setup(l => l.CreateLogger(It.IsAny <string>()))
                .Returns(logMock.Object);
                var commandFactory = new LoggingCommandFactory(dockerCommandFactory, logFactoryMock.Object);

                var credential = new ConnectionStringCredentials("fake");
                var identity   = new Mock <IModuleIdentity>();
                identity.Setup(id => id.Credentials).Returns(credential);
                identity.Setup(id => id.ModuleId).Returns(testConfig.Name);
                IImmutableDictionary <string, IModuleIdentity> identities = new Dictionary <string, IModuleIdentity>()
                {
                    [testConfig.Name] = identity.Object
                }.ToImmutableDictionary();
                var moduleIdentityLifecycleManager = new Mock <IModuleIdentityLifecycleManager>();
                moduleIdentityLifecycleManager.Setup(m => m.GetModuleIdentitiesAsync(It.IsAny <ModuleSet>(), It.IsAny <ModuleSet>())).Returns(Task.FromResult(identities));

                Agent agent = await Agent.Create(
                    configSource.Object,
                    new RestartPlanner(commandFactory),
                    new OrderedPlanRunner(),
                    reporter,
                    moduleIdentityLifecycleManager.Object,
                    environmentProvider,
                    configStore,
                    deploymentConfigInfoSerde,
                    NullEncryptionProvider.Instance);

                await agent.ReconcileAsync(CancellationToken.None);

                // Sometimes the container is still not ready by the time we run the validator.
                // So we attempt validation multiple times and bail only if all of them fail.
                bool      validated   = false;
                int       attempts    = 0;
                const int MaxAttempts = 5;
                while (!validated && attempts < MaxAttempts)
                {
                    validated = testConfig.Validator.Validate();
                    if (!validated)
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(5));
                    }

                    ++attempts;
                }

                Assert.Equal(true, validated);
            }
            finally
            {
                await RemoveContainer(client, testConfig);
            }
        }