This chapter starts examining coding examples which make use of the InControl API.
Similarities with the CLI
A useful principle to remember is that programming with the InControl API is very similar to constructing cOS Core Command Line Interface (CLI) commands. The two are similar since they both interact with the Configuration Engine which is the cOS Core subsystem that deals with the management of cOS Core configurations.Similarities to the CLI will be discussed further in this guide and example CLI commands will sometimes be given following InControl API based code in order to highlight the similarities. The CLI Reference Guide can be an extremely useful reference document when programming with the API since it lists all possible API parameter options.
A key difference between using the CLI and the InControl API is that an equivalent to the "cc" (change context/category) command does not need to be used to change the current context to be a particular object such as the main IP rule set when editing IP rules. Instead, the InControl API uses a more direct way of referring to a particular configuration object.
A Simple Example
A simple first example of API based source code can be found below. This example, like others used throughout this guide, is written in the C Sharp (C#) language and assumes that the development environment is setup accordingly with references to the WCF service (see Appendix A, Visual Studio Setup).The example's assumptions are:
Communication between the client and the InControl server in the example is achieved using HTTP/SOAP and this is the recommended method. Connection using the alternative of net.tcp is explained later.
Authentication is always required by the server and the required credentials for this example are assumed to be:
Username: MyUsername
Password: MyPassword
The credentials must match those of a user defined in the InControl server user database. The permissions defined for that user will be the permissions given to the API client.
The URL for the InControl server is assumed to be:
http://icserver.mycompany.com:8080/InControl
The port number must be specified otherwise it will default to the standard HTTP port number. Port 8080 is the InControl server's default listening port.
// Define the address for the connection EndpointAddress epa = new EndpointAddress("http://icserver.mycompany.com:8080/InControl"); // Create the binding WSHttpBinding wsHttpBinding = new WSHttpBinding(SecurityMode.Message); wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; wsHttpBinding.Security.Message.EstablishSecurityContext = true; // Get the security element for adding the parameter requirements BindingElementCollection bec = wsHttpBinding.CreateBindingElements(); SecurityBindingElement sbe = bec.Find<SecurityBindingElement>(); if (sbe == null) { throw new InvalidOperationException("No SecurityBindingElement found!"); } // Add the parameter requirements sbe.EndpointSupportingTokenParameters.SignedEncrypted.Add( new UserNameSecurityTokenParameters()); // Create the binding CustomBinding cb = new CustomBinding(bec); // Create the client ChannelFactory<InControl_API.IRemoteServer> cf = new ChannelFactory<InControl_API.IRemoteServer>(cb, epa); // Specify the client credentials cf.Credentials.UserName.UserName = "MyUsername"; cf.Credentials.UserName.Password = "MyPassword"; // Retrieve the server object IRemoteServer server = cf.CreateChannel(); // Increase the timeout to 3 seconds from the default of 1 // This may be required by the "DeployConfiguration" function ((IContextChannel)server).OperationTimeout = new TimeSpan(0, 3, 0); // Get the root domain which contains all defined security gateways Domain global = server.get_Root(); // Assume there is a device in the root domain called 'sgwStockholm' // Get this security gateway Device sgwStockholm = server.GetConfigObjectByName(global, "sgwStockholm") as Device; // Check out this security gateway server.CheckOutConfiguration(sgwStockholm); // Get the latest configuration for this gateway Configuration cfg = server.GetLatestConfiguration(sgwStockholm); // Add a new IP rule // Start by setting the properties of the rule Dictionary<string, string> properties = new Dictionary<string, string>(); properties.Add("Action", "NAT"); properties.Add("SourceInterface", "lan"); properties.Add("SourceNetwork", "lannet"); properties.Add("DestinationInterface", "wan"); properties.Add("DestinationNetwork","all-nets"); properties.Add("Service", "http-outbound"); properties.Add("LogEnabled", "True"); properties.Add("Comments", "Allow and NAT HTTP traffic from LAN to WAN"); // Get the main IPRuleSet folder for adding nodes // Note how the rule set identifier is constructed Node folder = server.GetRootNode(cfg); // Add the IP Rule as a child node to this folder server.AddChildNode(folder, "IPRule", "NAT_HTTP", properties); // Check in the new configuration server.CheckInConfiguration(cfg, "Added IP rule allowing NAT LAN to WAN HTTP traffic"); // Deploy and activate the new configuration on the security gateway server.DeployConfiguration(sgwStockholm); // Finished so close the connection to the InControl server (server as IClientChannel).Close();
![]() |
Note |
---|---|
Error handling try and catch blocks are not explicitly shown in these code examples. However, they should be used and follow normal error handling practices to catch any errors. |
Connection Using net.tcp
An alternative to using HTTP/SOAP is to use net.tcp as the connection protocol. Assuming that the URL for the server is net.tcp://localhost:33726/InControl, the connection code up until getting the IRemoteServer object instance is as follows:// Define the address for the connection EndpointAddress epa = new EndpointAddress("net.tcp://localhost:33726/InControl"); // Create the binding NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.Message); netTcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; // Get the security element for adding the parameter requirements BindingElementCollection bec = netTcpBinding.CreateBindingElements(); SecurityBindingElement sbe = bec.Find<SecurityBindingElement>(); if (sbe == null) { throw new InvalidOperationException("No SecurityBindingElement found!"); } // Add the parameter requirements sbe.EndpointSupportingTokenParameters.SignedEncrypted.Add( new UserNameSecurityTokenParameters()); // Create the binding CustomBinding cb = new CustomBinding(bec); // Create the client ChannelFactory<InControl_API.IRemoteServer> cf = new ChannelFactory<InControl_API.IRemoteServer>(cb, epa); // Specify the client credentials cf.Credentials.UserName.UserName = "MyUsername"; cf.Credentials.UserName.Password = "MyPassword"; // Retrieve the server object IRemoteServer server = cf.CreateChannel(); // Increase the timeout if required for deployment ((IContextChannel)cf).OperationTimeout = new TimeSpan(0, 3, 0);
The above code is identical to the HTTP/SOAP code from adding the parameter requirements onwards.
Reasons for using and Not Using net.tcp
There are a number of reasons for using and not using net.tcp instead of HTTP/SOAP :Adding a Security Gateway
The simplest case when adding a security gateway is adding a single standalone gateway below the global domain object. To make the following examples concise, it will be assumed that an IRemoteServer server object with the name server has already been retrieved.// Assume the security keys for all gateways are the following: String keys="DBC2A65220E2D3753149EDED524FC1A140CDA6810FA68E2A78F4FC1A1"; // First, get the global domain object Domain global = server.get_Root(); // Add the security gateway called MySGW Guid sgwId = server.AddSecurityGateway("MySGW", global.Id, "192.168.1.222", 999, keys, "Add gateway via API");
Deleting a Security Gateway
Deletion of a gateway is done in a similar way to deleting any other object.// Get the object for the device Device mySGW = server.GetConfigObjectById(null, sgwId) as Device; // Delete the object server.DeleteConfigObject(mySGW, true);
Adding a High Availability Cluster
The procedure to add an HA cluster involves first adding the cluster object and then adding the gateways to that.// Get the root object for the global domain Domain global = server.get_Root(); // Add a cluster under the root object Guid clusterId = server.AddCluster("MyCluster", global.Id, 0, 0, "Add Cluster via API"); // Add the cluster master Guid master = server.AddSecurityGateway("cluster_master", clusterId, "192.168.1.123", 999, keys, "Add master via API"); // Add the cluster slave Guid master = server.AddSecurityGateway("cluster_slave", clusterId, "192.168.1.124", 999, keys, "Add slave via API");
Deleting a High Availability Cluster
In order to delete an HA cluster, the individual gateways must first be deleted and then the cluster itself is deleted.// Delete the cluster master Device master_device = server.GetConfigObjectById(null,masterId) as Device; server.DeleteConfigObject(master_device, true); // Delete the cluster slave Device master_device = server.GetConfigObjectById(null,slaveId) as Device; server.DeleteConfigObject(master_device, true); // Delete the cluster itself Cluster myCluster = server.GetConfigObjectById(null,clusterId) as Cluster; server.DeleteConfigObject(myCluster, true);