diff --git a/MySql/Source/MySql.Data/MySql.Data.csproj b/MySql/Source/MySql.Data/MySql.Data.csproj index f039e7ee..64691dc8 100644 --- a/MySql/Source/MySql.Data/MySql.Data.csproj +++ b/MySql/Source/MySql.Data/MySql.Data.csproj @@ -70,7 +70,7 @@ obj\ ..\..\..\bin\ $(DefineConstants);TRACE - prompt + prompt 1 false diff --git a/Ntp.Analyzer.Validate.Cli/Ntp.Analyzer.Validate.Cli.csproj b/Ntp.Analyzer.Validate.Cli/Ntp.Analyzer.Validate.Cli.csproj index dc294c7b..a7debf26 100644 --- a/Ntp.Analyzer.Validate.Cli/Ntp.Analyzer.Validate.Cli.csproj +++ b/Ntp.Analyzer.Validate.Cli/Ntp.Analyzer.Validate.Cli.csproj @@ -21,7 +21,7 @@ prompt 4 true - ~/code/ntpa/example/ntpa.web.conf + --verbose ~/code/ntpa/example/ntpa.web.small.conf full diff --git a/Ntp.Analyzer.Validate.Cli/Program.cs b/Ntp.Analyzer.Validate.Cli/Program.cs index 1e66995d..d13f57c1 100644 --- a/Ntp.Analyzer.Validate.Cli/Program.cs +++ b/Ntp.Analyzer.Validate.Cli/Program.cs @@ -54,6 +54,9 @@ namespace Ntp.Analyzer.Validate.Cli }, { "v|verbose", v => { verbose = true; } + }, { "s|show", v => { + // TODO: Implement new option to show configuration + } } }; @@ -71,7 +74,7 @@ namespace Ntp.Analyzer.Validate.Cli Configuration config = null; try { - config = LoadConfig (args [0]); + config = LoadConfig (rem [0]); } catch (Exception e) { Console.WriteLine ("Unexpected error while loading configuration file: " + e.Message); return; @@ -80,7 +83,7 @@ namespace Ntp.Analyzer.Validate.Cli if (config == null) return; - Console.WriteLine ("Parsed config ..."); + Console.WriteLine ("Configuration is valid."); if (verbose) Console.WriteLine (config); @@ -92,7 +95,7 @@ namespace Ntp.Analyzer.Validate.Cli } if (!anyErrors) { - Console.WriteLine ("Filesystem configuration seems valid ..."); + Console.WriteLine ("Filesystem options seems valid."); Console.WriteLine (); } } diff --git a/Ntp.Analyzer.sln b/Ntp.Analyzer.sln index e2439152..7992c203 100644 --- a/Ntp.Analyzer.sln +++ b/Ntp.Analyzer.sln @@ -11,13 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ntp.Analyzer.Process", "Ntp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ntp.Analyzer.Log", "Ntp.Analyzer.Log\Ntp.Analyzer.Log.csproj", "{909C8729-ED63-4603-85EA-34A1FC4D63D9}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sql", "sql", "{F70A2719-A82B-49AE-9EDF-7DCEB231637D}" - ProjectSection(SolutionItems) = preProject - sql\create_tables.sql = sql\create_tables.sql - sql\create_data.sql = sql\create_data.sql - sql\create_user.sql = sql\create_user.sql - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ntp.Analyzer.Cli", "Ntp.Analyzer.Cli\Ntp.Analyzer.Cli.csproj", "{6A635537-E5E9-493E-8B89-E0E5EBB64E72}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ntp.Config", "Ntp.Config\Ntp.Config.csproj", "{43A1A769-6ED9-4AE1-821A-43F97814968C}" @@ -44,11 +37,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "MySql\Source\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ntp.System", "Ntp.System\Ntp.System.csproj", "{A98DB601-2993-4181-A573-5FCCC5E954C1}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{6D7079EB-9FEE-4EC7-AA28-3671C607FDC6}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "example", "example", "{8232668F-1BAA-4328-9E55-317263BFA2DC}" ProjectSection(SolutionItems) = preProject + example\ntp.conf = example\ntp.conf example\ntpa.graph.conf = example\ntpa.graph.conf example\ntpa.stat.conf = example\ntpa.stat.conf example\ntpa.web.conf = example\ntpa.web.conf + example\ntpa.web.small.conf = example\ntpa.web.small.conf EndProjectSection EndProject Global @@ -168,7 +163,7 @@ Global GlobalSection(NestedProjects) = preSolution EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Ntp.Analyzer.Cli\Ntp.Analyzer.Cli.csproj + StartupItem = Ntp.Analyzer.Validate.Cli\Ntp.Analyzer.Validate.Cli.csproj Policies = $0 $0.DotNetNamingPolicy = $1 $1.DirectoryNamespaceAssociation = PrefixedHierarchical diff --git a/Ntp.Analyzer/Config/Configuration.cs b/Ntp.Analyzer/Config/Configuration.cs index de1b31c4..059a9e18 100644 --- a/Ntp.Analyzer/Config/Configuration.cs +++ b/Ntp.Analyzer/Config/Configuration.cs @@ -147,6 +147,9 @@ namespace Ntp.Analyzer.Config { ConfigurationBlock databaseBlock = FindSingleBlock (DatabaseConfiguration.Identifier, block); DatabaseConfiguration database = DatabaseConfiguration.Create (databaseBlock); + if (database == null) { + ConfigError ("Database section is missing."); + } ConfigurationBlock clusterBlock = FindSingleBlock (ClusterConfiguration.Identifier, block); ClusterConfiguration cluster = ClusterConfiguration.Create (clusterBlock); diff --git a/Ntp.Analyzer/Config/Destination/DirectoryCollection.cs b/Ntp.Analyzer/Config/Destination/DirectoryCollection.cs index d79de1fd..d9c36188 100644 --- a/Ntp.Analyzer/Config/Destination/DirectoryCollection.cs +++ b/Ntp.Analyzer/Config/Destination/DirectoryCollection.cs @@ -79,11 +79,16 @@ namespace Ntp.Analyzer.Config.Destination { List directories = new List (); - String[] destinationLines = FindSingleBlock (Identifier, config).Lines; - string prefix = GetOptions (new[] { "Prefix" }, destinationLines) ["Prefix"]; + string prefix = String.Empty; + ConfigurationBlock block = FindSingleBlock (Identifier, config); - foreach (string destination in GetMultiOption("Directory", destinationLines)) - directories.Add (new DirectoryStreamDestination (server.FilePath, destination, prefix)); + if (block != null) { + String[] destinationLines = block.Lines; + prefix = GetOptions (new[] { "Prefix" }, destinationLines) ["Prefix"]; + + foreach (string destination in GetMultiOption("Directory", destinationLines)) + directories.Add (new DirectoryStreamDestination (server.FilePath, destination, prefix)); + } return new DirectoryCollection (String.Empty, config.IndentLevel + 1, directories, prefix); } diff --git a/Ntp.Analyzer/Config/Destination/FileCollection.cs b/Ntp.Analyzer/Config/Destination/FileCollection.cs index 701661e0..97b6225c 100644 --- a/Ntp.Analyzer/Config/Destination/FileCollection.cs +++ b/Ntp.Analyzer/Config/Destination/FileCollection.cs @@ -75,8 +75,12 @@ namespace Ntp.Analyzer.Config.Destination ConfigurationBlock config) { List files = new List(); - foreach (string destination in GetMultiOption("File", FindSingleBlock(Identifier, config))) - files.Add(new FileStreamDestination(server.FilePath, destination)); + + ConfigurationBlock block = FindSingleBlock (Identifier, config); + if (block != null) { + foreach (string destination in GetMultiOption("File", block)) + files.Add(new FileStreamDestination(server.FilePath, destination)); + } return new FileCollection(String.Empty, config.IndentLevel + 1, files); } diff --git a/Ntp.Analyzer/Config/Destination/WebLinkCollection.cs b/Ntp.Analyzer/Config/Destination/WebLinkCollection.cs index 42f4df4a..76e0f8b9 100644 --- a/Ntp.Analyzer/Config/Destination/WebLinkCollection.cs +++ b/Ntp.Analyzer/Config/Destination/WebLinkCollection.cs @@ -78,8 +78,10 @@ namespace Ntp.Analyzer.Config.Destination { List links = new List (); ConfigurationBlock linkBlock = FindSingleBlock (Identifier, config); - foreach (string link in GetMultiOption("Link", linkBlock)) - links.Add (new WebLink (link)); + if (linkBlock != null) { + foreach (string link in GetMultiOption("Link", linkBlock)) + links.Add (new WebLink (link)); + } return new WebLinkCollection (String.Empty, config.IndentLevel + 1, links); } diff --git a/Ntp.Analyzer/Config/Navigation/DropdownItemConfiguration.cs b/Ntp.Analyzer/Config/Navigation/DropdownItemConfiguration.cs index 7f33d8ab..5167ece5 100644 --- a/Ntp.Analyzer/Config/Navigation/DropdownItemConfiguration.cs +++ b/Ntp.Analyzer/Config/Navigation/DropdownItemConfiguration.cs @@ -97,6 +97,9 @@ namespace Ntp.Analyzer.Config.Navigation ConfigurationBlock config, IEnumerable linkables) { + if (config == null || linkables == null) + return null; + MenuConfiguration menu = MenuConfiguration.Create(config, linkables); return new DropdownItemConfiguration(String.Empty, config.IndentLevel, itemName, caption, menu); diff --git a/Ntp.Analyzer/Config/Navigation/MenuItemConfiguration.cs b/Ntp.Analyzer/Config/Navigation/MenuItemConfiguration.cs index f06196cf..49c842b3 100644 --- a/Ntp.Analyzer/Config/Navigation/MenuItemConfiguration.cs +++ b/Ntp.Analyzer/Config/Navigation/MenuItemConfiguration.cs @@ -113,7 +113,13 @@ namespace Ntp.Analyzer.Config.Navigation if (type == "page") { - linkable = linkables.Single(l => l.Name == page); + linkable = linkables.SingleOrDefault(l => l.Name == page); + if (linkable == null) { + ConfigError (String.Format ( + "Page {0} specified in {1} does not exist.", + page, "Menu")); + } + } switch (type) diff --git a/Ntp.Analyzer/Config/Page/AboutPageConfiguration.cs b/Ntp.Analyzer/Config/Page/AboutPageConfiguration.cs index e52621f5..d485f705 100644 --- a/Ntp.Analyzer/Config/Page/AboutPageConfiguration.cs +++ b/Ntp.Analyzer/Config/Page/AboutPageConfiguration.cs @@ -123,6 +123,11 @@ namespace Ntp.Analyzer.Config.Page Dictionary options = GetOptions (Params, config); ConfigurationBlock contentBlock = FindSingleBlock ("Content", config); + if (contentBlock == null) + { + ConfigError ("About page does not contain a Content section."); + return null; + } string content = String.Join (Environment.NewLine, contentBlock.Lines, 1, contentBlock.Lines.Length - 2) diff --git a/Ntp.Analyzer/Config/Page/Collection/SummaryCollection.cs b/Ntp.Analyzer/Config/Page/Collection/SummaryCollection.cs index d39812c3..42eaeb52 100644 --- a/Ntp.Analyzer/Config/Page/Collection/SummaryCollection.cs +++ b/Ntp.Analyzer/Config/Page/Collection/SummaryCollection.cs @@ -76,24 +76,28 @@ namespace Ntp.Analyzer.Config.Page.Collection public static SummaryCollection Create( ServerConfiguration server, - IEnumerable peerSummeries, + IEnumerable peerSummaries, ConfigurationBlock config, string configPath) { - List summeries = new List(); - foreach (string name in GetMultiOption("PeerSummaryPage", FindSingleBlock(Identifier, config))) - { - PeerSummaryPageConfiguration summary = peerSummeries.SingleOrDefault(ps => ps.ConfigName == name); + List summaries = new List(); - if (summary != null) - summeries.Add(summary); - else + ConfigurationBlock block = FindSingleBlock (Identifier, config); + if(block != null) { + foreach (string name in GetMultiOption(Identifier, block)) { - ConfigError("Cannot find PeerSummaryPage " + name + " specified in HostPage"); + PeerSummaryPageConfiguration summary = peerSummaries.SingleOrDefault(ps => ps.ConfigName == name); + + if (summary != null) + summaries.Add(summary); + else + { + ConfigError("Cannot find PeerSummaryPage " + name + " specified in HostPage"); + } } } - return new SummaryCollection(String.Empty, config.IndentLevel + 1, summeries); + return new SummaryCollection(String.Empty, config.IndentLevel + 1, summaries); } } } \ No newline at end of file diff --git a/Ntp.Analyzer/Config/Page/HostPageConfiguration.cs b/Ntp.Analyzer/Config/Page/HostPageConfiguration.cs index 0ce062ff..c0c1e6f6 100644 --- a/Ntp.Analyzer/Config/Page/HostPageConfiguration.cs +++ b/Ntp.Analyzer/Config/Page/HostPageConfiguration.cs @@ -127,7 +127,7 @@ namespace Ntp.Analyzer.Config.Page /// Gets the peer summeries to be linked from this page. /// /// The peer summeries. - public SummaryCollection PeerSummeries { + public SummaryCollection PeerSummaries { get { return summaries; } } @@ -153,9 +153,9 @@ namespace Ntp.Analyzer.Config.Page Theme, Title, PoolMember ? 1 : 0, - PeerPage.ConfigName, + PeerPage != null ? PeerPage.ConfigName : String.Empty, Graphs, - PeerSummeries, + PeerSummaries, Destinations, Link }; @@ -201,7 +201,7 @@ namespace Ntp.Analyzer.Config.Page ConfigurationBlock config, IEnumerable peerPages, IEnumerable hostGraphs, - IEnumerable peerSummeries) + IEnumerable peerSummaries) { OptionSet options = GetOptions (Params, config); @@ -228,7 +228,7 @@ namespace Ntp.Analyzer.Config.Page GetOptionBoolean (options, Params [6], Params [0], false), peerPage, GraphSetConfiguration.Create (server, hostGraphs, config, Params [0]), - SummaryCollection.Create (server, peerSummeries, config, Params [0]), + SummaryCollection.Create (server, peerSummaries, config, Params [0]), FileCollection.Create (server, config), GetOptionString (options, Params [11], Params [0], false, String.Empty) ); diff --git a/Ntp.Analyzer/Config/ServerConfiguration.cs b/Ntp.Analyzer/Config/ServerConfiguration.cs index 9d1fb8cf..085ef686 100644 --- a/Ntp.Analyzer/Config/ServerConfiguration.cs +++ b/Ntp.Analyzer/Config/ServerConfiguration.cs @@ -303,10 +303,10 @@ namespace Ntp.Analyzer.Config config.peerGraphs)); } - ConfigurationBlock[] peersummaryBlocks = FindBlocks (Params [14], configBlock); - foreach (ConfigurationBlock peersummaryBlock in peersummaryBlocks) { + ConfigurationBlock[] peerSummaryBlocks = FindBlocks (Params [14], configBlock); + foreach (ConfigurationBlock peerSummaryBlock in peerSummaryBlocks) { config.peerSummaryPages.Add (PeerSummaryPageConfiguration.Create ( - config, peersummaryBlock, + config, peerSummaryBlock, config.peerPages, config.peerGraphs)); } diff --git a/Ntp.Analyzer/Render/BootstrapMenuRender.cs b/Ntp.Analyzer/Render/BootstrapMenuRender.cs index 21e21a33..5489a13d 100644 --- a/Ntp.Analyzer/Render/BootstrapMenuRender.cs +++ b/Ntp.Analyzer/Render/BootstrapMenuRender.cs @@ -61,8 +61,8 @@ namespace Ntp.Analyzer.Render builder.AppendLine(@" "); builder.AppendLine(@" "); - HeadMenuItemConfiguration headItem = menu.MenuItems. - Single(i => i is HeadMenuItemConfiguration) as HeadMenuItemConfiguration; + HeadMenuItemConfiguration headItem = menu.MenuItems.SingleOrDefault( + i => i is HeadMenuItemConfiguration) as HeadMenuItemConfiguration; if (headItem != null) builder.AppendLine(this.AppendWithWebpath( diff --git a/Ntp.Analyzer/Render/Host/DefaultHostPageRender.cs b/Ntp.Analyzer/Render/Host/DefaultHostPageRender.cs index 8bfa435e..231b464f 100644 --- a/Ntp.Analyzer/Render/Host/DefaultHostPageRender.cs +++ b/Ntp.Analyzer/Render/Host/DefaultHostPageRender.cs @@ -100,18 +100,18 @@ namespace Ntp.Analyzer.Render.Host builder.Append (poolText); } - if (config.PeerSummeries.Pages.Count () != 0) { + if (config.PeerSummaries.Pages.Count () != 0) { builder.AppendLine ("

"); builder.Append ("Peer graphs are available with "); builder.Append (@""); - builder.Append (config.PeerSummeries.Pages.First ().Title); + builder.Append (config.PeerSummaries.Pages.First ().Title); builder.Append (@" and "); builder.Append (@""); - builder.Append (config.PeerSummeries.Pages.ToList () [1].Title); + builder.Append (config.PeerSummaries.Pages.ToList () [1].Title); builder.Append (@"."); } diff --git a/Ntp.Config/ConfigurationBase.cs b/Ntp.Config/ConfigurationBase.cs index 4a6eca45..ed424f3d 100644 --- a/Ntp.Config/ConfigurationBase.cs +++ b/Ntp.Config/ConfigurationBase.cs @@ -276,17 +276,18 @@ namespace Ntp.Config foreach (string line in lines) { - if (!line.Trim().StartsWith(option)) continue; + string currentLine = line.Trim (); + if (!currentLine.StartsWith(option)) continue; - int pos = line.IndexOf(' '); + int pos = currentLine.IndexOf(' '); if (pos == -1) continue; - if (line.Substring(0, pos).Trim() != option) + if (currentLine.Substring(0, pos).Trim() != option) continue; - string value = line.Substring(pos, line.Length - pos).Trim(); + string value = currentLine.Substring(pos, currentLine.Length - pos).Trim(); result.Add(value); } diff --git a/example/ntp.conf b/example/ntp.conf new file mode 100644 index 00000000..fe4e8056 --- /dev/null +++ b/example/ntp.conf @@ -0,0 +1,9 @@ +# Adding timeserver ID's to ntp.conf +# +# http://support.ntp.org/bin/view/Servers/PublicTimeServer000000 +# Take ID from URL and add the ID to end of each line +# +server 127.0.0.1 iburst minpoll 4 maxpoll 7 # 000001 +server 127.0.0.1 iburst minpoll 4 maxpoll 7 # 000002 + +... diff --git a/example/ntpa.web.conf b/example/ntpa.web.conf index 7c363608..a2195abc 100644 --- a/example/ntpa.web.conf +++ b/example/ntpa.web.conf @@ -1,5 +1,5 @@ ######################################################################## -# Configuration for NTP Analyzer Web Front # +# Configuration for small NTP Analyzer Web Front # ######################################################################## # Connection parameters to MySQL database instance. @@ -107,7 +107,7 @@ Server { } # Link to summary pages - Summeries { + Summaries { PeerSummaryPage ntp1-offset PeerSummaryPage ntp1-delay } @@ -329,7 +329,7 @@ Server { Graph offset60 } - Summeries { + Summaries { PeerSummaryPage example1-offset PeerSummaryPage example1-delay } diff --git a/example/ntpa.web.small.conf b/example/ntpa.web.small.conf new file mode 100644 index 00000000..1196a8fc --- /dev/null +++ b/example/ntpa.web.small.conf @@ -0,0 +1,125 @@ +######################################################################## +# Configuration for small NTP Analyzer Web Front # +######################################################################## + +# Connection parameters to MySQL database instance. +Database { + # Address of MySQL server + Host 127.0.0.1 + + # Name of database + Name ntpa + + # Database username + User ntpau + + # Password for the user + Pass xxxx +} + +Log { + # Levels: error, warn, notice, info, debug and trace + Severity info + File /var/log/ntpa/ntpa.web.log +} + +# Multiple server configurations are available +Server { + # Primary key in table 'host' + HostID 1 + + # Address queried by ntpq and ntpdc + HostAddress ntp1.example.net + + # The utility used to query ntpd. Use ntpdc for old hosts. + HostType ntpq + + # NTP configuration file from host + ConfigFile /usr/local/etc/ntpa/ntp1.conf + + # Base path for generated files + FilePath /usr/local/www/mypage + + # Base URL for generated files + WebPath / + + ########## Webpages ########## + + # Main page for a host + HostPage ntp1 { + # Indicate if generation should happen immediately after start up + InitialRun 1 + + # Minutes between generation of page + Frequency 5 + + PageTitle ntp1.example.net + + # Use either 'default' or 'bootstrap' + Template default + + # Set to 1 if this page should show a link to pool.ntp.org + PoolMember 0 + + # Links to graphs + Images { + # Index in graph destination array + LinkIndex 1 + + # Link to graphs in config file + Graph offset1 + Graph offset3 + } + + # Name and path to generated file. + Destinations { + File index.html + } + } + + HostGraph offset1 { + InitialRun 1 + Frequency 15 + Timespan 1 + + Title ntp1.example.net (1 day) + Width 1024 + Height 550 + + Stability 0 + GFrequency 1 + Jitter 1 + Offset 1 + + Destinations { + File ntp1.png + } + + Links { + Link ntp1.png + } + } + + HostGraph offset3 { + InitialRun 1 + Frequency 30 + Timespan 3 + + Title ntp1.example.net (3 days) + Width 1024 + Height 550 + + Stability 0 + GFrequency 1 + Jitter 1 + Offset 1 + + Destinations { + File ntp3.png + } + + Links { + Link ntp3.png + } + } +} diff --git a/script/ntpa.rc b/script/ntpa.rc index fe5cde26..31e5a245 100755 --- a/script/ntpa.rc +++ b/script/ntpa.rc @@ -13,7 +13,7 @@ # ntpa_tempdir (path): Set to "/tmp/" by default. # # Run additional instances of ntpa with: -# Use ln -s ntpa ntpa_graph +# ln -s ntpa ntpa_instance # . /etc/rc.subr diff --git a/sql/create_data.sql b/sql/create_data.sql index 0fcab845..ca37a1ee 100644 --- a/sql/create_data.sql +++ b/sql/create_data.sql @@ -1,8 +1,8 @@ USE ntpa; -INSERT INTO host (ip, name, orgId) VALUES ('90.184.222.114', 'ntp1.innolan.net', 900); +INSERT INTO host (ip, name, orgId) VALUES ('127.0.0.1', 'ntp1.example.net', 900); -INSERT INTO peer (ip, name, orgId) VALUES ('90.184.222.115', 'ntp2.innolan.net', 901); -INSERT INTO peer (ip, name, orgId) VALUES ('192.36.144.22', 'ntp1.sth.netnod.se', 250); +INSERT INTO peer (ip, name, orgId) VALUES ('127.0.0.2', 'ntp2.example.net', 901); +INSERT INTO peer (ip, name, orgId) VALUES ('127.0.0.2', 'ntp55.example.net', 250); COMMIT;